00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <sys/types.h>
00016 #include <string.h>
00017 #include <stdlib.h>
00018 #include <stdio.h>
00019 #include <unistd.h>
00020
00021
00022
00023
00024 #define DEF 1
00025 #define UNDEF 2
00026 #define IGN 3
00027
00028
00029 #define MUTABLE 1
00030 #define IMMUTABLE 2
00031
00032
00033 #define NO 0
00034 #define YES 1
00035
00036
00037 struct DEFINE {
00038 char *symbol;
00039 char type;
00040 char redef;
00041 struct DEFINE *next;
00042 };
00043
00044
00045 FILE *zin;
00046 struct DEFINE *defptr;
00047 struct DEFINE *defend;
00048 struct DEFINE *deftemp;
00049 int line = 1;
00050 int table = 0;
00051
00052 extern int optind;
00053 extern char *optarg;
00054
00055
00056 _PROTOTYPE(int main, (int argc, char **argv));
00057 _PROTOTYPE(char fgetarg, (FILE *stream, char *cbuf));
00058 _PROTOTYPE(int find, (char *symd));
00059 _PROTOTYPE(void defit, (char *sym, int redef, int typed));
00060 _PROTOTYPE(void stop, (void));
00061 _PROTOTYPE(void gotoeoln, (void));
00062 _PROTOTYPE(void prteoln, (void));
00063 _PROTOTYPE(void printtable, (void));
00064 _PROTOTYPE(char getendif, (void));
00065 _PROTOTYPE(void gettable, (void));
00066 _PROTOTYPE(void parse, (void));
00067 _PROTOTYPE(void usage, (void));
00068
00069 #ifdef __STDC__
00070 char fgetarg ( FILE *stream , char *cbuf )
00071 #else
00072 char fgetarg(stream, cbuf)
00073 FILE *stream;
00074 char *cbuf;
00075 #endif
00076 {
00077 int ch;
00078 int i;
00079
00080 i = 0;
00081 cbuf[i] = 0;
00082
00083 while (((ch = fgetc(stream)) == ' ') || (ch == '\t') || (ch == '\n'))
00084 if (ch == '\n') return(ch);
00085
00086 if (feof(stream)) return(EOF);
00087
00088 cbuf[i++] = ch;
00089
00090 while (((ch = fgetc(stream)) != ' ') && (ch != '\t') && (ch != '\n'))
00091 cbuf[i++] = ch;
00092
00093 cbuf[i] = 0;
00094 return(ch);
00095 }
00096
00097
00098 #ifdef __STDC__
00099 int find ( char *sym )
00100 #else
00101 int find(sym)
00102 char *sym;
00103 #endif
00104 {
00105
00106 deftemp = defptr;
00107 while (deftemp) {
00108 if (!strcmp(deftemp->symbol, sym))
00109 return(deftemp->type);
00110 deftemp = deftemp->next;
00111 }
00112 return(0);
00113 }
00114
00115
00116
00117 #define Define(x,y) defit(x,y,DEF)
00118 #define Undefine(x,y) defit(x,y,UNDEF)
00119 #define Ignore(x,y) defit(x,y,IGN)
00120
00121 #ifdef __STDC__
00122 void defit ( char *sym , int redef , int type )
00123 #else
00124 void defit(sym, redef, type)
00125 char *sym;
00126 char redef;
00127 char type;
00128 #endif
00129 {
00130 struct DEFINE *temp;
00131 char c;
00132
00133 c = find(sym);
00134 if (type == c) return;
00135 if (c) {
00136 if (deftemp->redef == IMMUTABLE)
00137 return;
00138 else {
00139 deftemp->type = type;
00140 deftemp->redef = redef;
00141 }
00142 } else {
00143
00144 if ((temp = (struct DEFINE *)malloc(sizeof(struct DEFINE))) == NULL) {
00145 (void)fprintf(stderr, "ifdef: could not malloc\n");
00146 exit(1);
00147 }
00148
00149
00150 if ((temp->symbol = (char *)malloc(strlen(sym) + 1)) == NULL) {
00151 (void)fprintf(stderr, "ifdef: could not malloc\n");
00152 exit(1);
00153 }
00154 (void)strcpy(temp->symbol, sym);
00155 temp->redef = redef;
00156 temp->type = type;
00157
00158
00159
00160 if (defptr == NULL)
00161 defptr = temp;
00162 else
00163 defend->next = temp;
00164 defend = temp;
00165 }
00166 }
00167
00168
00169
00170 #ifdef __STDC__
00171 void stop ( void )
00172 #else
00173 void stop()
00174 #endif
00175 {
00176 if (table) printtable();
00177 (void)fclose(zin);
00178 exit(0);
00179 }
00180
00181 #define Goto { line++; if (ch!='\n') gotoeoln(); }
00182 #define Print { line++; if (ch!='\n') prteoln(); }
00183
00184 #ifdef __STDC__
00185 void gotoeoln ( void )
00186 #else
00187 void gotoeoln()
00188 #endif
00189 {
00190 int ch;
00191 while ((ch = fgetc(zin)) != '\n')
00192 if (ch == EOF) stop();
00193 }
00194
00195
00196 #ifdef __STDC__
00197 void prteoln ( void )
00198 #else
00199 void prteoln()
00200 #endif
00201 {
00202 int ch;
00203 while ((ch = fgetc(zin)) != '\n')
00204 if (ch == EOF)
00205 stop();
00206 else
00207 (void)putchar(ch);
00208 (void)putchar('\n');
00209 }
00210
00211
00212 #ifdef __STDC__
00213 void printtable ( void )
00214 #else
00215 void printtable()
00216 #endif
00217 {
00218 struct DEFINE *temp;
00219
00220 (void)printf("Defined\n\n");
00221
00222 temp = defptr;
00223 while (temp) {
00224 if (temp->type == DEF) (void)printf("%s\n", temp->symbol);
00225 temp = temp->next;
00226 }
00227
00228 (void)printf("\n\nUndefined\n\n");
00229
00230 temp = defptr;
00231 while (temp) {
00232 if (temp->type == UNDEF) (void)printf("%s\n", temp->symbol);
00233 temp = temp->next;
00234 }
00235 }
00236
00237 #ifdef __STDC__
00238 char getendif ( void )
00239 #else
00240 char getendif()
00241 #endif
00242 {
00243 char word[80];
00244 int ch;
00245 int skip;
00246
00247 skip = 1;
00248
00249 while (1) {
00250
00251 if ((ch = fgetc(zin)) == EOF)
00252 stop();
00253 if (ch != '#') {
00254 (void)putchar(ch);
00255 Print;
00256 continue;
00257 }
00258 ch = fgetarg(zin, word);
00259
00260 if (!strcmp(word, "ifdef") || !strcmp(word, "ifndef")) skip++;
00261
00262 if (!strcmp(word, "endif")) skip--;
00263
00264 (void)printf("#%s%c", word, ch);
00265 Print;
00266 if (!skip) return('\n');
00267 }
00268 }
00269
00270
00271 #ifdef __STDC__
00272 void gettable ( void )
00273 #else
00274 void gettable()
00275 #endif
00276 {
00277
00278 char word[80];
00279 int ch;
00280
00281 while (1) {
00282
00283 if ((ch = fgetc(zin)) == EOF)
00284 stop();
00285 if (ch != '#') {
00286 Goto;
00287 continue;
00288 }
00289 ch = fgetarg(zin, word);
00290
00291 if (!strcmp(word, "define")) {
00292 ch = fgetarg(zin, word);
00293 Define(word, MUTABLE);
00294 Goto;
00295 continue;
00296 }
00297 if (!strcmp(word, "undef")) {
00298 ch = fgetarg(zin, word);
00299 Undefine(word, MUTABLE);
00300 Goto;
00301 continue;
00302 }
00303 if (!strcmp(word, "ifdef") || !strcmp(word, "ifndef")) {
00304 ch = fgetarg(zin, word);
00305 if (find(word) != DEF)
00306 Undefine(word, MUTABLE);
00307 Goto;
00308 continue;
00309 }
00310 Goto;
00311 }
00312 }
00313
00314
00315
00316 #ifdef __STDC__
00317 void parse ( void )
00318 #else
00319 void parse()
00320 #endif
00321 {
00322 char word[80];
00323 int ch;
00324 int proc;
00325 int skip;
00326
00327 proc = 1;
00328 skip = 0;
00329
00330 while (1) {
00331
00332 if ((ch = fgetc(zin)) == EOF)
00333 stop();
00334 if (ch != '#')
00335 if (proc) {
00336 (void)putchar(ch);
00337 Print;
00338 continue;
00339 } else {
00340 Goto;
00341 continue;
00342 }
00343
00344 ch = fgetarg(zin, word);
00345
00346 if (!strcmp(word, "define") && proc) {
00347 ch = fgetarg(zin, word);
00348 Define(word, MUTABLE);
00349 (void)printf("#define %s%c", word, ch);
00350 Print;
00351 continue;
00352 }
00353 if (!strcmp(word, "undef") && proc) {
00354 ch = fgetarg(zin, word);
00355 Undefine(word, MUTABLE);
00356 (void)printf("#undef %s%c", word, ch);
00357 Print;
00358 continue;
00359 }
00360 if (!strcmp(word, "if")) {
00361 if (!proc)
00362 skip++;
00363 else {
00364 (void)printf("#%s%c",word,ch);
00365 Print;
00366 ch = getendif();
00367 continue;
00368 }
00369 }
00370 if (!strcmp(word, "ifdef")) {
00371 if (!proc)
00372 skip++;
00373 else {
00374 ch = fgetarg(zin, word);
00375 switch (find(word)) {
00376 case DEF:
00377 break;
00378 case IGN:
00379 (void)printf("#ifdef %s%c", word, ch);
00380 Print;
00381 ch = getendif();
00382 break;
00383
00384 default:
00385 Undefine(word, MUTABLE);
00386 proc = 0;
00387 }
00388 }
00389 Goto;
00390 continue;
00391 }
00392 if (!strcmp(word, "ifndef")) {
00393
00394 if (!proc)
00395 skip++;
00396 else {
00397 ch = fgetarg(zin, word);
00398 switch (find(word)) {
00399 case DEF:
00400 proc = 0;
00401 break;
00402 case IGN:
00403 (void)printf("#ifdef %s%c", word, ch);
00404 Print;
00405 ch = getendif();
00406 break;
00407 }
00408 }
00409 Goto;
00410 continue;
00411 }
00412 if (!strcmp(word, "else") && !skip) {
00413 proc = !proc;
00414 Goto;
00415 continue;
00416 }
00417 if (!strcmp(word, "endif")) {
00418
00419 if (!skip)
00420 proc = 1;
00421 else
00422 skip--;
00423 Goto;
00424 continue;
00425 }
00426
00427
00428 if (proc) {
00429 (void)printf("#%s%c", word, ch);
00430 Print;
00431 } else
00432 Goto;
00433 }
00434 }
00435
00436
00437 #ifdef __STDC__
00438 void usage ( void )
00439 #else
00440 void usage()
00441 #endif
00442 {
00443 (void)fprintf(stderr, "Usage: ifdef [-t] [-Dsymbol] [-dsymbol] [-Usymbol] [-Isymbol] <file>\n");
00444 exit(0);
00445 }
00446
00447
00448 #ifdef __STDC__
00449 int main(int argc , char *argv [])
00450 #else
00451 int main(argc, argv)
00452 int argc;
00453 char *argv[];
00454 #endif
00455 {
00456 char sym[80];
00457 int c;
00458
00459 if (argc == 1) usage();
00460 while ((c = getopt(argc, argv, "tD:d:U:I:")) != EOF) {
00461 switch (c) {
00462 case 't':
00463 table = 1;
00464 break;
00465
00466 case 'd':
00467 (void)strcpy(sym, optarg);
00468 Define(sym, MUTABLE);
00469 break;
00470
00471 case 'D':
00472 (void)strcpy(sym, optarg);
00473 Define(sym, IMMUTABLE);
00474 break;
00475
00476 case 'U':
00477 (void)strcpy(sym, optarg);
00478 Undefine(sym, IMMUTABLE);
00479 break;
00480
00481 case 'I':
00482 (void)strcpy(sym, optarg);
00483 Ignore(sym, IMMUTABLE);
00484 break;
00485
00486 default: usage();
00487 }
00488 }
00489
00490 zin = stdin;
00491
00492 if (*argv[argc - 1] != '-') {
00493 (void)fclose(zin);
00494 if ((zin = fopen(argv[argc - 1], "r")) == NULL) {
00495 perror("ifdef");
00496 exit(1);
00497 }
00498 }
00499 if (table)
00500 gettable();
00501 else
00502 parse();
00503 return(0);
00504 }