diff options
author | Dag-Erling Smørgrav <des@FreeBSD.org> | 2023-08-21 17:33:42 +0000 |
---|---|---|
committer | Dag-Erling Smørgrav <des@FreeBSD.org> | 2023-08-21 17:33:42 +0000 |
commit | 2b7d40ea0c8e96b1322488f9154c89a7a7dd55e7 (patch) | |
tree | 5280e4e4936ebb72ad062c587af08d1ebc068892 | |
parent | 9b3517a49d4e15b97a68bf9e9d68ddda104bf79d (diff) |
Import unifdef 2.12vendor/unifdef/2.12
-rw-r--r-- | .travis.yml | 42 | ||||
-rw-r--r-- | COPYING | 2 | ||||
-rw-r--r-- | README | 13 | ||||
-rwxr-xr-x | ifdef-how.pl | 42 | ||||
-rwxr-xr-x | scripts/gitlog2changelog.sh | 3 | ||||
-rwxr-xr-x | scripts/runtests.sh | 5 | ||||
-rw-r--r-- | tests/000-init.experr | 0 | ||||
-rw-r--r-- | tests/000-init.expout | 0 | ||||
-rw-r--r-- | tests/000-init.exprc | 1 | ||||
-rw-r--r-- | tests/000-init.sh | 1 | ||||
-rw-r--r-- | tests/dangle.c | 6 | ||||
-rw-r--r-- | tests/dangle.experr | 0 | ||||
-rw-r--r-- | tests/dangle.expout | 6 | ||||
-rw-r--r-- | tests/dangle.exprc | 1 | ||||
-rw-r--r-- | tests/dangle.sh | 1 | ||||
-rw-r--r-- | tests/outperms.sh | 5 | ||||
-rw-r--r-- | tests/overperms.sh | 5 | ||||
-rw-r--r-- | tests/whitespace-1.experr | 2 | ||||
-rw-r--r-- | unifdef.1 | 38 | ||||
-rw-r--r-- | unifdef.c | 60 | ||||
-rw-r--r-- | win32/unifdef.h | 10 | ||||
-rw-r--r-- | win32/win32.c | 18 |
22 files changed, 198 insertions, 63 deletions
diff --git a/.travis.yml b/.travis.yml index eea1217fed50..39aa4292de14 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,19 +1,42 @@ language: c +sudo: false + +os: + - linux + - osx + compiler: - gcc - clang matrix: - include: - - compiler: i586-mingw32msvc-gcc - env: BUILD_MINGW="yes" - -before_install: - - sudo apt-get -qq update + include: + ## Ubuntu 14.04 Trusty (beta), sudo required! + - os: linux + dist: trusty + sudo: required + compiler: gcc + env: TRUSTY="yes" + - os: linux + dist: trusty + sudo: required + compiler: clang + env: TRUSTY="yes" + ## MinGW / wine + - os: linux + sudo: required + compiler: i586-mingw32msvc-gcc + env: BUILD_MINGW="yes" + allow_failures: + - compiler: i586-mingw32msvc-gcc install: - - if test "${BUILD_MINGW}" = "yes"; then sudo apt-get -qq install wine; fi + - env | grep -v "encrypted" | LC_ALL=C sort + - if test "${BUILD_MINGW}" = "yes"; then + sudo apt-get -qq update && + sudo apt-get -qq install wine; + fi script: - if test "${BUILD_MINGW}" != "yes"; then @@ -28,8 +51,9 @@ script: make -f win32/Makefile.mingw test; fi -## whitelist branches: only: - master - - tmp + - next + - /^travis.*/ + - /^tmp.*/ @@ -14,7 +14,7 @@ remain) so it now carries the more liberal two-clause licence. Unless otherwise stated, the files in this package are: - Copyright (c) 2002 - 2015 Tony Finch <dot@dotat.at> + Copyright (c) 2002 - 2020 Tony Finch <dot@dotat.at> unifdefall.sh is: @@ -11,9 +11,6 @@ Please see the INSTALL file for installation instructions. Pre-formatted documentation can be found in unifdef.txt -You can subscribe to release announcements at: - http://freecode.com/projects/unifdef - You can download the latest release tar and zip files from: http://dotat.at/prog/unifdef @@ -23,9 +20,10 @@ You can clone the development repository using: I also maintain a copy at http://github.com/fanf2/unifdef (Warning: GitHub's zip download is incomplete and unusable.) -Please send bug reports and patches to me. Unless you state otherwise, -I will assume that any contributions are under the two-clause BSD -licence. See the COPYING file for details. +Please send bug reports and patches to me via email to the +address above. Unless you state otherwise, I will assume that +any contributions are under the two-clause BSD licence. See +the COPYING file for details. Thanks to the following people for their contributions: @@ -38,6 +36,9 @@ Jonathan Nieder <jrnieder@gmail.com> Anders H Kaseorg <andersk@mit.edu> - bug fixes and other improvements +Ruediger Meier <ruediger.meier@ga-group.nl> + - build and portability cleanups + Ben Hutchings at Solarflare Communications - lenient evaluation of && and || diff --git a/ifdef-how.pl b/ifdef-how.pl new file mode 100755 index 000000000000..f8b487512c2c --- /dev/null +++ b/ifdef-how.pl @@ -0,0 +1,42 @@ +#!/usr/bin/perl + +use warnings; +use strict; + +if (@ARGV != 2) { + die <<END; +usage: ifdef-how <file> <line> + +Print the sequence of preprocessor conditionals which lead to the +given line being retained after preprocessing. There is no output +if the line is always retained. Conditionals that must be true are +printed verbatim; conditionals that musy be false have their +preprocessor keyword prefixed with NOT. + +Warning: this program does not parse comments or strings, so it will +not handle tricky code correctly. +END +} + +my $file = shift; +my $line = shift; + +open my $fh, '<', $file + or die "ifdef-how: open $file: $!\n"; + +my @stack; +while (<$fh>) { + last if $. == $line; + if (m{^\s*#\s*(if|ifdef|ifndef)\b}) { + push @stack, $_; + } + if (m{^\s*#\s*(elif|else)\b}) { + $stack[-1] =~ s{^(\s*#\s*)(?!NOT)\b}{${1}NOT}gm; + $stack[-1] .= $_; + } + if (m{^\s*#\s*endif\b}) { + pop @stack; + } +} + +print @stack; diff --git a/scripts/gitlog2changelog.sh b/scripts/gitlog2changelog.sh index 8d9e68f418b5..52130237e72a 100755 --- a/scripts/gitlog2changelog.sh +++ b/scripts/gitlog2changelog.sh @@ -2,7 +2,8 @@ line="---------------------------------------------------" -git log --no-merges --decorate -M --stat --pretty=format:"$line%n%ai %an <%ae>%d%n%n%s%n%n%b" | +git log --no-merges -M --stat \ + --pretty=format:"$line%n%ai %an <%ae>%n%n%s%n%n%b" | uniq | fold -s echo echo $line diff --git a/scripts/runtests.sh b/scripts/runtests.sh index 6a2682fa4b7b..452f0e9e06e1 100755 --- a/scripts/runtests.sh +++ b/scripts/runtests.sh @@ -10,6 +10,11 @@ do sh ./${cmd} >${t}.out 2>${t}.err echo $? >${t}.rc + # strip carriage returns from error output + # in case we are trying to run on MinGW + tr -d '
' >${t}.xerr <${t}.err + mv ${t}.xerr ${t}.err + ok=true for e in out err rc do diff --git a/tests/000-init.experr b/tests/000-init.experr new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tests/000-init.experr diff --git a/tests/000-init.expout b/tests/000-init.expout new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tests/000-init.expout diff --git a/tests/000-init.exprc b/tests/000-init.exprc new file mode 100644 index 000000000000..573541ac9702 --- /dev/null +++ b/tests/000-init.exprc @@ -0,0 +1 @@ +0 diff --git a/tests/000-init.sh b/tests/000-init.sh new file mode 100644 index 000000000000..174f5c4a84a6 --- /dev/null +++ b/tests/000-init.sh @@ -0,0 +1 @@ +unifdef </dev/null >/dev/null 2>&1 || true diff --git a/tests/dangle.c b/tests/dangle.c new file mode 100644 index 000000000000..370a976dbd14 --- /dev/null +++ b/tests/dangle.c @@ -0,0 +1,6 @@ +#ifdef FIRST +wombats +#endif /* com + mmm + mmmm + ment */ diff --git a/tests/dangle.experr b/tests/dangle.experr new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tests/dangle.experr diff --git a/tests/dangle.expout b/tests/dangle.expout new file mode 100644 index 000000000000..370a976dbd14 --- /dev/null +++ b/tests/dangle.expout @@ -0,0 +1,6 @@ +#ifdef FIRST +wombats +#endif /* com + mmm + mmmm + ment */ diff --git a/tests/dangle.exprc b/tests/dangle.exprc new file mode 100644 index 000000000000..573541ac9702 --- /dev/null +++ b/tests/dangle.exprc @@ -0,0 +1 @@ +0 diff --git a/tests/dangle.sh b/tests/dangle.sh new file mode 100644 index 000000000000..0520ac5bb372 --- /dev/null +++ b/tests/dangle.sh @@ -0,0 +1 @@ +unifdef dangle.c diff --git a/tests/outperms.sh b/tests/outperms.sh index 9d134620aecd..2583bf5c076d 100644 --- a/tests/outperms.sh +++ b/tests/outperms.sh @@ -1,7 +1,10 @@ umask 027 unifdef -DFOO=1 -DFOOB=42 -UBAR -ooutfile.c if1.c e=$? -ls -l outfile.c | cut -d' ' -f1 1>&2 +case ${BUILD_MINGW} in +(yes) printf '%s\n' '-rw-r-----' 1>&2 ;; +(*) ls -l outfile.c | cut -d' ' -f1 1>&2 ;; +esac cat outfile.c rm outfile.c exit $e diff --git a/tests/overperms.sh b/tests/overperms.sh index 6de7e5341bb4..fa1559333c40 100644 --- a/tests/overperms.sh +++ b/tests/overperms.sh @@ -3,7 +3,10 @@ chmod 640 outfile.c ls -l outfile.c | cut -d' ' -f1 1>&2 unifdef -DFOO=1 -DFOOB=42 -UBAR -m outfile.c e=$? -ls -l outfile.c | cut -d' ' -f1 1>&2 +case ${BUILD_MINGW} in +(yes) printf '%s\n' '-rw-r-----' 1>&2 ;; +(*) ls -l outfile.c | cut -d' ' -f1 1>&2 ;; +esac cat outfile.c rm outfile.c exit $e diff --git a/tests/whitespace-1.experr b/tests/whitespace-1.experr index 6c7d2adb314a..cb23fce713ce 100644 --- a/tests/whitespace-1.experr +++ b/tests/whitespace-1.experr @@ -1,2 +1,2 @@ -unifdef: whitespace.c: 3: Obfuscated preprocessor control line (#if line 1 depth 1) +unifdef: whitespace.c: 4: Obfuscated preprocessor control line (#if line 1 depth 1) unifdef: Output may be truncated diff --git a/unifdef.1 b/unifdef.1 index 646a2b9792d6..6d55a0048dcf 100644 --- a/unifdef.1 +++ b/unifdef.1 @@ -182,9 +182,12 @@ utility understands just enough about C to know when one of the directives is inactive because it is inside a comment, -or affected by a backslash-continued line. +or cannot be evaluated because it is split by a backslash-continued line. It spots unusually-formatted preprocessor directives -and knows when the layout is too odd for it to handle. +and passes them through unchanged when the layout is too odd for it to handle. +(See the +.Sx BUGS +section below.) .Pp A script called .Nm unifdefall @@ -485,30 +488,43 @@ command appeared in support was added in .Fx 4.7 . .Sh AUTHORS +.An -nosplit The original implementation was written by -.An Dave Yost Aq Dave@Yost.com . -.An Tony Finch Aq dot@dotat.at +.An Dave Yost Aq Mt Dave@Yost.com . +.An Tony Finch Aq Mt dot@dotat.at rewrote it to support .Tn ANSI\~C . .Sh BUGS +.Bl -bullet +.It Expression evaluation is very limited. -.Pp +.It Character constants are not evaluated. String literals and character constants in .Fl f definition files are ignored rather than parsed as part of a macro's replacement tokens. -.Pp -Handling one line at a time means -preprocessor directives split across more than one physical line +.It +Only the basic form of C++ raw string literals is recognized, +like +.Li R"(string)" +without delimiters as in +.Li R"delimiter(string)delimiter" . +.It +Source files are processed one line at a time, +so preprocessor directives split across more than one physical line (because of comments or backslash-newline) cannot be handled in every situation. -.Pp +.It Trigraphs are not recognized. -.Pp +.It There is no support for macros with different definitions at different points in the source file. -.Pp +.It The text-mode and ignore functionality does not correspond to modern .Xr cpp 1 behaviour. +.El +.Pp +Please send bug reports by email to +.Aq Mt dot@dotat.at . diff --git a/unifdef.c b/unifdef.c index 9a16fc941c21..dc145a24232f 100644 --- a/unifdef.c +++ b/unifdef.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 - 2015 Tony Finch <dot@dotat.at> + * Copyright (c) 2002 - 2020 Tony Finch <dot@dotat.at> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -114,7 +114,8 @@ typedef enum { STARTING_COMMENT, /* just after slash-backslash-newline */ FINISHING_COMMENT, /* star-backslash-newline in a C comment */ CHAR_LITERAL, /* inside '' */ - STRING_LITERAL /* inside "" */ + STRING_LITERAL, /* inside "" */ + RAW_STRING_LITERAL /* inside R"()" */ } Comment_state; static char const * const comment_name[] = { @@ -848,12 +849,14 @@ parseline(void) if (fgets(tline + len, MAXLINE - len, input) == NULL) { if (ferror(input)) err(2, "can't read %s", filename); - /* append the missing newline at eof */ + debug("parser insert newline at EOF", linenum); strcpy(tline + len, newline); cp += strlen(newline); linestate = LS_START; } else { - linestate = LS_DIRTY; + debug("parser concatenate dangling whitespace"); + ++linenum; + cp = skipcomment(cp); } } if (retval != LT_PLAIN && (wascomment || linestate != LS_START)) { @@ -974,24 +977,24 @@ struct ops { struct op op[5]; }; static const struct ops eval_ops[] = { - { eval_table, { { "||", op_or } } }, - { eval_table, { { "&&", op_and } } }, - { eval_table, { { "|", op_bor, "|" } } }, - { eval_table, { { "^", op_bxor } } }, - { eval_table, { { "&", op_band, "&" } } }, - { eval_table, { { "==", op_eq }, - { "!=", op_ne } } }, - { eval_table, { { "<=", op_le }, - { ">=", op_ge }, - { "<", op_lt, "<=" }, - { ">", op_gt, ">=" } } }, - { eval_table, { { "<<", op_blsh }, - { ">>", op_brsh } } }, - { eval_table, { { "+", op_add }, - { "-", op_sub } } }, - { eval_unary, { { "*", op_mul }, - { "/", op_div }, - { "%", op_mod } } }, + { eval_table, { { "||", op_or, NULL } } }, + { eval_table, { { "&&", op_and, NULL } } }, + { eval_table, { { "|", op_bor, "|" } } }, + { eval_table, { { "^", op_bxor, NULL } } }, + { eval_table, { { "&", op_band, "&" } } }, + { eval_table, { { "==", op_eq, NULL }, + { "!=", op_ne, NULL } } }, + { eval_table, { { "<=", op_le, NULL }, + { ">=", op_ge, NULL }, + { "<", op_lt, "<=" }, + { ">", op_gt, ">=" } } }, + { eval_table, { { "<<", op_blsh, NULL }, + { ">>", op_brsh, NULL } } }, + { eval_table, { { "+", op_add, NULL }, + { "-", op_sub, NULL } } }, + { eval_unary, { { "*", op_mul, NULL }, + { "/", op_div, NULL }, + { "%", op_mod, NULL } } }, }; /* Current operator precedence level */ @@ -1264,6 +1267,10 @@ skipcomment(const char *cp) incomment = STRING_LITERAL; linestate = LS_DIRTY; cp += 1; + } else if (strncmp(cp, "R\"(", 3) == 0) { + incomment = RAW_STRING_LITERAL; + linestate = LS_DIRTY; + cp += 3; } else if (strncmp(cp, "\n", 1) == 0) { linestate = LS_START; cp += 1; @@ -1298,6 +1305,13 @@ skipcomment(const char *cp) } else cp += 1; continue; + case RAW_STRING_LITERAL: + if (strncmp(cp, ")\"", 2) == 0) { + incomment = NO_COMMENT; + cp += 2; + } else + cp += 1; + continue; case C_COMMENT: if (strncmp(cp, "*\\\r\n", 4) == 0) { incomment = FINISHING_COMMENT; @@ -1626,7 +1640,7 @@ xstrdup(const char *start, const char *end) if (end < start) abort(); /* bug */ n = (size_t)(end - start) + 1; - s = malloc(n); + s = (char *)malloc(n); if (s == NULL) err(2, "malloc"); snprintf(s, n, "%s", start); diff --git a/win32/unifdef.h b/win32/unifdef.h index bebf7381e832..2fe301bd026e 100644 --- a/win32/unifdef.h +++ b/win32/unifdef.h @@ -52,11 +52,17 @@ /* used by err.c and getopt.c */ #define _getprogname() "unifdef" +/* + * The snprintf() workaround is unnecessary in Visual Studio 2015 or later + * but dogma dictates that #if directives are not allowed inside unifdef. + */ +#define snprintf c99_snprintf + /* win32.c */ -int replace(const char *old, const char *new); +int replace(const char *oldname, const char *newname); FILE *mktempmode(char *tmp, int mode); FILE *fbinmode(FILE *fp); -int snprintf(char *buf, size_t buflen, const char *format, ...); +int c99_snprintf(char *buf, size_t buflen, const char *format, ...); /* err.c */ void err(int, const char *, ...); diff --git a/win32/win32.c b/win32/win32.c index 168f7e7cc041..931b8194500b 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -31,11 +31,11 @@ * remove anything that might be in the way before renaming. */ int -replace(const char *old, const char *new) +replace(const char *oldname, const char *newname) { - if (remove(new) < 0) - warn("can't remove \"%s\"", new); - return (rename(old, new)); + if (remove(newname) < 0 && errno != ENOENT) + warn("can't remove \"%s\"", newname); + return (rename(oldname, newname)); } FILE * @@ -53,9 +53,13 @@ fbinmode(FILE *fp) } /* - * Windows has _snprintf() but it does not work like real snprintf(). + * This is more long-winded than seems necessary because MinGW + * doesn't have a proper implementation of _vsnprintf_s(). + * + * This link has some useful info about snprintf() on Windows: + * http://stackoverflow.com/questions/2915672/snprintf-and-visual-studio-2010 */ -int snprintf(char *buf, size_t buflen, const char *format, ...) +int c99_snprintf(char *buf, size_t buflen, const char *format, ...) { va_list ap; int outlen, cpylen, tmplen; @@ -73,7 +77,7 @@ int snprintf(char *buf, size_t buflen, const char *format, ...) /* Paranoia about off-by-one errors in _snprintf() */ tmplen = outlen + 2; - tmp = malloc(tmplen); + tmp = (char *)malloc(tmplen); if (tmp == NULL) err(2, "malloc"); va_start(ap, format); |