Commit bc93ee84 authored by Wayne Davison's avatar Wayne Davison

- Upgraded popt to version 1.10.2.

- Modified all sprintf() and strcpy() calls to use snprintf()
  and strlcpy().
parent 0c6d7952
......@@ -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;
......
......@@ -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@*/
......@@ -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
}
......
......@@ -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;
}
......
/* -*- 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),
......@@ -49,6 +60,17 @@ struct poptOption poptAliasOptions[] = {
/*@-castfcnptr@*/
/*@observer@*/ /*@unchecked@*/
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 },
......@@ -58,6 +80,9 @@ struct poptOption poptHelpOptions[] = {
#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@*/
......@@ -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
......
......@@ -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;
}
......@@ -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"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment