A little help, please, double checking that using popt(3) rather
than getopt(3) to get rid of POSIXLY_CORRECT with glibc doesn't
break anything. I rarely use parameterized macros.
The change passes my tmacro testing (with valgrind as well):
[jbj@wellfleet rpmio]$ cat ./testmacros
%bing(a:b:c) %{echo: argv[%#]%{?-a: %{-a} %{-a*}}%{?-b: %{-b} %{-
b*}}%{?-c: %{-c}} -- %*}
[jbj@wellfleet rpmio]$ cat .test
cat: .test: No such file or directory
[jbj@wellfleet rpmio]$ cat ./testmacros
%bing(a:b:c) %{echo: argv[%#]%{?-a: %{-a} %{-a*}}%{?-b: %{-b} %{-
b*}}%{?-c: %{-c}} -- %*}
[jbj@wellfleet rpmio]$ cat ./test
%bing Q -a A d e f
%bing U V -b B d e f
%bing -a A X Y Z -c C d e f
[jbj@wellfleet rpmio]$ ./tmacro
argv[4] -a A A -- Q d e f0->
argv[5] -b B B -- U V d e f0->
argv[7] -a A A -c -- X Y Z C d e f0->
73 de Jeff
On Feb 27, 2008, at 3:26 PM, Jeff Johnson wrote:
> RPM Package Manager, CVS Repository
> http://rpm5.org/cvs/
>
> ______________________________________________________________________
> ______
>
> Server: rpm5.org Name: Jeff Johnson
> Root: /v/rpm/cvs Email: jbj@rpm5.org
> Module: rpm Date: 27-Feb-2008
> 21:26:01
> Branch: HEAD Handle: 2008022720260001
>
> Modified files:
> rpm CHANGES
> rpm/rpmio Makefile.am macro.c
>
> Log:
> - jbj: macro: use popt rather than getopt(3), get rid of
> POSIXLY_CORRECT.
>
> Summary:
> Revision Changes Path
> 1.2211 +1 -0 rpm/CHANGES
> 1.140 +6 -6 rpm/rpmio/Makefile.am
> 2.189 +53 -79 rpm/rpmio/macro.c
>
> ______________________________________________________________________
> ______
>
> patch -p0 <<'@@ .'
> Index: rpm/CHANGES
>
> ======================================================================
> ======
> $ cvs diff -u -r1.2210 -r1.2211 CHANGES
> --- rpm/CHANGES 27 Feb 2008 18:27:10 -0000 1.2210
> +++ rpm/CHANGES 27 Feb 2008 20:26:00 -0000 1.2211
> @@ -1,4 +1,5 @@
> 5.0.0 -> 5.1a1:
> + - jbj: macro: use popt rather than getopt(3), get rid of
> POSIXLY_CORRECT.
> - jbj: rpmio: splint fiddles.
> - rpm.org: Rip ancient, unused setperms + unsetgid make
> targets.
> - rpm.org: Add %{sources} and %{patches} macros to build.
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/Makefile.am
>
> ======================================================================
> ======
> $ cvs diff -u -r1.139 -r1.140 Makefile.am
> --- rpm/rpmio/Makefile.am 18 Feb 2008 19:59:08 -0000 1.139
> +++ rpm/rpmio/Makefile.am 27 Feb 2008 20:26:00 -0000 1.140
> @@ -35,11 +35,11 @@
> $(top_builddir)/misc/librpmmisc.la \
> @LTLIBINTL@
>
> -RPM_LDADD = \
> - $(top_builddir)/build/librpmbuild.la \
> - $(top_builddir)/lib/librpm.la \
> - $(top_builddir)/rpmdb/librpmdb.la \
> - $(RPMIO_LDADD)
> +#RPM_LDADD = \
> +# $(top_builddir)/build/librpmbuild.la \
> +# $(top_builddir)/lib/librpm.la \
> +# $(top_builddir)/rpmdb/librpmdb.la \
> +# $(RPMIO_LDADD)
>
> pkgincdir = $(pkgincludedir)$(WITH_PATH_VERSIONED_SUFFIX)
> pkginc_HEADERS = \
> @@ -183,7 +183,7 @@
> -sh ./gengpg.sh > gengpg.h
>
> tmacro_SOURCES =
> -tmacro_LDADD = tmacro.o $(RPM_LDADD)
> +tmacro_LDADD = tmacro.o $(RPMIO_LDADD)
> tmacro.o: macro.c
> $(COMPILE) -DDEBUG_MACROS -o $@ -c $<
>
> @@ .
> patch -p0 <<'@@ .'
> Index: rpm/rpmio/macro.c
>
> ======================================================================
> ======
> $ cvs diff -u -r2.188 -r2.189 macro.c
> --- rpm/rpmio/macro.c 26 Feb 2008 20:42:00 -0000 2.188
> +++ rpm/rpmio/macro.c 27 Feb 2008 20:26:01 -0000 2.189
> @@ -22,6 +22,8 @@
> #include <stdlib.h>
> #include <string.h>
> #include <ctype.h>
> +#include <popt.h>
> +
> #define rpmlog fprintf
> #define RPMLOG_ERR stderr
> #undef _
> @@ -34,6 +36,7 @@
> #define xisalnum(_c) isalnum(_c)
> #define xisalpha(_c) isalpha(_c)
> #define xisdigit(_c) isdigit(_c)
> +#define xisspace(_c) isspace(_c)
>
> typedef FILE * FD_t;
> #define Fopen(_path, _fmode) fopen(_path, "r");
> @@ -985,20 +988,19 @@
> /*@dependent@*/ static const char *
> grabArgs(MacroBuf mb, const MacroEntry me, /*@returned@*/ const
> char * se,
> const char * lastc)
> - /*@globals rpmGlobalMacroContext, internalState @*/
> - /*@modifies mb, rpmGlobalMacroContext, internalState @*/
> + /*@globals rpmGlobalMacroContext, fileSystem, internalState @*/
> + /*@modifies mb, rpmGlobalMacroContext, fileSystem,
> internalState @*/
> {
> + poptContext optCon;
> + struct poptOption *optTbl;
> size_t bufn = _macro_BUFSIZ;
> char *buf = alloca(bufn);
> char *b, *be;
> char aname[16];
> - const char *opts, *o;
> + const char *opts;
> int argc = 0;
> const char **argv;
> int c;
> -#ifdef __GLIBC__
> - char *posixly_correct;
> -#endif
>
> /* Copy macro name as argv[0], save beginning of args. */
> buf[0] = '\0';
> @@ -1059,107 +1061,79 @@
> /* assert(b == be); */
> argv[argc] = NULL;
>
> - /* Citation from glibc/posix/getopt.c:
> - * Index in ARGV of the next element to be scanned.
> - * This is used for communication to and from the caller
> - * and for communication between successive calls to
> `getopt'.
> - *
> - * On entry to `getopt', zero means this is the first
> call; initialize.
> - *
> - * When `getopt' returns -1, this is the index of the
> first of the
> - * non-option elements that the caller should itself scan.
> - *
> - * Otherwise, `optind' communicates from one call to the
> next
> - * how much of ARGV has been scanned so far.
> - */
> - /* 1003.2 says this must be 1 before any call. */
> -
> -#ifdef __GLIBC__
> - /*@-mods@*/
> - optind = 0; /* XXX but posix != glibc */
> - /*@=mods@*/
> -#else
> - optind = 1;
> -#endif
> -
> - opts = me->opts;
> -
> -#ifdef __GLIBC__
> - /*
> - * Ensure option parsing is done without allowing option/
> argument permutations
> - * to avoid accidentally picking up and complaining about
> unknown options.
> - *
> - * Required standard POSIX getopt(3) behavior:
> - * $ rpm --define '%foo() <%*>' --eval '%{foo bar %(echo -n
> "quux") baz}'
> - * <bar quux baz>
> - *
> - * Unexpected non-standard Linux GLIBC getopt(3) behavior:
> - * $ rpm --define '%foo() <%*>' --eval '%{foo bar %(echo -n
> "quux") baz}'
> - * foo: invalid option -- n
> - * error: Unknown option ? in foo()
> - * <%*>
> - *
> - * Fixed standard POSIX getopt(3) behavior also under Linux
> GLIBC:
> - * $ POSIXLY_CORRECT=1 rpm --define '%foo() <%*>' --eval '%
> {foo bar %(echo -n "quux") baz}'
> - * <bar quux baz>
> - */
> - posixly_correct = getenv("POSIXLY_CORRECT");
> - (void) setenv("POSIXLY_CORRECT", "1", 1);
> -#endif
> -
> - /* Define option macros. */
> -/*@-nullstate@*/ /* FIX: argv[] can be NULL */
> - while((c = getopt(argc, (char **)argv, opts)) != -1)
> + /* Count the number of short options. */
> + for (c = 0, opts = me->opts; *opts != '\0'; opts++)
> + if (*opts != ':') c++;
> + /* Set up popt option table. */
> + optTbl = xcalloc(sizeof(*optTbl), (c + 1));
> + for (c = 0, opts = me->opts; *opts != '\0'; opts++) {
> + if (*opts == ':') continue;
> + optTbl[c].shortName = opts[0];
> + optTbl[c].val = (int) opts[0];
> + if (opts[1] == ':')
> + optTbl[c].argInfo = POPT_ARG_STRING;
> + c++;
> + }
> +
> + /* Parse the options, defining option macros. */
> +/*@-nullstate@*/
> + optCon = poptGetContext(argv[0], argc, argv, optTbl,
> POPT_CONTEXT_NO_EXEC);
> /*@=nullstate@*/
> - {
> - if (c == (int) '?' || (o = strchr(opts, c)) == NULL) {
> - rpmlog(RPMLOG_ERR, _("Unknown option %c in %s(%s)\n"),
> - (char)c, me->name, opts);
> - return se;
> - }
> + while ((c = poptGetNextOpt(optCon)) > 0) {
> + const char * optArg = poptGetOptArg(optCon);
> *be++ = '-';
> *be++ = (char) c;
> - if (o[1] == ':') {
> + if (optArg != NULL) {
> *be++ = ' ';
> - be = stpcpy(be, optarg);
> + be = stpcpy(be, optArg);
> }
> *be++ = '\0';
> aname[0] = '-'; aname[1] = (char)c; aname[2] = '\0';
> addMacro(mb->mc, aname, NULL, b, mb->depth);
> - if (o[1] == ':') {
> + if (optArg != NULL) {
> aname[0] = '-'; aname[1] = (char)c; aname[2] = '*'; aname
> [3] = '\0';
> - addMacro(mb->mc, aname, NULL, optarg, mb->depth);
> + addMacro(mb->mc, aname, NULL, optArg, mb->depth);
> }
> be = b; /* reuse the space */
> +/*@-dependenttrans -modobserver -observertrans @*/
> + optArg = _free(optArg);
> +/*@=dependenttrans =modobserver =observertrans @*/
> + }
> + if (c < -1) {
> + rpmlog(RPMLOG_ERR, _("Unknown option in macro %s(%s): %s: %s\n"),
> + me->name, me->opts,
> + poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(c));
> + goto exit;
> }
>
> -#ifdef __GLIBC__
> - if (posixly_correct != NULL)
> - (void) setenv("POSIXLY_CORRECT", posixly_correct, 1);
> - else
> - (void) unsetenv("POSIXLY_CORRECT");
> -#endif
> -
> + argv = poptGetArgs(optCon);
> + argc = 0;
> + if (argv != NULL)
> + for (c = 0; argv[c] != NULL; c++)
> + argc++;
> +
> /* Add arg count as macro. */
> - sprintf(aname, "%d", (argc - optind));
> + sprintf(aname, "%d", argc);
> addMacro(mb->mc, "#", NULL, aname, mb->depth);
>
> /* Add macro for each arg. Concatenate args for %*. */
> if (be) {
> *be = '\0';
> - for (c = optind; c < argc; c++) {
> - sprintf(aname, "%d", (c - optind + 1));
> + if (argv != NULL)
> + for (c = 0; c < argc; c++) {
> + sprintf(aname, "%d", (c + 1));
> addMacro(mb->mc, aname, NULL, argv[c], mb->depth);
> if (be != b) *be++ = ' '; /* Add space between args */
> -/*@-nullpass@*/ /* FIX: argv[] can be NULL */
> be = stpcpy(be, argv[c]);
> -/*@=nullpass@*/
> }
> }
>
> /* Add unexpanded args as macro. */
> addMacro(mb->mc, "*", NULL, b, mb->depth);
>
> +exit:
> + optCon = poptFreeContext(optCon);
> + optTbl = _free(optTbl);
> return se;
> }
>
> @@ .
> ______________________________________________________________________
> RPM Package Manager http://rpm5.org
> CVS Sources Repository rpm-cvs@rpm5.org
Received on Wed Feb 27 21:36:51 2008