source: trunk/minix/commands/simple/ifdef.c@ 9

Last change on this file since 9 was 9, checked in by Mattia Monga, 13 years ago

Minix 3.1.2a

File size: 11.7 KB
Line 
1/* ifdef - remove #ifdefs Author: Warren Toomey */
2
3/* Copyright 1989 by Warren Toomey wkt@cs.adfa.oz.au[@uunet.uu.net]
4 *
5 * You may freely copy or distribute this code as long as this notice
6 * remains intact.
7 *
8 * You may modify this code, as long as this notice remains intact, and
9 * you add another notice indicating that the code has been modified.
10 *
11 * You may NOT sell this code or in any way profit from this code without
12 * prior agreement from the author.
13 */
14
15#include <sys/types.h>
16#include <string.h>
17#include <stdlib.h>
18#include <stdio.h>
19#include <unistd.h>
20
21/* Definition of structures and constants used in ifdef.c */
22
23/* Types of symbols */
24#define DEF 1 /* Symbol is defined */
25#define UNDEF 2 /* Symbol isn't defined */
26#define IGN 3 /* Ignore this symbol unless defined */
27
28/* Redef mode values */
29#define MUTABLE 1 /* Symbol can change defined <-> undefined */
30#define IMMUTABLE 2 /* Symbol can't change as above */
31
32/* Processing modes */
33#define NO 0 /* Don't process */
34#define YES 1 /* Process */
35
36/* Ignore (IGN), ignore but process */
37struct DEFINE {
38 char *symbol; /* SLL of defined symbols. The redef */
39 char type; /* field indicates if this symbol can */
40 char redef; /* change from defined <-> undefined. */
41 struct DEFINE *next; /* Type is DEF or UNDEF. */
42};
43
44/* Global variables & structures */
45FILE *zin; /* Input file for processing */
46struct DEFINE *defptr; /* Defined symbols SLL */
47struct DEFINE *defend; /* Ptr to last node in defptr */
48struct DEFINE *deftemp; /* Ptr to last found node */
49int line = 1; /* Current line number */
50int table = 0; /* Don't normally want a table */
51
52extern int optind;
53extern char *optarg;
54
55/* Prototypes. */
56_PROTOTYPE(int main, (int argc, char **argv));
57_PROTOTYPE(char fgetarg, (FILE *stream, char *cbuf));
58_PROTOTYPE(int find, (char *symd));
59_PROTOTYPE(void defit, (char *sym, int redef, int typed));
60_PROTOTYPE(void stop, (void));
61_PROTOTYPE(void gotoeoln, (void));
62_PROTOTYPE(void prteoln, (void));
63_PROTOTYPE(void printtable, (void));
64_PROTOTYPE(char getendif, (void));
65_PROTOTYPE(void gettable, (void));
66_PROTOTYPE(void parse, (void));
67_PROTOTYPE(void usage, (void));
68
69#ifdef __STDC__
70char fgetarg ( FILE *stream , char *cbuf )
71#else
72char fgetarg(stream, cbuf) /* Get next arg from file into cbuf, */
73FILE *stream; /* returning the character that */
74char *cbuf; /* terminated it. Cbuf returns 0 */
75#endif
76{ /* if no arg. EOF is returned if no */
77 int ch; /* args left in file. */
78 int i;
79
80 i = 0;
81 cbuf[i] = 0;
82
83 while (((ch = fgetc(stream)) == ' ') || (ch == '\t') || (ch == '\n'))
84 if (ch == '\n') return(ch); /* Bypass leading */
85 /* Whitespace */
86 if (feof(stream)) return(EOF);
87
88 cbuf[i++] = ch;
89
90 while (((ch = fgetc(stream)) != ' ') && (ch != '\t') && (ch != '\n'))
91 cbuf[i++] = ch; /* Get the argument */
92
93 cbuf[i] = 0;
94 return(ch);
95}
96
97
98#ifdef __STDC__
99int find ( char *sym )
100#else
101int find(sym)
102char *sym;
103#endif
104{ /* Return DEF if defined else UNDEF */
105
106 deftemp = defptr;
107 while (deftemp) { /* Search for the symbol */
108 if (!strcmp(deftemp->symbol, sym))
109 return(deftemp->type); /* Setting up the type */
110 deftemp = deftemp->next;
111 }
112 return(0);
113}
114
115
116
117#define Define(x,y) defit(x,y,DEF)
118#define Undefine(x,y) defit(x,y,UNDEF)
119#define Ignore(x,y) defit(x,y,IGN)
120
121#ifdef __STDC__
122void defit ( char *sym , int redef , int type )
123#else
124void defit(sym, redef, type) /* Add symbol to the define list */
125char *sym;
126char redef; /* Mode: MUTABLE etc */
127char type; /* Type: DEF, UNDEF, IGN */
128#endif
129{
130 struct DEFINE *temp;
131 char c;
132
133 c = find(sym); /* First try finding the symbol */
134 if (type == c) return; /* Return if already declared */
135 if (c) { /* We have to move if from DEF <-> UNDEF */
136 if (deftemp->redef == IMMUTABLE)
137 return;
138 else {
139 deftemp->type = type;
140 deftemp->redef = redef;
141 }
142 } else { /* We must create a struct & add it */
143 /* Malloc room for the struct */
144 if ((temp = (struct DEFINE *)malloc(sizeof(struct DEFINE))) == NULL) {
145 (void)fprintf(stderr, "ifdef: could not malloc\n");
146 exit(1);
147 }
148
149 /* Malloc room for symbol */
150 if ((temp->symbol = (char *)malloc(strlen(sym) + 1)) == NULL) {
151 (void)fprintf(stderr, "ifdef: could not malloc\n");
152 exit(1);
153 }
154 (void)strcpy(temp->symbol, sym); /* Copy symbol into struct */
155 temp->redef = redef; /* and set its redef mode too */
156 temp->type = type; /* as well as making it defined */
157
158
159 /* Now add to the SLL */
160 if (defptr == NULL) /* If first node set */
161 defptr = temp; /* the pointers to it */
162 else
163 defend->next = temp; /* else add it to the */
164 defend = temp; /* end of the list. */
165 }
166}
167
168
169
170#ifdef __STDC__
171void stop ( void )
172#else
173void stop()
174#endif
175{ /* Stop: Tidy up at EOF */
176 if (table) printtable();
177 (void)fclose(zin);
178 exit(0);
179}
180
181#define Goto { line++; if (ch!='\n') gotoeoln(); }
182#define Print { line++; if (ch!='\n') prteoln(); }
183
184#ifdef __STDC__
185void gotoeoln ( void )
186#else
187void gotoeoln() /* Go to the end of the line */
188#endif
189{
190 int ch;
191 while ((ch = fgetc(zin)) != '\n')
192 if (ch == EOF) stop();
193}
194
195
196#ifdef __STDC__
197void prteoln ( void )
198#else
199void prteoln() /* Print to the end of the line */
200#endif
201{
202 int ch;
203 while ((ch = fgetc(zin)) != '\n')
204 if (ch == EOF)
205 stop();
206 else
207 (void)putchar(ch);
208 (void)putchar('\n');
209}
210
211
212#ifdef __STDC__
213void printtable ( void )
214#else
215void printtable() /* Print the defines in the SLL */
216#endif
217{
218 struct DEFINE *temp;
219
220 (void)printf("Defined\n\n");
221
222 temp = defptr;
223 while (temp) {
224 if (temp->type == DEF) (void)printf("%s\n", temp->symbol);
225 temp = temp->next;
226 }
227
228 (void)printf("\n\nUndefined\n\n");
229
230 temp = defptr;
231 while (temp) {
232 if (temp->type == UNDEF) (void)printf("%s\n", temp->symbol);
233 temp = temp->next;
234 }
235}
236
237#ifdef __STDC__
238char getendif ( void )
239#else
240char getendif()
241#endif
242{ /* Find matching endif when ignoring */
243 char word[80]; /* Buffer for symbols */
244 int ch;
245 int skip; /* Number of skipped #ifdefs */
246
247 skip = 1;
248
249 while (1) {
250 /* Scan through the file looking for starting lines */
251 if ((ch = fgetc(zin)) == EOF)
252 stop(); /* Get first char on the line */
253 if (ch != '#') { /* If not a # ignore line */
254 (void)putchar(ch);
255 Print;
256 continue;
257 }
258 ch = fgetarg(zin, word); /* Get the word after the # */
259
260 if (!strcmp(word, "ifdef") || !strcmp(word, "ifndef")) skip++;
261 /* Keep track of ifdefs & */
262 if (!strcmp(word, "endif")) skip--; /* endifs */
263
264 (void)printf("#%s%c", word, ch); /* Print the line out */
265 Print;
266 if (!skip) return('\n'); /* If matching endif, return */
267 }
268}
269
270
271#ifdef __STDC__
272void gettable ( void )
273#else
274void gettable() /* Get & print a table of defines etc. */
275#endif
276{
277
278 char word[80]; /* Buffer for symbols */
279 int ch;
280
281 while (1) {
282 /* Scan through the file looking for starting lines */
283 if ((ch = fgetc(zin)) == EOF)
284 stop(); /* Get first char on the line */
285 if (ch != '#') { /* If not a # ignore line */
286 Goto;
287 continue;
288 }
289 ch = fgetarg(zin, word); /* Get the word after the # */
290
291 if (!strcmp(word, "define")) { /* Define: Define the */
292 ch = fgetarg(zin, word); /* symbol, and goto */
293 Define(word, MUTABLE); /* the end of line */
294 Goto;
295 continue;
296 }
297 if (!strcmp(word, "undef")) { /* Undef: Undefine the */
298 ch = fgetarg(zin, word); /* symbol, and goto */
299 Undefine(word, MUTABLE); /* the end of line */
300 Goto;
301 continue;
302 } /* Ifdef: */
303 if (!strcmp(word, "ifdef") || !strcmp(word, "ifndef")) {
304 ch = fgetarg(zin, word); /* Get the symbol */
305 if (find(word) != DEF)
306 Undefine(word, MUTABLE); /* undefine it */
307 Goto;
308 continue;
309 }
310 Goto; /* else ignore the line */
311 }
312}
313
314
315
316#ifdef __STDC__
317void parse ( void )
318#else
319void parse()
320#endif
321{ /* Parse & remove ifdefs from C source */
322 char word[80]; /* Buffer for symbols */
323 int ch;
324 int proc; /* Should we be processing this bit? */
325 int skip; /* Number of skipped #ifdefs */
326
327 proc = 1;
328 skip = 0;
329
330 while (1) {
331 /* Scan through the file looking for starting lines */
332 if ((ch = fgetc(zin)) == EOF)
333 stop(); /* Get first char on the line */
334 if (ch != '#')
335 if (proc) { /* If not # and we're processing */
336 (void)putchar(ch); /* then print the line */
337 Print;
338 continue;
339 } else {
340 Goto; /* else just skip the line */
341 continue;
342 }
343
344 ch = fgetarg(zin, word); /* Get the word after the # */
345
346 if (!strcmp(word, "define") && proc) { /* Define: Define the */
347 ch = fgetarg(zin, word); /* symbol, and goto */
348 Define(word, MUTABLE); /* the end of line */
349 (void)printf("#define %s%c", word, ch);
350 Print;
351 continue;
352 }
353 if (!strcmp(word, "undef") && proc) { /* Undef: Undefine the */
354 ch = fgetarg(zin, word); /* symbol, and goto */
355 Undefine(word, MUTABLE); /* the end of line */
356 (void)printf("#undef %s%c", word, ch);
357 Print;
358 continue;
359 }
360 if (!strcmp(word, "if")) { /* If: we cannot handle these */
361 if (!proc) /* at the moment, so just */
362 skip++; /* treat them as an ignored */
363 else { /* definition */
364 (void)printf("#%s%c",word,ch);
365 Print;
366 ch = getendif(); /* Get matching endif */
367 continue;
368 }
369 }
370 if (!strcmp(word, "ifdef")) { /* Ifdef: */
371 if (!proc) /* If not processing */
372 skip++; /* skip it */
373 else {
374 ch = fgetarg(zin, word); /* Get the symbol */
375 switch (find(word)) {
376 case DEF:
377 break;
378 case IGN:
379 (void)printf("#ifdef %s%c", word, ch);
380 Print;
381 ch = getendif(); /* Get matching endif */
382 break;
383 /* If symbol undefined */
384 default:
385 Undefine(word, MUTABLE); /* undefine it */
386 proc = 0; /* & stop processing */
387 }
388 }
389 Goto;
390 continue;
391 }
392 if (!strcmp(word, "ifndef")) {
393 /* Ifndef: */
394 if (!proc) /* If not processing */
395 skip++; /* skip the line */
396 else {
397 ch = fgetarg(zin, word); /* Get the symbol */
398 switch (find(word)) { /* If defined, stop */
399 case DEF:
400 proc = 0; /* processing */
401 break;
402 case IGN:
403 (void)printf("#ifdef %s%c", word, ch);
404 Print;
405 ch = getendif(); /* Get matching endif */
406 break;
407 }
408 }
409 Goto;
410 continue;
411 }
412 if (!strcmp(word, "else") && !skip) { /* Else: Flip processing */
413 proc = !proc;
414 Goto;
415 continue;
416 }
417 if (!strcmp(word, "endif")) { /* Endif: If no skipped */
418 /* ifdefs turn processing */
419 if (!skip) /* on, else decrement the */
420 proc = 1; /* number of skips */
421 else
422 skip--;
423 Goto;
424 continue;
425 }
426 /* The word fails all of the above tests, so if we're */
427 /* processing, print the line. */
428 if (proc) {
429 (void)printf("#%s%c", word, ch);
430 Print;
431 } else
432 Goto;
433 }
434}
435
436
437#ifdef __STDC__
438void usage ( void )
439#else
440void usage()
441#endif
442{
443 (void)fprintf(stderr, "Usage: ifdef [-t] [-Dsymbol] [-dsymbol] [-Usymbol] [-Isymbol] <file>\n");
444 exit(0);
445}
446
447
448#ifdef __STDC__
449int main(int argc , char *argv [])
450#else
451int main(argc, argv)
452int argc;
453char *argv[];
454#endif
455{
456 char sym[80]; /* Temp symbol storage */
457 int c;
458
459 if (argc == 1) usage(); /* Catch the curious user */
460 while ((c = getopt(argc, argv, "tD:d:U:I:")) != EOF) {
461 switch (c) {
462 case 't':
463 table = 1; /* Get the various options */
464 break;
465
466 case 'd':
467 (void)strcpy(sym, optarg);
468 Define(sym, MUTABLE);
469 break;
470
471 case 'D':
472 (void)strcpy(sym, optarg);
473 Define(sym, IMMUTABLE);
474 break;
475
476 case 'U':
477 (void)strcpy(sym, optarg);
478 Undefine(sym, IMMUTABLE);
479 break;
480
481 case 'I':
482 (void)strcpy(sym, optarg);
483 Ignore(sym, IMMUTABLE);
484 break;
485
486 default: usage();
487 }
488 }
489
490 zin = stdin; /* If a C file is named */
491 /* Open stdin with it */
492 if (*argv[argc - 1] != '-') {
493 (void)fclose(zin);
494 if ((zin = fopen(argv[argc - 1], "r")) == NULL) {
495 perror("ifdef");
496 exit(1);
497 }
498 }
499 if (table)
500 gettable(); /* Either generate a table or */
501 else
502 parse(); /* parse & replace with the file */
503 return(0);
504}
Note: See TracBrowser for help on using the repository browser.