#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; }