aboutsummaryrefslogtreecommitdiff
path: root/csv_table_gen.c
diff options
context:
space:
mode:
Diffstat (limited to 'csv_table_gen.c')
-rw-r--r--csv_table_gen.c125
1 files changed, 125 insertions, 0 deletions
diff --git a/csv_table_gen.c b/csv_table_gen.c
new file mode 100644
index 0000000..ae80b78
--- /dev/null
+++ b/csv_table_gen.c
@@ -0,0 +1,125 @@
+#include <dirent.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define EXT ".csv"
+#define EXT_LEN strlen(".csv")
+#define CSV_PATH "csv"
+#define OUT_PATH "analyzer/" CSV_PATH
+
+#define BUFFER_SIZE 256
+#define MAX_ARR_SIZE 4096
+
+// read values from input csv and save them to buffers
+// returns max_index of the array
+int read_csv(char *path, char *from, char *to, char from_to_array[][BUFFER_SIZE]) {
+ FILE *fp = fopen(path, "r");
+
+ // read field names
+ fscanf(fp, "%[^,],%[^\n]", from, to);
+
+ // read values
+ size_t max_index = 0;
+ size_t val1;
+ char val2[BUFFER_SIZE];
+ while (fscanf(fp, "%zu,%[^\n]", &val1, val2) == 2) {
+ strcpy(from_to_array[val1], val2);
+ if (val1 > max_index)
+ max_index = val1;
+ }
+
+ fclose(fp);
+
+ return max_index;
+}
+
+// create output .h file
+void create_h(char *path, char *from, char *to) {
+ FILE *fp = fopen(path, "w");
+
+ // write comments and function prototype
+ fprintf(fp, "// %s\n", strstr(path, CSV_PATH));
+ fprintf(fp, "// translate %s to %s - generated from csv\n\n", from, to);
+ fprintf(fp, "// get %s from %s\n", to, from);
+ fprintf(fp, "// params:\n");
+ fprintf(fp, "// - %s - %s to translate from\n", from, from);
+ fprintf(fp, "// returns:\n");
+ fprintf(fp, "// %s corresponding to %s\n", to, from);
+ fprintf(fp, "extern const char *get_%s_from_%s(int %s);", to, from, from);
+
+ fclose(fp);
+}
+
+// create output .c file
+void create_c(char *path, char *h_path, char *from, char *to, char from_to_array[][BUFFER_SIZE], size_t max_index) {
+ FILE *fp = fopen(path, "w");
+
+ char arr_name[BUFFER_SIZE], arr_len_name[BUFFER_SIZE];
+ sprintf(arr_name, "%s_to_%s", from, to);
+ sprintf(arr_len_name, "%s_to_%s_len", from, to);
+
+ // write includes and the beginning of array
+ fprintf(fp, "#include \"%s\"\n\n", strstr(h_path, CSV_PATH));
+ fprintf(fp, "#include <stdio.h>\n\n");
+ fprintf(fp, "static const char *%s[] = {\n", arr_name);
+
+ // write values
+ for (size_t i = 0; i <= max_index; i++) {
+ if (strlen(from_to_array[i]) > 0)
+ fprintf(fp, " \"%s\",\n", from_to_array[i]);
+ else
+ fprintf(fp, " \"%zu\",\n", i);
+ }
+
+ // write the end of array and len
+ fprintf(fp, "};\n");
+ fprintf(fp, "int %s = %zu;\n\n", arr_len_name, max_index + 1);
+
+ // write the getter
+ fprintf(fp, "const char *get_%s_from_%s(int %s) {\n", to, from, from);
+ fprintf(fp, " if (%s >= 0 && %s < %s)\n", from, from, arr_len_name);
+ fprintf(fp, " return %s[%s];\n", arr_name, from);
+ fprintf(fp, " fprintf(stderr, \"%s = %%d is outside of table range [0; %%d]\\n\", %s, %s - 1);\n", from, from, arr_len_name);
+ fprintf(fp, " return \"null\";\n");
+ fprintf(fp, "}");
+
+ fclose(fp);
+}
+
+void create_table(char *file_name) {
+ // read from input file
+ char input_path[BUFFER_SIZE];
+ sprintf(input_path, "%s/%s", CSV_PATH, file_name);
+ char from[BUFFER_SIZE], to[BUFFER_SIZE];
+ char from_to_array[MAX_ARR_SIZE][BUFFER_SIZE] = {0};
+ size_t max_index = read_csv(input_path, from, to, from_to_array);
+
+ // create output .h file
+ char h_path[BUFFER_SIZE];
+ sprintf(h_path, "%s/%s_to_%s.h", OUT_PATH, from, to);
+ create_h(h_path, from, to);
+
+ // create output .c file
+ char c_path[BUFFER_SIZE];
+ sprintf(c_path, "%s/%s_to_%s.c", OUT_PATH, from, to);
+ create_c(c_path, h_path, from, to, from_to_array, max_index);
+}
+
+int main() {
+ // make directory for output files
+ mkdir(OUT_PATH, 0755);
+
+ DIR *csv_dir = opendir(CSV_PATH);
+ struct dirent *entry;
+ while ((entry = readdir(csv_dir))) {
+ char *file_name = entry->d_name;
+ size_t file_name_len = strlen(file_name);
+ // create lookup tables for each *.csv file
+ if (file_name_len > EXT_LEN && !strcmp(file_name + file_name_len - EXT_LEN, EXT))
+ create_table(entry->d_name);
+ }
+ closedir(csv_dir);
+
+ return 0;
+}