From owner-svn-src-stable-8@FreeBSD.ORG Tue Jan 18 19:31:40 2011 Return-Path: Delivered-To: svn-src-stable-8@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C87281065672; Tue, 18 Jan 2011 19:31:40 +0000 (UTC) (envelope-from fanf@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 7FED08FC15; Tue, 18 Jan 2011 19:31:38 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p0IJVcr6049233; Tue, 18 Jan 2011 19:31:38 GMT (envelope-from fanf@svn.freebsd.org) Received: (from fanf@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p0IJVc20049228; Tue, 18 Jan 2011 19:31:38 GMT (envelope-from fanf@svn.freebsd.org) Message-Id: <201101181931.p0IJVc20049228@svn.freebsd.org> From: Tony Finch Date: Tue, 18 Jan 2011 19:31:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r217551 - stable/8/usr.bin/unifdef X-BeenThere: svn-src-stable-8@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for only the 8-stable src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Jan 2011 19:31:40 -0000 Author: fanf Date: Tue Jan 18 19:31:38 2011 New Revision: 217551 URL: http://svn.freebsd.org/changeset/base/217551 Log: MFC unifdef-2.5 Modified: stable/8/usr.bin/unifdef/Makefile stable/8/usr.bin/unifdef/unifdef.1 stable/8/usr.bin/unifdef/unifdef.c stable/8/usr.bin/unifdef/unifdefall.sh Directory Properties: stable/8/usr.bin/unifdef/ (props changed) Modified: stable/8/usr.bin/unifdef/Makefile ============================================================================== --- stable/8/usr.bin/unifdef/Makefile Tue Jan 18 19:13:03 2011 (r217550) +++ stable/8/usr.bin/unifdef/Makefile Tue Jan 18 19:31:38 2011 (r217551) @@ -4,6 +4,5 @@ PROG= unifdef SCRIPTS=unifdefall.sh MLINKS= unifdef.1 unifdefall.1 -WARNS?= 5 .include Modified: stable/8/usr.bin/unifdef/unifdef.1 ============================================================================== --- stable/8/usr.bin/unifdef/unifdef.1 Tue Jan 18 19:13:03 2011 (r217550) +++ stable/8/usr.bin/unifdef/unifdef.1 Tue Jan 18 19:31:38 2011 (r217551) @@ -1,6 +1,6 @@ .\" Copyright (c) 1985, 1991, 1993 .\" The Regents of the University of California. All rights reserved. -.\" Copyright (c) 2002 - 2009 Tony Finch . All rights reserved. +.\" Copyright (c) 2002 - 2010 Tony Finch . All rights reserved. .\" .\" This code is derived from software contributed to Berkeley by .\" Dave Yost. It was rewritten to support ANSI C by Tony Finch. @@ -29,11 +29,9 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)unifdef.1 8.2 (Berkeley) 4/1/94 -.\" $dotat: unifdef/unifdef.1,v 1.60 2009/11/25 00:11:02 fanf2 Exp $ .\" $FreeBSD$ .\" -.Dd September 24, 2002 +.Dd March 11, 2010 .Dt UNIFDEF 1 .Os .Sh NAME @@ -41,14 +39,15 @@ .Nd remove preprocessor conditionals from code .Sh SYNOPSIS .Nm -.Op Fl BbcdeKknst +.Op Fl bBcdeKknsStV .Op Fl I Ns Ar path .Op Fl D Ns Ar sym Ns Op = Ns Ar val .Op Fl U Ns Ar sym .Op Fl iD Ns Ar sym Ns Op = Ns Ar val .Op Fl iU Ns Ar sym .Ar ... -.Op Ar file +.Op Fl o Ar outfile +.Op Ar infile .Nm unifdefall .Op Fl I Ns Ar path .Ar ... @@ -167,26 +166,22 @@ with appropriate arguments to process th .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. If the same symbol appears in more than one argument, the last occurrence dominates. .Pp -.It Fl B -Compress blank lines around a deleted section. -Mutually exclusive with the -.Fl b -option. -.Pp .It Fl b Replace removed lines with blank lines instead of deleting them. @@ -194,6 +189,12 @@ Mutually exclusive with the .Fl B option. .Pp +.It Fl B +Compress blank lines around a deleted section. +Mutually exclusive with the +.Fl b +option. +.Pp .It Fl c If the .Fl c @@ -205,7 +206,7 @@ i.e., the lines that would have been rem are retained and vice versa. .Pp .It Fl d -Turn on printing of degugging messages. +Turn on printing of debugging messages. .Pp .It Fl e Because @@ -254,6 +255,18 @@ directives to the output following any d so that errors produced when compiling the output file correspond to line numbers in the input file. .Pp +.It Fl o Ar outfile +Write output to the file +.Ar outfile +instead of the standard output. +If +.Ar outfile +is the same as the input file, +the output is written to a temporary file +which is renamed into place when +.Nm +completes successfully. +.Pp .It Fl s Instead of processing the input file as usual, this option causes @@ -270,6 +283,13 @@ for creating .Nm command lines. .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 Disables parsing for C comments and line continuations, @@ -314,6 +334,9 @@ for compatibility with .Xr cpp 1 and to simplify the implementation of .Nm unifdefall . +.Pp +.It Fl V +Print version details. .El .Pp The Modified: stable/8/usr.bin/unifdef/unifdef.c ============================================================================== --- stable/8/usr.bin/unifdef/unifdef.c Tue Jan 18 19:13:03 2011 (r217550) +++ stable/8/usr.bin/unifdef/unifdef.c Tue Jan 18 19:31:38 2011 (r217551) @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002 - 2009 Tony Finch + * Copyright (c) 2002 - 2010 Tony Finch * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -24,27 +24,14 @@ */ /* + * unifdef - remove ifdef'ed lines + * * This code was derived from software contributed to Berkeley by Dave Yost. * It was rewritten to support ANSI C by Tony Finch. The original version * of unifdef carried the 4-clause BSD copyright licence. None of its code * remains in this version (though some of the names remain) so it now * carries a more liberal licence. * - * The latest version is available from http://dotat.at/prog/unifdef - */ - -#include - -#ifdef __IDSTRING -__IDSTRING(dotat, "$dotat: unifdef/unifdef.c,v 1.190 2009/11/27 17:21:26 fanf2 Exp $"); -#endif -#ifdef __FBSDID -__FBSDID("$FreeBSD$"); -#endif - -/* - * unifdef - remove ifdef'ed lines - * * Wishlist: * provide an option which will append the name of the * appropriate symbol after #else's and #endif's @@ -52,12 +39,16 @@ __FBSDID("$FreeBSD$"); * #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 +#include + #include #include +#include #include #include #include @@ -65,6 +56,13 @@ __FBSDID("$FreeBSD$"); #include #include +const char copyright[] = + "@(#) $Version: unifdef-2.5 $\n" + "@(#) $FreeBSD$\n" + "@(#) $Author: Tony Finch (dot@dotat.at) $\n" + "@(#) $URL: http://dotat.at/prog/unifdef $\n" +; + /* types of input lines: */ typedef enum { LT_TRUEI, /* a true #if with ignore flag */ @@ -157,6 +155,11 @@ static char const * const linestate_name #define EDITSLOP 10 /* + * For temporary filenames + */ +#define TEMPLATE "unifdef.XXXXXX" + +/* * Globals. */ @@ -169,6 +172,7 @@ static bool strictlogic; /* static bool killconsts; /* -k: eval constant #ifs */ static bool lnnum; /* -n: add #line directives */ static bool symlist; /* -s: output symbol list */ +static bool symdepth; /* -S: output symbol depth */ static bool text; /* -t: this is a text file */ static const char *symname[MAXSYMS]; /* symbol name */ @@ -179,10 +183,18 @@ static int nsyms; /* numb static FILE *input; /* input file pointer */ static const char *filename; /* input file name */ static int linenum; /* current line number */ +static FILE *output; /* output file pointer */ +static const char *ofilename; /* output file name */ +static bool overwriting; /* output overwrites input */ +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 */ @@ -193,10 +205,13 @@ static int delcount; /* co static unsigned blankcount; /* count of blank lines */ static unsigned blankmax; /* maximum recent blankcount */ 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 void addsym(bool, bool, char *); +static void closeout(void); static void debug(const char *, ...); static void done(void); static void error(const char *); @@ -216,6 +231,7 @@ static void state(Ifstate); static int strlcmp(const char *, const char *, size_t); static void unnest(void); static void usage(void); +static void version(void); #define endsym(c) (!isalnum((unsigned char)c) && c != '_') @@ -227,7 +243,7 @@ main(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "i:D:U:I:BbcdeKklnst")) != -1) + while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1) switch (opt) { case 'i': /* treat stuff controlled by these symbols as text */ /* @@ -249,16 +265,15 @@ main(int argc, char *argv[]) case 'U': /* undef a symbol */ addsym(false, false, optarg); break; - case 'I': - /* no-op for compatibility with cpp */ - break; - case 'B': /* compress blank lines around removed section */ - compblank = true; + case 'I': /* no-op for compatibility with cpp */ break; case 'b': /* blank deleted lines instead of omitting them */ case 'l': /* backwards compatibility */ lnblank = true; break; + case 'B': /* compress blank lines around removed section */ + compblank = true; + break; case 'c': /* treat -D as -U and vice versa */ complement = true; break; @@ -277,12 +292,20 @@ main(int argc, char *argv[]) case 'n': /* add #line directive after deleted lines */ lnnum = true; break; + case 'o': /* output to a file */ + ofilename = optarg; + break; case 's': /* only output list of symbols that control #ifs */ symlist = true; break; + case 'S': /* list symbols with their nesting depth */ + symlist = symdepth = true; + break; case 't': /* don't parse C comments */ text = true; break; + case 'V': /* print version */ + version(); default: usage(); } @@ -294,21 +317,68 @@ main(int argc, char *argv[]) errx(2, "can only do one file"); } else if (argc == 1 && strcmp(*argv, "-") != 0) { filename = *argv; - input = fopen(filename, "r"); + input = fopen(filename, "rb"); if (input == NULL) err(2, "can't open %s", filename); } else { filename = "[stdin]"; input = stdin; } + if (ofilename == NULL) { + ofilename = "[stdout]"; + output = stdout; + } else { + struct stat ist, ost; + if (stat(ofilename, &ost) == 0 && + fstat(fileno(input), &ist) == 0) + overwriting = (ist.st_dev == ost.st_dev + && ist.st_ino == ost.st_ino); + if (overwriting) { + const char *dirsep; + int ofd; + + dirsep = strrchr(ofilename, '/'); + if (dirsep != NULL) + snprintf(tempname, sizeof(tempname), + "%.*s/" TEMPLATE, + (int)(dirsep - ofilename), ofilename); + else + snprintf(tempname, sizeof(tempname), + TEMPLATE); + ofd = mkstemp(tempname); + if (ofd != -1) + output = fdopen(ofd, "wb+"); + if (output == NULL) + err(2, "can't create temporary file"); + fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)); + } else { + output = fopen(ofilename, "wb"); + if (output == NULL) + err(2, "can't open %s", ofilename); + } + } process(); 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 usage(void) { - fprintf(stderr, "usage: unifdef [-BbcdeKknst] [-Ipath]" + fprintf(stderr, "usage: unifdef [-bBcdeKknsStV] [-Ipath]" " [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n"); exit(2); } @@ -326,7 +396,8 @@ usage(void) * 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 edit the - * latter into a #if to keep the nesting correct. + * latter into a #if to keep the nesting correct. We use strncpy() to + * overwrite the 4 byte token "elif" with "if " without a '\0' byte. * * 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 @@ -379,11 +450,11 @@ static void Oelif (void) { if (!iocccok) static void Idrop (void) { Fdrop(); ignoreon(); } static void Itrue (void) { Ftrue(); ignoreon(); } static void Ifalse(void) { Ffalse(); ignoreon(); } -/* edit this line */ +/* modify 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 */ @@ -435,13 +506,6 @@ static state_fn * const trans_table[IS_C * State machine utility functions */ static void -done(void) -{ - if (incomment) - error("EOF in comment"); - exit(exitstat); -} -static void ignoreoff(void) { if (depth == 0) @@ -456,7 +520,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 @@ -491,24 +556,26 @@ 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); - fputs(tline, stdout); + printf("#line %d%s", linenum, newline); + fputs(tline, output); delcount = 0; blankmax = blankcount = blankline ? blankcount + 1 : 0; } } else { if (lnblank) - putc('\n', stdout); + fputs(newline, output); exitstat = 1; delcount += 1; blankcount = 0; } + if (debugging) + fflush(output); } /* @@ -517,22 +584,55 @@ flushline(bool keep) static void process(void) { - Linetype lineval; - /* When compressing blank lines, act as if the file is preceded by a large number of blank lines. */ blankmax = blankcount = 1000; for (;;) { - linenum++; - lineval = parseline(); + Linetype lineval = parseline(); trans_table[ifstate[depth]][lineval](); - debug("process %s -> %s depth %d", - linetype_name[lineval], + debug("process line %d %s -> %s depth %d", + linenum, linetype_name[lineval], ifstate_name[ifstate[depth]], depth); } } /* + * Flush the output and handle errors. + */ +static void +closeout(void) +{ + if (symdepth && !zerosyms) + printf("\n"); + if (fclose(output) == EOF) { + warn("couldn't write to %s", ofilename); + if (overwriting) { + unlink(tempname); + errx(2, "%s unchanged", filename); + } else { + exit(2); + } + } +} + +/* + * Clean up and exit. + */ +static void +done(void) +{ + if (incomment) + error("EOF in comment"); + closeout(); + if (overwriting && rename(tempname, ofilename) == -1) { + warn("couldn't rename temporary file"); + unlink(tempname); + errx(2, "%s unchanged", ofilename); + } + exit(exitstat); +} + +/* * Parse a line and determine its type. We keep the preprocessor line * parser state between calls in the global variable linestate, with * help from skipcomment(). @@ -546,14 +646,22 @@ parseline(void) Linetype retval; Comment_state wascomment; + linenum++; 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); if (linestate == LS_START) { if (*cp == '#') { linestate = LS_HASH; + firstsym = true; cp = skipcomment(cp + 1); } else if (*cp != '\0') linestate = LS_DIRTY; @@ -563,7 +671,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) { @@ -614,9 +723,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; @@ -627,7 +735,7 @@ parseline(void) while (*cp != '\0') 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]); return (retval); } @@ -872,11 +980,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) { @@ -896,7 +1009,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); @@ -928,7 +1041,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) { @@ -1012,7 +1128,13 @@ findsym(const char *str) if (cp == str) return (-1); 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 */ return (0); } @@ -1049,7 +1171,7 @@ addsym(bool ignorethis, bool definethis, value[symind] = val+1; *val = '\0'; } else if (*val == '\0') - value[symind] = ""; + value[symind] = "1"; else usage(); } else { @@ -1057,6 +1179,8 @@ addsym(bool ignorethis, bool definethis, usage(); value[symind] = NULL; } + debug("addsym %s=%s", symname[symind], + value[symind] ? value[symind] : "undef"); } /* @@ -1097,5 +1221,6 @@ error(const char *msg) else warnx("%s: %d: %s (#if line %d depth %d)", filename, linenum, msg, stifline[depth], depth); + closeout(); errx(2, "output may be truncated"); } Modified: stable/8/usr.bin/unifdef/unifdefall.sh ============================================================================== --- stable/8/usr.bin/unifdef/unifdefall.sh Tue Jan 18 19:13:03 2011 (r217550) +++ stable/8/usr.bin/unifdef/unifdefall.sh Tue Jan 18 19:31:38 2011 (r217551) @@ -2,7 +2,8 @@ # # unifdefall: remove all the #if's from a source file # -# Copyright (c) 2002 - 2009 Tony Finch . All rights reserved. +# Copyright (c) 2002 - 2010 Tony Finch +# Copyright (c) 2009 - 2010 Jonathan Nieder # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -25,19 +26,30 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $dotat: unifdef/unifdefall.sh,v 1.24 2009/11/26 12:54:39 fanf2 Exp $ # $FreeBSD$ set -e -basename=$(basename $0) +unifdef="$(dirname "$0")/unifdef" +if [ ! -e "$unifdef" ] +then + unifdef=unifdef +fi + +case "$@" in +"-d "*) echo DEBUGGING 1>&2 + debug=-d + shift +esac + +basename=$(basename "$0") 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 # list of all controlling macros -unifdef -s "$@" | sort | uniq >"$tmp/ctrl" +"$unifdef" $debug -s "$@" | sort | uniq >"$tmp/ctrl" # list of all macro definitions cpp -dM "$@" | sort | sed 's/^#define //' >"$tmp/hashdefs" # list of defined macro names @@ -49,7 +61,7 @@ comm -12 "$tmp/ctrl" "$tmp/alldef" >"$tm # and converts them to unifdef command-line arguments sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D&=/p|' <"$tmp/def" >"$tmp/script" # create the final unifdef command -{ echo unifdef -k \\ +{ echo "$unifdef" $debug -k '\' # convert the controlling undefined macros to -U arguments sed 's/.*/-U& \\/' <"$tmp/undef" # convert the controlling defined macros to quoted -D arguments @@ -57,5 +69,11 @@ sed 's|.*|s/^&\\(([^)]*)\\)\\{0,1\\} /-D sed "s/'/'\\\\''/g;s/.*/'&' \\\\/" echo '"$@"' } >"$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 sh "$tmp/cmd" "$@"