ae2f_docs
main.c
1#include "./main.auto.h"
2
3#if NDEBUG
4#define DEBUG 0
5#else
6#define DEBUG 1
7#endif
8
9#include <stdio.h>
10#include <string.h>
11#include <assert.h>
12
13enum STATE_t {
14 STATE_GOOD,
15 STATE_EOF,
16 STATE_OPENING_UNKNOWN,
17 STATE_STACK_SMASHED,
18 STATE_ARGC_UNEXPECTED,
19 STATE_FOPEN_BAD,
20 STATE_UNEXPECTED
21};
22
23struct STACK_T {
24 FILE* m_inp;
25 char m_dir[DIRLEN + 1];
26 char m_current[DIRLEN + PATHLEN + 1];
27} STACK[STACKLEN + 1];
28size_t STACK_IDX = 0;
29size_t STACK_IDX_BUFF;
30
31#define STACK_LAST STACK[STACK_IDX]
32#define STACK_NXT STACK[STACK_IDX + 1]
33
34int Ch;
35int i;
36
37char inc_key[sizeof("#include")] = {0, };
38char inc_path_buff[PATHLEN + 1] = {0, };
39
40typedef unsigned char flag_t;
41struct FLAGS_t {
42 /** is a key of include */
43 flag_t m_Key : 1;
44 flag_t m_path_nclosed : 1;
45 flag_t m_ManyCmtOutMaybe : 1;
46 flag_t m_Key_Idx : 4;
47} FLAGS;
48
49char path_closing;
50char* path_cursor;
51
52int main(int argc, char** argv) {
53 assert(argc > 0);
54 if(argc < 1) {
55 return -STATE_ARGC_UNEXPECTED;
56 }
57 for(i = argc; i-- != 1;) {
58 if(strlen(argv[i]) > DIRLEN)
59 return -1;
60 }
61
62 STACK_LAST.m_inp = stdin;
63 STACK_LAST.m_dir[0] = 0;
64
65KEYGET:
66
67 Ch = 0;
68
69 memset(inc_key, 0, sizeof(inc_key));
70 inc_key[0] = '#';
71
72 assert(STACK_LAST.m_inp);
73
74 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF) {
75 switch(Ch) {
76 case '\'':
77 {
78 fputc('\'', stdout);
79
80 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF) {
81 fputc(Ch, stdout);
82 if(Ch == '\'') {
83 goto KEYGET;
84 }
85 }
86
87 } return -STATE_EOF;
88
89#if 1
90 case '"':
91 {
92 fputc('"', stdout);
93
94 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF) {
95 fputc(Ch, stdout);
96 if(Ch == '"') {
97 goto KEYGET;
98 }
99 }
100
101 } return -STATE_EOF;
102#endif
103
104 case '#':
105 {
106 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF
107 && (Ch == ' '
108 || Ch == '\t')
109 );
110 if(Ch == EOF) return -STATE_EOF;
111 inc_key[1] = Ch;
112
113 FLAGS.m_Key_Idx = 2;
114
115 if(Ch == 'i')
116 for(
117 ;
118 FLAGS.m_Key_Idx < sizeof("#include") - 1
119 && (inc_key[FLAGS.m_Key_Idx] = fgetc(STACK_LAST.m_inp))
120 == "#include"[FLAGS.m_Key_Idx];
121 FLAGS.m_Key_Idx++
122 );
123
124 if(FLAGS.m_Key_Idx == sizeof("#include") - 1) {
125 goto STACK_SUB;
126 } else {
127 fputs(inc_key, stdout);
128 }
129 }
130 goto KEYGET;
131
132 case '/':
133 switch(Ch = fgetc(STACK_LAST.m_inp)) {
134 case '/':
135 {
136#if DEBUG
137 fputs("//", stdout);
138#endif
139
140 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF && Ch != '\n' && Ch != '\r') {
141#if DEBUG
142 fputc(Ch, stdout);
143#endif
144 }
145
146 if(Ch == EOF) return -STATE_EOF;
147 puts("");
148 goto KEYGET;
149 }
150 default:
151 fputc('/', stdout);
152 fputc(Ch, stdout);
153 goto KEYGET;
154#if 1
155 case '*':
156#if DEBUG
157 fputs("/*", stdout);
158#endif
159
160 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF) {
161 if(Ch == '*') {
162 if((Ch = fgetc(STACK_LAST.m_inp)) == '/') {
163#if DEBUG
164 fputs("*/", stdout);
165#endif
166 goto KEYGET;
167 }
168#if DEBUG
169 fputc('*', stdout);
170 fputc(Ch, stdout);
171#endif
172 }
173#if DEBUG
174 fputc(Ch, stdout);
175#endif
176 }
177
178 goto KEYGET;
179#endif
180 } return -STATE_UNEXPECTED;
181
182 default:
183 {
184 fputc(Ch, stdout);
185 goto KEYGET;
186 }
187 }
188 }
189
190 goto STACK_ADD;
191STACK_SUB:
192 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF && (Ch == ' ' || Ch == '\t'));
193 switch(Ch) {
194 case EOF:
195#if DEBUG
196 puts("/** Unknown EOF bug has appeared. */ \\");
197#endif
198 return -STATE_EOF;
199 case '\"': path_closing = '\"'; break;
200 case '<': path_closing = '>'; break;
201 default:
202 fputc(Ch, stdout);
203 goto KEYGET;
204 }
205
206#if DEBUG
207 puts("/** include detected */ \\");
208#endif
209
210 path_cursor = inc_path_buff;
211 FLAGS.m_path_nclosed = 1;
212#if DEBUG
213 puts("/** Path cursor */ \\");
214#endif
215 if(STACK_IDX == STACKLEN) {
216#if DEBUG
217 puts("/** Stack has smashed. shame. */ \\");
218 fputs("/*", stdout);
219#endif
220
221 while((Ch = fgetc(STACK_LAST.m_inp)) != EOF && Ch != '\n' && Ch != '\r') {
222#if DEBUG
223 fputc(Ch, stdout);
224#endif
225 }
226
227#if DEBUG
228 puts("*/ \\");
229#endif
230
231
233
234
235 goto KEYGET;
236#endif
237 return -STATE_STACK_SMASHED;
238 }
239
240 while(path_cursor - inc_path_buff < PATHLEN) {
241 if((Ch = fgetc(STACK_LAST.m_inp)) == EOF)
242 return -STATE_EOF;
243 if(Ch == path_closing) {
244 *path_cursor = 0;
245 FLAGS.m_path_nclosed = 0;
246 break;
247 }
248 *path_cursor = Ch;
249 path_cursor++;
250 }
251 if(FLAGS.m_path_nclosed) return -STATE_OPENING_UNKNOWN;
252
253 strcpy(STACK_NXT.m_current, STACK_LAST.m_dir);
254 strcat(STACK_NXT.m_current, inc_path_buff);
255
256#if DEBUG
257 fputs("/* Opening: ", stdout);
258 fputs(STACK_NXT.m_current, stdout);
259 fputs(" */ \\\n", stdout);
260#endif
261 STACK_NXT.m_inp = fopen(STACK_NXT.m_current, "r");
262
263#if DEBUG
264 printf("/** first fp: %p */ \\\n", STACK_NXT.m_inp);
265#endif
266
267
268 for(i = argc; !STACK_NXT.m_inp && i-- != 1;) {
269 strcpy( STACK_NXT.m_current, argv[i]);
270 strcat(STACK_NXT.m_current, inc_path_buff);
271
272#if DEBUG
273 fputs("/* Opening: ", stdout);
274 fputs(STACK_NXT.m_current, stdout);
275 fputs(" */ \\\n", stdout);
276#endif
277 STACK_NXT.m_inp = fopen(STACK_NXT.m_current, "r");
278 }
279 if(!STACK_NXT.m_inp)
281 {
282#if DEBUG
283 puts("/** Failed but ignoring it. */ \\");
284#endif
286 fputs("#include <", stdout);
287 fputs(inc_path_buff, stdout);
288 puts(">");
289#endif
290
291 goto KEYGET;
292 }
293#else
294 {
295#if DEBUG
296 puts("/** Failed. */ \\");
297#endif
298 return -STATE_FOPEN_BAD;
299 }
300#endif
301
302 for(i = strlen(STACK_NXT.m_current); i--;) {
303 if(STACK_NXT.m_current[i] == '/') {
304 Ch = STACK_NXT.m_current[i + 1];
305 STACK_NXT.m_current[i + 1] = 0;
306 strcpy(STACK_NXT.m_dir, STACK_NXT.m_current);
307 STACK_NXT.m_current[i + 1] = Ch;
308
309#if DEBUG
310 printf("/** Current %s */ \\\n", STACK_NXT.m_current);
311 printf("/** Dir %s */ \\\n", STACK_NXT.m_dir);
312#endif
313 break;
314 }
315 }
316
317
319#if DEBUG
320 puts("/** Found something. Now let's validate. */ \\");
321#endif
322
323 for(STACK_IDX_BUFF = STACK_IDX; STACK_IDX_BUFF--;) {
324 if(!strcmp(STACK[STACK_IDX_BUFF].m_current, STACK_NXT.m_current)) {
325#if DEBUG
326 puts("/** It's repeating himself for some reason. */ \\");
327
328#endif
329 goto KEYGET;
330 }
331 }
332
333#if DEBUG
334 puts("/** It's not repeating */ \\");
335#endif
336#endif
337
338
339#if DEBUG
340 fputs(
341 "/******************** */\\\n"
342 "/* Now the path will be: */ \\\n /*"
343 , stdout
344 );
345
346 fputs(STACK_NXT.m_current, stdout);
347
348 puts(" */ \\");
349#endif
350 ++STACK_IDX;
351 goto KEYGET;
352
353STACK_ADD:
354 if(STACK_IDX) {
355 fclose(STACK_LAST.m_inp);
356 --STACK_IDX;
357
358#if DEBUG
359 puts("/** One eof gracefully */ \\");
360#endif
361
362 goto KEYGET;
363 }
364
365#if DEBUG
366 puts("/** All done. */");
367#endif
368
369 return -STATE_GOOD;
370}
#define INC_IGNORE_NFOUND
Definition main.auto.h:6
#define PATHLEN
Definition main.auto.h:4
#define INC_REPT_CHECK
Definition main.auto.h:8
#define NDEBUG
Definition main.auto.h:10
#define DIRLEN
Definition main.auto.h:3
#define INC_IGNORE_SMASH
Definition main.auto.h:7
#define INC_LEAVE_NFOUND
Definition main.auto.h:9
#define STACKLEN
Definition main.auto.h:5
#define DEBUG
Definition main.c:4
#define STACK_NXT
Definition main.c:32
#define STACK_LAST
Definition main.c:31
Definition main.c:41
flag_t m_Key
Definition main.c:43
Definition main.c:23