* Copyright (c) 1985 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* %sccs.include.redist.c%
"@(#) Copyright (c) 1985 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)unifdef.c 4.7 (Berkeley) %G%";
* unifdef - remove ifdef'ed lines
* Warning: will not work correctly if input contains null characters.
* provide an option which will append the name of the
* appropriate symbol after #else's and #endif's
* provide an option which will check symbols after
* #else's and #endif's to see that they match their
* corresponding #ifdef or #ifndef
char text BSS
; /* -t option in effect: this is a text file */
char lnblank BSS
; /* -l option in effect: blank deleted lines */
char complement BSS
; /* -c option in effect: complement the operation */
char *symname
[MAXSYMS
] BSS
; /* symbol name */
char true[MAXSYMS
] BSS
; /* -Dsym */
char ignore
[MAXSYMS
] BSS
; /* -iDsym or -iUsym */
char insym
[MAXSYMS
] BSS
; /* state: false, inactive, true */
#define SYM_INACTIVE 0 /* symbol is currently inactive */
#define SYM_FALSE 1 /* symbol is currently false */
#define SYM_TRUE 2 /* symbol is currently true */
char incomment BSS
; /* inside C comment */
char inquote BSS
; /* inside single or double quotes */
progname
= argv
[0][0] ? argv
[0] : "unifdef";
for (curarg
= &argv
[1]; --argc
> 0; curarg
++) {
if (*(cp1
= cp
= *curarg
) != '-')
if ((symind
= findsym (&cp1
[1])) < 0) {
fprintf (stderr
, "too many symbols.\n");
symname
[symind
] = &cp1
[1];
insym
[symind
] = SYM_INACTIVE
;
ignore
[symind
] = ignorethis
;
true[symind
] = *cp1
== 'D' ? YES
: NO
;
else if (strcmp (&cp
[1], "t") == 0)
else if (strcmp (&cp
[1], "l") == 0)
else if (strcmp (&cp
[1], "c") == 0)
fprintf (stderr
, "unrecognized option: %s\n", cp
);
Usage: %s [-l] [-t] [-c] [[-Dsym] [-Usym] [-iDsym] [-iUsym]]... [file]\n\
At least one arg from [-D -U -iD -iU] is required\n", progname
);
fprintf (stderr
, "can only do one file.\n");
if ((input
= fopen (filename
, "r")) != NULL
) {
fprintf (stderr
, "can't open ");
/* types of input lines: */
#define LT_PLAIN 0 /* ordinary line */
#define LT_TRUE 1 /* a true #ifdef of a symbol known to us */
#define LT_FALSE 2 /* a false #ifdef of a symbol known to us */
#define LT_OTHER 3 /* an #ifdef of a symbol not known to us */
#define LT_IF 4 /* an #ifdef of a symbol not known to us */
#define LT_ELSE 5 /* #else */
#define LT_ENDIF 6 /* #endif */
#define LT_LEOF 7 /* end of file */
extern Linetype
checkline ();
typedef int Reject_level
;
Reject_level reject BSS
; /* 0 or 1: pass thru; 1 or 2: ignore comments */
int linenum BSS
; /* current line number */
int stqcline BSS
; /* start of current coment or quote */
"Premature EOF in ifdef",
"Premature EOF in comment",
"Premature EOF in quoted character",
"Premature EOF in quoted string"
/* States for inif arg to doif */
(void) doif (-1, IN_NONE
, reject
, 0);
doif (thissym
, inif
, prevreject
, depth
)
register int thissym
; /* index of the symbol who was last ifdef'ed */
int inif
; /* YES or NO we are inside an ifdef */
Reject_level prevreject
;/* previous value of reject */
int depth
; /* depth of ifdef's */
register Linetype lineval
;
register Reject_level thisreject
;
int doret
; /* tmp return value of doif */
int cursym
; /* index of the symbol returned by checkline */
int stline
; /* line number when called this time */
switch (lineval
= checkline (&cursym
)) {
insym
[cursym
] = SYM_TRUE
;
reject
= ignore
[cursym
] ? REJ_IGNORE
: REJ_YES
;
insym
[cursym
] = SYM_FALSE
;
if ((doret
= doif (cursym
, IN_IF
, thisreject
, depth
+ 1)) != NO_ERR
)
return error (doret
, stline
, depth
);
if ((doret
= doif (-1, IN_IF
, reject
, depth
+ 1)) != NO_ERR
)
return error (doret
, stline
, depth
);
return error (ELSE_ERR
, linenum
, depth
);
if (insym
[thissym
] == SYM_TRUE
) {
reject
= ignore
[thissym
] ? REJ_IGNORE
: REJ_YES
;
insym
[thissym
] = SYM_FALSE
;
} else { /* (insym[thissym] == SYM_FALSE) */
insym
[thissym
] = SYM_TRUE
;
return error (ENDIF_ERR
, linenum
, depth
);
insym
[thissym
] = SYM_INACTIVE
;
: inquote
== QUOTE_SINGLE
: inquote
== QUOTE_DOUBLE
(void) error (err
, stqcline
, depth
);
return error (IEOF_ERR
, stline
, depth
);
} else if (err
!= NO_ERR
)
return error (err
, stqcline
, depth
);
#define endsym(c) (!isalpha (c) && !isdigit (c) && c != '_')
int *cursym
; /* if LT_TRUE or LT_FALSE returned, set this to sym index */
if (getlin (tline
, sizeof tline
, input
, NO
) == EOF
)
if ( *(cp
= tline
) != '#'
|| inquote
== QUOTE_SINGLE
|| inquote
== QUOTE_DOUBLE
if (++symp
>= &keyword
[KWSIZE
])
if (strcmp (keyword
, "ifdef") == 0) {
} else if (strcmp (keyword
, "ifndef") == 0) {
scp
= cp
= skipcomment (++cp
);
if ((symind
= findsym (scp
)) >= 0)
retval
= (retval
^ true[*cursym
= symind
])
} else if (strcmp (keyword
, "if") == 0)
else if (strcmp (keyword
, "else") == 0)
else if (strcmp (keyword
, "endif") == 0)
if (!text
&& reject
!= REJ_IGNORE
)
else if (inquote
== QUOTE_SINGLE
)
cp
= skipquote (cp
, QUOTE_SINGLE
);
else if (inquote
== QUOTE_DOUBLE
)
cp
= skipquote (cp
, QUOTE_DOUBLE
);
else if (*cp
== '/' && cp
[1] == '*')
cp
= skipquote (cp
, QUOTE_SINGLE
);
cp
= skipquote (cp
, QUOTE_DOUBLE
);
* Skip over comments and stop at the next charaacter
* position that is not whitespace.
while (*cp
== ' ' || *cp
== '\t')
* Skip over a quoted string or character and stop at the next charaacter
* position that is not whitespace.
qchar
= type
== QUOTE_SINGLE
? '\'' : '"';
|| *cp
== '\\' && *++cp
== '\0'
* findsym - look for the symbol in the symbol table.
* if found, return symbol table index,
for (symind
= 0; symind
< nsyms
; ++symind
) {
if (insym
[symind
] == SYM_INACTIVE
) {
for ( symp
= symname
[symind
], cp
= str
if (*symp
== '\0' && endsym (chr
))
* getlin - expands tabs if asked for
* and (if compiled in) treats form-feed as an end-of-line
getlin (line
, maxline
, inp
, expandtabs
)
static char havechar
= NO
; /* have leftover char from last time */
while (num
+ 8 < maxline
) { /* leave room for tab */
num
+= tmp
= 8 - (num
& 7);
if ((keep
&& reject
!= REJ_YES
) ^ complement
) {
register char *line
= tline
;
register FILE *out
= stdout
;
fprintf (stderr
, "%s: ", progname
);
int err
; /* type of error & index into error string array */
int line
; /* line number */
int depth
; /* how many ifdefs we are inside */
fprintf (stderr
, "Error in %s line %d: %s.\n", filename
, line
, errs
[err
]);
fprintf (stderr
, "Error in %s line %d: %s. ", filename
, line
, errs
[err
]);
fprintf (stderr
, "ifdef depth: %d\n", depth
);
return depth
> 1 ? IEOF_ERR
: END_ERR
;