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