diff options
-rw-r--r-- | .splintrc | 6 | ||||
-rw-r--r-- | CHANGES | 6 | ||||
-rwxr-xr-x | configure.ac | 43 | ||||
-rw-r--r-- | findme.c | 3 | ||||
-rw-r--r-- | popt.c | 107 | ||||
-rw-r--r-- | popt.h | 3 | ||||
-rw-r--r-- | poptconfig.c | 53 | ||||
-rw-r--r-- | poptint.c | 81 | ||||
-rw-r--r-- | poptint.h | 3 | ||||
-rw-r--r-- | poptparse.c | 4 | ||||
-rw-r--r-- | system.h | 15 |
11 files changed, 153 insertions, 171 deletions
@@ -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 @@ -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]) @@ -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; @@ -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; } @@ -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 @@ -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; } @@ -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; @@ -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__)) |