1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
#include <dirent.h>
#include <limits.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[PATH_MAX];
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[PATH_MAX];
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[PATH_MAX];
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;
}
|