📄 ifdef.c
字号:
/* ifdef - remove #ifdefs Author: Warren Toomey *//* Copyright 1989 by Warren Toomey wkt@cs.adfa.oz.au[@uunet.uu.net] * * You may freely copy or distribute this code as long as this notice * remains intact. * * You may modify this code, as long as this notice remains intact, and * you add another notice indicating that the code has been modified. * * You may NOT sell this code or in any way profit from this code without * prior agreement from the author. */#include <sys/types.h>#include <string.h>#include <stdlib.h>#include <stdio.h>/* Definition of structures and constants used in ifdef.c *//* Types of symbols */#define DEF 1 /* Symbol is defined */#define UNDEF 2 /* Symbol isn't defined */#define IGN 3 /* Ignore this symbol unless defined *//* Redef mode values */#define MUTABLE 1 /* Symbol can change defined <-> undefined */#define IMMUTABLE 2 /* Symbol can't change as above *//* Processing modes */#define NO 0 /* Don't process */#define YES 1 /* Process *//* Ignore (IGN), ignore but process */struct DEFINE { char *symbol; /* SLL of defined symbols. The redef */ char type; /* field indicates if this symbol can */ char redef; /* change from defined <-> undefined. */ struct DEFINE *next; /* Type is DEF or UNDEF. */};/* Global variables & structures */FILE *zin; /* Input file for processing */struct DEFINE *defptr; /* Defined symbols SLL */struct DEFINE *defend; /* Ptr to last node in defptr */struct DEFINE *deftemp; /* Ptr to last found node */int line = 1; /* Current line number */int table = 0; /* Don't normally want a table */extern int optind;extern char *optarg;/* Prototypes. */_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(char fgetarg, (FILE *stream, char *cbuf));_PROTOTYPE(int find, (char *symd));_PROTOTYPE(void defit, (char *sym, int redef, int typed));_PROTOTYPE(void stop, (void));_PROTOTYPE(void gotoeoln, (void));_PROTOTYPE(void prteoln, (void));_PROTOTYPE(void printtable, (void));_PROTOTYPE(char getendif, (void));_PROTOTYPE(void gettable, (void));_PROTOTYPE(void parse, (void));_PROTOTYPE(void usage, (void));#ifdef __STDC__char fgetarg ( FILE *stream , char *cbuf )#elsechar fgetarg(stream, cbuf) /* Get next arg from file into cbuf, */FILE *stream; /* returning the character that */char *cbuf; /* terminated it. Cbuf returns 0 */#endif{ /* if no arg. EOF is returned if no */ int ch; /* args left in file. */ int i; i = 0; cbuf[i] = 0; while (((ch = fgetc(stream)) == ' ') || (ch == '\t') || (ch == '\n')) if (ch == '\n') return(ch); /* Bypass leading */ /* Whitespace */ if (feof(stream)) return(EOF); cbuf[i++] = ch; while (((ch = fgetc(stream)) != ' ') && (ch != '\t') && (ch != '\n')) cbuf[i++] = ch; /* Get the argument */ cbuf[i] = 0; return(ch);}#ifdef __STDC__int find ( char *sym )#elseint find(sym)char *sym;#endif{ /* Return DEF if defined else UNDEF */ deftemp = defptr; while (deftemp) { /* Search for the symbol */ if (!strcmp(deftemp->symbol, sym)) return(deftemp->type); /* Setting up the type */ deftemp = deftemp->next; } return(0);}#define Define(x,y) defit(x,y,DEF)#define Undefine(x,y) defit(x,y,UNDEF)#define Ignore(x,y) defit(x,y,IGN)#ifdef __STDC__void defit ( char *sym , int redef , int type )#elsevoid defit(sym, redef, type) /* Add symbol to the define list */char *sym;char redef; /* Mode: MUTABLE etc */char type; /* Type: DEF, UNDEF, IGN */#endif{ struct DEFINE *temp; char c; c = find(sym); /* First try finding the symbol */ if (type == c) return; /* Return if already declared */ if (c) { /* We have to move if from DEF <-> UNDEF */ if (deftemp->redef == IMMUTABLE) return; else { deftemp->type = type; deftemp->redef = redef; } } else { /* We must create a struct & add it */ /* Malloc room for the struct */ if ((temp = (struct DEFINE *)malloc(sizeof(struct DEFINE))) == NULL) { (void)fprintf(stderr, "ifdef: could not malloc\n"); exit(1); } /* Malloc room for symbol */ if ((temp->symbol = (char *)malloc(strlen(sym) + 1)) == NULL) { (void)fprintf(stderr, "ifdef: could not malloc\n"); exit(1); } (void)strcpy(temp->symbol, sym); /* Copy symbol into struct */ temp->redef = redef; /* and set its redef mode too */ temp->type = type; /* as well as making it defined */ /* Now add to the SLL */ if (defptr == NULL) /* If first node set */ defptr = temp; /* the pointers to it */ else defend->next = temp; /* else add it to the */ defend = temp; /* end of the list. */ }}#ifdef __STDC__void stop ( void )#elsevoid stop()#endif{ /* Stop: Tidy up at EOF */ if (table) printtable(); (void)fclose(zin); exit(0);}#define Goto { line++; if (ch!='\n') gotoeoln(); }#define Print { line++; if (ch!='\n') prteoln(); }#ifdef __STDC__void gotoeoln ( void )#elsevoid gotoeoln() /* Go to the end of the line */#endif{ int ch; while ((ch = fgetc(zin)) != '\n') if (ch == EOF) stop();}#ifdef __STDC__void prteoln ( void )#elsevoid prteoln() /* Print to the end of the line */#endif{ int ch; while ((ch = fgetc(zin)) != '\n') if (ch == EOF) stop(); else (void)putchar(ch); (void)putchar('\n');}#ifdef __STDC__void printtable ( void )#elsevoid printtable() /* Print the defines in the SLL */#endif{ struct DEFINE *temp; (void)printf("Defined\n\n"); temp = defptr; while (temp) { if (temp->type == DEF) (void)printf("%s\n", temp->symbol); temp = temp->next; } (void)printf("\n\nUndefined\n\n"); temp = defptr; while (temp) { if (temp->type == UNDEF) (void)printf("%s\n", temp->symbol); temp = temp->next; }}#ifdef __STDC__char getendif ( void )#elsechar getendif()#endif{ /* Find matching endif when ignoring */ char word[80]; /* Buffer for symbols */ int ch; int skip; /* Number of skipped #ifdefs */ skip = 1; while (1) { /* Scan through the file looking for starting lines */ if ((ch = fgetc(zin)) == EOF) stop(); /* Get first char on the line */ if (ch != '#') { /* If not a # ignore line */ (void)putchar(ch); Print; continue; } ch = fgetarg(zin, word); /* Get the word after the # */ if (!strcmp(word, "ifdef") || !strcmp(word, "ifndef")) skip++; /* Keep track of ifdefs & */ if (!strcmp(word, "endif")) skip--; /* endifs */ (void)printf("#%s%c", word, ch); /* Print the line out */ Print; if (!skip) return('\n'); /* If matching endif, return */ }}#ifdef __STDC__void gettable ( void )#elsevoid gettable() /* Get & print a table of defines etc. */#endif{ char word[80]; /* Buffer for symbols */ int ch; while (1) { /* Scan through the file looking for starting lines */ if ((ch = fgetc(zin)) == EOF) stop(); /* Get first char on the line */ if (ch != '#') { /* If not a # ignore line */ Goto; continue; } ch = fgetarg(zin, word); /* Get the word after the # */ if (!strcmp(word, "define")) { /* Define: Define the */ ch = fgetarg(zin, word); /* symbol, and goto */ Define(word, MUTABLE); /* the end of line */ Goto; continue; } if (!strcmp(word, "undef")) { /* Undef: Undefine the */ ch = fgetarg(zin, word); /* symbol, and goto */ Undefine(word, MUTABLE); /* the end of line */ Goto; continue; } /* Ifdef: */ if (!strcmp(word, "ifdef") || !strcmp(word, "ifndef")) { ch = fgetarg(zin, word); /* Get the symbol */ if (find(word) != DEF) Undefine(word, MUTABLE); /* undefine it */ Goto; continue; } Goto; /* else ignore the line */ }}#ifdef __STDC__void parse ( void )#elsevoid parse()#endif{ /* Parse & remove ifdefs from C source */ char word[80]; /* Buffer for symbols */ int ch; int proc; /* Should we be processing this bit? */ int skip; /* Number of skipped #ifdefs */ proc = 1; skip = 0; while (1) { /* Scan through the file looking for starting lines */ if ((ch = fgetc(zin)) == EOF) stop(); /* Get first char on the line */ if (ch != '#') if (proc) { /* If not # and we're processing */ (void)putchar(ch); /* then print the line */ Print; continue; } else { Goto; /* else just skip the line */ continue; } ch = fgetarg(zin, word); /* Get the word after the # */ if (!strcmp(word, "define") && proc) { /* Define: Define the */ ch = fgetarg(zin, word); /* symbol, and goto */ Define(word, MUTABLE); /* the end of line */ (void)printf("#define %s%c", word, ch); Print; continue; } if (!strcmp(word, "undef") && proc) { /* Undef: Undefine the */ ch = fgetarg(zin, word); /* symbol, and goto */ Undefine(word, MUTABLE); /* the end of line */ (void)printf("#undef %s%c", word, ch); Print; continue; } if (!strcmp(word, "if")) { /* If: we cannot handle these */ if (!proc) /* at the moment, so just */ skip++; /* treat them as an ignored */ else { /* definition */ (void)printf("#%s%c",word,ch); Print; ch = getendif(); /* Get matching endif */ continue; } } if (!strcmp(word, "ifdef")) { /* Ifdef: */ if (!proc) /* If not processing */ skip++; /* skip it */ else { ch = fgetarg(zin, word); /* Get the symbol */ switch (find(word)) { case DEF: break; case IGN: (void)printf("#ifdef %s%c", word, ch); Print; ch = getendif(); /* Get matching endif */ break; /* If symbol undefined */ default: Undefine(word, MUTABLE); /* undefine it */ proc = 0; /* & stop processing */ } } Goto; continue; } if (!strcmp(word, "ifndef")) { /* Ifndef: */ if (!proc) /* If not processing */ skip++; /* skip the line */ else { ch = fgetarg(zin, word); /* Get the symbol */ switch (find(word)) { /* If defined, stop */ case DEF: proc = 0; /* processing */ break; case IGN: (void)printf("#ifdef %s%c", word, ch); Print; ch = getendif(); /* Get matching endif */ break; } } Goto; continue; } if (!strcmp(word, "else") && !skip) { /* Else: Flip processing */ proc = !proc; Goto; continue; } if (!strcmp(word, "endif")) { /* Endif: If no skipped */ /* ifdefs turn processing */ if (!skip) /* on, else decrement the */ proc = 1; /* number of skips */ else skip--; Goto; continue; } /* The word fails all of the above tests, so if we're */ /* processing, print the line. */ if (proc) { (void)printf("#%s%c", word, ch); Print; } else Goto; }}#ifdef __STDC__void usage ( void )#elsevoid usage()#endif{ (void)fprintf(stderr, "Usage: ifdef [-t] [-Dsymbol] [-dsymbol] [-Usymbol] [-Isymbol] <file>\n"); exit(0);}#ifdef __STDC__int main(int argc , char *argv [])#elseint main(argc, argv)int argc;char *argv[];#endif{ char sym[80]; /* Temp symbol storage */ int c; if (argc == 1) usage(); /* Catch the curious user */ while ((c = getopt(argc, argv, "tD:d:U:I:")) != EOF) { switch (c) { case 't': table = 1; /* Get the various options */ break; case 'd': (void)strcpy(sym, optarg); Define(sym, MUTABLE); break; case 'D': (void)strcpy(sym, optarg); Define(sym, IMMUTABLE); break; case 'U': (void)strcpy(sym, optarg); Undefine(sym, IMMUTABLE); break; case 'I': (void)strcpy(sym, optarg); Ignore(sym, IMMUTABLE); break; default: usage(); } } zin = stdin; /* If a C file is named */ /* Open stdin with it */ if (*argv[argc - 1] != '-') { (void)fclose(zin); if ((zin = fopen(argv[argc - 1], "r")) == NULL) { perror("ifdef"); exit(1); } } if (table) gettable(); /* Either generate a table or */ else parse(); /* parse & replace with the file */ return(0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -