Update to upstream version 1.338

Fix a long-standing cpp compatibility bug: The -DFOO argument
(without an explicit value) should define FOO to 1 not to the empty
string.

Add support for CRLF newlines, based on a suggestion from Mark Rushakoff.

Obtained from:	http://dotat.at/prog/unifdef/
This commit is contained in:
Tony Finch 2010-02-19 16:54:51 +00:00
parent fe2f808774
commit 86eea914a7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=204092
2 changed files with 50 additions and 27 deletions

View File

@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94
.\" $dotat: unifdef/unifdef.1,v 1.62 2010/01/19 17:33:53 fanf2 Exp $
.\" $dotat: unifdef/unifdef.1,v 1.63 2010/02/19 16:41:15 fanf2 Exp $
.\" $FreeBSD$
.\"
.Dd January 19, 2010
@ -168,14 +168,16 @@ with appropriate arguments to process the file.
.Sh OPTIONS
.Pp
.Bl -tag -width indent -compact
.It Fl D Ns Ar sym Ns Op = Ns Ar val
Specify that a symbol is defined,
and optionally specify what value to give it
for the purpose of handling
.It Fl D Ns Ar sym Ns = Ns Ar val
Specify that a symbol is defined to a given value
which is used when evaluating
.Ic #if
and
.Ic #elif
directives.
control expressions.
.Pp
.It Fl D Ns Ar sym
Specify that a symbol is defined to the value 1.
.Pp
.It Fl U Ns Ar sym
Specify that a symbol is undefined.

View File

