Update to upstream version 2.3

Add -V (display version) and -S (list controlling symbols per #if
with nesting information) options, and improve unifdefall debug output.
Done committing 0 revisions to SVN

Obtained from: http://dotat.at/prog/unifdef
This commit is contained in:
Tony Finch 2010-03-12 17:55:29 +00:00
parent c1b90938b1
commit 3548be4a24
3 changed files with 91 additions and 41 deletions

View File

@ -29,11 +29,9 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94
.\" $dotat: unifdef/unifdef.1,v 1.63 2010/02/19 16:41:15 fanf2 Exp $
.\" $FreeBSD$ .\" $FreeBSD$
.\" .\"
.Dd January 19, 2010 .Dd March 11, 2010
.Dt UNIFDEF 1 .Dt UNIFDEF 1
.Os .Os
.Sh NAME .Sh NAME
@ -41,7 +39,7 @@
.Nd remove preprocessor conditionals from code .Nd remove preprocessor conditionals from code
.Sh SYNOPSIS .Sh SYNOPSIS
.Nm .Nm
.Op Fl BbcdeKknst .Op Fl bBcdeKknsStV
.Op Fl I Ns Ar path .Op Fl I Ns Ar path
.Op Fl D Ns Ar sym Ns Op = Ns Ar val .Op Fl D Ns Ar sym Ns Op = Ns Ar val
.Op Fl U Ns Ar sym .Op Fl U Ns Ar sym
@ -184,12 +182,6 @@ Specify that a symbol is undefined.
If the same symbol appears in more than one argument, If the same symbol appears in more than one argument,
the last occurrence dominates. the last occurrence dominates.
.Pp .Pp
.It Fl B
Compress blank lines around a deleted section.
Mutually exclusive with the
.Fl b
option.
.Pp
.It Fl b .It Fl b
Replace removed lines with blank lines Replace removed lines with blank lines
instead of deleting them. instead of deleting them.
@ -197,6 +189,12 @@ Mutually exclusive with the
.Fl B .Fl B
option. option.
.Pp .Pp
.It Fl B
Compress blank lines around a deleted section.
Mutually exclusive with the
.Fl b
option.
.Pp
.It Fl c .It Fl c
If the If the
.Fl c .Fl c
@ -285,6 +283,13 @@ for creating
.Nm .Nm
command lines. command lines.
.Pp .Pp
.It Fl S
Like the
.Fl s
option, but the nesting depth of each symbol is also printed.
This is useful for working out the number of possible combinations
of interdependent defined/undefined symbols.
.Pp
.It Fl t .It Fl t
Disables parsing for C comments Disables parsing for C comments
and line continuations, and line continuations,
@ -329,6 +334,9 @@ for compatibility with
.Xr cpp 1 .Xr cpp 1
and to simplify the implementation of and to simplify the implementation of
.Nm unifdefall . .Nm unifdefall .
.Pp
.It Fl V
Print version details.
.El .El
.Pp .Pp
The The

View File

