aboutsummaryrefslogtreecommitdiffstats
path: root/popt
diff options
context:
space:
mode:
authorWayne Davison <wayned@samba.org>2006-11-09 00:57:55 +0000
committerWayne Davison <wayned@samba.org>2006-11-09 00:57:55 +0000
commitbc93ee842fd5dd2a1cc2b2cb25656a98c673d772 (patch)
tree63cf1bca7f6cde16d120de9750e50399325cc010 /popt
parent0c6d79528ac651ef064173327d769ba7a2b338ab (diff)
downloadandroid_external_rsync-bc93ee842fd5dd2a1cc2b2cb25656a98c673d772.tar.gz
android_external_rsync-bc93ee842fd5dd2a1cc2b2cb25656a98c673d772.tar.bz2
android_external_rsync-bc93ee842fd5dd2a1cc2b2cb25656a98c673d772.zip
- Upgraded popt to version 1.10.2.
- Modified all sprintf() and strcpy() calls to use snprintf() and strlcpy().
Diffstat (limited to 'popt')
-rw-r--r--popt/findme.c17
-rw-r--r--popt/popt.c202
-rw-r--r--popt/popt.h216
-rw-r--r--popt/poptconfig.c41
-rw-r--r--popt/popthelp.c378
-rw-r--r--popt/poptint.h54
-rw-r--r--popt/poptparse.c119
-rw-r--r--popt/system.h50
8 files changed, 791 insertions, 286 deletions
diff --git a/popt/findme.c b/popt/findme.c
index e98e0611..ac4cbaed 100644
--- a/popt/findme.c
+++ b/popt/findme.c
@@ -2,18 +2,20 @@
* \file popt/findme.c
*/
-/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
+/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
#include "findme.h"
-const char * findProgramPath(const char * argv0) {
+const char * findProgramPath(const char * argv0)
+{
char * path = getenv("PATH");
char * pathbuf;
char * start, * chptr;
char * buf;
+ size_t bufsize;
if (argv0 == NULL) return NULL; /* XXX can't happen */
/* If there is a / in the argv[0], it has to be an absolute path */
@@ -22,17 +24,20 @@ const char * findProgramPath(const char * argv0) {
if (path == NULL) return NULL;
- start = pathbuf = alloca(strlen(path) + 1);
- buf = malloc(strlen(path) + strlen(argv0) + sizeof("/"));
+ bufsize = strlen(path) + 1;
+ start = pathbuf = alloca(bufsize);
+ if (pathbuf == NULL) return NULL; /* XXX can't happen */
+ strlcpy(pathbuf, path, bufsize);
+ bufsize += sizeof "/" - 1 + strlen(argv0);
+ buf = malloc(bufsize);
if (buf == NULL) return NULL; /* XXX can't happen */
- strcpy(pathbuf, path);
chptr = NULL;
/*@-branchstate@*/
do {
if ((chptr = strchr(start, ':')))
*chptr = '\0';
- sprintf(buf, "%s/%s", start, argv0);
+ snprintf(buf, bufsize, "%s/%s", start, argv0);
if (!access(buf, X_OK))
return buf;
diff --git a/popt/popt.c b/popt/popt.c
index 9e007693..9ce3b355 100644
--- a/popt/popt.c
+++ b/popt/popt.c
@@ -2,7 +2,7 @@
* \file popt/popt.c
*/
-/* (C) 19982000 Red Hat, Inc. -- Licensing details are in the COPYING
+/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.rpm.org/pub/rpm/dist */
@@ -18,8 +18,14 @@
#include "findme.h"
#include "poptint.h"
-#ifndef HAVE_STRERROR
-static char * strerror(int errno) {
+#ifdef MYDEBUG
+/*@unchecked@*/
+int _popt_debug = 0;
+#endif
+
+#if !defined(HAVE_STRERROR) && !defined(__LCLINT__)
+static char * strerror(int errno)
+{
extern int sys_nerr;
extern char * sys_errlist[];
@@ -31,7 +37,8 @@ static char * strerror(int errno) {
#endif
#ifdef MYDEBUG
-/*@unused@*/ static void prtcon(const char *msg, poptContext con)
+/*@unused@*/
+static void prtcon(const char *msg, poptContext con)
{
if (msg) fprintf(stderr, "%s", msg);
fprintf(stderr, "\tcon %p os %p nextCharArg \"%s\" nextArg \"%s\" argv[%d] \"%s\"\n",
@@ -49,7 +56,7 @@ void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
con->execPath = _free(con->execPath);
con->execPath = xstrdup(path);
con->execAbsolute = allowAbsolute;
- /*@-nullstate@*/ /* LCL: con->execPath can be NULL? */
+ /*@-nullstate@*/ /* LCL: con->execPath not NULL */
return;
/*@=nullstate@*/
}
@@ -62,17 +69,22 @@ static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)
for (; opt->longName || opt->shortName || opt->arg; opt++) {
if (opt->arg == NULL) continue; /* XXX program error. */
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ void * arg = opt->arg;
+/*@-branchstate@*/
+ /* XXX sick hack to preserve pretense of ABI. */
+ if (arg == poptHelpOptions) arg = poptHelpOptionsI18N;
+/*@=branchstate@*/
/* Recurse on included sub-tables. */
- invokeCallbacksPRE(con, opt->arg);
+ invokeCallbacksPRE(con, arg);
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&
(opt->argInfo & POPT_CBFLAG_PRE))
{ /*@-castfcnptr@*/
poptCallbackType cb = (poptCallbackType)opt->arg;
/*@=castfcnptr@*/
/* Perform callback. */
- /*@-moduncon -noeffectuncon @*/
+ /*@-noeffectuncon @*/
cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip);
- /*@=moduncon =noeffectuncon @*/
+ /*@=noeffectuncon @*/
}
}
}
@@ -85,17 +97,22 @@ static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt)
for (; opt->longName || opt->shortName || opt->arg; opt++) {
if (opt->arg == NULL) continue; /* XXX program error. */
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ void * arg = opt->arg;
+/*@-branchstate@*/
+ /* XXX sick hack to preserve pretense of ABI. */
+ if (arg == poptHelpOptions) arg = poptHelpOptionsI18N;
+/*@=branchstate@*/
/* Recurse on included sub-tables. */
- invokeCallbacksPOST(con, opt->arg);
+ invokeCallbacksPOST(con, arg);
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_CALLBACK &&
(opt->argInfo & POPT_CBFLAG_POST))
{ /*@-castfcnptr@*/
poptCallbackType cb = (poptCallbackType)opt->arg;
/*@=castfcnptr@*/
/* Perform callback. */
- /*@-moduncon -noeffectuncon @*/
+ /*@-noeffectuncon @*/
cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip);
- /*@=moduncon =noeffectuncon @*/
+ /*@=noeffectuncon @*/
}
}
}
@@ -112,6 +129,11 @@ static void invokeCallbacksOPTION(poptContext con,
if (opt != NULL)
for (; opt->longName || opt->shortName || opt->arg; opt++) {
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
+ void * arg = opt->arg;
+/*@-branchstate@*/
+ /* XXX sick hack to preserve pretense of ABI. */
+ if (arg == poptHelpOptions) arg = poptHelpOptionsI18N;
+/*@=branchstate@*/
/* Recurse on included sub-tables. */
if (opt->arg != NULL) /* XXX program error */
invokeCallbacksOPTION(con, opt->arg, myOpt, myData, shorty);
@@ -133,10 +155,10 @@ static void invokeCallbacksOPTION(poptContext con,
const void * cbData = (cbopt->descrip ? cbopt->descrip : myData);
/* Perform callback. */
if (cb != NULL) { /* XXX program error */
- /*@-moduncon -noeffectuncon @*/
+ /*@-noeffectuncon @*/
cb(con, POPT_CALLBACK_REASON_OPTION, myOpt,
con->os->nextArg, cbData);
- /*@=moduncon =noeffectuncon @*/
+ /*@=noeffectuncon @*/
}
/* Terminate (unless explcitly continuing). */
if (!(cbopt->argInfo & POPT_CBFLAG_CONTINUE))
@@ -181,8 +203,12 @@ poptContext poptGetContext(const char * name, int argc, const char ** argv,
con->flags |= POPT_CONTEXT_POSIXMEHARDER;
if (name) {
- char * t = malloc(strlen(name) + 1);
- if (t) con->appName = strcpy(t, name);
+ size_t bufsize = strlen(name) + 1;
+ char * t = malloc(bufsize);
+ if (t) {
+ strlcpy(t, name, bufsize);
+ con->appName = t;
+ }
}
/*@-internalglobs@*/
@@ -202,6 +228,7 @@ static void cleanOSE(/*@special@*/ struct optionStackEntry *os)
os->argb = PBM_FREE(os->argb);
}
+/*@-boundswrite@*/
void poptResetContext(poptContext con)
{
int i;
@@ -222,10 +249,11 @@ void poptResetContext(poptContext con)
con->doExec = NULL;
if (con->finalArgv != NULL)
- for (i = 0; i < con->finalArgvCount; i++)
+ for (i = 0; i < con->finalArgvCount; i++) {
/*@-unqualifiedtrans@*/ /* FIX: typedef double indirection. */
con->finalArgv[i] = _free(con->finalArgv[i]);
/*@=unqualifiedtrans@*/
+ }
con->finalArgvCount = 0;
con->arg_strip = PBM_FREE(con->arg_strip);
@@ -233,8 +261,10 @@ void poptResetContext(poptContext con)
return;
/*@=nullstate@*/
}
+/*@=boundswrite@*/
/* Only one of longName, shortName should be set, not both. */
+/*@-boundswrite@*/
static int handleExec(/*@special@*/ poptContext con,
/*@null@*/ const char * longName, char shortName)
/*@uses con->execs, con->numExecs, con->flags, con->doExec,
@@ -277,12 +307,13 @@ static int handleExec(/*@special@*/ poptContext con,
i = con->finalArgvCount++;
if (con->finalArgv != NULL) /* XXX can't happen */
- { char *s = malloc((longName ? strlen(longName) : 0) + 3);
+ { size_t bufsize = (longName ? strlen(longName) : 0) + 3;
+ char *s = malloc(bufsize);
if (s != NULL) { /* XXX can't happen */
if (longName)
- sprintf(s, "--%s", longName);
+ snprintf(s, bufsize, "--%s", longName);
else
- sprintf(s, "-%c", shortName);
+ snprintf(s, bufsize, "-%c", shortName);
con->finalArgv[i] = s;
} else
con->finalArgv[i] = NULL;
@@ -292,11 +323,12 @@ static int handleExec(/*@special@*/ poptContext con,
return 1;
/*@=nullstate@*/
}
+/*@=boundswrite@*/
/* Only one of longName, shortName may be set at a time */
static int handleAlias(/*@special@*/ poptContext con,
/*@null@*/ const char * longName, char shortName,
- /*@keep@*/ /*@null@*/ const char * nextCharArg)
+ /*@exposed@*/ /*@null@*/ const char * nextCharArg)
/*@uses con->aliases, con->numAliases, con->optionStack, con->os,
con->os->currAlias, con->os->currAlias->option.longName @*/
/*@modifies con @*/
@@ -330,8 +362,10 @@ static int handleAlias(/*@special@*/ poptContext con,
if ((con->os - con->optionStack + 1) == POPT_OPTION_DEPTH)
return POPT_ERROR_OPTSTOODEEP;
+/*@-boundsread@*/
if (nextCharArg && *nextCharArg)
con->os->nextCharArg = nextCharArg;
+/*@=boundsread@*/
con->os++;
con->os->next = 0;
@@ -346,8 +380,10 @@ static int handleAlias(/*@special@*/ poptContext con,
return (rc ? rc : 1);
}
+/*@-bounds -boundswrite @*/
static int execCommand(poptContext con)
- /*@*/
+ /*@globals internalState @*/
+ /*@modifies internalState @*/
{
poptItem item = con->doExec;
const char ** argv;
@@ -363,15 +399,15 @@ static int execCommand(poptContext con)
argv = malloc(sizeof(*argv) *
(6 + item->argc + con->numLeftovers + con->finalArgvCount));
- if (argv == NULL) return POPT_ERROR_MALLOC; /* XXX can't happen */
+ if (argv == NULL) return POPT_ERROR_MALLOC;
- if (!strchr(item->argv[0], '/') && con->execPath) {
- char *s = alloca(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));
- sprintf(s, "%s/%s", con->execPath, item->argv[0]);
+ if (!strchr(item->argv[0], '/') && con->execPath != NULL) {
+ size_t bufsize = strlen(con->execPath) + strlen(item->argv[0]) + sizeof "/";
+ char *s = alloca(bufsize);
+ snprintf(s, bufsize, "%s/%s", con->execPath, item->argv[0]);
argv[argc] = s;
- } else {
+ } else
argv[argc] = findProgramPath(item->argv[0]);
- }
if (argv[argc++] == NULL) return POPT_ERROR_NOARG;
if (item->argc > 1) {
@@ -386,9 +422,6 @@ static int execCommand(poptContext con)
}
if (con->leftovers != NULL && con->numLeftovers > 0) {
-#if 0
- argv[argc++] = "--";
-#endif
memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers);
argc += con->numLeftovers;
}
@@ -396,6 +429,8 @@ static int execCommand(poptContext con)
argv[argc] = NULL;
#ifdef __hpux
+ rc = setresgid(getgid(), getgid(),-1);
+ if (rc) return POPT_ERROR_ERRNO;
rc = setresuid(getuid(), getuid(),-1);
if (rc) return POPT_ERROR_ERRNO;
#else
@@ -405,10 +440,14 @@ static int execCommand(poptContext con)
* XXX from Norbert Warmuth <nwarmuth@privat.circular.de>
*/
#if defined(HAVE_SETUID)
+ rc = setgid(getgid());
+ if (rc) return POPT_ERROR_ERRNO;
rc = setuid(getuid());
if (rc) return POPT_ERROR_ERRNO;
#elif defined (HAVE_SETREUID)
- rc = setreuid(getuid(), getuid()); /*hlauer: not portable to hpux9.01 */
+ rc = setregid(getgid(), getgid());
+ if (rc) return POPT_ERROR_ERRNO;
+ rc = setreuid(getuid(), getuid());
if (rc) return POPT_ERROR_ERRNO;
#else
; /* Can't drop privileges */
@@ -417,7 +456,9 @@ static int execCommand(poptContext con)
if (argv[0] == NULL)
return POPT_ERROR_NOARG;
-#ifdef MYDEBUG
+
+#ifdef MYDEBUG
+if (_popt_debug)
{ const char ** avp;
fprintf(stderr, "==> execvp(%s) argv[%d]:", argv[0], argc);
for (avp = argv; *avp; avp++)
@@ -427,9 +468,12 @@ static int execCommand(poptContext con)
#endif
rc = execvp(argv[0], (char *const *)argv);
+
return POPT_ERROR_ERRNO;
}
+/*@=bounds =boundswrite @*/
+/*@-boundswrite@*/
/*@observer@*/ /*@null@*/ static const struct poptOption *
findOption(const struct poptOption * opt, /*@null@*/ const char * longName,
char shortName,
@@ -448,10 +492,15 @@ findOption(const struct poptOption * opt, /*@null@*/ const char * longName,
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
const struct poptOption * opt2;
+ void * arg = opt->arg;
+/*@-branchstate@*/
+ /* XXX sick hack to preserve pretense of ABI. */
+ if (arg == poptHelpOptions) arg = poptHelpOptionsI18N;
+/*@=branchstate@*/
/* Recurse on included sub-tables. */
- if (opt->arg == NULL) continue; /* XXX program error */
- opt2 = findOption(opt->arg, longName, shortName, callback,
+ if (arg == NULL) continue; /* XXX program error */
+ opt2 = findOption(arg, longName, shortName, callback,
callbackData, singleDash);
if (opt2 == NULL) continue;
/* Sub-table data will be inheirited if no data yet. */
@@ -496,6 +545,7 @@ findOption(const struct poptOption * opt, /*@null@*/ const char * longName,
return opt;
}
+/*@=boundswrite@*/
static const char * findNextArg(/*@special@*/ poptContext con,
unsigned argx, int delete_arg)
@@ -534,6 +584,7 @@ static const char * findNextArg(/*@special@*/ poptContext con,
return arg;
}
+/*@-boundswrite@*/
static /*@only@*/ /*@null@*/ const char *
expandNextArg(/*@special@*/ poptContext con, const char * s)
/*@uses con->optionStack, con->os,
@@ -541,7 +592,7 @@ expandNextArg(/*@special@*/ poptContext con, const char * s)
/*@modifies con @*/
{
const char * a = NULL;
- size_t alen;
+ size_t alen, pos;
char *t, *te;
size_t tn = strlen(s) + 1;
char c;
@@ -567,9 +618,9 @@ expandNextArg(/*@special@*/ poptContext con, const char * s)
alen = strlen(a);
tn += alen;
- *te = '\0';
+ pos = te - t;
t = realloc(t, tn);
- te = t + strlen(t);
+ te = t + pos;
strncpy(te, a, alen); te += alen;
continue;
/*@notreached@*/ /*@switchbreak@*/ break;
@@ -582,6 +633,7 @@ expandNextArg(/*@special@*/ poptContext con, const char * s)
t = realloc(t, strlen(t) + 1); /* XXX memory leak, hard to plug */
return t;
}
+/*@=boundswrite@*/
static void poptStripArg(/*@special@*/ poptContext con, int which)
/*@uses con->arg_strip, con->optionStack @*/
@@ -599,26 +651,26 @@ static void poptStripArg(/*@special@*/ poptContext con, int which)
/*@=compdef@*/
}
-static int poptSaveLong(const struct poptOption * opt, long aLong)
- /*@modifies opt->arg @*/
+int poptSaveLong(long * arg, int argInfo, long aLong)
{
- if (opt->arg == NULL)
+ /* XXX Check alignment, may fail on funky platforms. */
+ if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
return POPT_ERROR_NULLARG;
- if (opt->argInfo & POPT_ARGFLAG_NOT)
+ if (argInfo & POPT_ARGFLAG_NOT)
aLong = ~aLong;
- switch (opt->argInfo & POPT_ARGFLAG_LOGICALOPS) {
+ switch (argInfo & POPT_ARGFLAG_LOGICALOPS) {
case 0:
- *((long *) opt->arg) = aLong;
+ *arg = aLong;
break;
case POPT_ARGFLAG_OR:
- *((long *) opt->arg) |= aLong;
+ *arg |= aLong;
break;
case POPT_ARGFLAG_AND:
- *((long *) opt->arg) &= aLong;
+ *arg &= aLong;
break;
case POPT_ARGFLAG_XOR:
- *((long *) opt->arg) ^= aLong;
+ *arg ^= aLong;
break;
default:
return POPT_ERROR_BADOPERATION;
@@ -627,26 +679,26 @@ static int poptSaveLong(const struct poptOption * opt, long aLong)
return 0;
}
-static int poptSaveInt(const struct poptOption * opt, long aLong)
- /*@modifies opt->arg @*/
+int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong)
{
- if (opt->arg == NULL)
+ /* XXX Check alignment, may fail on funky platforms. */
+ if (arg == NULL || (((unsigned long)arg) & (sizeof(*arg)-1)))
return POPT_ERROR_NULLARG;
- if (opt->argInfo & POPT_ARGFLAG_NOT)
+ if (argInfo & POPT_ARGFLAG_NOT)
aLong = ~aLong;
- switch (opt->argInfo & POPT_ARGFLAG_LOGICALOPS) {
+ switch (argInfo & POPT_ARGFLAG_LOGICALOPS) {
case 0:
- *((int *) opt->arg) = aLong;
+ *arg = aLong;
break;
case POPT_ARGFLAG_OR:
- *((int *) opt->arg) |= aLong;
+ *arg |= aLong;
break;
case POPT_ARGFLAG_AND:
- *((int *) opt->arg) &= aLong;
+ *arg &= aLong;
break;
case POPT_ARGFLAG_XOR:
- *((int *) opt->arg) ^= aLong;
+ *arg ^= aLong;
break;
default:
return POPT_ERROR_BADOPERATION;
@@ -655,6 +707,7 @@ static int poptSaveInt(const struct poptOption * opt, long aLong)
return 0;
}
+/*@-boundswrite@*/
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
int poptGetNextOpt(poptContext con)
{
@@ -714,8 +767,12 @@ int poptGetNextOpt(poptContext con)
}
/* Make a copy we can hack at */
- localOptString = optString =
- strcpy(alloca(strlen(origOptString) + 1), origOptString);
+ { size_t bufsize = strlen(origOptString) + 1;
+ localOptString = optString = alloca(bufsize);
+ if (optString == NULL) /* XXX can't happen */
+ return POPT_ERROR_BADOPT;
+ strlcpy(optString, origOptString, bufsize);
+ }
if (optString[0] == '\0')
return POPT_ERROR_BADOPT;
@@ -800,11 +857,11 @@ int poptGetNextOpt(poptContext con)
if (opt == NULL) return POPT_ERROR_BADOPT; /* XXX can't happen */
if (opt->arg && (opt->argInfo & POPT_ARG_MASK) == POPT_ARG_NONE) {
- if (poptSaveInt(opt, 1L))
+ if (poptSaveInt((int *)opt->arg, opt->argInfo, 1L))
return POPT_ERROR_BADOPERATION;
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_VAL) {
if (opt->arg) {
- if (poptSaveInt(opt, (long)opt->val))
+ if (poptSaveInt((int *)opt->arg, opt->argInfo, (long)opt->val))
return POPT_ERROR_BADOPERATION;
}
} else if ((opt->argInfo & POPT_ARG_MASK) != POPT_ARG_NONE) {
@@ -873,12 +930,12 @@ int poptGetNextOpt(poptContext con)
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_LONG) {
if (aLong == LONG_MIN || aLong == LONG_MAX)
return POPT_ERROR_OVERFLOW;
- if (poptSaveLong(opt, aLong))
+ if (poptSaveLong((long *)opt->arg, opt->argInfo, aLong))
return POPT_ERROR_BADOPERATION;
} else {
if (aLong > INT_MAX || aLong < INT_MIN)
return POPT_ERROR_OVERFLOW;
- if (poptSaveInt(opt, aLong))
+ if (poptSaveInt((int *)opt->arg, opt->argInfo, aLong))
return POPT_ERROR_BADOPERATION;
}
} /*@switchbreak@*/ break;
@@ -904,13 +961,10 @@ int poptGetNextOpt(poptContext con)
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_DOUBLE) {
*((double *) opt->arg) = aDouble;
} else {
-#ifndef DBL_EPSILON
-#define DBL_EPSILON 2.2204460492503131e-16
-#endif
-#define MY_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
- if ((MY_ABS(aDouble) - FLT_MAX) > DBL_EPSILON)
+#define _ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
+ if ((_ABS(aDouble) - FLT_MAX) > DBL_EPSILON)
return POPT_ERROR_OVERFLOW;
- if ((FLT_MIN - MY_ABS(aDouble)) > DBL_EPSILON)
+ if ((FLT_MIN - _ABS(aDouble)) > DBL_EPSILON)
return POPT_ERROR_OVERFLOW;
*((float *) opt->arg) = aDouble;
}
@@ -939,14 +993,15 @@ int poptGetNextOpt(poptContext con)
}
if (con->finalArgv != NULL)
- { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + 3);
+ { ssize_t bufsize = (opt->longName ? strlen(opt->longName) : 0) + 3;
+ char *s = malloc(bufsize);
if (s != NULL) { /* XXX can't happen */
if (opt->longName)
- sprintf(s, "%s%s",
+ snprintf(s, bufsize, "%s%s",
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
opt->longName);
else
- sprintf(s, "-%c", opt->shortName);
+ snprintf(s, bufsize, "-%c", opt->shortName);
con->finalArgv[con->finalArgvCount++] = s;
} else
con->finalArgv[con->finalArgvCount++] = NULL;
@@ -967,6 +1022,7 @@ int poptGetNextOpt(poptContext con)
return (opt ? opt->val : -1); /* XXX can't happen */
}
+/*@=boundswrite@*/
const char * poptGetOptArg(poptContext con)
{
@@ -996,6 +1052,7 @@ const char * poptPeekArg(poptContext con)
return ret;
}
+/*@-boundswrite@*/
const char ** poptGetArgs(poptContext con)
{
if (con == NULL ||
@@ -1009,6 +1066,7 @@ const char ** poptGetArgs(poptContext con)
return (con->leftovers + con->nextLeftover);
/*@=nullret =nullstate @*/
}
+/*@=boundswrite@*/
poptContext poptFreeContext(poptContext con)
{
@@ -1071,6 +1129,7 @@ int poptAddAlias(poptContext con, struct poptAlias alias,
return poptAddItem(con, item, 0);
}
+/*@-boundswrite@*/
/*@-mustmod@*/ /* LCL: con not modified? */
int poptAddItem(poptContext con, poptItem newItem, int flags)
{
@@ -1115,6 +1174,7 @@ int poptAddItem(poptContext con, poptItem newItem, int flags)
return 0;
}
/*@=mustmod@*/
+/*@=boundswrite@*/
const char * poptBadOption(poptContext con, int flags)
{
@@ -1184,6 +1244,7 @@ const char * poptGetInvocationName(poptContext con)
return (con->os->argv ? con->os->argv[0] : "");
}
+/*@-boundswrite@*/
int poptStrippedArgv(poptContext con, int argc, char ** argv)
{
int numargs = argc;
@@ -1207,3 +1268,4 @@ int poptStrippedArgv(poptContext con, int argc, char ** argv)
return numargs;
}
+/*@=boundswrite@*/
diff --git a/popt/popt.h b/popt/popt.h
index 06978f3d..4f85d9e3 100644
--- a/popt/popt.h
+++ b/popt/popt.h
@@ -112,33 +112,42 @@
/** \ingroup popt
*/
struct poptOption {
-/*@observer@*/ /*@null@*/ const char * longName; /*!< may be NULL */
- char shortName; /*!< may be '\0' */
+/*@observer@*/ /*@null@*/
+ const char * longName; /*!< may be NULL */
+ char shortName; /*!< may be NUL */
int argInfo;
-/*@shared@*/ /*@null@*/ void * arg; /*!< depends on argInfo */
+/*@shared@*/ /*@null@*/
+ void * arg; /*!< depends on argInfo */
int val; /*!< 0 means don't return, just update flag */
-/*@observer@*/ /*@null@*/ const char * descrip; /*!< description for autohelp -- may be NULL */
-/*@observer@*/ /*@null@*/ const char * argDescrip; /*!< argument description for autohelp */
+/*@observer@*/ /*@null@*/
+ const char * descrip; /*!< description for autohelp -- may be NULL */
+/*@observer@*/ /*@null@*/
+ const char * argDescrip; /*!< argument description for autohelp */
};
/** \ingroup popt
* A popt alias argument for poptAddAlias().
*/
struct poptAlias {
-/*@owned@*/ /*@null@*/ const char * longName; /*!< may be NULL */
- char shortName; /*!< may be '\0' */
+/*@owned@*/ /*@null@*/
+ const char * longName; /*!< may be NULL */
+ char shortName; /*!< may be NUL */
int argc;
-/*@owned@*/ const char ** argv; /*!< must be free()able */
+/*@owned@*/
+ const char ** argv; /*!< must be free()able */
};
/** \ingroup popt
* A popt alias or exec argument for poptAddItem().
*/
+/*@-exporttype@*/
typedef struct poptItem_s {
struct poptOption option; /*!< alias/exec name(s) and description. */
int argc; /*!< (alias) no. of args. */
-/*@owned@*/ const char ** argv; /*!< (alias) args, must be free()able. */
+/*@owned@*/
+ const char ** argv; /*!< (alias) args, must be free()able. */
} * poptItem;
+/*@=exporttype@*/
/** \ingroup popt
* \name Auto-generated help/usage
@@ -148,16 +157,26 @@ typedef struct poptItem_s {
/**
* Empty table marker to enable displaying popt alias/exec options.
*/
-/*@observer@*/ /*@checked@*/
+/*@-exportvar@*/
+/*@unchecked@*/ /*@observer@*/
extern struct poptOption poptAliasOptions[];
+/*@=exportvar@*/
#define POPT_AUTOALIAS { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptAliasOptions, \
0, "Options implemented via popt alias/exec:", NULL },
/**
* Auto help table options.
*/
-/*@observer@*/ /*@checked@*/
+/*@-exportvar@*/
+/*@unchecked@*/ /*@observer@*/
extern struct poptOption poptHelpOptions[];
+/*@=exportvar@*/
+
+/*@-exportvar@*/
+/*@unchecked@*/ /*@observer@*/
+extern struct poptOption * poptHelpOptionsI18N;
+/*@=exportvar@*/
+
#define POPT_AUTOHELP { NULL, '\0', POPT_ARG_INCLUDE_TABLE, poptHelpOptions, \
0, "Help options:", NULL },
@@ -166,19 +185,25 @@ extern struct poptOption poptHelpOptions[];
/** \ingroup popt
*/
+/*@-exporttype@*/
typedef /*@abstract@*/ struct poptContext_s * poptContext;
+/*@=exporttype@*/
/** \ingroup popt
*/
#ifndef __cplusplus
-/*@-typeuse@*/
+/*@-exporttype -typeuse@*/
typedef struct poptOption * poptOption;
-/*@=typeuse@*/
+/*@=exporttype =typeuse@*/
#endif
-enum poptCallbackReason { POPT_CALLBACK_REASON_PRE,
- POPT_CALLBACK_REASON_POST,
- POPT_CALLBACK_REASON_OPTION };
+/*@-exportconst@*/
+enum poptCallbackReason {
+ POPT_CALLBACK_REASON_PRE = 0,
+ POPT_CALLBACK_REASON_POST = 1,
+ POPT_CALLBACK_REASON_OPTION = 2
+};
+/*@=exportconst@*/
#ifdef __cplusplus
extern "C" {
@@ -198,18 +223,20 @@ typedef void (*poptCallbackType) (poptContext con,
/*@null@*/ const struct poptOption * opt,
/*@null@*/ const char * arg,
/*@null@*/ const void * data)
- /*@*/;
+ /*@globals internalState @*/
+ /*@modifies internalState @*/;
/** \ingroup popt
* Initialize popt context.
- * @param name
+ * @param name context name (usually argv[0] program name)
* @param argc no. of arguments
* @param argv argument array
* @param options address of popt option table
* @param flags or'd POPT_CONTEXT_* bits
* @return initialized popt context
*/
-/*@only@*/ /*@null@*/ poptContext poptGetContext(
+/*@only@*/ /*@null@*/
+poptContext poptGetContext(
/*@dependent@*/ /*@keep@*/ const char * name,
int argc, /*@dependent@*/ /*@keep@*/ const char ** argv,
/*@dependent@*/ /*@keep@*/ const struct poptOption * options,
@@ -220,6 +247,7 @@ typedef void (*poptCallbackType) (poptContext con,
* Reinitialize popt context.
* @param con context
*/
+/*@unused@*/
void poptResetContext(/*@null@*/poptContext con)
/*@modifies con @*/;
@@ -229,57 +257,62 @@ void poptResetContext(/*@null@*/poptContext con)
* @return next option val, -1 on last item, POPT_ERROR_* on error
*/
int poptGetNextOpt(/*@null@*/poptContext con)
- /*@globals fileSystem@*/
- /*@modifies con, fileSystem @*/;
+ /*@globals fileSystem, internalState @*/
+ /*@modifies con, fileSystem, internalState @*/;
-/*@-redecl@*/
/** \ingroup popt
* Return next option argument (if any).
* @param con context
- * @return option argument, NULL if no more options are available
+ * @return option argument, NULL if no argument is available
*/
-/*@observer@*/ /*@null@*/ const char * poptGetOptArg(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/ /*@unused@*/
+const char * poptGetOptArg(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
- * Return current option's argument.
+ * Return next argument.
* @param con context
- * @return option argument, NULL if no more options are available
+ * @return next argument, NULL if no argument is available
*/
-/*@observer@*/ /*@null@*/ const char * poptGetArg(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/ /*@unused@*/
+const char * poptGetArg(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
- * Peek at current option's argument.
+ * Peek at current argument.
* @param con context
- * @return option argument
+ * @return current argument, NULL if no argument is available
*/
-/*@observer@*/ /*@null@*/ const char * poptPeekArg(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/ /*@unused@*/
+const char * poptPeekArg(/*@null@*/poptContext con)
/*@*/;
/** \ingroup popt
* Return remaining arguments.
* @param con context
- * @return argument array, terminated with NULL
+ * @return argument array, NULL terminated
*/
-/*@observer@*/ /*@null@*/ const char ** poptGetArgs(/*@null@*/poptContext con)
+/*@observer@*/ /*@null@*/
+const char ** poptGetArgs(/*@null@*/poptContext con)
/*@modifies con @*/;
/** \ingroup popt
* Return the option which caused the most recent error.
* @param con context
+ * @param flags
* @return offending option
*/
-/*@observer@*/ const char * poptBadOption(/*@null@*/poptContext con, int flags)
+/*@observer@*/
+const char * poptBadOption(/*@null@*/poptContext con, int flags)
/*@*/;
-/*@=redecl@*/
/** \ingroup popt
* Destroy context.
* @param con context
* @return NULL always
*/
-/*@null@*/ poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
+/*@null@*/
+poptContext poptFreeContext( /*@only@*/ /*@null@*/ poptContext con)
/*@modifies con @*/;
/** \ingroup popt
@@ -288,6 +321,7 @@ int poptGetNextOpt(/*@null@*/poptContext con)
* @param argv argument array, NULL terminated
* @return 0 on success, POPT_ERROR_OPTSTOODEEP on failure
*/
+/*@unused@*/
int poptStuffArgs(poptContext con, /*@keep@*/ const char ** argv)
/*@modifies con @*/;
@@ -307,7 +341,7 @@ int poptAddAlias(poptContext con, struct poptAlias alias, int flags)
/** \ingroup popt
* Add alias/exec item to context.
* @param con context
- * @param item alias/exec item to add
+ * @param newItem alias/exec item to add
* @param flags 0 for alias, 1 for exec
* @return 0 on success
*/
@@ -321,9 +355,9 @@ int poptAddItem(poptContext con, poptItem newItem, int flags)
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
int poptReadConfigFile(poptContext con, const char * fn)
- /*@globals fileSystem@*/
- /*@modifies fileSystem,
- con->execs, con->numExecs @*/;
+ /*@globals errno, fileSystem, internalState @*/
+ /*@modifies con->execs, con->numExecs,
+ errno, fileSystem, internalState @*/;
/** \ingroup popt
* Read default configuration from /etc/popt and $HOME/.popt.
@@ -331,10 +365,11 @@ int poptReadConfigFile(poptContext con, const char * fn)
* @param useEnv (unused)
* @return 0 on success, POPT_ERROR_ERRNO on failure
*/
+/*@unused@*/
int poptReadDefaultConfig(poptContext con, /*@unused@*/ int useEnv)
- /*@globals fileSystem@*/
- /*@modifies fileSystem,
- con->execs, con->numExecs @*/;
+ /*@globals fileSystem, internalState @*/
+ /*@modifies con->execs, con->numExecs,
+ fileSystem, internalState @*/;
/** \ingroup popt
* Duplicate an argument array.
@@ -363,19 +398,70 @@ int poptDupArgv(int argc, /*@null@*/ const char **argv,
* @retval argcPtr address of returned no. of arguments
* @retval argvPtr address of returned argument array
*/
-int poptParseArgvString(const unsigned char * s,
+int poptParseArgvString(const char * s,
/*@out@*/ int * argcPtr, /*@out@*/ const char *** argvPtr)
/*@modifies *argcPtr, *argvPtr @*/;
/** \ingroup popt
+ * Parses an input configuration file and returns an string that is a
+ * command line. For use with popt. You must free the return value when done.
+ *
+ * Given the file:
+\verbatim
+# this line is ignored
+ # this one too
+aaa
+ bbb
+ ccc
+bla=bla
+
+this_is = fdsafdas
+ bad_line=
+ reall bad line
+ reall bad line = again
+5555= 55555
+ test = with lots of spaces
+\endverbatim
+*
+* The result is:
+\verbatim
+--aaa --bbb --ccc --bla="bla" --this_is="fdsafdas" --5555="55555" --test="with lots of spaces"
+\endverbatim
+*
+* Passing this to poptParseArgvString() yields an argv of:
+\verbatim
+'--aaa'
+'--bbb'
+'--ccc'
+'--bla=bla'
+'--this_is=fdsafdas'
+'--5555=55555'
+'--test=with lots of spaces'
+\endverbatim
+ *
+ * @bug NULL is returned if file line is too long.
+ * @bug Silently ignores invalid lines.
+ *
+ * @param fp file handle to read
+ * @param *argstrp return string of options (malloc'd)
+ * @param flags unused
+ * @return 0 on success
+ * @see poptParseArgvString
+ */
+/*@-fcnuse@*/
+int poptConfigFileToString(FILE *fp, /*@out@*/ char ** argstrp, int flags)
+ /*@globals fileSystem @*/
+ /*@modifies *fp, *argstrp, fileSystem @*/;
+/*@=fcnuse@*/
+
+/** \ingroup popt
* Return formatted error string for popt failure.
* @param error popt error
* @return error string
*/
-/*@-redecl@*/
-/*@observer@*/ const char * poptStrerror(const int error)
+/*@observer@*/
+const char * poptStrerror(const int error)
/*@*/;
-/*@=redecl@*/
/** \ingroup popt
* Limit search for executables.
@@ -383,6 +469,7 @@ int poptParseArgvString(const unsigned char * s,
* @param path single path to search for executables
* @param allowAbsolute absolute paths only?
*/
+/*@unused@*/
void poptSetExecPath(poptContext con, const char * path, int allowAbsolute)
/*@modifies con @*/;
@@ -421,10 +508,11 @@ void poptSetOtherOptionHelp(poptContext con, const char * text)
* @param con context
* @return argv[0]
*/
-/*@-redecl -fcnuse@*/
-/*@observer@*/ const char * poptGetInvocationName(poptContext con)
+/*@-fcnuse@*/
+/*@observer@*/
+const char * poptGetInvocationName(poptContext con)
/*@*/;
-/*@=redecl =fcnuse@*/
+/*@=fcnuse@*/
/** \ingroup popt
* Shuffle argv pointers to remove stripped args, returns new argc.
@@ -438,6 +526,36 @@ int poptStrippedArgv(poptContext con, int argc, char ** argv)
/*@modifies *argv @*/;
/*@=fcnuse@*/
+/**
+ * Save a long, performing logical operation with value.
+ * @warning Alignment check may be too strict on certain platorms.
+ * @param arg integer pointer, aligned on int boundary.
+ * @param argInfo logical operation (see POPT_ARGFLAG_*)
+ * @param aLong value to use
+ * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
+ */
+/*@-incondefs@*/
+/*@unused@*/
+int poptSaveLong(/*@null@*/ long * arg, int argInfo, long aLong)
+ /*@modifies *arg @*/
+ /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/;
+/*@=incondefs@*/
+
+/**
+ * Save an integer, performing logical operation with value.
+ * @warning Alignment check may be too strict on certain platorms.
+ * @param arg integer pointer, aligned on int boundary.
+ * @param argInfo logical operation (see POPT_ARGFLAG_*)
+ * @param aLong value to use
+ * @return 0 on success, POPT_ERROR_NULLARG/POPT_ERROR_BADOPERATION
+ */
+/*@-incondefs@*/
+/*@unused@*/
+int poptSaveInt(/*@null@*/ int * arg, int argInfo, long aLong)
+ /*@modifies *arg @*/
+ /*@requires maxSet(arg) >= 0 /\ maxRead(arg) == 0 @*/;
+/*@=incondefs@*/
+
/*@=type@*/
#ifdef __cplusplus
}
diff --git a/popt/poptconfig.c b/popt/poptconfig.c
index 50235661..63c3ee29 100644
--- a/popt/poptconfig.c
+++ b/popt/poptconfig.c
@@ -2,30 +2,32 @@
* \file popt/poptconfig.c
*/
-/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
+/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
#include "poptint.h"
+/*@access poptContext @*/
/*@-compmempass@*/ /* FIX: item->option.longName kept, not dependent. */
-static void configLine(poptContext con, unsigned char * line)
+static void configLine(poptContext con, char * line)
/*@modifies con @*/
{
- /*@-type@*/
- int nameLength = strlen(con->appName);
- /*@=type@*/
+ size_t nameLength;
const char * entryType;
const char * opt;
poptItem item = (poptItem) alloca(sizeof(*item));
int i, j;
+
+ if (con->appName == NULL)
+ return;
+ nameLength = strlen(con->appName);
+/*@-boundswrite@*/
memset(item, 0, sizeof(*item));
- /*@-type@*/
if (strncmp(line, con->appName, nameLength)) return;
- /*@=type@*/
line += nameLength;
if (*line == '\0' || !isspace(*line)) return;
@@ -80,6 +82,7 @@ static void configLine(poptContext con, unsigned char * line)
item->argc = j;
}
/*@=modobserver@*/
+/*@=boundswrite@*/
/*@-nullstate@*/ /* FIX: item->argv[] may be NULL */
if (!strcmp(entryType, "alias"))
@@ -92,9 +95,9 @@ static void configLine(poptContext con, unsigned char * line)
int poptReadConfigFile(poptContext con, const char * fn)
{
- const unsigned char * file, * chptr, * end;
- unsigned char * buf;
-/*@dependent@*/ unsigned char * dst;
+ const char * file, * chptr, * end;
+ char * buf;
+/*@dependent@*/ char * dst;
int fd, rc;
off_t fileLength;
@@ -106,9 +109,7 @@ int poptReadConfigFile(poptContext con, const char * fn)
if (fileLength == -1 || lseek(fd, 0, 0) == -1) {
rc = errno;
(void) close(fd);
- /*@-mods@*/
errno = rc;
- /*@=mods@*/
return POPT_ERROR_ERRNO;
}
@@ -116,14 +117,13 @@ int poptReadConfigFile(poptContext con, const char * fn)
if (read(fd, (char *)file, fileLength) != fileLength) {
rc = errno;
(void) close(fd);
- /*@-mods@*/
errno = rc;
- /*@=mods@*/
return POPT_ERROR_ERRNO;
}
if (close(fd) == -1)
return POPT_ERROR_ERRNO;
+/*@-boundswrite@*/
dst = buf = alloca(fileLength + 1);
chptr = file;
@@ -155,6 +155,7 @@ int poptReadConfigFile(poptContext con, const char * fn)
}
}
/*@=infloops@*/
+/*@=boundswrite@*/
return 0;
}
@@ -164,18 +165,16 @@ int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv))
char * fn, * home;
int rc;
- /*@-type@*/
- if (!con->appName) return 0;
- /*@=type@*/
+ if (con->appName == NULL) return 0;
rc = poptReadConfigFile(con, "/etc/popt");
if (rc) return rc;
- if (getuid() != geteuid()) return 0;
if ((home = getenv("HOME"))) {
- fn = alloca(strlen(home) + 20);
- strcpy(fn, home);
- strcat(fn, "/.popt");
+ size_t bufsize = strlen(home) + 20;
+ fn = alloca(bufsize);
+ if (fn == NULL) return 0;
+ snprintf(fn, bufsize, "%s/.popt", home);
rc = poptReadConfigFile(con, fn);
if (rc) return rc;
}
diff --git a/popt/popthelp.c b/popt/popthelp.c
index 07020370..eb735ffb 100644
--- a/popt/popthelp.c
+++ b/popt/popthelp.c
@@ -1,20 +1,31 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
-/*@-type@*/
/** \ingroup popt
* \file popt/popthelp.c
*/
-/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
+/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.rpm.org/pub/rpm/dist. */
#include "system.h"
+
+#define POPT_WCHAR_HACK
+#ifdef POPT_WCHAR_HACK
+#include <wchar.h> /* for mbsrtowcs */
+/*@access mbstate_t @*/
+#endif
#include "poptint.h"
+/*@access poptContext@*/
+
/**
+ * Display arguments.
* @param con context
+ * @param foo (unused)
* @param key option(s)
+ * @param arg (unused)
+ * @param data (unused)
*/
static void displayArgs(poptContext con,
/*@unused@*/ UNUSED(enum poptCallbackReason foo),
@@ -52,12 +63,26 @@ struct poptOption poptHelpOptions[] = {
{ NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
{ "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
{ "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
+ POPT_TABLEEND
+} ;
+
+/*@observer@*/ /*@unchecked@*/
+static struct poptOption poptHelpOptions2[] = {
+/*@-readonlytrans@*/
+ { NULL, '\0', POPT_ARG_INTL_DOMAIN, PACKAGE, 0, NULL, NULL},
+/*@=readonlytrans@*/
+ { NULL, '\0', POPT_ARG_CALLBACK, (void *)&displayArgs, '\0', NULL, NULL },
+ { "help", '?', 0, NULL, '?', N_("Show this help message"), NULL },
+ { "usage", '\0', 0, NULL, 'u', N_("Display brief usage message"), NULL },
#ifdef NOTYET
{ "defaults", '\0', POPT_ARG_NONE, &show_option_defaults, 0,
N_("Display option defaults in message"), NULL },
#endif
POPT_TABLEEND
} ;
+
+/*@observer@*/ /*@unchecked@*/
+struct poptOption * poptHelpOptionsI18N = poptHelpOptions2;
/*@=castfcnptr@*/
/**
@@ -83,7 +108,7 @@ getTableTranslationDomain(/*@null@*/ const struct poptOption *table)
*/
/*@observer@*/ /*@null@*/ static const char *
getArgDescrip(const struct poptOption * opt,
- /*@-paramuse@*/ /* FIX: wazzup? */
+ /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */
/*@null@*/ UNUSED(const char * translation_domain))
/*@=paramuse@*/
/*@*/
@@ -97,7 +122,11 @@ getArgDescrip(const struct poptOption * opt,
switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_NONE: return POPT_("NONE");
+#ifdef DYING
case POPT_ARG_VAL: return POPT_("VAL");
+#else
+ case POPT_ARG_VAL: return NULL;
+#endif
case POPT_ARG_INT: return POPT_("INT");
case POPT_ARG_LONG: return POPT_("LONG");
case POPT_ARG_STRING: return POPT_("STRING");
@@ -108,61 +137,65 @@ getArgDescrip(const struct poptOption * opt,
}
/**
+ * Display default value for an option.
+ * @param lineLength display positions remaining
* @param opt option(s)
* @param translation_domain translation domain
+ * @return
*/
static /*@only@*/ /*@null@*/ char *
-singleOptionDefaultValue(int lineLength,
+singleOptionDefaultValue(size_t lineLength,
const struct poptOption * opt,
- /*@-paramuse@*/ /* FIX: i18n macros disable with lclint */
+ /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */
/*@null@*/ UNUSED(const char * translation_domain))
/*@=paramuse@*/
/*@*/
{
const char * defstr = D_(translation_domain, "default");
- char * le = malloc(4*lineLength + 1);
+ size_t limit, bufsize = 4*lineLength + 1;
+ char * le = malloc(bufsize);
char * l = le;
if (le == NULL) return NULL; /* XXX can't happen */
- *le = '\0';
+/*@-boundswrite@*/
*le++ = '(';
- strcpy(le, defstr); le += strlen(le);
+ le += strlcpy(le, defstr, bufsize - 3);
*le++ = ':';
*le++ = ' ';
+ limit = bufsize - (le - l) - 1; /* -1 for closing paren */
if (opt->arg) /* XXX programmer error */
switch (opt->argInfo & POPT_ARG_MASK) {
case POPT_ARG_VAL:
case POPT_ARG_INT:
{ long aLong = *((int *)opt->arg);
- sprintf(le, "%ld", aLong);
- le += strlen(le);
+ le += snprintf(le, limit, "%ld", aLong);
} break;
case POPT_ARG_LONG:
{ long aLong = *((long *)opt->arg);
- sprintf(le, "%ld", aLong);
- le += strlen(le);
+ le += snprintf(le, limit, "%ld", aLong);
} break;
case POPT_ARG_FLOAT:
{ double aDouble = *((float *)opt->arg);
- sprintf(le, "%g", aDouble);
- le += strlen(le);
+ le += snprintf(le, limit, "%g", aDouble);
} break;
case POPT_ARG_DOUBLE:
{ double aDouble = *((double *)opt->arg);
- sprintf(le, "%g", aDouble);
- le += strlen(le);
+ le += snprintf(le, limit, "%g", aDouble);
} break;
case POPT_ARG_STRING:
{ const char * s = *(const char **)opt->arg;
if (s == NULL) {
- strcpy(le, "null"); le += strlen(le);
+ le += strlcpy(le, "null", limit);
} else {
- size_t slen = 4*lineLength - (le - l) - sizeof("\"...\")");
+ size_t len;
+ limit -= 2; /* make room for quotes */
*le++ = '"';
- strncpy(le, s, slen); le[slen] = '\0'; le += strlen(le);
- if (slen < strlen(s)) {
- strcpy(le, "..."); le += strlen(le);
- }
+ len = strlcpy(le, s, limit);
+ if (len >= limit) {
+ le += limit - 3 - 1;
+ *le++ = '.'; *le++ = '.'; *le++ = '.';
+ } else
+ le += len;
*le++ = '"';
}
} break;
@@ -174,50 +207,57 @@ singleOptionDefaultValue(int lineLength,
}
*le++ = ')';
*le = '\0';
+/*@=boundswrite@*/
return l;
}
/**
+ * Display help text for an option.
* @param fp output file handle
+ * @param maxLeftCol largest argument display width
* @param opt option(s)
* @param translation_domain translation domain
*/
-static void singleOptionHelp(FILE * fp, int maxLeftCol,
+static void singleOptionHelp(FILE * fp, size_t maxLeftCol,
const struct poptOption * opt,
- /*@null@*/ const char * translation_domain)
+ /*@null@*/ UNUSED(const char * translation_domain))
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
- int indentLength = maxLeftCol + 5;
- int lineLength = 79 - indentLength;
- const unsigned char * help = D_(translation_domain, opt->descrip);
+ size_t indentLength = maxLeftCol + 5;
+ size_t lineLength = 79 - indentLength;
+ const char * help = D_(translation_domain, opt->descrip);
const char * argDescrip = getArgDescrip(opt, translation_domain);
- int helpLength;
- unsigned char * defs = NULL;
- unsigned char * left;
- int nb = maxLeftCol + 1;
+ size_t helpLength;
+ char * defs = NULL;
+ char * left;
+ size_t lelen, limit;
+ size_t nb = maxLeftCol + 1;
+ int displaypad = 0;
/* Make sure there's more than enough room in target buffer. */
if (opt->longName) nb += strlen(opt->longName);
if (argDescrip) nb += strlen(argDescrip);
+/*@-boundswrite@*/
left = malloc(nb);
if (left == NULL) return; /* XXX can't happen */
left[0] = '\0';
left[maxLeftCol] = '\0';
if (opt->longName && opt->shortName)
- sprintf(left, "-%c, %s%s", opt->shortName,
+ snprintf(left, nb, "-%c, %s%s", opt->shortName,
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
opt->longName);
else if (opt->shortName != '\0')
- sprintf(left, "-%c", opt->shortName);
+ snprintf(left, nb, "-%c", opt->shortName);
else if (opt->longName)
- sprintf(left, "%s%s",
+ snprintf(left, nb, "%s%s",
((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "-" : "--"),
opt->longName);
if (!*left) goto out;
+
if (argDescrip) {
char * le = left + strlen(left);
@@ -229,16 +269,10 @@ static void singleOptionHelp(FILE * fp, int maxLeftCol,
if (opt->argInfo & POPT_ARGFLAG_SHOW_DEFAULT) {
defs = singleOptionDefaultValue(lineLength, opt, translation_domain);
if (defs) {
- char * t = malloc((help ? strlen(help) : 0) +
- strlen(defs) + sizeof(" "));
+ size_t bufsize = (help ? strlen(help) : 0) + sizeof " " + strlen(defs);
+ char * t = malloc(bufsize);
if (t) {
- char * te = t;
- *te = '\0';
- if (help) {
- strcpy(te, help); te += strlen(te);
- }
- *te++ = ' ';
- strcpy(te, defs);
+ snprintf(t, bufsize, "%s %s", help ? help : "", defs);
defs = _free(defs);
}
defs = t;
@@ -251,6 +285,7 @@ static void singleOptionHelp(FILE * fp, int maxLeftCol,
case POPT_ARG_NONE:
break;
case POPT_ARG_VAL:
+#ifdef NOTNOW /* XXX pug ugly nerdy output */
{ long aLong = opt->val;
int ops = (opt->argInfo & POPT_ARGFLAG_LOGICALOPS);
int negate = (opt->argInfo & POPT_ARGFLAG_NOT);
@@ -272,50 +307,78 @@ static void singleOptionHelp(FILE * fp, int maxLeftCol,
default:
/*@innerbreak@*/ break;
}
- *le++ = '=';
+ *le++ = (opt->longName != NULL ? '=' : ' ');
if (negate) *le++ = '~';
/*@-formatconst@*/
- sprintf(le, (ops ? "0x%lx" : "%ld"), aLong);
- le += strlen(le);
+ limit = nb - (le - left);
+ lelen = snprintf(le, limit, (ops ? "0x%lx" : "%ld"), aLong);
+ le += lelen >= limit ? limit - 1 : lelen;
/*@=formatconst@*/
*le++ = ']';
- } break;
+ }
+#endif
+ break;
case POPT_ARG_INT:
case POPT_ARG_LONG:
case POPT_ARG_FLOAT:
case POPT_ARG_DOUBLE:
case POPT_ARG_STRING:
- *le++ = '=';
- strcpy(le, argDescrip); le += strlen(le);
+ *le++ = (opt->longName != NULL ? '=' : ' ');
+ limit = nb - (le - left);
+ lelen = strlcpy(le, argDescrip, limit);
+ le += lelen >= limit ? limit - 1 : lelen;
break;
default:
break;
}
} else {
+
*le++ = '=';
- strcpy(le, argDescrip); le += strlen(le);
+ limit = nb - (le - left);
+ lelen = strlcpy(le, argDescrip, limit);
+ if (lelen >= limit)
+ lelen = limit - 1;
+ le += lelen;
+
+#ifdef POPT_WCHAR_HACK
+ { const char * scopy = argDescrip;
+ mbstate_t t;
+ size_t n;
+
+ memset ((void *)&t, '\0', sizeof (t)); /* In initial state. */
+ /* Determine number of characters. */
+ n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
+
+ displaypad = (int) (lelen-n);
+ }
+#endif
}
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL)
*le++ = ']';
*le = '\0';
}
+/*@=boundswrite@*/
if (help)
- fprintf(fp," %-*s ", maxLeftCol, left);
+ fprintf(fp," %-*s ", maxLeftCol+displaypad, left);
else {
fprintf(fp," %s\n", left);
goto out;
}
left = _free(left);
+/*@-branchstate@*/
if (defs) {
- help = defs; defs = NULL;
+ help = defs;
+ defs = NULL;
}
+/*@=branchstate@*/
helpLength = strlen(help);
+/*@-boundsread@*/
while (helpLength > lineLength) {
- const unsigned char * ch;
- char format[10];
+ const char * ch;
+ char format[16];
ch = help + lineLength - 1;
while (ch > help && !isspace(*ch)) ch--;
@@ -323,7 +386,7 @@ static void singleOptionHelp(FILE * fp, int maxLeftCol,
while (ch > (help + 1) && isspace(*ch)) ch--;
ch++;
- sprintf(format, "%%.%ds\n%%%ds", (int) (ch - help), indentLength);
+ snprintf(format, sizeof format, "%%.%ds\n%%%ds", (int) (ch - help), (int) indentLength);
/*@-formatconst@*/
fprintf(fp, format, help, " ");
/*@=formatconst@*/
@@ -331,6 +394,7 @@ static void singleOptionHelp(FILE * fp, int maxLeftCol,
while (isspace(*help) && *help) help++;
helpLength = strlen(help);
}
+/*@=boundsread@*/
if (helpLength) fprintf(fp, "%s\n", help);
@@ -342,15 +406,17 @@ out:
}
/**
+ * Find display width for longest argument string.
* @param opt option(s)
* @param translation_domain translation domain
+ * @return display width
*/
-static int maxArgWidth(const struct poptOption * opt,
- /*@null@*/ const char * translation_domain)
+static size_t maxArgWidth(const struct poptOption * opt,
+ /*@null@*/ UNUSED(const char * translation_domain))
/*@*/
{
- int max = 0;
- int len = 0;
+ size_t max = 0;
+ size_t len = 0;
const char * s;
if (opt != NULL)
@@ -370,8 +436,26 @@ static int maxArgWidth(const struct poptOption * opt,
}
s = getArgDescrip(opt, translation_domain);
+
+#ifdef POPT_WCHAR_HACK
+ /* XXX Calculate no. of display characters. */
+ if (s) {
+ const char * scopy = s;
+ mbstate_t t;
+ size_t n;
+
+/*@-boundswrite@*/
+ memset ((void *)&t, '\0', sizeof (t)); /* In initial state. */
+/*@=boundswrite@*/
+ /* Determine number of characters. */
+ n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
+ len += sizeof("=")-1 + n;
+ }
+#else
if (s)
len += sizeof("=")-1 + strlen(s);
+#endif
+
if (opt->argInfo & POPT_ARGFLAG_OPTIONAL) len += sizeof("[]")-1;
if (len > max) max = len;
}
@@ -387,11 +471,12 @@ static int maxArgWidth(const struct poptOption * opt,
* @param fp output file handle
* @param items alias/exec array
* @param nitems no. of alias/exec entries
+ * @param left largest argument display width
* @param translation_domain translation domain
*/
static void itemHelp(FILE * fp,
- /*@null@*/ poptItem items, int nitems, int left,
- /*@null@*/ const char * translation_domain)
+ /*@null@*/ poptItem items, int nitems, size_t left,
+ /*@null@*/ UNUSED(const char * translation_domain))
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
@@ -409,13 +494,16 @@ static void itemHelp(FILE * fp,
}
/**
+ * Display help text for a table of options.
+ * @param con context
* @param fp output file handle
* @param table option(s)
+ * @param left largest argument display width
* @param translation_domain translation domain
*/
static void singleTableHelp(poptContext con, FILE * fp,
- /*@null@*/ const struct poptOption * table, int left,
- /*@null@*/ const char * translation_domain)
+ /*@null@*/ const struct poptOption * table, size_t left,
+ /*@null@*/ UNUSED(const char * translation_domain))
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
@@ -463,9 +551,11 @@ static int showHelpIntro(poptContext con, FILE * fp)
fprintf(fp, POPT_("Usage:"));
if (!(con->flags & POPT_CONTEXT_KEEP_FIRST)) {
- /*@-nullderef@*/ /* LCL: wazzup? */
+/*@-boundsread@*/
+ /*@-nullderef -type@*/ /* LCL: wazzup? */
fn = con->optionStack->argv[0];
- /*@=nullderef@*/
+ /*@=nullderef =type@*/
+/*@=boundsread@*/
if (fn == NULL) return len;
if (strchr(fn, '/')) fn = strrchr(fn, '/') + 1;
fprintf(fp, " %s", fn);
@@ -477,7 +567,7 @@ static int showHelpIntro(poptContext con, FILE * fp)
void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags))
{
- int leftColWidth;
+ size_t leftColWidth;
(void) showHelpIntro(con, fp);
if (con->otherHelp)
@@ -490,47 +580,76 @@ void poptPrintHelp(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags))
}
/**
+ * Display usage text for an option.
* @param fp output file handle
+ * @param cursor current display position
* @param opt option(s)
* @param translation_domain translation domain
*/
-static int singleOptionUsage(FILE * fp, int cursor,
+static size_t singleOptionUsage(FILE * fp, size_t cursor,
const struct poptOption * opt,
/*@null@*/ const char *translation_domain)
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
- int len = 3;
+ size_t len = 4;
char shortStr[2] = { '\0', '\0' };
const char * item = shortStr;
const char * argDescrip = getArgDescrip(opt, translation_domain);
- if (opt->shortName!= '\0' ) {
- if (!(opt->argInfo & POPT_ARG_MASK))
- return cursor; /* we did these already */
+ if (opt->shortName != '\0' && opt->longName != NULL) {
+ len += 2;
+ if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
+ len += strlen(opt->longName);
+ } else if (opt->shortName != '\0') {
len++;
shortStr[0] = opt->shortName;
shortStr[1] = '\0';
} else if (opt->longName) {
- len += 1 + strlen(opt->longName);
+ len += strlen(opt->longName);
+ if (!(opt->argInfo & POPT_ARGFLAG_ONEDASH)) len++;
item = opt->longName;
}
- if (len == 3) return cursor;
+ if (len == 4) return cursor;
+#ifdef POPT_WCHAR_HACK
+ /* XXX Calculate no. of display characters. */
+ if (argDescrip) {
+ const char * scopy = argDescrip;
+ mbstate_t t;
+ size_t n;
+
+/*@-boundswrite@*/
+ memset ((void *)&t, '\0', sizeof (t)); /* In initial state. */
+/*@=boundswrite@*/
+ /* Determine number of characters. */
+ n = mbsrtowcs (NULL, &scopy, strlen(scopy), &t);
+ len += sizeof("=")-1 + n;
+ }
+#else
if (argDescrip)
- len += strlen(argDescrip) + 1;
+ len += sizeof("=")-1 + strlen(argDescrip);
+#endif
if ((cursor + len) > 79) {
fprintf(fp, "\n ");
cursor = 7;
}
- fprintf(fp, " [-%s%s%s%s]",
- ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
- item,
- (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
- (argDescrip ? argDescrip : ""));
+ if (opt->longName && opt->shortName) {
+ fprintf(fp, " [-%c|-%s%s%s%s]",
+ opt->shortName, ((opt->argInfo & POPT_ARGFLAG_ONEDASH) ? "" : "-"),
+ opt->longName,
+ (argDescrip ? " " : ""),
+ (argDescrip ? argDescrip : ""));
+ } else {
+ fprintf(fp, " [-%s%s%s%s]",
+ ((opt->shortName || (opt->argInfo & POPT_ARGFLAG_ONEDASH)) ? "" : "-"),
+ item,
+ (argDescrip ? (opt->shortName != '\0' ? " " : "=") : ""),
+ (argDescrip ? argDescrip : ""));
+ }
return cursor + len + 1;
}
@@ -538,12 +657,14 @@ static int singleOptionUsage(FILE * fp, int cursor,
/**
* Display popt alias and exec usage.
* @param fp output file handle
+ * @param cursor current display position
* @param item alias/exec array
* @param nitems no. of ara/exec entries
* @param translation_domain translation domain
*/
-static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems,
- /*@null@*/ const char * translation_domain)
+static size_t itemUsage(FILE * fp, size_t cursor,
+ /*@null@*/ poptItem item, int nitems,
+ /*@null@*/ UNUSED(const char * translation_domain))
/*@globals fileSystem @*/
/*@modifies *fp, fileSystem @*/
{
@@ -567,15 +688,30 @@ static int itemUsage(FILE * fp, int cursor, poptItem item, int nitems,
}
/**
+ * Keep track of option tables already processed.
+ */
+typedef struct poptDone_s {
+ int nopts;
+ int maxopts;
+ const void ** opts;
+} * poptDone;
+
+/**
+ * Display usage text for a table of options.
+ * @param con context
* @param fp output file handle
+ * @param cursor current display position
* @param opt option(s)
* @param translation_domain translation domain
+ * @param done tables already processed
+ * @return
*/
-static int singleTableUsage(poptContext con, FILE * fp,
- int cursor, const struct poptOption * opt,
- /*@null@*/ const char * translation_domain)
+static size_t singleTableUsage(poptContext con, FILE * fp, size_t cursor,
+ /*@null@*/ const struct poptOption * opt,
+ /*@null@*/ UNUSED(const char * translation_domain),
+ /*@null@*/ poptDone done)
/*@globals fileSystem @*/
- /*@modifies *fp, fileSystem @*/
+ /*@modifies *fp, done, fileSystem @*/
{
/*@-branchstate@*/ /* FIX: W2DO? */
if (opt != NULL)
@@ -583,9 +719,26 @@ static int singleTableUsage(poptContext con, FILE * fp,
if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INTL_DOMAIN) {
translation_domain = (const char *)opt->arg;
} else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE) {
- if (opt->arg) /* XXX program error */
+ if (done) {
+ int i = 0;
+ for (i = 0; i < done->nopts; i++) {
+/*@-boundsread@*/
+ const void * that = done->opts[i];
+/*@=boundsread@*/
+ if (that == NULL || that != opt->arg)
+ /*@innercontinue@*/ continue;
+ /*@innerbreak@*/ break;
+ }
+ /* Skip if this table has already been processed. */
+ if (opt->arg == NULL || i < done->nopts)
+ continue;
+/*@-boundswrite@*/
+ if (done->nopts < done->maxopts)
+ done->opts[done->nopts++] = (const void *) opt->arg;
+/*@=boundswrite@*/
+ }
cursor = singleTableUsage(con, fp, cursor, opt->arg,
- translation_domain);
+ translation_domain, done);
} else if ((opt->longName || opt->shortName) &&
!(opt->argInfo & POPT_ARGFLAG_DOC_HIDDEN)) {
cursor = singleOptionUsage(fp, cursor, opt, translation_domain);
@@ -598,6 +751,7 @@ static int singleTableUsage(poptContext con, FILE * fp,
/**
* Return concatenated short options for display.
+ * @todo Sub-tables should be recursed.
* @param opt option(s)
* @param fp output file handle
* @retval str concatenation of short options
@@ -607,42 +761,51 @@ static int showShortOptions(const struct poptOption * opt, FILE * fp,
/*@null@*/ char * str)
/*@globals fileSystem @*/
/*@modifies *str, *fp, fileSystem @*/
+ /*@requires maxRead(str) >= 0 @*/
{
- char * s = alloca(300); /* larger then the ascii set */
-
- s[0] = '\0';
- /*@-branchstate@*/ /* FIX: W2DO? */
- if (str == NULL) {
- memset(s, 0, sizeof(s));
- str = s;
- }
- /*@=branchstate@*/
+ /* bufsize larger then the ascii set, lazy alloca on top level call. */
+ char * s = (str != NULL ? str : memset(alloca(300), 0, 300));
+ int len = 0;
+/*@-boundswrite@*/
if (opt != NULL)
for (; (opt->longName || opt->shortName || opt->arg); opt++) {
if (opt->shortName && !(opt->argInfo & POPT_ARG_MASK))
- str[strlen(str)] = opt->shortName;
+ s[strlen(s)] = opt->shortName;
else if ((opt->argInfo & POPT_ARG_MASK) == POPT_ARG_INCLUDE_TABLE)
if (opt->arg) /* XXX program error */
- (void) showShortOptions(opt->arg, fp, str);
+ len = showShortOptions(opt->arg, fp, s);
}
+/*@=boundswrite@*/
- if (s != str || *s != '\0')
- return 0;
-
- fprintf(fp, " [-%s]", s);
- return strlen(s) + 4;
+ /* On return to top level, print the short options, return print length. */
+ if (s == str && *s != '\0') {
+ fprintf(fp, " [-%s]", s);
+ len = strlen(s) + sizeof(" [-]")-1;
+ }
+ return len;
}
void poptPrintUsage(poptContext con, FILE * fp, /*@unused@*/ UNUSED(int flags))
{
- int cursor;
+ poptDone done = memset(alloca(sizeof(*done)), 0, sizeof(*done));
+ size_t cursor;
+
+ done->nopts = 0;
+ done->maxopts = 64;
+ cursor = done->maxopts * sizeof(*done->opts);
+/*@-boundswrite@*/
+ done->opts = memset(alloca(cursor), 0, cursor);
+ /*@-keeptrans@*/
+ done->opts[done->nopts++] = (const void *) con->options;
+ /*@=keeptrans@*/
+/*@=boundswrite@*/
cursor = showHelpIntro(con, fp);
cursor += showShortOptions(con->options, fp, NULL);
- (void) singleTableUsage(con, fp, cursor, con->options, NULL);
- (void) itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
- (void) itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
+ cursor = singleTableUsage(con, fp, cursor, con->options, NULL, done);
+ cursor = itemUsage(fp, cursor, con->aliases, con->numAliases, NULL);
+ cursor = itemUsage(fp, cursor, con->execs, con->numExecs, NULL);
if (con->otherHelp) {
cursor += strlen(con->otherHelp) + 1;
@@ -658,4 +821,3 @@ void poptSetOtherOptionHelp(poptContext con, const char * text)
con->otherHelp = _free(con->otherHelp);
con->otherHelp = xstrdup(text);
}
-/*@=type@*/
diff --git a/popt/poptint.h b/popt/poptint.h
index 30172fea..5e75712c 100644
--- a/popt/poptint.h
+++ b/popt/poptint.h
@@ -23,13 +23,17 @@ _free(/*@only@*/ /*@null@*/ const void * p)
}
/* Bit mask macros. */
+/*@-exporttype -redef @*/
typedef unsigned int __pbm_bits;
+/*@=exporttype =redef @*/
#define __PBM_NBITS (8 * sizeof (__pbm_bits))
#define __PBM_IX(d) ((d) / __PBM_NBITS)
#define __PBM_MASK(d) ((__pbm_bits) 1 << (((unsigned)(d)) % __PBM_NBITS))
+/*@-exporttype -redef @*/
typedef struct {
__pbm_bits bits[1];
} pbm_set;
+/*@=exporttype =redef @*/
#define __PBM_BITS(set) ((set)->bits)
#define PBM_ALLOC(d) calloc(__PBM_IX (d) + 1, sizeof(__pbm_bits))
@@ -40,37 +44,53 @@ typedef struct {
struct optionStackEntry {
int argc;
-/*@only@*/ /*@null@*/ const char ** argv;
-/*@only@*/ /*@null@*/ pbm_set * argb;
+/*@only@*/ /*@null@*/
+ const char ** argv;
+/*@only@*/ /*@null@*/
+ pbm_set * argb;
int next;
-/*@only@*/ /*@null@*/ const char * nextArg;
-/*@keep@*/ /*@null@*/ const char * nextCharArg;
-/*@dependent@*/ /*@null@*/ poptItem currAlias;
+/*@only@*/ /*@null@*/
+ const char * nextArg;
+/*@observer@*/ /*@null@*/
+ const char * nextCharArg;
+/*@dependent@*/ /*@null@*/
+ poptItem currAlias;
int stuffed;
};
struct poptContext_s {
struct optionStackEntry optionStack[POPT_OPTION_DEPTH];
-/*@dependent@*/ struct optionStackEntry * os;
-/*@owned@*/ /*@null@*/ const char ** leftovers;
+/*@dependent@*/
+ struct optionStackEntry * os;
+/*@owned@*/ /*@null@*/
+ const char ** leftovers;
int numLeftovers;
int nextLeftover;
-/*@keep@*/ const struct poptOption * options;
+/*@keep@*/
+ const struct poptOption * options;
int restLeftover;
-/*@only@*/ /*@null@*/ const char * appName;
-/*@only@*/ /*@null@*/ poptItem aliases;
+/*@only@*/ /*@null@*/
+ const char * appName;
+/*@only@*/ /*@null@*/
+ poptItem aliases;
int numAliases;
int flags;
-/*@owned@*/ /*@null@*/ poptItem execs;
+/*@owned@*/ /*@null@*/
+ poptItem execs;
int numExecs;
-/*@only@*/ /*@null@*/ const char ** finalArgv;
+/*@only@*/ /*@null@*/
+ const char ** finalArgv;
int finalArgvCount;
int finalArgvAlloced;
-/*@dependent@*/ /*@null@*/ poptItem doExec;
-/*@only@*/ const char * execPath;
+/*@dependent@*/ /*@null@*/
+ poptItem doExec;
+/*@only@*/
+ const char * execPath;
int execAbsolute;
-/*@only@*/ const char * otherHelp;
-/*@null@*/ pbm_set * arg_strip;
+/*@only@*/ /*@relnull@*/
+ const char * otherHelp;
+/*@null@*/
+ pbm_set * arg_strip;
};
#ifdef HAVE_LIBINTL_H
@@ -83,7 +103,7 @@ struct poptContext_s {
#define _(foo) foo
#endif
-#if defined(HAVE_DGETTEXT) && !defined(__LCLINT__)
+#if defined(HAVE_DCGETTEXT) && !defined(__LCLINT__)
#define D_(dom, str) dgettext(dom, str)
#define POPT_(foo) D_("popt", foo)
#else
diff --git a/popt/poptparse.c b/popt/poptparse.c
index ff770175..ccc2ac82 100644
--- a/popt/poptparse.c
+++ b/popt/poptparse.c
@@ -2,7 +2,7 @@
* \file popt/poptparse.c
*/
-/* (C) 1998-2000 Red Hat, Inc. -- Licensing details are in the COPYING
+/* (C) 1998-2002 Red Hat, Inc. -- Licensing details are in the COPYING
file accompanying popt source distributions, available from
ftp://ftp.rpm.org/pub/rpm/dist. */
@@ -10,6 +10,7 @@
#define POPT_ARGV_ARRAY_GROW_DELTA 5
+/*@-boundswrite@*/
int poptDupArgv(int argc, const char **argv,
int * argcPtr, const char *** argvPtr)
{
@@ -35,7 +36,7 @@ int poptDupArgv(int argc, const char **argv,
/*@-branchstate@*/
for (i = 0; i < argc; i++) {
argv2[i] = dst;
- dst += strlen(strcpy(dst, argv[i])) + 1;
+ dst += strlcpy(dst, argv[i], nb) + 1;
}
/*@=branchstate@*/
argv2[argc] = NULL;
@@ -50,11 +51,13 @@ int poptDupArgv(int argc, const char **argv,
*argcPtr = argc;
return 0;
}
+/*@=boundswrite@*/
-int poptParseArgvString(const unsigned char * s, int * argcPtr, const char *** argvPtr)
+/*@-bounds@*/
+int poptParseArgvString(const char * s, int * argcPtr, const char *** argvPtr)
{
- const unsigned char * src;
- unsigned char quote = '\0';
+ const char * src;
+ char quote = '\0';
int argvAlloced = POPT_ARGV_ARRAY_GROW_DELTA;
const char ** argv = malloc(sizeof(*argv) * argvAlloced);
int argc = 0;
@@ -116,3 +119,109 @@ exit:
if (argv) free(argv);
return rc;
}
+/*@=bounds@*/
+
+/* still in the dev stage.
+ * return values, perhaps 1== file erro
+ * 2== line to long
+ * 3== umm.... more?
+ */
+int poptConfigFileToString(FILE *fp, char ** argstrp, /*@unused@*/ UNUSED(int flags))
+{
+ char line[999];
+ char * argstr;
+ char * p;
+ char * q;
+ char * x;
+ int t;
+ int argvlen = 0;
+ size_t maxlinelen = sizeof(line);
+ size_t linelen;
+ int maxargvlen = 480;
+ int linenum = 0;
+
+ *argstrp = NULL;
+
+ /* | this_is = our_line
+ * p q x
+ */
+
+ if (fp == NULL)
+ return POPT_ERROR_NULLARG;
+
+ argstr = calloc(maxargvlen, sizeof(*argstr));
+ if (argstr == NULL) return POPT_ERROR_MALLOC;
+
+ while (fgets(line, (int)maxlinelen, fp) != NULL) {
+ linenum++;
+ p = line;
+
+ /* loop until first non-space char or EOL */
+ while( *p != '\0' && isspace(*p) )
+ p++;
+
+ linelen = strlen(p);
+ if (linelen >= maxlinelen-1)
+ return POPT_ERROR_OVERFLOW; /* XXX line too long */
+
+ if (*p == '\0' || *p == '\n') continue; /* line is empty */
+ if (*p == '#') continue; /* comment line */
+
+ q = p;
+
+ while (*q != '\0' && (!isspace(*q)) && *q != '=')
+ q++;
+
+ if (isspace(*q)) {
+ /* a space after the name, find next non space */
+ *q++='\0';
+ while( *q != '\0' && isspace((int)*q) ) q++;
+ }
+ if (*q == '\0') {
+ /* single command line option (ie, no name=val, just name) */
+ q[-1] = '\0'; /* kill off newline from fgets() call */
+ argvlen += (t = q - p) + (sizeof(" --")-1);
+ if (argvlen >= maxargvlen) {
+ maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
+ argstr = realloc(argstr, maxargvlen);
+ if (argstr == NULL) return POPT_ERROR_MALLOC;
+ }
+ strcat(argstr, " --");
+ strcat(argstr, p);
+ continue;
+ }
+ if (*q != '=')
+ continue; /* XXX for now, silently ignore bogus line */
+
+ /* *q is an equal sign. */
+ *q++ = '\0';
+
+ /* find next non-space letter of value */
+ while (*q != '\0' && isspace(*q))
+ q++;
+ if (*q == '\0')
+ continue; /* XXX silently ignore missing value */
+
+ /* now, loop and strip all ending whitespace */
+ x = p + linelen;
+ while (isspace(*--x))
+ *x = 0; /* null out last char if space (including fgets() NL) */
+
+ /* rest of line accept */
+ t = x - p;
+ argvlen += t + (sizeof("' --='")-1);
+ if (argvlen >= maxargvlen) {
+ maxargvlen = (t > maxargvlen) ? t*2 : maxargvlen*2;
+ argstr = realloc(argstr, maxargvlen);
+ if (argstr == NULL) return POPT_ERROR_MALLOC;
+ }
+ strcat(argstr, " --");
+ strcat(argstr, p);
+ strcat(argstr, "=\"");
+ strcat(argstr, q);
+ strcat(argstr, "\"");
+ }
+
+ *argstrp = argstr;
+ return 0;
+}
diff --git a/popt/system.h b/popt/system.h
index 02f05c18..db63dd4b 100644
--- a/popt/system.h
+++ b/popt/system.h
@@ -2,7 +2,17 @@
#include "config.h"
#endif
+#if defined (__GLIBC__) && defined(__LCLINT__)
+/*@-declundef@*/
+/*@unchecked@*/
+extern __const __int32_t *__ctype_tolower;
+/*@unchecked@*/
+extern __const __int32_t *__ctype_toupper;
+/*@=declundef@*/
+#endif
+
#include <ctype.h>
+
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
@@ -19,12 +29,8 @@
#include <unistd.h>
#endif
-#if !defined(__GNUC__) || defined(APPLE)
-/* Apparently the OS X port of gcc gags on __attribute__.
- *
- * <http://www.opensource.apple.com/bugs/X/gcc/2512150.html> */
+#ifndef __GNUC__
#define __attribute__(x)
-
#endif
#ifdef __NeXT
@@ -34,11 +40,12 @@
#endif
#if defined(__LCLINT__)
-/*@-declundef -incondefs -redecl@*/ /* LCL: missing annotation */
-/*@only@*/ void * alloca (size_t __size)
+/*@-declundef -incondefs @*/ /* LCL: missing annotation */
+/*@only@*/ /*@out@*/
+void * alloca (size_t __size)
/*@ensures MaxSet(result) == (__size - 1) @*/
/*@*/;
-/*@=declundef =incondefs =redecl@*/
+/*@=declundef =incondefs @*/
#endif
/* AIX requires this to be the first thing in the file. */
@@ -49,7 +56,7 @@
# ifdef _AIX
#pragma alloca
# else
-# if HAVE_ALLOCA
+# ifdef HAVE_ALLOCA
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
@@ -66,7 +73,8 @@ char *alloca ();
#endif
/*@-redecl -redef@*/
-/*@mayexit@*/ /*@only@*/ char * xstrdup (const char *str)
+/*@mayexit@*/ /*@only@*/ /*@unused@*/
+char * xstrdup (const char *str)
/*@*/;
/*@=redecl =redef@*/
@@ -77,6 +85,28 @@ char *alloca ();
#define xstrdup(_str) strdup(_str)
#endif /* HAVE_MCHECK_H && defined(__GNUC__) */
+#if HAVE___SECURE_GETENV && !defined(__LCLINT__)
+#define getenv(_s) __secure_getenv(_s)
+#endif
+
+#ifndef HAVE_STRLCPY
+size_t strlcpy(char *d, const char *s, size_t bufsize);
+#endif
+
+#ifndef HAVE_STRLCAT
+size_t strlcat(char *d, const char *s, size_t bufsize);
+#endif
+
#define UNUSED(x) x __attribute__((__unused__))
+#define PACKAGE "rsync"
+
+#ifndef DBL_EPSILON
+#define DBL_EPSILON 2.2204460492503131e-16
+#endif
+
+#ifdef _ABS
+#undef _ABS
+#endif
+
#include "popt.h"