Remove building with NOCRYPTO option
[minix.git] / minix / commands / ifdef / ifdef.c
blob1c39d21a959da9ec1386af89d1c32f9db434a13e
1 /* ifdef - remove #ifdefs Author: Warren Toomey */
3 /* Copyright 1989 by Warren Toomey wkt@cs.adfa.oz.au[@uunet.uu.net]
5 * You may freely copy or distribute this code as long as this notice
6 * remains intact.
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.
11 * You may NOT sell this code or in any way profit from this code without
12 * prior agreement from the author.
15 #include <sys/types.h>
16 #include <string.h>
17 #include <stdlib.h>
18 #include <stdio.h>
19 #include <unistd.h>
21 /* Definition of structures and constants used in ifdef.c */
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 */
28 /* Redef mode values */
29 #define MUTABLE 1 /* Symbol can change defined <-> undefined */
30 #define IMMUTABLE 2 /* Symbol can't change as above */
32 /* Processing modes */
33 #define NO 0 /* Don't process */
34 #define YES 1 /* Process */
36 /* Ignore (IGN), ignore but process */
37 struct 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. */
44 /* Global variables & structures */
45 FILE *zin; /* Input file for processing */
46 struct DEFINE *defptr; /* Defined symbols SLL */
47 struct DEFINE *defend; /* Ptr to last node in defptr */
48 struct DEFINE *deftemp; /* Ptr to last found node */
49 int line = 1; /* Current line number */
50 int table = 0; /* Don't normally want a table */
52 extern int optind;
53 extern char *optarg;
55 /* Prototypes. */
56 int main(int argc, char **argv);
57 char fgetarg(FILE *stream, char *cbuf);
58 int find(char *symd);
59 void defit(char *sym, int redef, int typed);
60 void stop(void);
61 void gotoeoln(void);
62 void prteoln(void);
63 void printtable(void);
64 char getendif(void);
65 void gettable(void);
66 void parse(void);
67 void usage(void);
69 #ifdef __STDC__
70 char fgetarg ( FILE *stream , char *cbuf )
71 #else
72 char fgetarg(stream, cbuf) /* Get next arg from file into cbuf, */
73 FILE *stream; /* returning the character that */
74 char *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;
80 i = 0;
81 cbuf[i] = 0;
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);
88 cbuf[i++] = ch;
90 while (((ch = fgetc(stream)) != ' ') && (ch != '\t') && (ch != '\n'))
91 cbuf[i++] = ch; /* Get the argument */
93 cbuf[i] = 0;
94 return(ch);
98 #ifdef __STDC__
99 int find ( char *sym )
100 #else
101 int find(sym)
102 char *sym;
103 #endif
104 { /* Return DEF if defined else UNDEF */
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;
112 return(0);
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)
121 #ifdef __STDC__
122 void defit ( char *sym , int redef , int type )
123 #else
124 void defit(sym, redef, type) /* Add symbol to the define list */
125 char *sym;
126 char redef; /* Mode: MUTABLE etc */
127 char type; /* Type: DEF, UNDEF, IGN */
128 #endif
130 struct DEFINE *temp;
131 char c;
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;
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);
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);
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 */
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. */
170 #ifdef __STDC__
171 void stop ( void )
172 #else
173 void stop()
174 #endif
175 { /* Stop: Tidy up at EOF */
176 if (table) printtable();
177 (void)fclose(zin);
178 exit(0);
181 #define Goto { line++; if (ch!='\n') gotoeoln(); }
182 #define Print { line++; if (ch!='\n') prteoln(); }
184 #ifdef __STDC__
185 void gotoeoln ( void )
186 #else
187 void gotoeoln() /* Go to the end of the line */
188 #endif
190 int ch;
191 while ((ch = fgetc(zin)) != '\n')
192 if (ch == EOF) stop();
196 #ifdef __STDC__
197 void prteoln ( void )
198 #else
199 void prteoln() /* Print to the end of the line */
200 #endif
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');
212 #ifdef __STDC__
213 void printtable ( void )
214 #else
215 void printtable() /* Print the defines in the SLL */
216 #endif
218 struct DEFINE *temp;
220 (void)printf("Defined\n\n");
222 temp = defptr;
223 while (temp) {
224 if (temp->type == DEF) (void)printf("%s\n", temp->symbol);
225 temp = temp->next;
228 (void)printf("\n\nUndefined\n\n");
230 temp = defptr;
231 while (temp) {
232 if (temp->type == UNDEF) (void)printf("%s\n", temp->symbol);
233 temp = temp->next;
237 #ifdef __STDC__
238 char getendif ( void )
239 #else
240 char 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 */
247 skip = 1;
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;
258 ch = fgetarg(zin, word); /* Get the word after the # */
260 if (!strcmp(word, "ifdef") || !strcmp(word, "ifndef")) skip++;
261 /* Keep track of ifdefs & */
262 if (!strcmp(word, "endif")) skip--; /* endifs */
264 (void)printf("#%s%c", word, ch); /* Print the line out */
265 Print;
266 if (!skip) return('\n'); /* If matching endif, return */
271 #ifdef __STDC__
272 void gettable ( void )
273 #else
274 void gettable() /* Get & print a table of defines etc. */
275 #endif
278 char word[80]; /* Buffer for symbols */
279 int ch;
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;
289 ch = fgetarg(zin, word); /* Get the word after the # */
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;
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;
310 Goto; /* else ignore the line */
316 #ifdef __STDC__
317 void parse ( void )
318 #else
319 void 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 */
327 proc = 1;
328 skip = 0;
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;
345 ch = fgetarg(zin, word); /* Get the word after the # */
347 if (!strcmp(word, "define") && proc) { /* Define: Define the */
348 ch = fgetarg(zin, word); /* symbol, and goto */
349 Define(word, MUTABLE); /* the end of line */
350 (void)printf("#define %s%c", word, ch);
351 Print;
352 continue;
354 if (!strcmp(word, "undef") && proc) { /* Undef: Undefine the */
355 ch = fgetarg(zin, word); /* symbol, and goto */
356 Undefine(word, MUTABLE); /* the end of line */
357 (void)printf("#undef %s%c", word, ch);
358 Print;
359 continue;
361 if (!strcmp(word, "if")) { /* If: we cannot handle these */
362 if (!proc) /* at the moment, so just */
363 skip++; /* treat them as an ignored */
364 else { /* definition */
365 (void)printf("#%s%c",word,ch);
366 Print;
367 ch = getendif(); /* Get matching endif */
368 continue;
371 if (!strcmp(word, "ifdef")) { /* Ifdef: */
372 if (!proc) /* If not processing */
373 skip++; /* skip it */
374 else {
375 ch = fgetarg(zin, word); /* Get the symbol */
376 switch (find(word)) {
377 case DEF:
378 break;
379 case IGN:
380 (void)printf("#ifdef %s%c", word, ch);
381 Print;
382 ch = getendif(); /* Get matching endif */
383 break;
384 /* If symbol undefined */
385 default:
386 Undefine(word, MUTABLE); /* undefine it */
387 proc = 0; /* & stop processing */
390 Goto;
391 continue;
393 if (!strcmp(word, "ifndef")) {
394 /* Ifndef: */
395 if (!proc) /* If not processing */
396 skip++; /* skip the line */
397 else {
398 ch = fgetarg(zin, word); /* Get the symbol */
399 switch (find(word)) { /* If defined, stop */
400 case DEF:
401 proc = 0; /* processing */
402 break;
403 case IGN:
404 (void)printf("#ifdef %s%c", word, ch);
405 Print;
406 ch = getendif(); /* Get matching endif */
407 break;
410 Goto;
411 continue;
413 if (!strcmp(word, "else") && !skip) { /* Else: Flip processing */
414 proc = !proc;
415 Goto;
416 continue;
418 if (!strcmp(word, "endif")) { /* Endif: If no skipped */
419 /* ifdefs turn processing */
420 if (!skip) /* on, else decrement the */
421 proc = 1; /* number of skips */
422 else
423 skip--;
424 Goto;
425 continue;
427 /* The word fails all of the above tests, so if we're */
428 /* processing, print the line. */
429 if (proc) {
430 (void)printf("#%s%c", word, ch);
431 Print;
432 } else
433 Goto;
438 #ifdef __STDC__
439 void usage ( void )
440 #else
441 void usage()
442 #endif
444 (void)fprintf(stderr, "Usage: ifdef [-t] [-Dsymbol] [-dsymbol] [-Usymbol] [-Isymbol] <file>\n");
445 exit(0);
449 #ifdef __STDC__
450 int main(int argc , char *argv [])
451 #else
452 int main(argc, argv)
453 int argc;
454 char *argv[];
455 #endif
457 char sym[80]; /* Temp symbol storage */
458 int c;
460 if (argc == 1) usage(); /* Catch the curious user */
461 while ((c = getopt(argc, argv, "tD:d:U:I:")) != EOF) {
462 switch (c) {
463 case 't':
464 table = 1; /* Get the various options */
465 break;
467 case 'd':
468 (void)strcpy(sym, optarg);
469 Define(sym, MUTABLE);
470 break;
472 case 'D':
473 (void)strcpy(sym, optarg);
474 Define(sym, IMMUTABLE);
475 break;
477 case 'U':
478 (void)strcpy(sym, optarg);
479 Undefine(sym, IMMUTABLE);
480 break;
482 case 'I':
483 (void)strcpy(sym, optarg);
484 Ignore(sym, IMMUTABLE);
485 break;
487 default: usage();
491 zin = stdin; /* If a C file is named */
492 /* Open stdin with it */
493 if (*argv[argc - 1] != '-') {
494 (void)fclose(zin);
495 if ((zin = fopen(argv[argc - 1], "r")) == NULL) {
496 perror("ifdef");
497 exit(1);
500 if (table)
501 gettable(); /* Either generate a table or */
502 else
503 parse(); /* parse & replace with the file */
504 return(0);