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