90354c2723bfde29b264a1c1346949c90542437d
[picodrive.git] / tools / textfilter.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <ctype.h>
4
5
6 static int check_defines(const char **defs, int defcount, char *tdef)
7 {
8         int i, len;
9
10         while (isspace(*tdef)) tdef++;
11         len = strlen(tdef);
12         for (i = 0; i < len; i++)
13                 if (tdef[i] == ' ' || tdef[i] == '\r' || tdef[i] == '\n') break;
14         tdef[i] = 0;
15
16         for (i = 0; i < defcount; i++)
17         {
18                 if (strcmp(defs[i], tdef) == 0)
19                         return 1;
20         }
21
22         return 0;
23 }
24
25
26 static void do_counters(char *str)
27 {
28         static int counter_id = -1, counter;
29         char buff[1024];
30         char *s = str;
31
32         while ((s = strstr(s, "@@")))
33         {
34                 if (s[2] < '0' || s[2] > '9') { s++; continue; }
35
36                 if (counter_id != s[2] - '0') {
37                         counter_id = s[2] - '0';
38                         counter = 1;
39                 }
40                 snprintf(buff, sizeof(buff), "%i%s", counter++, s + 3);
41                 strcpy(s, buff);
42         }
43 }
44
45
46 int main(int argc, char *argv[])
47 {
48         char buff[1024];
49         FILE *fi, *fo;
50         int skip_mode = 0, ifdef_level = 0, skip_level = 0, line = 0;
51
52         if (argc < 3)
53         {
54                 printf("usage:\n%s <file_in> <file_out> [defines...]\n", argv[0]);
55                 return 1;
56         }
57
58         fi = fopen(argv[1], "r");
59         if (fi == NULL)
60         {
61                 printf("failed to open: %s\n", argv[1]);
62                 return 2;
63         }
64
65         fo = fopen(argv[2], "w");
66         if (fo == NULL)
67         {
68                 printf("failed to open: %s\n", argv[2]);
69                 return 3;
70         }
71
72         for (++line; !feof(fi); line++)
73         {
74                 char *fgs;
75
76                 fgs = fgets(buff, sizeof(buff), fi);
77                 if (fgs == NULL) break;
78
79                 if (buff[0] == '#')
80                 {
81                         /* control char */
82                         if (strncmp(buff, "#ifdef ", 7) == 0)
83                         {
84                                 ifdef_level++;
85                                 if (!skip_mode && !check_defines((void *) &argv[3], argc-3, buff + 7))
86                                         skip_mode = 1, skip_level = ifdef_level;
87                         }
88                         else if (strncmp(buff, "#ifndef ", 8) == 0)
89                         {
90                                 ifdef_level++;
91                                 if (!skip_mode &&  check_defines((void *) &argv[3], argc-3, buff + 8))
92                                         skip_mode = 1, skip_level = ifdef_level;
93                         }
94                         else if (strncmp(buff, "#else", 5) == 0)
95                         {
96                                 if (!skip_mode || skip_level == ifdef_level)
97                                         skip_mode ^= 1, skip_level = ifdef_level;
98                         }
99                         else if (strncmp(buff, "#endif", 6) == 0)
100                         {
101                                 if (skip_level == ifdef_level)
102                                         skip_mode = 0;
103                                 ifdef_level--;
104                                 if (ifdef_level == 0) skip_mode = 0;
105                                 if (ifdef_level < 0)
106                                 {
107                                         printf("%i: warning: #endif without #ifdef, ignoring\n", line);
108                                         ifdef_level = 0;
109                                 }
110                         }
111                         else if (strncmp(buff, "#include ", 9) == 0)
112                         {
113                                 char *pe, *p = buff + 9;
114                                 FILE *ftmp;
115                                 if (skip_mode) continue;
116                                 while (*p && (*p == ' ' || *p == '\"')) p++;
117                                 for (pe = p + strlen(p) - 1; pe > p; pe--)
118                                         if (isspace(*pe) || *pe == '\"') *pe = 0;
119                                         else break;
120                                 ftmp = fopen(p, "r");
121                                 if (ftmp == NULL) {
122                                         printf("%i: error: failed to include \"%s\"\n", line, p);
123                                         return 1;
124                                 }
125                                 while (!feof(ftmp))
126                                 {
127                                         fgs = fgets(buff, sizeof(buff), ftmp);
128                                         if (fgs == NULL) break;
129                                         fputs(buff, fo);
130                                 }
131                                 fclose(ftmp);
132                                 continue;
133                         }
134
135                         /* skip line */
136                         continue;
137                 }
138                 if (!skip_mode)
139                 {
140                         do_counters(buff);
141                         fputs(buff, fo);
142                 }
143         }
144
145         fclose(fi);
146         fclose(fo);
147
148         return 0;
149 }
150