Sync with upstream again:
* Be less strict about multi-line preprocessor directives (e.g. those with comments hanging off the right-hand end) since they're more of a problem in practise than I expected. Prompted by phk. * Fix the handling of "ignore" symbols. * Style pedantry from OpenBSD and Ted Unangst <tedu@stanford.edu>, including some whitespace fixes and removal of strcpy() (and not including excessively strict KNF enforcement). * Fix some typos and terminological inconsistencies.
This commit is contained in:
parent
8ec22a9363
commit
0723ff0c6a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=109567
@ -6,5 +6,6 @@ MAINTAINER= fanf@FreeBSD.org
|
||||
PROG= unifdef
|
||||
SCRIPTS=unifdefall.sh
|
||||
MLINKS= unifdef.1 unifdefall.1
|
||||
WARNS?= 5
|
||||
|
||||
.include <bsd.prog.mk>
|
||||
|
@ -33,7 +33,7 @@
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94
|
||||
.\" $dotat: things/unifdef.1,v 1.40 2002/12/13 11:33:34 fanf2 Exp $
|
||||
.\" $dotat: things/unifdef.1,v 1.43 2003/01/20 11:36:12 fanf2 Exp $
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 24, 2002
|
||||
@ -44,7 +44,7 @@
|
||||
.Nd remove preprocessor conditionals from code
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Op Fl cklst
|
||||
.Op Fl ceklst
|
||||
.Oo
|
||||
.Fl I Ns Ar path
|
||||
.Fl D Ns Ar sym Ns Op = Ns Ar val
|
||||
@ -157,6 +157,24 @@ is complemented,
|
||||
i.e., the lines that would have been removed or blanked
|
||||
are retained and vice versa.
|
||||
.Pp
|
||||
.It Fl e
|
||||
Because
|
||||
.Nm
|
||||
processes its input one line at a time,
|
||||
it cannot remove preprocessor directives that span more than one line.
|
||||
The most common example of this is a directive with a multi-line
|
||||
comment hanging off its right hand end.
|
||||
By default,
|
||||
if
|
||||
.Nm
|
||||
has to process such a directive,
|
||||
it will complain that the line is too obfuscated.
|
||||
The
|
||||
.Fl e
|
||||
option changes the behaviour so that,
|
||||
where possible,
|
||||
such lines are left unprocessed instead of reporting an error.
|
||||
.Pp
|
||||
.It Fl k
|
||||
Process
|
||||
.Ic #if
|
||||
@ -285,7 +303,7 @@ Expression evaluation is very limited.
|
||||
.Pp
|
||||
Preprocessor control lines split across more than one physical line
|
||||
(because of comments or backslash-newline)
|
||||
cannot be handled.
|
||||
cannot be handled in every situation.
|
||||
.Pp
|
||||
Trigraphs are not recognized.
|
||||
.Pp
|
||||
|
@ -44,7 +44,7 @@ static const char copyright[] =
|
||||
#ifdef __IDSTRING
|
||||
__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93");
|
||||
__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $");
|
||||
__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.133 2003/01/17 19:04:36 fanf2 Exp $");
|
||||
__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.148 2003/01/20 12:05:41 fanf2 Exp $");
|
||||
#endif
|
||||
#ifdef __FBSDID
|
||||
__FBSDID("$FreeBSD$");
|
||||
@ -61,6 +61,9 @@ __FBSDID("$FreeBSD$");
|
||||
* #else's and #endif's to see that they match their
|
||||
* corresponding #ifdef or #ifndef
|
||||
* generate #line directives in place of deleted code
|
||||
*
|
||||
* The first two items above require better buffer handling, which would
|
||||
* also make it possible to handle all "dodgy" directives correctly.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
@ -74,7 +77,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
/* types of input lines: */
|
||||
typedef enum {
|
||||
LT_PLAIN, /* ordinary line */
|
||||
LT_TRUEI, /* a true #if with ignore flag */
|
||||
LT_FALSEI, /* a false #if with ignore flag */
|
||||
LT_IF, /* an unknown #if */
|
||||
@ -85,13 +87,21 @@ typedef enum {
|
||||
LT_ELFALSE, /* a false #elif */
|
||||
LT_ELSE, /* #else */
|
||||
LT_ENDIF, /* #endif */
|
||||
LT_DODGY, /* flag: directive is not on one line */
|
||||
LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
|
||||
LT_PLAIN, /* ordinary line */
|
||||
LT_EOF, /* end of file */
|
||||
LT_COUNT
|
||||
} Linetype;
|
||||
|
||||
static char const * const linetype_name[] = {
|
||||
"PLAIN", "TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
|
||||
"ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF", "EOF"
|
||||
"TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
|
||||
"ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF",
|
||||
"DODGY TRUEI", "DODGY FALSEI",
|
||||
"DODGY IF", "DODGY TRUE", "DODGY FALSE",
|
||||
"DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
|
||||
"DODGY ELSE", "DODGY ENDIF",
|
||||
"PLAIN", "EOF"
|
||||
};
|
||||
|
||||
/* state of #if processing */
|
||||
@ -111,8 +121,8 @@ typedef enum {
|
||||
|
||||
static char const * const ifstate_name[] = {
|
||||
"OUTSIDE", "FALSE_PREFIX", "TRUE_PREFIX",
|
||||
"PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
|
||||
"PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
|
||||
"PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
|
||||
"PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
|
||||
"FALSE_TRAILER"
|
||||
};
|
||||
|
||||
@ -147,12 +157,19 @@ static char const * const linestate_name[] = {
|
||||
#define MAXLINE 4096 /* maximum length of line */
|
||||
#define MAXSYMS 4096 /* maximum number of symbols */
|
||||
|
||||
/*
|
||||
* Sometimes when editing a keyword the replacement text is longer, so
|
||||
* we leave some space at the end of the tline buffer to accommodate this.
|
||||
*/
|
||||
#define EDITSLOP 10
|
||||
|
||||
/*
|
||||
* Globals.
|
||||
*/
|
||||
|
||||
static bool complement; /* -c: do the complement */
|
||||
static bool debugging; /* -d: debugging reports */
|
||||
static bool iocccok; /* -e: fewer IOCCC errors */
|
||||
static bool killconsts; /* -k: eval constant #ifs */
|
||||
static bool lnblank; /* -l: blank deleted lines */
|
||||
static bool symlist; /* -s: output symbol list */
|
||||
@ -167,7 +184,7 @@ static FILE *input; /* input file pointer */
|
||||
static const char *filename; /* input file name */
|
||||
static int linenum; /* current line number */
|
||||
|
||||
static char tline[MAXLINE+10]; /* input buffer plus space */
|
||||
static char tline[MAXLINE+EDITSLOP];/* input buffer plus space */
|
||||
static char *keyword; /* used for editing #elif's */
|
||||
|
||||
static Comment_state incomment; /* comment parser state */
|
||||
@ -187,13 +204,15 @@ static int findsym(const char *);
|
||||
static void flushline(bool);
|
||||
static Linetype getline(void);
|
||||
static Linetype ifeval(const char **);
|
||||
static void ignoreoff(void);
|
||||
static void ignoreon(void);
|
||||
static void keywordedit(const char *);
|
||||
static void nest(void);
|
||||
static void process(void);
|
||||
static const char *skipcomment(const char *);
|
||||
static const char *skipsym(const char *);
|
||||
static void state(Ifstate);
|
||||
static int strlcmp(const char *, const char *, size_t);
|
||||
static void unignore(void);
|
||||
static void usage(void);
|
||||
|
||||
#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_')
|
||||
@ -206,7 +225,7 @@ main(int argc, char *argv[])
|
||||
{
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt(argc, argv, "i:D:U:I:cdklst")) != -1)
|
||||
while ((opt = getopt(argc, argv, "i:D:U:I:cdeklst")) != -1)
|
||||
switch (opt) {
|
||||
case 'i': /* treat stuff controlled by these symbols as text */
|
||||
/*
|
||||
@ -237,6 +256,9 @@ main(int argc, char *argv[])
|
||||
case 'd':
|
||||
debugging = true;
|
||||
break;
|
||||
case 'e': /* fewer errors from dodgy lines */
|
||||
iocccok = true;
|
||||
break;
|
||||
case 'k': /* process constant #ifs */
|
||||
killconsts = true;
|
||||
break;
|
||||
@ -279,9 +301,9 @@ main(int argc, char *argv[])
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
fprintf(stderr, "usage: %s",
|
||||
"unifdef [-cdklst] [[-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym]] ... [file]\n");
|
||||
exit (2);
|
||||
fprintf(stderr, "usage: unifdef [-cdeklst]"
|
||||
" [[-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym]] ... [file]\n");
|
||||
exit(2);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -291,19 +313,28 @@ usage(void)
|
||||
* indicate that processing is complete.
|
||||
*
|
||||
* Nesting is handled by keeping a stack of states; some transition
|
||||
* functions increase or decrease the depth. They also maintin the
|
||||
* functions increase or decrease the depth. They also maintain the
|
||||
* ignore state on a stack. In some complicated cases they have to
|
||||
* alter the preprocessor directive, as follows.
|
||||
*
|
||||
* When we have processed a group that starts off with a known-false
|
||||
* #if/#elif sequence (which has therefore been deleted) followed by a
|
||||
* #elif that we don't understand and therefore must keep, we turn the
|
||||
* #elif that we don't understand and therefore must keep, we edit the
|
||||
* latter into a #if to keep the nesting correct.
|
||||
*
|
||||
* When we find a true #elif in a group, the following block will
|
||||
* always be kept and the rest of the sequence after the next #elif or
|
||||
* #else will be discarded. We change the #elif to #else and the
|
||||
* #else will be discarded. We edit the #elif into a #else and the
|
||||
* following directive to #endif since this has the desired behaviour.
|
||||
*
|
||||
* "Dodgy" directives are split across multiple lines, the most common
|
||||
* example being a multi-line comment hanging off the right of the
|
||||
* directive. We can handle them correctly only if there is no change
|
||||
* from printing to dropping (or vice versa) caused by that directive.
|
||||
* If the directive is the first of a group we have a choice between
|
||||
* failing with an error, or passing it through unchanged instead of
|
||||
* evaluating it. The latter is not the default to avoid questions from
|
||||
* users about unifdef unexpectedly leaving behind preprocessor directives.
|
||||
*/
|
||||
typedef void state_fn(void);
|
||||
|
||||
@ -317,65 +348,103 @@ static void Eioccc(void) { error("Obfuscated preprocessor control line"); }
|
||||
static void print (void) { flushline(true); }
|
||||
static void drop (void) { flushline(false); }
|
||||
/* output lacks group's start line */
|
||||
static void Strue (void) { drop(); unignore(); state(IS_TRUE_PREFIX); }
|
||||
static void Sfalse(void) { drop(); unignore(); state(IS_FALSE_PREFIX); }
|
||||
static void Selse (void) { drop(); state(IS_TRUE_ELSE); }
|
||||
static void Strue (void) { drop(); ignoreoff(); state(IS_TRUE_PREFIX); }
|
||||
static void Sfalse(void) { drop(); ignoreoff(); state(IS_FALSE_PREFIX); }
|
||||
static void Selse (void) { drop(); state(IS_TRUE_ELSE); }
|
||||
/* print/pass this block */
|
||||
static void Pelif (void) { print(); unignore(); state(IS_PASS_MIDDLE); }
|
||||
static void Pelse (void) { print(); state(IS_PASS_ELSE); }
|
||||
static void Pelif (void) { print(); ignoreoff(); state(IS_PASS_MIDDLE); }
|
||||
static void Pelse (void) { print(); state(IS_PASS_ELSE); }
|
||||
static void Pendif(void) { print(); --depth; }
|
||||
/* discard this block */
|
||||
static void Dfalse(void) { drop(); unignore(); state(IS_FALSE_TRAILER); }
|
||||
static void Delif (void) { drop(); unignore(); state(IS_FALSE_MIDDLE); }
|
||||
static void Delse (void) { drop(); state(IS_FALSE_ELSE); }
|
||||
static void Dfalse(void) { drop(); ignoreoff(); state(IS_FALSE_TRAILER); }
|
||||
static void Delif (void) { drop(); ignoreoff(); state(IS_FALSE_MIDDLE); }
|
||||
static void Delse (void) { drop(); state(IS_FALSE_ELSE); }
|
||||
static void Dendif(void) { drop(); --depth; }
|
||||
/* first line of group */
|
||||
static void Fdrop (void) { nest(); Dfalse(); }
|
||||
static void Fpass (void) { nest(); Pelif(); }
|
||||
static void Ftrue (void) { nest(); Strue(); }
|
||||
static void Ffalse(void) { nest(); Sfalse(); }
|
||||
/* variable pedantry for obfuscated lines */
|
||||
static void Oiffy (void) { if (iocccok) Fpass(); else Eioccc(); ignoreon(); }
|
||||
static void Oif (void) { if (iocccok) Fpass(); else Eioccc(); }
|
||||
static void Oelif (void) { if (iocccok) Pelif(); else Eioccc(); }
|
||||
/* ignore comments in this block */
|
||||
static void Idrop (void) { Fdrop(); ignore[depth] = true; }
|
||||
static void Itrue (void) { Ftrue(); ignore[depth] = true; }
|
||||
static void Ifalse(void) { Ffalse(); ignore[depth] = true; }
|
||||
/* modify this line */
|
||||
static void
|
||||
Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); }
|
||||
static void
|
||||
Mtrue (void) { strcpy(keyword, "else\n"); print(); state(IS_TRUE_MIDDLE); }
|
||||
static void
|
||||
Melif (void) { strcpy(keyword, "endif\n"); print(); state(IS_FALSE_TRAILER); }
|
||||
static void
|
||||
Melse (void) { strcpy(keyword, "endif\n"); print(); state(IS_FALSE_ELSE); }
|
||||
static void Idrop (void) { Fdrop(); ignoreon(); }
|
||||
static void Itrue (void) { Ftrue(); ignoreon(); }
|
||||
static void Ifalse(void) { Ffalse(); ignoreon(); }
|
||||
/* edit this line */
|
||||
static void Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); }
|
||||
static void Mtrue (void) { keywordedit("else\n"); state(IS_TRUE_MIDDLE); }
|
||||
static void Melif (void) { keywordedit("endif\n"); state(IS_FALSE_TRAILER); }
|
||||
static void Melse (void) { keywordedit("endif\n"); state(IS_FALSE_ELSE); }
|
||||
|
||||
static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
|
||||
/* IS_OUTSIDE */
|
||||
{print,Itrue,Ifalse,Fpass,Ftrue,Ffalse,Eelif, Eelif, Eelif, Eelse,Eendif,NULL},
|
||||
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
|
||||
Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif,
|
||||
print, NULL },
|
||||
/* IS_FALSE_PREFIX */
|
||||
{drop, Idrop,Idrop, Fdrop,Fdrop,Fdrop, Mpass, Strue, Sfalse,Selse,Dendif,Eeof},
|
||||
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
|
||||
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
|
||||
drop, Eeof },
|
||||
/* IS_TRUE_PREFIX */
|
||||
{print,Itrue,Ifalse,Fpass,Ftrue,Ffalse,Dfalse,Dfalse,Dfalse,Delse,Dendif,Eeof},
|
||||
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
|
||||
Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
|
||||
print, Eeof },
|
||||
/* IS_PASS_MIDDLE */
|
||||
{print,Itrue,Ifalse,Fpass,Ftrue,Ffalse,Pelif, Mtrue, Delif, Pelse,Pendif,Eeof},
|
||||
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
|
||||
Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif,
|
||||
print, Eeof },
|
||||
/* IS_FALSE_MIDDLE */
|
||||
{drop, Idrop,Idrop, Fdrop,Fdrop,Fdrop, Pelif, Mtrue, Delif, Pelse,Pendif,Eeof},
|
||||
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
|
||||
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
|
||||
drop, Eeof },
|
||||
/* IS_TRUE_MIDDLE */
|
||||
{print,Itrue,Ifalse,Fpass,Ftrue,Ffalse,Melif, Melif, Melif, Melse,Pendif,Eeof},
|
||||
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
|
||||
Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
|
||||
print, Eeof },
|
||||
/* IS_PASS_ELSE */
|
||||
{print,Itrue,Ifalse,Fpass,Ftrue,Ffalse,Eelif, Eelif, Eelif, Eelse,Pendif,Eeof},
|
||||
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
|
||||
Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif,
|
||||
print, Eeof },
|
||||
/* IS_FALSE_ELSE */
|
||||
{drop, Idrop,Idrop, Fdrop,Fdrop,Fdrop, Eelif, Eelif, Eelif, Eelse,Dendif,Eeof},
|
||||
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
|
||||
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
|
||||
drop, Eeof },
|
||||
/* IS_TRUE_ELSE */
|
||||
{print,Itrue,Ifalse,Fpass,Ftrue,Ffalse,Eelif, Eelif, Eelif, Eelse,Dendif,Eeof},
|
||||
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
|
||||
Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc,
|
||||
print, Eeof },
|
||||
/* IS_FALSE_TRAILER */
|
||||
{drop, Idrop,Idrop, Fdrop,Fdrop,Fdrop, Dfalse,Dfalse,Dfalse,Delse,Dendif,Eeof}
|
||||
/*PLAIN TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF EOF*/
|
||||
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
|
||||
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
|
||||
drop, Eeof }
|
||||
/*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF
|
||||
TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY)
|
||||
PLAIN EOF */
|
||||
};
|
||||
|
||||
/*
|
||||
* State machine utility functions
|
||||
*/
|
||||
static void
|
||||
ignoreoff(void)
|
||||
{
|
||||
ignoring[depth] = ignoring[depth-1];
|
||||
}
|
||||
static void
|
||||
ignoreon(void)
|
||||
{
|
||||
ignoring[depth] = true;
|
||||
}
|
||||
static void
|
||||
keywordedit(const char *replacement)
|
||||
{
|
||||
strlcpy(keyword, replacement, tline + sizeof(tline) - keyword);
|
||||
print();
|
||||
}
|
||||
static void
|
||||
nest(void)
|
||||
{
|
||||
depth += 1;
|
||||
@ -388,11 +457,6 @@ state(Ifstate is)
|
||||
{
|
||||
ifstate[depth] = is;
|
||||
}
|
||||
static void
|
||||
unignore(void)
|
||||
{
|
||||
ignore[depth] = ignore[depth-1];
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a line to the output or not, according to command line options.
|
||||
@ -464,6 +528,7 @@ getline(void)
|
||||
keyword = tline + (cp - tline);
|
||||
cp = skipsym(cp);
|
||||
kwlen = cp - keyword;
|
||||
/* no way can we deal with a continuation inside a keyword */
|
||||
if (strncmp(cp, "\\\n", 2) == 0)
|
||||
Eioccc();
|
||||
if (strlcmp("ifdef", keyword, kwlen) == 0 ||
|
||||
@ -503,8 +568,12 @@ getline(void)
|
||||
if (retval == LT_ELTRUE || retval == LT_ELFALSE)
|
||||
retval = LT_ELIF;
|
||||
}
|
||||
if (retval != LT_PLAIN && (wascomment || incomment))
|
||||
Eioccc();
|
||||
if (retval != LT_PLAIN && (wascomment || incomment)) {
|
||||
retval += LT_DODGY;
|
||||
if (incomment)
|
||||
linestate = LS_DIRTY;
|
||||
}
|
||||
/* skipcomment should have changed the state */
|
||||
if (linestate == LS_HASH)
|
||||
abort(); /* bug */
|
||||
}
|
||||
@ -582,7 +651,7 @@ eval_unary(const struct ops *ops, int *valp, const char **cpp)
|
||||
int sym;
|
||||
|
||||
cp = skipcomment(*cpp);
|
||||
if(*cp == '!') {
|
||||
if (*cp == '!') {
|
||||
debug("eval%d !", ops - eval_ops);
|
||||
cp++;
|
||||
if (eval_unary(ops, valp, &cp) == LT_IF)
|
||||
@ -869,8 +938,9 @@ static void
|
||||
error(const char *msg)
|
||||
{
|
||||
if (depth == 0)
|
||||
errx(2, "%s: %d: %s", filename, linenum, msg);
|
||||
warnx("%s: %d: %s", filename, linenum, msg);
|
||||
else
|
||||
errx(2, "%s: %d: %s (#if line %d depth %d)",
|
||||
warnx("%s: %d: %s (#if line %d depth %d)",
|
||||
filename, linenum, msg, stifline[depth], depth);
|
||||
errx(2, "output may be truncated");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user