add a hack for Decap Attack
[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 static void do_counters(char *str)
26 {
27         static int counter_id = -1, counter;
28         char buff[1024];
29         char *s = str;
30
31         while ((s = strstr(s, "@@")))
32         {
33                 if (s[2] < '0' || s[2] > '9') { s++; continue; }
34
35                 if (counter_id != s[2] - '0') {
36                         counter_id = s[2] - '0';
37                         counter = 1;
38                 }
39                 snprintf(buff, sizeof(buff), "%i%s", counter++, s + 3);
40                 strcpy(s, buff);
41         }
42 }
43
44 static int my_fputs(char *s, FILE *stream)
45 {
46         char *p;
47
48         for (p = s + strlen(s) - 1; p >= s; p--)
49                 if (!isspace(*p))
50                         break;
51         p++;
52
53         /* use DOS endings for better viewer compatibility */
54         memcpy(p, "\r\n", 3);
55
56         return fputs(s, stream);
57 }
58
59 int main(int argc, char *argv[])
60 {
61         char path[256], path_file[256];
62         char buff[1024];
63         FILE *fi, *fo;
64         int skip_mode = 0, ifdef_level = 0, skip_level = 0, line = 0;
65         char *p;
66
67         if (argc < 3)
68         {
69                 printf("usage:\n%s <file_in> <file_out> [defines...]\n", argv[0]);
70                 return 1;
71         }
72
73         fi = fopen(argv[1], "r");
74         if (fi == NULL)
75         {
76                 printf("failed to open: %s\n", argv[1]);
77                 return 2;
78         }
79
80         fo = fopen(argv[2], "wb");
81         if (fo == NULL)
82         {
83                 printf("failed to open: %s\n", argv[2]);
84                 return 3;
85         }
86
87         snprintf(path, sizeof(path), "%s", argv[1]);
88         for (p = path + strlen(path) - 1; p > path; p--) {
89                 if (*p == '/' || *p == '\\') {
90                         p[1] = 0;
91                         break;
92                 }
93         }
94
95         for (++line; !feof(fi); line++)
96         {
97                 char *fgs;
98
99                 fgs = fgets(buff, sizeof(buff), fi);
100                 if (fgs == NULL) break;
101
102                 if (buff[0] == '#')
103                 {
104                         /* control char */
105                         if (strncmp(buff, "#ifdef ", 7) == 0)
106                         {
107                                 ifdef_level++;
108                                 if (!skip_mode && !check_defines((void *) &argv[3], argc-3, buff + 7))
109                                         skip_mode = 1, skip_level = ifdef_level;
110                         }
111                         else if (strncmp(buff, "#ifndef ", 8) == 0)
112                         {
113                                 ifdef_level++;
114                                 if (!skip_mode &&  check_defines((void *) &argv[3], argc-3, buff + 8))
115                                         skip_mode = 1, skip_level = ifdef_level;
116                         }
117                         else if (strncmp(buff, "#else", 5) == 0)
118                         {
119                                 if (!skip_mode || skip_level == ifdef_level)
120                                         skip_mode ^= 1, skip_level = ifdef_level;
121                         }
122                         else if (strncmp(buff, "#endif", 6) == 0)
123                         {
124                                 if (skip_level == ifdef_level)
125                                         skip_mode = 0;
126                                 ifdef_level--;
127                                 if (ifdef_level == 0) skip_mode = 0;
128                                 if (ifdef_level < 0)
129                                 {
130                                         printf("%i: warning: #endif without #ifdef, ignoring\n", line);
131                                         ifdef_level = 0;
132                                 }
133                         }
134                         else if (strncmp(buff, "#include ", 9) == 0)
135                         {
136                                 char *pe, *p = buff + 9;
137                                 FILE *ftmp;
138                                 if (skip_mode)
139                                         continue;
140                                 while (*p && (*p == ' ' || *p == '\"'))
141                                         p++;
142                                 for (pe = p + strlen(p) - 1; pe > p; pe--) {
143                                         if (isspace(*pe) || *pe == '\"') *pe = 0;
144                                         else break;
145                                 }
146                                 snprintf(path_file, sizeof(path_file), "%s%s", path, p);
147                                 ftmp = fopen(path_file, "r");
148                                 if (ftmp == NULL) {
149                                         printf("%i: error: failed to include \"%s\"\n", line, p);
150                                         return 1;
151                                 }
152                                 while (!feof(ftmp))
153                                 {
154                                         fgs = fgets(buff, sizeof(buff), ftmp);
155                                         if (fgs == NULL)
156                                                 break;
157                                         my_fputs(buff, fo);
158                                 }
159                                 fclose(ftmp);
160                                 continue;
161                         }
162
163                         /* skip line */
164                         continue;
165                 }
166                 if (!skip_mode)
167                 {
168                         do_counters(buff);
169                         my_fputs(buff, fo);
170                 }
171         }
172
173         fclose(fi);
174         fclose(fo);
175
176         return 0;
177 }
178