@ -39,8 +39,8 @@
* #else's and #endif's to see that they match their
* corresponding #ifdef or #ifndef
*
* The first two items above require better buffer handling, which would
* also make it possible to handle all "dodgy" directives correctly.
* These require better buffer handling, which would also make
* it possible to handle all "dodgy" directives correctly.
*/
#include <sys/types.h>
@ -57,7 +57,7 @@
#include <unistd.h>
#ifdef __IDSTRING
__IDSTRING(dotat, "$dotat: unifdef/unifdef.c,v 1.193 2010/01/19 18:03:02 fanf2 Exp $");
__IDSTRING(dotat, "$dotat: unifdef/unifdef.c,v 1.198 2010/02/19 16:37:05 fanf2 Exp $");
#endif
#ifdef __FBSDID
__FBSDID("$FreeBSD$");
@ -190,6 +190,10 @@ static char tempname[FILENAME_MAX]; /* used when overwriting */
static char tline[MAXLINE+EDITSLOP];/* input buffer plus space */
static char *keyword; /* used for editing #elif's */
static const char *newline; /* input file format */
static const char newline_unix[] = "\n";
static const char newline_crlf[] = "\r\n";
static Comment_state incomment; /* comment parser state */
static Line_state linestate; /* #if line parser state */
static Ifstate ifstate[MAXDEPTH]; /* #if processor state */
@ -313,6 +317,7 @@ main(int argc, char *argv[])
input = stdin;
}
if (ofilename == NULL) {
ofilename = "[stdout]";
output = stdout;
} else {
struct stat ist, ost;
@ -336,7 +341,8 @@ main(int argc, char *argv[])
"%.*s/" TEMPLATE,
(int)(dirsep - ofilename), ofilename);
else
strlcpy(tempname, TEMPLATE, sizeof(tempname));
snprintf(tempname, sizeof(tempname),
TEMPLATE);
ofd = mkstemp(tempname);
if (ofd != -1)
output = fdopen(ofd, "w+");
@ -429,9 +435,9 @@ 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 void Mtrue (void) { keywordedit("else"); state(IS_TRUE_MIDDLE); }
static void Melif (void) { keywordedit("endif"); state(IS_FALSE_TRAILER); }
static void Melse (void) { keywordedit("endif"); state(IS_FALSE_ELSE); }
static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
/* IS_OUTSIDE */
@ -497,7 +503,8 @@ ignoreon(void)
static void
keywordedit(const char *replacement)
{
strlcpy(keyword, replacement, tline + sizeof(tline) - keyword);
snprintf(keyword, tline + sizeof(tline) - keyword,
"%s%s", replacement, newline);
print();
}
static void
@ -532,20 +539,20 @@ flushline(bool keep)
if (symlist)
return;
if (keep ^ complement) {
bool blankline = tline[strspn(tline, " \t\n")] == '\0';
bool blankline = tline[strspn(tline, " \t\r\n")] == '\0';
if (blankline && compblank && blankcount != blankmax) {
delcount += 1;
blankcount += 1;
} else {
if (lnnum && delcount > 0)
printf("#line %d\n", linenum);
printf("#line %d%s", linenum, newline);
fputs(tline, output);
delcount = 0;
blankmax = blankcount = blankline ? blankcount + 1 : 0;
}
} else {
if (lnblank)
putc('\n', output);
fputs(newline, output);
exitstat = 1;
delcount += 1;
blankcount = 0;
@ -580,7 +587,7 @@ static void
closeout(void)
{
if (fclose(output) == EOF) {
warn("couldn't write to output");
warn("couldn't write to %s", ofilename);
if (overwriting) {
unlink(tempname);
errx(2, "%s unchanged", filename);
@ -623,6 +630,12 @@ parseline(void)
if (fgets(tline, MAXLINE, input) == NULL)
return (LT_EOF);
if (newline == NULL) {
if (strrchr(tline, '\n') == strrchr(tline, '\r') + 1)
newline = newline_crlf;
else
newline = newline_unix;
}
retval = LT_PLAIN;
wascomment = incomment;
cp = skipcomment(tline);
@ -638,7 +651,8 @@ parseline(void)
cp = skipsym(cp);
kwlen = cp - keyword;
/* no way can we deal with a continuation inside a keyword */
if (strncmp(cp, "\\\n", 2) == 0)
if (strncmp(cp, "\\\r\n", 3) == 0 ||
strncmp(cp, "\\\n", 2) == 0)
Eioccc();
if (strlcmp("ifdef", keyword, kwlen) == 0 ||
strlcmp("ifndef", keyword, kwlen) == 0) {
@ -689,9 +703,8 @@ parseline(void)
size_t len = cp - tline;
if (fgets(tline + len, MAXLINE - len, input) == NULL) {
/* append the missing newline */
tline[len+0] = '\n';
tline[len+1] = '\0';
cp++;
strcpy(tline + len, newline);
cp += strlen(newline);
linestate = LS_START;
} else {
linestate = LS_DIRTY;
@ -947,11 +960,16 @@ skipcomment(const char *cp)
}
while (*cp != '\0')
/* don't reset to LS_START after a line continuation */
if (strncmp(cp, "\\\n", 2) == 0)
if (strncmp(cp, "\\\r\n", 3) == 0)
cp += 3;
else if (strncmp(cp, "\\\n", 2) == 0)
cp += 2;
else switch (incomment) {
case NO_COMMENT:
if (strncmp(cp, "/\\\n", 3) == 0) {
if (strncmp(cp, "/\\\r\n", 4) == 0) {
incomment = STARTING_COMMENT;
cp += 4;
} else if (strncmp(cp, "/\\\n", 3) == 0) {
incomment = STARTING_COMMENT;
cp += 3;
} else if (strncmp(cp, "/*", 2) == 0) {
@ -971,7 +989,7 @@ skipcomment(const char *cp)
} else if (strncmp(cp, "\n", 1) == 0) {
linestate = LS_START;
cp += 1;
} else if (strchr(" \t", *cp) != NULL) {
} else if (strchr(" \r\t", *cp) != NULL) {
cp += 1;
} else
return (cp);
@ -1003,7 +1021,10 @@ skipcomment(const char *cp)
cp += 1;
continue;
case C_COMMENT:
if (strncmp(cp, "*\\\n", 3) == 0) {
if (strncmp(cp, "*\\\r\n", 4) == 0) {
incomment = FINISHING_COMMENT;
cp += 4;
} else if (strncmp(cp, "*\\\n", 3) == 0) {
incomment = FINISHING_COMMENT;
cp += 3;
} else if (strncmp(cp, "*/", 2) == 0) {
@ -1124,7 +1145,7 @@ addsym(bool ignorethis, bool definethis, char *sym)
value[symind] = val+1;
*val = '\0';
} else if (*val == '\0')
value[symind] = "";
value[symind] = "1";
else
usage();
} else {