summaryrefslogblamecommitdiffstats
path: root/src/tt.c
blob: 01c9614fffd9365a925a88cda207dfa2240e76dc (plain) (tree)



























































































































                                                                                                                           
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>

#define DEFAULT_DELIMITER "$"

void compile_c_code(char * s) {
  printf("%.*s\n", (int) strlen(s), s);
}

void compile_byte_array(char * s) {
  printf("write(OUT, \"");
  uint64_t slen = strlen(s);
  for (uint64_t i = 0; i < slen; ++i) {
    printf("\\x%02x", s[i]);
  }
  printf("\", %lu);\n", strlen(s));
}

char *read_file_to_string(const char *filename) {
  FILE *file = fopen(filename, "rb");
  if (!file) {
    perror("Error opening file");
    return NULL;
  }

  fseek(file, 0, SEEK_END);
  long file_size = ftell(file);
  rewind(file);

  char *buffer = (char *)malloc(file_size + 1);
  if (!buffer) {
    perror("Memory allocation failed");
    fclose(file);
    return NULL;
  }

  fread(buffer, 1, file_size, file);
  buffer[file_size] = '\0';

  fclose(file);
  return buffer;
}

#define CHARSET_SIZE 128  // Covering standard ASCII characters

int print_good_delimiters(const char * s) {
    int seen[CHARSET_SIZE] = {0};  // Array to track seen characters

    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++) {
      if (s[i] >= 0 && (int)s[i] < CHARSET_SIZE) {
        seen[(int)s[i]] = 1;
      }
    }

    // Define the characters to check: A-Za-z0-9 and common symbols
    char *valid_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*()-_=+[{]}\\|;:'\",<.>/?`~";

    int flag = 0;
    printf("Good options for delimiters:\n");
    for (int i = 0; valid_chars[i] != '\0'; i++) {
        if (!seen[(unsigned char)valid_chars[i]]) {
          putchar(valid_chars[i]);
          flag++;
        }
    }
    if (!flag) {
      printf(" :( none found, compromises shall be made");
    }
    putchar('\n');

    return 0;
}


int main(int argc, char *argv[])
{
  if (argc < 2) {
    fprintf(stderr, "Usage: %s <template> [delim|-d] [> OUTPUT]\n", argv[0]);
    return 1;
  }

  const char *filepath = argv[1];
  char *template = read_file_to_string(filepath);
  if (!template) return 1;

  if (argc > 2 && 0 == strcmp(argv[2], "-d")) {
    print_good_delimiters(template);
    exit(0);
  }

  char delim[1024] = DEFAULT_DELIMITER;
  if (argc > 2) {
    strcpy(delim, argv[2]);
  }


  int c_code_mode = 1;
  for (int i = 0; delim[i] != '\0'; i++) {
    if (template[i] != delim[i]) {
      c_code_mode = 0;
      break;
    }
  }

  char *token = strtok(template, delim);
  while (token) {
    if (c_code_mode) {
      compile_c_code(token);
    } else {
      compile_byte_array(token);
    }
    c_code_mode = !c_code_mode;

    token = strtok(NULL, delim);
  }

  free(template);
  return 0;
}