From d4fed4bde1aafd03c328b7ebd710a8e33c7f2203 Mon Sep 17 00:00:00 2001 From: jbj Date: Fri, 22 Oct 1999 18:10:51 +0000 Subject: [PATCH] fix: long options like "--long=val" needed longArg reset to NULL at top of poptGetNextOpt() while loop. Variables in poptGetNextOpt() are also locally scoped. CVS patchset: 3396 CVS date: 1999/10/22 18:10:51 --- popt/.cvsignore | 1 + popt/Makefile.am | 4 +- popt/po/popt.pot | 2 +- popt/popt.c | 96 +++++++++++++++++++----------------- popt/test2.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ popt/testit.sh | 61 +++++++++++------------ 6 files changed, 233 insertions(+), 76 deletions(-) create mode 100644 popt/test2.c diff --git a/popt/.cvsignore b/popt/.cvsignore index 6fe1398..1263a59 100644 --- a/popt/.cvsignore +++ b/popt/.cvsignore @@ -16,6 +16,7 @@ config.sub stamp-h stamp-h.in test1 +test2 libtool ltconfig ltmain.sh diff --git a/popt/Makefile.am b/popt/Makefile.am index 903109f..c0aca77 100644 --- a/popt/Makefile.am +++ b/popt/Makefile.am @@ -11,9 +11,11 @@ INCLUDES = -I$(top_srcdir) noinst_INCLUDES = findme.h poptint.h -noinst_PROGRAMS = test1 +noinst_PROGRAMS = test1 test2 test1_SOURCES = test1.c test1_LDADD = $(lib_LTLIBRARIES) +test2_SOURCES = test2.c +test2_LDADD = $(lib_LTLIBRARIES) noinst_SCRIPTS = testit.sh diff --git a/popt/po/popt.pot b/popt/po/popt.pot index c7230f1..c337343 100644 --- a/popt/po/popt.pot +++ b/popt/po/popt.pot @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 1999-10-21 16:18-0400\n" +"POT-Creation-Date: 1999-10-22 14:06-0400\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/popt/popt.c b/popt/popt.c index df3b7f5..27b014e 100644 --- a/popt/popt.c +++ b/popt/popt.c @@ -1,5 +1,5 @@ /* (C) 1998 Red Hat Software, Inc. -- Licensing details are in the COPYING - file accompanying popt source distributions, available from + file accompanying popt source distributions, available from ftp://ftp.redhat.com/pub/code/popt */ #ifdef HAVE_CONFIG_H @@ -45,7 +45,7 @@ static void invokeCallbacks(poptContext con, const struct poptOption * table, int post) { const struct poptOption * opt = table; poptCallbackType cb; - + while (opt->longName || opt->shortName || opt->arg) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { invokeCallbacks(con, opt->arg, post); @@ -60,7 +60,7 @@ static void invokeCallbacks(poptContext con, const struct poptOption * table, } } -poptContext poptGetContext(const char * name, int argc, char ** argv, +poptContext poptGetContext(const char * name, int argc, char ** argv, const struct poptOption * options, int flags) { poptContext con = malloc(sizeof(*con)); @@ -82,7 +82,7 @@ poptContext poptGetContext(const char * name, int argc, char ** argv, if (getenv("POSIXLY_CORRECT") || getenv("POSIX_ME_HARDER")) con->flags |= POPT_CONTEXT_POSIXMEHARDER; - + if (name) con->appName = strcpy(malloc(strlen(name) + 1), name); @@ -146,7 +146,7 @@ static int handleExec(poptContext con, char * longName, char shortName) { { char *s = malloc((longName ? strlen(longName) : 0) + 3); if (longName) sprintf(s, "--%s", longName); - else + else sprintf(s, "-%c", shortName); con->finalArgv[i] = s; } @@ -160,9 +160,9 @@ static int handleAlias(poptContext con, const char * longName, char shortName, int i; if (con->os->currAlias && con->os->currAlias->longName && longName && - !strcmp(con->os->currAlias->longName, longName)) + !strcmp(con->os->currAlias->longName, longName)) return 0; - if (con->os->currAlias && shortName && + if (con->os->currAlias && shortName && shortName == con->os->currAlias->shortName) return 0; @@ -177,7 +177,7 @@ static int handleAlias(poptContext con, const char * longName, char shortName, if (i < 0) return 0; - if ((con->os - con->optionStack + 1) + if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH) return POPT_ERROR_OPTSTOODEEP; @@ -201,7 +201,7 @@ static void execCommand(poptContext con) { int pos = 0; const char * script = con->doExec->script; - argv = malloc(sizeof(*argv) * + argv = malloc(sizeof(*argv) * (6 + con->numLeftovers + con->finalArgvCount)); if (!con->execAbsolute && strchr(script, '/')) return; @@ -266,7 +266,7 @@ findOption(const struct poptOption * table, const char * longName, while (opt->longName || opt->shortName || opt->arg) { if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) { - opt2 = findOption(opt->arg, longName, shortName, callback, + opt2 = findOption(opt->arg, longName, shortName, callback, callbackData, singleDash); if (opt2) { if (*callback && !*callbackData) @@ -275,7 +275,7 @@ findOption(const struct poptOption * table, const char * longName, } } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK) { cb = opt; - } else if (longName && opt->longName && + } else if (longName && opt->longName && (!singleDash || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) && !strcmp(longName, opt->longName)) { break; @@ -298,21 +298,18 @@ findOption(const struct poptOption * table, const char * longName, } /* returns 'val' element, -1 on last item, POPT_ERROR_* on error */ -int poptGetNextOpt(poptContext con) { - char * optString, * chptr, * localOptString; - const char * longArg = NULL; - const char * origOptString; - long aLong; - char * end; +int poptGetNextOpt(poptContext con) +{ const struct poptOption * opt = NULL; int done = 0; - int i; - poptCallbackType cb = NULL; - const void * cbData = NULL; - int singleDash; while (!done) { - while (!con->os->nextCharArg && con->os->next == con->os->argc + const char * origOptString = NULL; + poptCallbackType cb = NULL; + const void * cbData = NULL; + const char * longArg = NULL; + + while (!con->os->nextCharArg && con->os->next == con->os->argc && con->os > con->optionStack) con->os--; if (!con->os->nextCharArg && con->os->next == con->os->argc) { @@ -322,7 +319,8 @@ int poptGetNextOpt(poptContext con) { } if (!con->os->nextCharArg) { - + char * localOptString, * optString; + origOptString = con->os->argv[con->os->next++]; if (con->restLeftover || *origOptString != '-') { @@ -333,8 +331,8 @@ int poptGetNextOpt(poptContext con) { } /* Make a copy we can hack at */ - localOptString = optString = - strcpy(alloca(strlen(origOptString) + 1), + localOptString = optString = + strcpy(alloca(strlen(origOptString) + 1), origOptString); if (!optString[0]) @@ -344,6 +342,9 @@ int poptGetNextOpt(poptContext con) { con->restLeftover = 1; continue; } else { + char *oe; + int singleDash; + optString++; if (*optString == '-') singleDash = 0, optString++; @@ -355,16 +356,19 @@ int poptGetNextOpt(poptContext con) { if (handleExec(con, optString, '\0')) continue; - chptr = optString; - while (*chptr && *chptr != '=') chptr++; - if (*chptr == '=') { - longArg = origOptString + (chptr - localOptString) + 1; - *chptr = '\0'; + /* Check for "--long=arg" option. */ + for (oe = optString; *oe && *oe != '='; oe++) + ; + if (*oe == '=') { + *oe++ = '\0'; + /* XXX longArg is mapped back to persistent storage. */ + longArg = origOptString + (oe - localOptString); } opt = findOption(con->options, optString, '\0', &cb, &cbData, singleDash); - if (!opt && !singleDash) return POPT_ERROR_BADOPT; + if (!opt && !singleDash) + return POPT_ERROR_BADOPT; } if (!opt) @@ -384,9 +388,10 @@ int poptGetNextOpt(poptContext con) { if (handleExec(con, NULL, *origOptString)) continue; - opt = findOption(con->options, NULL, *origOptString, &cb, + opt = findOption(con->options, NULL, *origOptString, &cb, &cbData, 0); - if (!opt) return POPT_ERROR_BADOPT; + if (!opt) + return POPT_ERROR_BADOPT; origOptString++; if (*origOptString) @@ -396,15 +401,16 @@ int poptGetNextOpt(poptContext con) { if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) { *((int *)opt->arg) = 1; } else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) { - if (opt->arg) *((int *) opt->arg) = opt->val; + if (opt->arg) + *((int *) opt->arg) = opt->val; } else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) { if (longArg) { con->os->nextArg = longArg; } else if (con->os->nextCharArg) { con->os->nextArg = con->os->nextCharArg; con->os->nextCharArg = NULL; - } else { - while (con->os->next == con->os->argc && + } else { + while (con->os->next == con->os->argc && con->os > con->optionStack) con->os--; if (con->os->next == con->os->argc) @@ -414,6 +420,9 @@ int poptGetNextOpt(poptContext con) { } if (opt->arg) { + long aLong; + char *end; + switch (opt->argInfo & POPT_ARG_MASK) { case POPT_ARG_STRING: *((const char **) opt->arg) = con->os->nextArg; @@ -422,7 +431,7 @@ int poptGetNextOpt(poptContext con) { case POPT_ARG_INT: case POPT_ARG_LONG: aLong = strtol(con->os->nextArg, &end, 0); - if (!(end && *end == '\0')) + if (!(end && *end == '\0')) return POPT_ERROR_BADNUMBER; if (aLong == LONG_MIN || aLong == LONG_MAX) @@ -432,7 +441,7 @@ int poptGetNextOpt(poptContext con) { } else { if (aLong > INT_MAX || aLong < INT_MIN) return POPT_ERROR_OVERFLOW; - *((int *) opt->arg) =aLong; + *((int *) opt->arg) = aLong; } break; @@ -455,17 +464,16 @@ int poptGetNextOpt(poptContext con) { sizeof(*con->finalArgv) * con->finalArgvAlloced); } - i = con->finalArgvCount++; { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + 3); if (opt->longName) sprintf(s, "--%s", opt->longName); - else + else sprintf(s, "-%c", opt->shortName); - con->finalArgv[i] = s; + con->finalArgv[con->finalArgvCount++] = s; } if (opt->arg && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE - && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL) + && (opt->argInfo & POPT_ARG_MASK) != POPT_ARG_VAL) con->finalArgv[con->finalArgvCount++] = strdup(con->os->nextArg); } @@ -532,10 +540,10 @@ int poptAddAlias(poptContext con, struct poptAlias newAlias, if (!con->aliases) con->aliases = malloc(sizeof(newAlias) * con->numAliases); else - con->aliases = realloc(con->aliases, + con->aliases = realloc(con->aliases, sizeof(newAlias) * con->numAliases); alias = con->aliases + aliasNum; - + alias->longName = (newAlias.longName) ? strcpy(malloc(strlen(newAlias.longName) + 1), newAlias.longName) : NULL; diff --git a/popt/test2.c b/popt/test2.c new file mode 100644 index 0000000..4e9275d --- /dev/null +++ b/popt/test2.c @@ -0,0 +1,145 @@ +/* + Popt Library Test Program Number Too + + --> "a real world test of popt bugs" <-- + + Copyright (C) 1999 US Interactive, Inc. + + This program can be used under the GPL or LGPL at your + whim as long as this Copyright remains attached. +*/ + +#include +#include +#include + +#define TEST2 + +char *PathnameOfKeyFile = NULL; +char *PathnameOfOfferFile = NULL; + +char *txHost = NULL; +int txSslPort = 443; +int txStoreId = 0; + +char *contentProtocol = NULL; +char *contentHost = NULL; +int contentPort = 80; +char *contentPath = NULL; + +char *dbPassword = NULL; +char *dbUserName = NULL; + +char *rcfile = "createuser-defaults"; +char *username=NULL; + +char *password = NULL; +char *firstname = NULL; +char *lastname = NULL; +char *addr1 = NULL; +char *addr2 = NULL; +char *city = NULL; +char *state = NULL; +char *postal = NULL; +char *country = NULL; + +char *email = NULL; + +char *dayphone = NULL; +char *fax = NULL; + + +int +main(int argc, char**argv ) { + + poptContext optCon; /* context for parsing command-line options */ + struct poptOption userOptionsTable[] = { + { "first", 'f', POPT_ARG_STRING, &firstname, 0, + "user's first name", "first" }, + { "last", 'l', POPT_ARG_STRING, &lastname, 0, + "user's last name", "last" }, + { "username", 'u', POPT_ARG_STRING, &username, 0, + "system user name", "user" }, + { "password", 'p', POPT_ARG_STRING, &password, 0, + "system password name", "password" }, + { "addr1", '1', POPT_ARG_STRING, &addr1, 0, + "line 1 of address", "addr1" }, + { "addr2", '2', POPT_ARG_STRING, &addr2, 0, + "line 2 of address", "addr2" }, + { "city", 'c', POPT_ARG_STRING, &city, 0, + "city", "city" }, + { "state", 's', POPT_ARG_STRING, &state, 0, + "state or province", "state" }, + { "postal", 'P', POPT_ARG_STRING, &postal, 0, + "postal or zip code", "postal" }, + { "zip", 'z', POPT_ARG_STRING, &postal, 0, + "postal or zip code", "postal" }, + { "country", 'C', POPT_ARG_STRING, &country, 0, + "two letter ISO country code", "country" }, + { "email", 'e', POPT_ARG_STRING, &email, 0, + "user's email address", "email" }, + { "dayphone", 'd', POPT_ARG_STRING, &dayphone, 0, + "day time phone number", "dayphone" }, + { "fax", 'F', POPT_ARG_STRING, &fax, 0, + "fax number", "fax" }, + { NULL, 0, 0, NULL, 0, NULL, NULL } + }; + struct poptOption transactOptionsTable[] = { + { "keyfile", '\0', POPT_ARG_STRING, &PathnameOfKeyFile, 0, + "transact offer key file (flat_O.kf)", "key-file" }, + { "offerfile", '\0', POPT_ARG_STRING, &PathnameOfOfferFile, 0, + "offer template file (osl.ofr)", "offer-file" }, + { "storeid", '\0', POPT_ARG_INT, &txStoreId, 0, + "store id", "store-id" }, + { "rcfile", '\0', POPT_ARG_STRING, &rcfile, 0, + "default command line options (in popt format)", "rcfile" }, + { "txhost", '\0', POPT_ARG_STRING, &txHost, 0, + "transact host", "transact-host" }, + { "txsslport", '\0', POPT_ARG_INT, &txSslPort, 0, + "transact server ssl port ", "transact ssl port" }, + { "cnhost", '\0', POPT_ARG_STRING, &contentHost, 0, + "content host", "content-host" }, + { "cnpath", '\0', POPT_ARG_STRING, &contentPath, 0, + "content url path", "content-path" }, + { NULL, 0, 0, NULL, 0, NULL, NULL } + }; + + struct poptOption databaseOptionsTable[] = { + { "dbpassword", '\0', POPT_ARG_STRING, &dbPassword, 0, + "Database password", "DB password" }, + { "dbusername", '\0', POPT_ARG_STRING, &dbUserName, 0, + "Database user name", "DB UserName" }, + { NULL, 0, 0, NULL, 0, NULL, NULL } + }; + + struct poptOption optionsTable[] = { + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, transactOptionsTable, 0, + "Transact Options (not all will apply)", NULL }, + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, databaseOptionsTable, 0, + "Transact Database Names", NULL }, + { NULL, '\0', POPT_ARG_INCLUDE_TABLE, userOptionsTable, 0, + "User Fields", NULL }, + POPT_AUTOHELP + { NULL, 0, 0, NULL, 0, NULL, NULL } + }; + + optCon = poptGetContext("createuser", argc, argv, optionsTable, 0); + poptReadConfigFile(optCon, rcfile ); + + /* although there are no options to be parsed, check for --help */ + poptGetNextOpt(optCon); + + poptFreeContext(optCon); + + printf( "dbusername %s\tdbpassword %s\n" + "txhost %s\ttxsslport %d\ttxstoreid %d\tpathofkeyfile %s\n" + "username %s\tpassword %s\tfirstname %s\tlastname %s\n" + "addr1 %s\taddr2 %s\tcity %s\tstate %s\tpostal %s\n" + "country %s\temail %s\tdayphone %s\tfax %s\n", + dbUserName, dbPassword, + txHost, txSslPort, txStoreId, PathnameOfKeyFile, + username, password, firstname, lastname, + addr1,addr2, city, state, postal, + country, email, dayphone, fax); + return 0; +} diff --git a/popt/testit.sh b/popt/testit.sh index e54b737..8883510 100755 --- a/popt/testit.sh +++ b/popt/testit.sh @@ -1,6 +1,6 @@ #!/bin/sh -${test1:=./test1} +${test1:=`pwd`/.libs/lt-test1} run() { prog=$1; shift @@ -9,7 +9,7 @@ run() { echo Running test $name. - result=`$prog $*` + result=`./$prog $*` if [ "$answer" != "$result" ]; then echo "Test \"$*\" failed with: $result" exit 2 @@ -18,34 +18,35 @@ run() { make -q testcases -run ${test1} "test1 - 1" "arg1: 1 arg2: (none)" --arg1 -run ${test1} "test1 - 2" "arg1: 0 arg2: foo" --arg2 foo -run ${test1} "test1 - 3" "arg1: 1 arg2: something" --arg1 --arg2 something -run ${test1} "test1 - 4" "arg1: 0 arg2: another" --simple another -run ${test1} "test1 - 5" "arg1: 1 arg2: alias" --two -run ${test1} "test1 - 6" "arg1: 1 arg2: (none) rest: --arg2" --arg1 -- --arg2 -run ${test1} "test1 - 7" "arg1: 0 arg2: abcd rest: --arg1" --simple abcd -- --arg1 -run ${test1} "test1 - 8" "arg1: 1 arg2: (none) rest: --arg2" --arg1 --takerest --arg2 -run ${test1} "test1 - 9" "arg1: 0 arg2: foo" -2 foo -run ${test1} "test1 - 10" "arg1: 0 arg2: (none) arg3: 50" -3 50 -run ${test1} "test1 - 11" "arg1: 0 arg2: bar" -T bar -run ${test1} "test1 - 12" "arg1: 1 arg2: (none)" -O -run ${test1} "test1 - 13" "arg1: 1 arg2: foo" -OT foo -run ${test1} "test1 - 14" "arg1: 0 arg2: (none) inc: 1" --inc -run ${test1} "test1 - 15" "arg1: 0 arg2: foo inc: 1" -i --arg2 foo -POSIX_ME_HARDER=1 run ${test1} "test1 - 16" "arg1: 1 arg2: (none) rest: foo --arg2 something" --arg1 foo --arg2 something -POSIXLY_CORRECT=1 run ${test1} "test1 - 17" "arg1: 1 arg2: (none) rest: foo --arg2 something" --arg1 foo --arg2 something -run ${test1} "test1 - 18" "callback: c sampledata bar arg1: 1 arg2: (none)" --arg1 --cb bar -run ${test1} "test1 - 19" "${test1} ;" --echo-args -run ${test1} "test1 - 20" "${test1} ; --arg1" --echo-args --arg1 -run ${test1} "test1 - 21" "${test1} ; --arg2 something" -T something -e -run ${test1} "test1 - 22" "${test1} ; --arg2 something -- more args" -T something -a more args -run ${test1} "test1 - 23" "${test1} ; --echo-args -a" --echo-args -e -a -run ${test1} "test1 - 24" "arg1: 0 arg2: (none) short: 1" -shortoption -run ${test1} "test1 - 25" "arg1: 0 arg2: (none) short: 1" --shortoption -run ${test1} "test1 - 26" "callback: c arg for cb2 foo arg1: 0 arg2: (none)" --cb2 foo -run ${test1} "test1 - 27" "arg1: 0 arg2: (none) -" - -run ${test1} "test1 - 28" "arg1: 0 arg2: foo -" - -2 foo +run test1 "test1 - 1" "arg1: 1 arg2: (none)" --arg1 +run test1 "test1 - 2" "arg1: 0 arg2: foo" --arg2 foo +run test1 "test1 - 3" "arg1: 1 arg2: something" --arg1 --arg2 something +run test1 "test1 - 4" "arg1: 0 arg2: another" --simple another +run test1 "test1 - 5" "arg1: 1 arg2: alias" --two +run test1 "test1 - 6" "arg1: 1 arg2: (none) rest: --arg2" --arg1 -- --arg2 +run test1 "test1 - 7" "arg1: 0 arg2: abcd rest: --arg1" --simple abcd -- --arg1 +run test1 "test1 - 8" "arg1: 1 arg2: (none) rest: --arg2" --arg1 --takerest --arg2 +run test1 "test1 - 9" "arg1: 0 arg2: foo" -2 foo +run test1 "test1 - 10" "arg1: 0 arg2: (none) arg3: 50" -3 50 +run test1 "test1 - 11" "arg1: 0 arg2: bar" -T bar +run test1 "test1 - 12" "arg1: 1 arg2: (none)" -O +run test1 "test1 - 13" "arg1: 1 arg2: foo" -OT foo +run test1 "test1 - 14" "arg1: 0 arg2: (none) inc: 1" --inc +run test1 "test1 - 15" "arg1: 0 arg2: foo inc: 1" -i --arg2 foo +POSIX_ME_HARDER=1 run test1 "test1 - 16" "arg1: 1 arg2: (none) rest: foo --arg2 something" --arg1 foo --arg2 something +POSIXLY_CORRECT=1 run test1 "test1 - 17" "arg1: 1 arg2: (none) rest: foo --arg2 something" --arg1 foo --arg2 something +run test1 "test1 - 18" "callback: c sampledata bar arg1: 1 arg2: (none)" --arg1 --cb bar +run test1 "test1 - 19" "${test1} ;" --echo-args +run test1 "test1 - 20" "${test1} ; --arg1" --echo-args --arg1 +run test1 "test1 - 21" "${test1} ; --arg2 something" -T something -e +run test1 "test1 - 22" "${test1} ; --arg2 something -- more args" -T something -a more args +run test1 "test1 - 23" "${test1} ; --echo-args -a" --echo-args -e -a +run test1 "test1 - 24" "arg1: 0 arg2: (none) short: 1" -shortoption +run test1 "test1 - 25" "arg1: 0 arg2: (none) short: 1" --shortoption +run test1 "test1 - 26" "callback: c arg for cb2 foo arg1: 0 arg2: (none)" --cb2 foo +run test1 "test1 - 27" "arg1: 0 arg2: (none) -" - +run test1 "test1 - 28" "arg1: 0 arg2: foo -" - -2 foo +run test1 "test1 - 29" "arg1: 0 arg2: bbbb" --arg2=aaaa -2 bbbb echo "" echo "Passed." -- 2.7.4