summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.splintrc6
-rw-r--r--CHANGES6
-rwxr-xr-xconfigure.ac43
-rw-r--r--findme.c3
-rw-r--r--popt.c107
-rw-r--r--popt.h3
-rw-r--r--poptconfig.c53
-rw-r--r--poptint.c81
-rw-r--r--poptint.h3
-rw-r--r--poptparse.c4
-rw-r--r--system.h15
11 files changed, 153 insertions, 171 deletions
diff --git a/.splintrc b/.splintrc
index 9dd8a71..431c99a 100644
--- a/.splintrc
+++ b/.splintrc
@@ -14,7 +14,6 @@
# --- in progress
#+bounds
-bufferoverflowhigh
-
-branchstate
# --- +partial artifacts
@@ -35,8 +34,7 @@
# --- not-yet at checks level
-mustfree # 38
-predboolptr # 82
--usedef # 7
# --- not-yet at standard level
--boolops # 127
--predboolint # 42
+-boolops # 124
+-predboolint # 53
diff --git a/CHANGES b/CHANGES
index 0a34193..c826bba 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,10 @@
1.13 -> 1.14:
+ - jbj: study the mess with splint, remove annotations where possible.
+ - jbj: add -D_GNU_SOURCE for gcc to use __builtin_stpcpy when available.
+ - jbj: add static inline stpcpy for the deprived.
+ - jbj: use stpcpy to eliminate sprintf calls everywhere but popthelp.c
+ - jbj: remove (now unneeded afaik) va_copy() from POPT_fprintf().
+ - jbj: inline strdup_fprintf() => POPT_fprintf keeping (unneeded?) va_copy.
- rse: fix memcpy(3) based va_copy(3) fallbacks
- jbj: fix: short option with "foo=bar" argument was mishandled.
(Wayne Davison<wayned@samba.org>).
diff --git a/configure.ac b/configure.ac
index 5bfda5b..71bcea5 100755
--- a/configure.ac
+++ b/configure.ac
@@ -20,34 +20,13 @@ AC_PROG_CC
AC_PROG_INSTALL
AC_PROG_LIBTOOL
-if test "X$CC" = Xgcc; then
- CFLAGS="-Wall -W $CFLAGS"
-fi
-
-AC_GCC_TRADITIONAL
-AC_SYS_LARGEFILE
-
-AC_ISC_POSIX
-AM_C_PROTOTYPES
-AC_CHECK_VA_COPY
-
-dnl XXX lose rpm libs
-LIBS=
-addlib() {
- l=$1
- shift
- case "$target" in
- *-*-solaris*) LIBS="$LIBS -L$l -R $l $*";;
- *) LIBS="$LIBS -L$l $*";;
- esac
-}
-
dnl
dnl if CC is gcc, we can rebuild the dependencies (since the depend rule
dnl requires gcc). If it's not, don't rebuild dependencies -- use what was
dnl shipped with RPM.
dnl
if test X"$GCC" = "Xyes" ; then
+ CFLAGS="-Wall -W -D_GNU_SOURCE -D_REENTRANT $CFLAGS"
TARGET="depend allprogs"
else
TARGET="everything"
@@ -59,7 +38,14 @@ else
fi
AC_SUBST(TARGET)
-AC_CHECK_HEADERS(float.h glob.h libintl.h mcheck.h unistd.h langinfo.h)
+AC_GCC_TRADITIONAL
+AC_SYS_LARGEFILE
+
+AC_ISC_POSIX
+AM_C_PROTOTYPES
+AC_CHECK_VA_COPY
+
+AC_CHECK_HEADERS(float.h glob.h langinfo.h libintl.h mcheck.h unistd.h)
# For some systems we know that we have ld_version scripts.
# Use it then as default.
@@ -80,19 +66,10 @@ AC_ARG_ENABLE([ld-version-script],
[ : ] )
AM_CONDITIONAL(HAVE_LD_VERSION_SCRIPT, test "$have_ld_version_script" = "yes")
-if test ! -f ../rpm.c
-then
- AC_MSG_CHECKING(for GNU xgettext)
- xgettext --version 2>&1 | grep 'GNU gettext' >/dev/null 2>&1 || AC_MSG_ERROR([
- *** GNU gettext is required. The latest version
- *** is always available from ftp://ftp.gnu.org/gnu/gettext/.])
- AC_MSG_RESULT(yes)
-fi
-
AC_CHECK_FUNC(setreuid, [], [
AC_CHECK_LIB(ucb, setreuid, [if echo $LIBS | grep -- -lucb >/dev/null ;then :; else LIBS="$LIBS -lc -lucb" USEUCB=y;fi])
])
-AC_CHECK_FUNCS(getuid geteuid mtrace __secure_getenv setregid strerror iconv)
+AC_CHECK_FUNCS(getuid geteuid iconv mtrace __secure_getenv setregid stpcpy strerror)
AM_GNU_GETTEXT([external])
diff --git a/findme.c b/findme.c
index e60d77a..82c5ce6 100644
--- a/findme.c
+++ b/findme.c
@@ -33,8 +33,7 @@ const char * POPT_findProgramPath(const char * argv0)
do {
if ((chptr = strchr(start, ':')))
*chptr = '\0';
- sprintf(buf, "%s/%s", start, argv0);
-
+ (void) stpcpy(stpcpy(stpcpy(buf, start), "/"), argv0);
if (!access(buf, X_OK)) {
free(pathbuf);
return buf;
diff --git a/popt.c b/popt.c
index 5c28a8d..2727e74 100644
--- a/popt.c
+++ b/popt.c
@@ -10,6 +10,14 @@
#include "system.h"
+#if defined(__LCLINT__)
+/*@-declundef -exportheader @*/
+extern long long int strtoll(const char *nptr, /*@null@*/ char **endptr,
+ int base)
+ /*@modifies *endptr@*/;
+/*@=declundef =exportheader @*/
+#endif
+
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
@@ -56,9 +64,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 not NULL */
return;
-/*@=nullstate@*/
}
static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)
@@ -77,9 +83,9 @@ static void invokeCallbacksPRE(poptContext con, const struct poptOption * opt)
case POPT_ARG_CALLBACK: /* Perform callback. */
if (!CBF_ISSET(opt, PRE))
/*@switchbreak@*/ break;
- /*@-noeffectuncon @*/
+/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
arg.cb(con, POPT_CALLBACK_REASON_PRE, NULL, NULL, opt->descrip);
- /*@=noeffectuncon @*/
+/*@=noeffectuncon @*/
/*@switchbreak@*/ break;
}
}
@@ -101,9 +107,9 @@ static void invokeCallbacksPOST(poptContext con, const struct poptOption * opt)
case POPT_ARG_CALLBACK: /* Perform callback. */
if (!CBF_ISSET(opt, POST))
/*@switchbreak@*/ break;
- /*@-noeffectuncon @*/
+/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
arg.cb(con, POPT_CALLBACK_REASON_POST, NULL, NULL, opt->descrip);
- /*@=noeffectuncon @*/
+/*@=noeffectuncon @*/
/*@switchbreak@*/ break;
}
}
@@ -142,10 +148,10 @@ static void invokeCallbacksOPTION(poptContext con,
|| (myOpt->longName != NULL && opt->longName != NULL &&
!strcmp(myOpt->longName, opt->longName)))
{ const void *cbData = (cbopt->descrip ? cbopt->descrip : myData);
- /*@-noeffectuncon @*/
+/*@-noeffectuncon @*/ /* XXX no known way to annotate (*vector) calls. */
cbarg.cb(con, POPT_CALLBACK_REASON_OPTION,
myOpt, con->os->nextArg, cbData);
- /*@=noeffectuncon @*/
+/*@=noeffectuncon @*/
/* Terminate (unless explcitly continuing). */
if (!CBF_ISSET(cbopt, CONTINUE))
return;
@@ -195,9 +201,7 @@ poptContext poptGetContext(const char * name, int argc, const char ** argv,
if (t) con->appName = strcpy(t, name);
}
-/*@-internalglobs@*/
invokeCallbacksPRE(con, con->options);
-/*@=internalglobs@*/
return con;
}
@@ -288,13 +292,15 @@ 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);
+ { char *s = malloc((longName ? strlen(longName) : 0) + sizeof("--"));
if (s != NULL) { /* XXX can't happen */
+ con->finalArgv[i] = s;
+ *s++ = '-';
if (longName)
- sprintf(s, "--%s", longName);
+ s = stpcpy( stpcpy(s, "-"), longName);
else
- sprintf(s, "-%c", shortName);
- con->finalArgv[i] = s;
+ *s++ = shortName;
+ *s = '\0';
} else
con->finalArgv[i] = NULL;
}
@@ -403,7 +409,8 @@ static int execCommand(poptContext con)
if (!strchr(item->argv[0], '/') && con->execPath != NULL) {
char *s = malloc(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/"));
if (s)
- sprintf(s, "%s/%s", con->execPath, item->argv[0]);
+ (void)stpcpy(stpcpy(stpcpy(s, con->execPath), "/"), item->argv[0]);
+
argv[argc] = s;
} else
argv[argc] = POPT_findProgramPath(item->argv[0]);
@@ -629,51 +636,44 @@ expandNextArg(/*@special@*/ poptContext con, const char * s)
}
static void poptStripArg(/*@special@*/ poptContext con, int which)
- /*@uses con->arg_strip, con->optionStack @*/
+ /*@uses con->optionStack @*/
/*@defines con->arg_strip @*/
/*@modifies con @*/
{
-/*@-sizeoftype@*/
+/*@-compdef -sizeoftype -usedef @*/
if (con->arg_strip == NULL)
con->arg_strip = PBM_ALLOC(con->optionStack[0].argc);
if (con->arg_strip != NULL) /* XXX can't happen */
PBM_SET(which, con->arg_strip);
-/*@=sizeoftype@*/
-/*@-compdef@*/ /* LCL: con->arg_strip undefined? */
return;
-/*@=compdef@*/
+/*@=compdef =sizeoftype =usedef @*/
}
int poptSaveString(const char *** argvp,
/*@unused@*/ UNUSED(unsigned int argInfo), const char * val)
{
- poptArgv argv;
int argc = 0;
if (argvp == NULL)
return -1;
/* XXX likely needs an upper bound on argc. */
- if (*argvp)
+ if (*argvp != NULL)
while ((*argvp)[argc] != NULL)
argc++;
-/*@-unqualifiedtrans@*/
- *argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp));
-/*@=unqualifiedtrans@*/
- if ((argv = *argvp) != NULL) {
- argv[argc++] = xstrdup(val);
- argv[argc ] = NULL;
+/*@-unqualifiedtrans -nullstate@*/ /* XXX no annotation for (*argvp) */
+ if ((*argvp = xrealloc(*argvp, (argc + 1 + 1) * sizeof(**argvp))) != NULL) {
+ (*argvp)[argc++] = xstrdup(val);
+ (*argvp)[argc ] = NULL;
}
-/*@-nullstate@*/
return 0;
-/*@=nullstate@*/
+/*@=unqualifiedtrans =nullstate@*/
}
/*@unchecked@*/
static unsigned int seed = 0;
-/*@-bitwisesigned@*/ /* LCL: logical ops with unsigned. */
int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong)
{
if (arg == NULL
@@ -699,13 +699,13 @@ int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong)
*arg = aLongLong;
break;
case POPT_ARGFLAG_OR:
- *arg |= aLongLong;
+ *(unsigned long long *)arg |= (unsigned long long)aLongLong;
break;
case POPT_ARGFLAG_AND:
- *arg &= aLongLong;
+ *(unsigned long long *)arg &= (unsigned long long)aLongLong;
break;
case POPT_ARGFLAG_XOR:
- *arg ^= aLongLong;
+ *(unsigned long long *)arg ^= (unsigned long long)aLongLong;
break;
default:
return POPT_ERROR_BADOPERATION;
@@ -713,9 +713,7 @@ int poptSaveLongLong(long long * arg, unsigned int argInfo, long long aLongLong)
}
return 0;
}
-/*@=bitwisesigned@*/
-/*@-bitwisesigned@*/ /* LCL: logical ops with unsigned. */
int poptSaveLong(long * arg, unsigned int argInfo, long aLong)
{
/* XXX Check alignment, may fail on funky platforms. */
@@ -737,13 +735,13 @@ int poptSaveLong(long * arg, unsigned int argInfo, long aLong)
*arg = aLong;
break;
case POPT_ARGFLAG_OR:
- *arg |= aLong;
+ *(unsigned long *)arg |= (unsigned long)aLong;
break;
case POPT_ARGFLAG_AND:
- *arg &= aLong;
+ *(unsigned long *)arg &= (unsigned long)aLong;
break;
case POPT_ARGFLAG_XOR:
- *arg ^= aLong;
+ *(unsigned long *)arg ^= (unsigned long)aLong;
break;
default:
return POPT_ERROR_BADOPERATION;
@@ -751,9 +749,7 @@ int poptSaveLong(long * arg, unsigned int argInfo, long aLong)
}
return 0;
}
-/*@=bitwisesigned@*/
-/*@-bitwisesigned@*/ /* LCL: logical ops with unsigned. */
int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong)
{
/* XXX Check alignment, may fail on funky platforms. */
@@ -775,13 +771,13 @@ int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong)
*arg = (int) aLong;
break;
case POPT_ARGFLAG_OR:
- *arg |= (int) aLong;
+ *(unsigned int *)arg |= (unsigned int) aLong;
break;
case POPT_ARGFLAG_AND:
- *arg &= (int) aLong;
+ *(unsigned int *)arg &= (unsigned int) aLong;
break;
case POPT_ARGFLAG_XOR:
- *arg ^= (int) aLong;
+ *(unsigned int *)arg ^= (unsigned int) aLong;
break;
default:
return POPT_ERROR_BADOPERATION;
@@ -789,7 +785,6 @@ int poptSaveInt(/*@null@*/ int * arg, unsigned int argInfo, long aLong)
}
return 0;
}
-/*@=bitwisesigned@*/
/* returns 'val' element, -1 on last item, POPT_ERROR_* on error */
int poptGetNextOpt(poptContext con)
@@ -1018,12 +1013,10 @@ int poptGetNextOpt(poptContext con)
case POPT_ARG_LONG:
case POPT_ARG_LONGLONG:
{ long long aNUM = 0;
- char *end;
+ char *end = NULL;
if (con->os->nextArg) {
-/*@-unrecog@*/
aNUM = strtoll(con->os->nextArg, &end, 0);
-/*@=unrecog@*/
if (!(end && *end == '\0'))
return POPT_ERROR_BADNUMBER;
}
@@ -1076,7 +1069,7 @@ int poptGetNextOpt(poptContext con)
if (poptArgType(opt) == POPT_ARG_DOUBLE) {
arg.doublep[0] = aDouble;
} else {
-#ifndef DBL_EPSILON
+#if !defined(DBL_EPSILON) && !defined(__LCLINT__)
#define DBL_EPSILON 2.2204460492503131e-16
#endif
#define POPT_ABS(a) ((((a) - 0.0) < DBL_EPSILON) ? -(a) : (a))
@@ -1114,14 +1107,18 @@ int poptGetNextOpt(poptContext con)
}
if (con->finalArgv != NULL)
- { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + 3);
+ { char *s = malloc((opt->longName ? strlen(opt->longName) : 0) + sizeof("--"));
if (s != NULL) { /* XXX can't happen */
- if (opt->longName)
- sprintf(s, "%s%s", (F_ISSET(opt, ONEDASH) ? "-" : "--"),
- opt->longName);
- else
- sprintf(s, "-%c", opt->shortName);
con->finalArgv[con->finalArgvCount++] = s;
+ *s++ = '-';
+ if (opt->longName) {
+ if (!F_ISSET(opt, ONEDASH))
+ *s++ = '-';
+ s = stpcpy(s, opt->longName);
+ } else {
+ *s++ = opt->shortName;
+ *s = '\0';
+ }
} else
con->finalArgv[con->finalArgvCount++] = NULL;
}
diff --git a/popt.h b/popt.h
index 637ef43..ba802bf 100644
--- a/popt.h
+++ b/popt.h
@@ -248,7 +248,8 @@ poptContext poptGetContext(
int argc, /*@dependent@*/ /*@keep@*/ const char ** argv,
/*@dependent@*/ /*@keep@*/ const struct poptOption * options,
unsigned int flags)
- /*@*/;
+ /*@globals internalState @*/
+ /*@modifies internalState @*/;
/** \ingroup popt
* Reinitialize popt context.
diff --git a/poptconfig.c b/poptconfig.c
index aef4082..bf8fef3 100644
--- a/poptconfig.c
+++ b/poptconfig.c
@@ -9,8 +9,22 @@
#include "system.h"
#include "poptint.h"
#include <sys/stat.h>
+
#if defined(HAVE_GLOB_H)
#include <glob.h>
+
+#if defined(__LCLINT__)
+/*@-declundef -exportheader -incondefs -protoparammatch -redecl -type @*/
+extern int glob (const char *__pattern, int __flags,
+ /*@null@*/ int (*__errfunc) (const char *, int),
+ /*@out@*/ glob_t *__pglob)
+ /*@globals errno, fileSystem @*/
+ /*@modifies *__pglob, errno, fileSystem @*/;
+ /* XXX only annotation is a white lie */
+extern void globfree (/*@only@*/ glob_t *__pglob)
+ /*@modifies *__pglob @*/;
+/*@=declundef =exportheader =incondefs =protoparammatch =redecl =type @*/
+#endif
#endif
/*@access poptContext @*/
@@ -117,7 +131,8 @@ int poptReadConfigFile(poptContext con, const char * fn)
return POPT_ERROR_ERRNO;
}
- file = malloc((size_t)fileLength + 1);
+ if ((file = malloc((size_t)fileLength + 1)) != NULL)
+ *file = '\0';
if (file == NULL
|| read(fd, (char *)file, (size_t)fileLength) != (ssize_t)fileLength)
{
@@ -137,10 +152,8 @@ int poptReadConfigFile(poptContext con, const char * fn)
if (dst == NULL)
return POPT_ERROR_ERRNO;
- chptr = file;
end = (file + fileLength);
-/*@-infloops@*/ /* LCL: can't detect chptr++ */
- while (chptr < end) {
+ for (chptr = file; chptr < end; chptr++) {
switch (*chptr) {
case '\n':
*dst = '\0';
@@ -148,24 +161,20 @@ int poptReadConfigFile(poptContext con, const char * fn)
while (*dst && _isspaceptr(dst)) dst++;
if (*dst && *dst != '#')
configLine(con, dst);
- chptr++;
/*@switchbreak@*/ break;
case '\\':
- *dst++ = *chptr++;
- if (chptr < end) {
- if (*chptr == '\n')
- dst--, chptr++;
- /* \ at the end of a line does not insert a \n */
- else
- *dst++ = *chptr++;
+ *dst = *chptr++;
+ /* \ at the end of a line does not insert a \n */
+ if (chptr < end && *chptr != '\n') {
+ dst++;
+ *dst++ = *chptr;
}
/*@switchbreak@*/ break;
default:
- *dst++ = *chptr++;
+ *dst++ = *chptr;
/*@switchbreak@*/ break;
}
}
-/*@=infloops@*/
free(file);
free(buf);
@@ -193,12 +202,11 @@ int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv))
#if defined(HAVE_GLOB_H)
if (!stat("/etc/popt.d", &s) && S_ISDIR(s.st_mode)) {
- glob_t g;
-/*@-moduncon -nullpass -type @*/ /* FIX: annotations for glob/globfree */
- if (!glob("/etc/popt.d/*", 0, NULL, &g)) {
- unsigned i;
- for (i=0; i<g.gl_pathc; i++) {
- char *f=g.gl_pathv[i];
+ glob_t _g, *pglob = &_g;
+ if (!glob("/etc/popt.d/*", 0, NULL, pglob)) {
+ size_t i;
+ for (i = 0; i < pglob->gl_pathc; i++) {
+ char * f = pglob->gl_pathv[i];
if (strstr(f, ".rpmnew") || strstr(f, ".rpmsave"))
continue;
if (!stat(f, &s)) {
@@ -208,11 +216,8 @@ int poptReadDefaultConfig(poptContext con, /*@unused@*/ UNUSED(int useEnv))
rc = poptReadConfigFile(con, f);
if (rc) return rc;
}
-/*@-noeffectuncon@*/
- globfree(&g);
-/*@=noeffectuncon@*/
+ globfree(pglob);
}
-/*@=moduncon =nullpass =type @*/
}
#endif
diff --git a/poptint.c b/poptint.c
index 04e0d7d..de2ebbc 100644
--- a/poptint.c
+++ b/poptint.c
@@ -55,7 +55,7 @@ strdup_locale_from_utf8 (/*@null@*/ char *buffer)
/*@=type@*/
#endif
- if (codeset && strcmp(codeset, "UTF-8")
+ if (codeset != NULL && strcmp(codeset, "UTF-8") != 0
&& (fd = iconv_open(codeset, "UTF-8")) != (iconv_t)-1)
{
char *pin = buffer;
@@ -74,7 +74,7 @@ strdup_locale_from_utf8 (/*@null@*/ char *buffer)
*dest_str = '\0';
done = is_error = 0;
if (pout != NULL)
- while (!done && !is_error) {
+ while (done == 0 && is_error == 0) {
err = iconv(fd, &pin, &ib, &pout, &ob);
if (err == (size_t)-1) {
@@ -123,30 +123,6 @@ strdup_locale_from_utf8 (/*@null@*/ char *buffer)
}
#endif
-/*@-mustmod@*/ /* LCL: can't see the ap modification. */
-static /*@only@*/ /*@null@*/ char *
-strdup_vprintf (const char *format, va_list ap)
- /*@modifies ap @*/
-{
- char *buffer;
- char c;
- va_list apc;
- int xx;
-
-/*@-noeffectuncon -unrecog @*/
- va_copy(apc, ap); /* XXX linux amd64/ppc needs a copy. */
-/*@=noeffectuncon =unrecog @*/
-
- buffer = calloc(sizeof(*buffer), (size_t)vsnprintf (&c, (size_t)1, format, ap) + 1);
- if (buffer != NULL)
- xx = vsprintf(buffer, format, apc);
-
- va_end(apc);
-
- return buffer;
-}
-/*@=mustmod@*/
-
const char *
POPT_prev_char (const char *str)
{
@@ -173,32 +149,39 @@ POPT_next_char (const char *str)
}
int
-POPT_fprintf (FILE* stream, const char *format, ...)
+POPT_fprintf (FILE * stream, const char * format, ...)
{
- int retval = 0;
- va_list args;
- char *buffer = NULL;
-#ifdef HAVE_ICONV
- char *locale_str = NULL;
-#endif
-
- va_start (args, format);
- buffer = strdup_vprintf(format, args);
- va_end (args);
- if (buffer == NULL)
- return retval;
+ char * b = NULL, * ob = NULL;
+ size_t nb = (size_t)1;
+ int rc;
+ va_list ap;
+
+ va_start(ap, format);
+ while ((b = realloc(b, nb)) != NULL) {
+ rc = vsnprintf(b, nb, format, ap);
+ if (rc > -1) { /* glibc 2.1 */
+ if ((size_t)rc < nb)
+ break;
+ nb = (size_t)(rc + 1); /* precise buffer length known */
+ } else /* glibc 2.0 */
+ nb += (nb < (size_t)100 ? (size_t)100 : nb);
+ ob = b;
+ }
+ va_end(ap);
+ rc = 0;
+ if (b != NULL) {
#ifdef HAVE_ICONV
- locale_str = strdup_locale_from_utf8(buffer);
- if (locale_str) {
- retval = fprintf(stream, "%s", locale_str);
- free(locale_str);
- } else
+ ob = strdup_locale_from_utf8(b);
+ if (ob != NULL) {
+ rc = fprintf(stream, "%s", ob);
+ free(ob);
+ } else
#endif
- {
- retval = fprintf(stream, "%s", buffer);
- }
- free (buffer);
+ rc = fprintf(stream, "%s", b);
+ free (b);
+ } else if (ob != NULL)
+ free(ob);
- return retval;
+ return rc;
}
diff --git a/poptint.h b/poptint.h
index d8e829c..9c2b73b 100644
--- a/poptint.h
+++ b/poptint.h
@@ -120,10 +120,11 @@ struct poptContext_s {
poptArgv finalArgv;
int finalArgvCount;
int finalArgvAlloced;
+/*@null@*/
int (*maincall) (int argc, const char **argv);
/*@dependent@*/ /*@null@*/
poptItem doExec;
-/*@only@*/
+/*@only@*/ /*@null@*/
const char * execPath;
int execAbsolute;
/*@only@*/ /*@relnull@*/
diff --git a/poptparse.c b/poptparse.c
index f203743..d196cc8 100644
--- a/poptparse.c
+++ b/poptparse.c
@@ -31,10 +31,12 @@ int poptDupArgv(int argc, const char **argv,
return POPT_ERROR_MALLOC;
argv2 = (void *) dst;
dst += (argc + 1) * sizeof(*argv);
+ *dst = '\0';
for (i = 0; i < argc; i++) {
argv2[i] = dst;
- dst += strlen(strcpy(dst, argv[i])) + 1;
+ dst = stpcpy(dst, argv[i]);
+ dst++; /* trailing NUL */
}
argv2[argc] = NULL;
diff --git a/system.h b/system.h
index 9ed5a09..863526b 100644
--- a/system.h
+++ b/system.h
@@ -64,6 +64,19 @@ char * xstrdup (const char *str)
/*@*/;
/*@=incondefs@*/
+#if !defined(HAVE_STPCPY)
+/* Copy SRC to DEST, returning the address of the terminating '\0' in DEST. */
+static inline char * stpcpy (char *dest, const char * src) {
+ register char *d = dest;
+ register const char *s = src;
+
+ do
+ *d++ = *s;
+ while (*s++ != '\0');
+ return d - 1;
+}
+#endif
+
/* Memory allocation via macro defs to get meaningful locations from mtrace() */
#if defined(HAVE_MCHECK_H) && defined(__GNUC__)
#define vmefail() (fprintf(stderr, "virtual memory exhausted.\n"), exit(EXIT_FAILURE), NULL)
@@ -82,7 +95,7 @@ char * xstrdup (const char *str)
#define getenv(_s) __secure_getenv(_s)
#endif
-#ifndef __GNUC__
+#if !defined(__GNUC__) && !defined(__attribute__)
#define __attribute__(x)
#endif
#define UNUSED(x) x __attribute__((__unused__))