rmifdef - remove ifdefs from C source
Sjoerd Mullender
sjoerd at botter.UUCP
Mon Jul 21 23:41:59 AEST 1986
Some people asked for a program to selectively remove ifdefs from a file.
I wrote this program some time ago and it seems this is about what they
wanted. Therefore I submit this program to the public domain. You can do
anything with this program, except say that you wrote it.
Compile this as follows:
lex rmifdef.l; cc -o rmifdef lex.yy.c
--
Sjoerd Mullender <sjoerd at vu44.uucp>
: This is a shar archive. Extract with sh, not csh.
: This archive ends with exit, so do not worry about trailing junk.
: --------------------------- cut here --------------------------
PATH=/bin:/usr/bin
echo Extracting \r\m\i\f\d\e\f\.\1
sed 's/^X//' > \r\m\i\f\d\e\f\.\1 << '+ END-OF-FILE '\r\m\i\f\d\e\f\.\1
X.TH RMIFDEF 1 local
X.SH NAME
Xrmifdef \- remove ifdefs from file
X.SH SYNOPSIS
X.B rmifdef
X[
X.I flags
X] [
X.I files
X]
X.SH DESCRIPTION
X.I Rmifdef
Xreads the specified files (standard input default) and produces on standard
Xoutput the same files with #ifdef and #ifndef lines removed.
XIf the
X.B \-w
Xoption is given, the input files will be overwritten.
XWith the
X.BI \-D name
Xand
X.BI \-U name
Xoptions you can specify which identifiers are to be considered defined or
Xundefined respectively.
XIf no
X.B \-a
Xoption is given,
X.I rmifdef
Xwill ask for each identifier it doesn't know yet if it should be considered
Xdefined or undefined.
XIf the answer is
X.I y
Xor
X.IR n ,
Xthe identifier will be remembered and the lines after the #ifdef or #ifndef
Xwill be retained or removed according to the answer.
XIf the answer is something else
X.RI ( e . g .
Xan empty line) the identifier will be remembered and the #ifdef or #ifndef
Xline and the following lines will be kept.
XIf the
X.B \-a
Xoption is given the lines will be kept if the identifier is unknown.
X.SH EXAMPLE
XIf the input file looks like
X.br
X #ifdef m68000
X.br
X short i;
X.br
X #else
X.br
X int i;
X.br
X #endif
X.br
X #ifdef BSD
X.br
X blah
X.br
X #else
X.br
X blech
X.br
X #endif
X.br
X \&...
X.br
Xand you invoke it like this:
X.br
X rmifdef -a -DSYS5 -Dm68000 <x.c >x.c.new
X.br
Xthe output would be
X.br
X short i;
X.br
X #ifdef BSD
X.br
X blah
X.br
X #else
X.br
X blech
X.br
X #endif
X.br
X \&...
X.br
XIf you invoke it like this:
X.br
X rmifdef -a -UBSD -Dm68000 <x.c >x.c.new
X.br
Xthe output would be:
X.br
X short i;
X.br
X blech
X.br
X \&...
X.SH BUGS
X.I Rmifdef
Xdoesn't look at #defines in the file.
X.br
XYou have to specify each and every identifier that is used in an #ifdef
Xor #ifndef if you want to remove all #ifdefs.
X.SH AUTHOR
XSjoerd Mullender, Vrije Universiteit, Amsterdam
X.br
Xsjoerd at vu44.uucp
+ END-OF-FILE rmifdef.1
chmod 'u=rw,g=r,o=r' \r\m\i\f\d\e\f\.\1
echo Extracting \r\m\i\f\d\e\f\.\l
sed 's/^X//' > \r\m\i\f\d\e\f\.\l << '+ END-OF-FILE '\r\m\i\f\d\e\f\.\l
XL [_A-Za-z]
XD [0-9]
X
X%Start SKIP
X
X%{
X#define STACKSIZ 100
X#define NTAB 1000
X
X#define DEFINED 1
X#define UNDEFINED 2
X#define UNKNOWN 3
X
Xshort *sp;
Xint changed;
X%}
X
X%%
X
X^#[ \t]*ifdef[ \t]+{L}({L}|{D})* {
X if (*sp & 4 ? (*sp & 2) == 0 : (*sp & 1) == 0)
X *++sp = 0;
X else
X switch (defined()) {
X case DEFINED: *++sp = 1; changed++; break;
X case UNDEFINED: *++sp = 2; changed++; break;
X case UNKNOWN: *++sp = 3; ECHO; break;
X }
X if (*sp != 3)
X BEGIN SKIP;
X }
X
X^#[ \t]*ifndef[ \t]+{L}({L}|{D})* {
X if (*sp & 4 ? (*sp & 2) == 0 : (*sp & 1) == 0)
X *++sp = 0;
X else
X switch (defined()) {
X case DEFINED: *++sp = 2; changed++; break;
X case UNDEFINED: *++sp = 1; changed++; break;
X case UNKNOWN: *++sp = 3; ECHO; break;
X }
X if (*sp != 3)
X BEGIN SKIP;
X }
X
X^#[ \t]*if[ \t].*\n {
X if (*sp & 4 ? (*sp & 2) == 0 : (*sp & 1) == 0)
X *++sp = 0;
X else
X switch (true()) {
X case DEFINED: *++sp = 1; changed++; break;
X case UNDEFINED: *++sp = 2; changed++; break;
X case UNKNOWN: *++sp = 3; ECHO; break;
X }
X }
X
X^#[ \t]*else.*\n {
X if (*sp == 3)
X ECHO;
X *sp |= 4;
X }
X
X^#[ \t]*endif.*\n {
X if ((*sp & 3) == 3)
X ECHO;
X --sp;
X }
X
X<SKIP>\n { BEGIN 0; }
X
X<SKIP>. { /* do nothing */; }
X
X.|\n {
X if (*sp & 4 ? *sp & 2 : *sp & 1)
X ECHO;
X }
X
X%%
X
X#include <signal.h>
X
Xstruct table {
X short t_flag;
X char *t_name;
X} table[NTAB];
X
Xstruct table *tabend;
X
Xshort stack[STACKSIZ];
X
Xchar tmpfil[] = "/tmp/rmifdXXXXXX";
Xchar *cmd;
Xint overwrite, dontask;
X
Xmain(argc, argv)
Xregister char **argv;
X{
X extern cleanup();
X
X tabend = &table[0]; sp = &stack[0]; *sp = 3;
X cmd = *argv;
X while (--argc > 0) {
X if (**++argv == '-') {
X switch (*++*argv) {
X case 'a': dontask++; break;
X case 'A': dontask = 0; break;
X case 'd':
X case 'D': defsym(++*argv); break;
X case 'u':
X case 'U': undefsym(++*argv); break;
X case 'w': overwrite++; break;
X case 'W': overwrite = 0; break;
X default: error("unknown option"); break;
X }
X } else
X break;
X }
X if (overwrite) {
X signal(SIGINT, cleanup);
X signal(SIGQUIT, cleanup);
X signal(SIGHUP, cleanup);
X signal(SIGTERM, cleanup);
X mktemp(tmpfil);
X }
X if (argc == 0) {
X dontask = 1;
X yylex();
X exit(0);
X }
X while (argc > 0) {
X if ((yyin = fopen(*argv, "r")) == NULL)
X fprintf(stderr, "%s: cannot open %s\n", cmd, *argv);
X else {
X if (overwrite)
X yyout = fopen(tmpfil, "w");
X changed = 0;
X yylex();
X fclose(yyin);
X if (overwrite) {
X fclose(yyout);
X yyout = stdout;
X if (changed)
X copy(tmpfil, *argv);
X unlink(tmpfil);
X }
X }
X argv++;
X argc--;
X }
X exit(0);
X}
X
Xdefsym(sym)
Xchar *sym;
X{
X tabend->t_flag = DEFINED;
X tabend->t_name = sym;
X tabend++;
X}
X
Xundefsym(sym)
Xchar *sym;
X{
X tabend->t_flag = UNDEFINED;
X tabend->t_name = sym;
X tabend++;
X}
X
Xunknownsym(sym)
Xchar *sym;
X{
X tabend->t_flag = UNKNOWN;
X tabend->t_name = sym;
X tabend++;
X}
X
Xdefined()
X{
X register char *s;
X register struct table *p;
X
X s = &yytext[yyleng];
X while (*--s > 32)
X ;
X s++;
X for (p = &table[0]; p < tabend; p++)
X if (strcmp(p->t_name, s) == 0)
X return p->t_flag;
X if (dontask)
X return UNKNOWN;
X return ask(s);
X}
X
Xask(sym)
Xchar *sym;
X{
X register char *s;
X char buf[128];
X extern char *malloc(), *strcpy();
X
X fprintf(stderr, "is \"%s\" defined? ", sym);
X s = strcpy(malloc(strlen(sym)+1), sym);
X gets(buf);
X if (buf[0] == 'y' || buf[0] == 'Y') {
X defsym(s);
X return DEFINED;
X } else if (buf[0] == 'n' || buf[0] == 'N') {
X undefsym(s);
X return UNDEFINED;
X } else {
X unknownsym(s);
X return UNKNOWN;
X }
X}
X
Xtrue()
X{
X register char *s = yytext;
X char buf[128];
X
X if (dontask)
X return UNKNOWN;
X while (*s++ != 'f')
X ;
X while (*s == ' ' || *s == '\t')
X s++;
X yytext[yyleng - 1] = 0;
X fprintf(stderr, "is \"%s\" true? ", s);
X yytext[yyleng - 1] = '\n';
X gets(buf);
X switch (buf[0]) {
X case 'y':
X case 'Y':
X return DEFINED;
X case 'n':
X case 'N':
X return UNDEFINED;
X default:
X return UNKNOWN;
X }
X}
X
Xerror(s)
Xchar *s;
X{
X fprintf(stderr, "%s: %s\n", cmd, s);
X exit(1);
X}
X
Xyywrap()
X{
X return 1;
X}
X
Xcleanup(sig)
X{
X unlink(tmpfil);
X exit(sig);
X}
X
Xcopy(file1, file2)
Xchar *file1, *file2;
X{
X static char buf[1024];
X register int n, f1, f2;
X
X if ((f1 = open(file1, 0)) < 0) {
X fprintf(stderr, "can't open temporary file");
X return;
X }
X if ((f2 = creat(file2, 0666)) < 0) {
X fprintf(stderr, "%s: cannot re-create %s\n", cmd, file2);
X return;
X }
X while ((n = read(f1, buf, 1024)) > 0)
X write(f2, buf, n);
X close(f1);
X close(f2);
X}
+ END-OF-FILE rmifdef.l
chmod 'u=rw,g=r,o=r' \r\m\i\f\d\e\f\.\l
exit 0
More information about the Comp.sources.unix
mailing list