@ -56,12 +56,12 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#ifdef __IDSTRING const char copyright[] =
__IDSTRING(dotat, "$dotat: unifdef/unifdef.c,v 1.198 2010/02/19 16:37:05 fanf2 Exp $"); "@(#) $Version: unifdef-2.3 $\n"
#endif "@(#) $FreeBSD$\n"
#ifdef __FBSDID "@(#) $Author: Tony Finch (dot@dotat.at) $\n"
__FBSDID("$FreeBSD$"); "@(#) $URL: http://dotat.at/prog/unifdef $\n"
#endif ;
/* types of input lines: */ /* types of input lines: */
typedef enum { typedef enum {
@ -172,6 +172,7 @@ static bool strictlogic; /* -K: keep ambiguous #ifs */
static bool killconsts; /* -k: eval constant #ifs */ static bool killconsts; /* -k: eval constant #ifs */
static bool lnnum; /* -n: add #line directives */ static bool lnnum; /* -n: add #line directives */
static bool symlist; /* -s: output symbol list */ static bool symlist; /* -s: output symbol list */
static bool symdepth; /* -S: output symbol depth */
static bool text; /* -t: this is a text file */ static bool text; /* -t: this is a text file */
static const char *symname[MAXSYMS]; /* symbol name */ static const char *symname[MAXSYMS]; /* symbol name */
@ -204,6 +205,8 @@ static int delcount; /* count of deleted lines */
static unsigned blankcount; /* count of blank lines */ static unsigned blankcount; /* count of blank lines */
static unsigned blankmax; /* maximum recent blankcount */ static unsigned blankmax; /* maximum recent blankcount */
static bool constexpr; /* constant #if expression */ static bool constexpr; /* constant #if expression */
static bool zerosyms = true; /* to format symdepth output */
static bool firstsym; /* ditto */
static int exitstat; /* program exit status */ static int exitstat; /* program exit status */
@ -228,6 +231,7 @@ static void state(Ifstate);
static int strlcmp(const char *, const char *, size_t); static int strlcmp(const char *, const char *, size_t);
static void unnest(void); static void unnest(void);
static void usage(void); static void usage(void);
static void version(void);
#define endsym(c) (!isalnum((unsigned char)c) && c != '_') #define endsym(c) (!isalnum((unsigned char)c) && c != '_')
@ -239,7 +243,7 @@ main(int argc, char *argv[])
{ {
int opt; int opt;
while ((opt = getopt(argc, argv, "i:D:U:I:o:BbcdeKklnst")) != -1) while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1)
switch (opt) { switch (opt) {
case 'i': /* treat stuff controlled by these symbols as text */ case 'i': /* treat stuff controlled by these symbols as text */
/* /*
@ -261,16 +265,15 @@ main(int argc, char *argv[])
case 'U': /* undef a symbol */ case 'U': /* undef a symbol */
addsym(false, false, optarg); addsym(false, false, optarg);
break; break;
case 'I': case 'I': /* no-op for compatibility with cpp */
/* no-op for compatibility with cpp */
break;
case 'B': /* compress blank lines around removed section */
compblank = true;
break; break;
case 'b': /* blank deleted lines instead of omitting them */ case 'b': /* blank deleted lines instead of omitting them */
case 'l': /* backwards compatibility */ case 'l': /* backwards compatibility */
lnblank = true; lnblank = true;
break; break;
case 'B': /* compress blank lines around removed section */
compblank = true;
break;
case 'c': /* treat -D as -U and vice versa */ case 'c': /* treat -D as -U and vice versa */
complement = true; complement = true;
break; break;
@ -295,9 +298,14 @@ main(int argc, char *argv[])
case 's': /* only output list of symbols that control #ifs */ case 's': /* only output list of symbols that control #ifs */
symlist = true; symlist = true;
break; break;
case 'S': /* list symbols with their nesting depth */
symlist = symdepth = true;
break;
case 't': /* don't parse C comments */ case 't': /* don't parse C comments */
text = true; text = true;
break; break;
case 'V': /* print version */
version();
default: default:
usage(); usage();
} }
@ -309,7 +317,7 @@ main(int argc, char *argv[])
errx(2, "can only do one file"); errx(2, "can only do one file");
} else if (argc == 1 && strcmp(*argv, "-") != 0) { } else if (argc == 1 && strcmp(*argv, "-") != 0) {
filename = *argv; filename = *argv;
input = fopen(filename, "r"); input = fopen(filename, "rb");
if (input == NULL) if (input == NULL)
err(2, "can't open %s", filename); err(2, "can't open %s", filename);
} else { } else {
@ -345,12 +353,12 @@ main(int argc, char *argv[])
TEMPLATE); TEMPLATE);
ofd = mkstemp(tempname); ofd = mkstemp(tempname);
if (ofd != -1) if (ofd != -1)
output = fdopen(ofd, "w+"); output = fdopen(ofd, "wb+");
if (output == NULL) if (output == NULL)
err(2, "can't create temporary file"); err(2, "can't create temporary file");
fchmod(ofd, ist.st_mode & ACCESSPERMS); fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO));
} else { } else {
output = fopen(ofilename, "w"); output = fopen(ofilename, "wb");
if (output == NULL) if (output == NULL)
err(2, "can't open %s", ofilename); err(2, "can't open %s", ofilename);
} }
@ -359,10 +367,24 @@ main(int argc, char *argv[])
abort(); /* bug */ abort(); /* bug */
} }
static void
version(void)
{
const char *c = copyright;
for (;;) {
while (*++c != '$')
if (*c == '\0')
exit(0);
while (*++c != '$')
putc(*c, stderr);
putc('\n', stderr);
}
}
static void static void
usage(void) usage(void)
{ {
fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]" fprintf(stderr, "usage: unifdef [-bBcdeKknsStV] [-Ipath]"
" [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
exit(2); exit(2);
} }
@ -557,6 +579,8 @@ flushline(bool keep)
delcount += 1; delcount += 1;
blankcount = 0; blankcount = 0;
} }
if (debugging)
fflush(output);
} }
/* /*
@ -565,17 +589,14 @@ flushline(bool keep)
static void static void
process(void) process(void)
{ {
Linetype lineval;
/* When compressing blank lines, act as if the file /* When compressing blank lines, act as if the file
is preceded by a large number of blank lines. */ is preceded by a large number of blank lines. */
blankmax = blankcount = 1000; blankmax = blankcount = 1000;
for (;;) { for (;;) {
linenum++; Linetype lineval = parseline();
lineval = parseline();
trans_table[ifstate[depth]][lineval](); trans_table[ifstate[depth]][lineval]();
debug("process %s -> %s depth %d", debug("process line %d %s -> %s depth %d",
linetype_name[lineval], linenum, linetype_name[lineval],
ifstate_name[ifstate[depth]], depth); ifstate_name[ifstate[depth]], depth);
} }
} }
@ -586,6 +607,8 @@ process(void)
static void static void
closeout(void) closeout(void)
{ {
if (symdepth && !zerosyms)
printf("\n");
if (fclose(output) == EOF) { if (fclose(output) == EOF) {
warn("couldn't write to %s", ofilename); warn("couldn't write to %s", ofilename);
if (overwriting) { if (overwriting) {
@ -628,6 +651,7 @@ parseline(void)
Linetype retval; Linetype retval;
Comment_state wascomment; Comment_state wascomment;
linenum++;
if (fgets(tline, MAXLINE, input) == NULL) if (fgets(tline, MAXLINE, input) == NULL)
return (LT_EOF); return (LT_EOF);
if (newline == NULL) { if (newline == NULL) {
@ -642,6 +666,7 @@ parseline(void)
if (linestate == LS_START) { if (linestate == LS_START) {
if (*cp == '#') { if (*cp == '#') {
linestate = LS_HASH; linestate = LS_HASH;
firstsym = true;
cp = skipcomment(cp + 1); cp = skipcomment(cp + 1);
} else if (*cp != '\0') } else if (*cp != '\0')
linestate = LS_DIRTY; linestate = LS_DIRTY;
@ -715,7 +740,7 @@ parseline(void)
while (*cp != '\0') while (*cp != '\0')
cp = skipcomment(cp + 1); cp = skipcomment(cp + 1);
} }
debug("parser %s comment %s line", debug("parser line %d state %s comment %s line", linenum,
comment_name[incomment], linestate_name[linestate]); comment_name[incomment], linestate_name[linestate]);
return (retval); return (retval);
} }
@ -1108,7 +1133,13 @@ findsym(const char *str)
if (cp == str) if (cp == str)
return (-1); return (-1);
if (symlist) { if (symlist) {
printf("%.*s\n", (int)(cp-str), str); if (symdepth && firstsym)
printf("%s%3d", zerosyms ? "" : "\n", depth);
firstsym = zerosyms = false;
printf("%s%.*s%s",
symdepth ? " " : "",
(int)(cp-str), str,
symdepth ? "" : "\n");
/* we don't care about the value of the symbol */ /* we don't care about the value of the symbol */
return (0); return (0);
} }
@ -1153,6 +1184,8 @@ addsym(bool ignorethis, bool definethis, char *sym)
usage(); usage();
value[symind] = NULL; value[symind] = NULL;
} }
debug("addsym %s=%s", symname[symind],
value[symind] ? value[symind] : "undef");
} }
/* /*

View File

@ -26,7 +26,6 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE. # SUCH DAMAGE.
# #
# $dotat: unifdef/unifdefall.sh,v 1.27 2010/01/19 16:09:50 fanf2 Exp $
# $FreeBSD$ # $FreeBSD$
set -e set -e
@ -36,17 +35,21 @@ if [ ! -e "$unifdef" ]
then then
unifdef=unifdef unifdef=unifdef
fi fi
# export to the final shell command
export unifdef case "$@" in
"-d "*) echo DEBUGGING 1>&2
debug=-d
shift
esac
basename=$(basename "$0") basename=$(basename "$0")
tmp=$(mktemp -d "${TMPDIR:-/tmp}/$basename.XXXXXXXXXX") || exit 2 tmp=$(mktemp -d "${TMPDIR:-/tmp}/$basename.XXXXXXXXXX") || exit 2
trap 'rm -r "$tmp" || exit 1' EXIT trap 'rm -r "$tmp" || exit 2' EXIT
export LC_ALL=C export LC_ALL=C
# list of all controlling macros # list of all controlling macros
"$unifdef" -s "$@" | sort | uniq >"$tmp/ctrl" "$unifdef" $debug -s "$@" | sort | uniq >"$tmp/ctrl"
# list of all macro definitions # list of all macro definitions
cpp -dM "$@" | sort | sed 's/^#define //' >"$tmp/hashdefs" cpp -dM "$@" | sort | sed 's/^#define //' >"$tmp/hashdefs"
# list of defined macro names # list of defined macro names
@ -58,7 +61,7 @@ comm -12 "$tmp/ctrl" "$tmp/alldef" >"$tmp/def"
# and converts them to unifdef command-line arguments # and converts them to unifdef command-line arguments
sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script" sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script"
# create the final unifdef command # create the final unifdef command
{ echo '"$unifdef" -k \' { echo "$unifdef" $debug -k '\'
# convert the controlling undefined macros to -U arguments # convert the controlling undefined macros to -U arguments
sed 's/.*/-U& \\/' <"$tmp/undef" sed 's/.*/-U& \\/' <"$tmp/undef"
# convert the controlling defined macros to quoted -D arguments # convert the controlling defined macros to quoted -D arguments
@ -66,5 +69,11 @@ sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script"
sed "s/'/'\\\\''/g;s/.*/'&' \\\\/" sed "s/'/'\\\\''/g;s/.*/'&' \\\\/"
echo '"$@"' echo '"$@"'
} >"$tmp/cmd" } >"$tmp/cmd"
case $debug in
-d) for i in ctrl hashdefs alldef undef def script cmd
do echo ==== $i
cat "$tmp/$i"
done 1>&2
esac
# run the command we just created # run the command we just created
sh "$tmp/cmd" "$@" sh "$tmp/cmd" "$@"