1.80 readme and filter for it
[picodrive.git] / tools / textfilter.c
... / ...
CommitLineData
1#include <stdio.h>
2#include <string.h>
3#include <ctype.h>
4
5
6static 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
26static 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
46int 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