
URL: https://svn.lrde.epita.fr/svn/argp/trunk ChangeLog: 2007-02-02 SIGOURE Benoit <tsuna@lrde.epita.fr> Update to argp-1.4. * bootstrap: New. * build-aux: New. * strcasecmp.c: New. * vsnprintf.c: New. * argp-fs-xinl.c: Remove. * argp-xinl.c: Remove. * ChangeLog, * Makefile.am, * argp-ba.c, * argp-eexst.c, * argp-fmtstream.c, * argp-fmtstream.h, * argp-help.c, * argp-namefrob.h, * argp-parse.c, * argp-pv.c, * argp-pvh.c, * argp-test.c, * argp.h, * configure.ac: Update to 1.4. The following changes have been imported: 2004-03-02 Niels Möller <nisse@lysator.liu.se> * Makefile.am (EXTRA_DIST): Added strcasecmp.c. * argp-help.c: Declare strcasecmp. * strcasecmp.c (strcasecmp): New file. * argp-parse.c, argp-help.c: Conditionally include malloc.h. 2004-03-01 Niels Möller <nisse@lysator.liu.se> * argp-fmtstream.h [!HAVE_UNISTD_H]: Define ssize_t as int. * Makefile.am (EXTRA_PROGRAMS): Don't build argp-test, as it's the only program depending on the functions asprintf/vsnprintf. * configure.ac: Check for sleep and getpid. * argp-parse.c: Make inclusion of unistd.h conditional. (OPT_HANG): Recognize this option only if getpid and sleep are available. * argp-fmtstream.h: Make inclusion of unistd.h conditional. It's needed for ssize_t, at least on freebsd. 2004-03-01 Niels Möller <niels@s3.kth.se> * argp-eexst.c [!HAVE_SYSEXITS_H]: Hardcode EX_USAGE = 64. * configure.ac: Check for sysexits.h. trunk/Makefile.am | 3 trunk/argp-ba.c | 6 trunk/argp-eexst.c | 10 trunk/argp-fmtstream.c | 6 trunk/argp-fmtstream.h | 14 trunk/argp-help.c | 16 trunk/argp-namefrob.h | 6 trunk/argp-parse.c | 19 - trunk/argp-pv.c | 6 trunk/argp-pvh.c | 6 trunk/argp-test.c | 6 trunk/argp.h | 6 trunk/bootstrap | 3 trunk/configure.ac | 14 trunk/strcasecmp.c | 28 + trunk/vsnprintf.c | 833 +++++++++++++++++++++++++++++++++++++++++++++++++ 16 files changed, 938 insertions(+), 44 deletions(-) Index: trunk/argp.h =================================================================== --- trunk/argp.h (revision 2) +++ trunk/argp.h (revision 3) @@ -1,5 +1,5 @@ /* Hierarchial argument parsing. - Copyright (C) 1995, 96, 97, 98, 99, 2003, 2005 Free Software Foundation, Inc. + Copyright (C) 96, 97, 98, 99, 1995, 2003, 2005, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifndef _ARGP_H #define _ARGP_H Index: trunk/argp-fmtstream.h =================================================================== --- trunk/argp-fmtstream.h (revision 2) +++ trunk/argp-fmtstream.h (revision 3) @@ -1,5 +1,5 @@ /* Word-wrapping and line-truncating streams. - Copyright (C) 1997, 2003 Free Software Foundation, Inc. + Copyright (C) 1997, 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* This package emulates glibc `line_wrap_stream' semantics for systems that don't have that. If the system does have it, it is just a wrapper for @@ -28,7 +28,15 @@ #include <stdio.h> #include <string.h> + +#if HAVE_UNISTD_H #include <unistd.h> +#else +/* This is a kludge to make the code compile on windows. Perhaps it + would be better to just replace ssize_t with int through out the + code. */ +# define ssize_t int +#endif #if _LIBC || (defined (HAVE_FLOCKFILE) && defined(HAVE_PUTC_UNLOCKED) \ && defined (HAVE_FPUTS_UNLOCKED) && defined (HAVE_FWRITE_UNLOCKED) ) Index: trunk/argp-parse.c =================================================================== --- trunk/argp-parse.c (revision 2) +++ trunk/argp-parse.c (revision 3) @@ -1,5 +1,5 @@ /* Hierarchial argument parsing - Copyright (C) 1995, 96, 97, 98, 99, 2000,2003 Free Software Foundation, Inc. + Copyright (C) 96, 97, 98, 99, 1995, 2000, 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 @@ -43,10 +43,17 @@ #include <stdlib.h> #include <string.h> +#if HAVE_UNISTD_H #include <unistd.h> +#endif #include <limits.h> #include <assert.h> +#if HAVE_MALLOC_H +/* Needed, for alloca on windows */ +# include <malloc.h> +#endif + #ifndef _ /* This is for other GNU distributions with internationalized messages. When compiling libc, the _ macro is predefined. */ @@ -95,7 +102,9 @@ #define OPT_PROGNAME -2 #define OPT_USAGE -3 +#if HAVE_SLEEP && HAVE_GETPID #define OPT_HANG -4 +#endif static const struct argp_option argp_default_options[] = { @@ -103,8 +112,10 @@ {"usage", OPT_USAGE, 0, 0, N_("Give a short usage message"), 0 }, {"program-name",OPT_PROGNAME,"NAME", OPTION_HIDDEN, N_("Set the program name"), 0}, +#if OPT_HANG {"HANG", OPT_HANG, "SECS", OPTION_ARG_OPTIONAL | OPTION_HIDDEN, N_("Hang for SECS seconds (default 3600)"), 0 }, +#endif {0, 0, 0, 0, 0, 0} }; @@ -144,6 +155,7 @@ break; +#if OPT_HANG case OPT_HANG: _argp_hang = atoi (arg ? arg : "3600"); fprintf(state->err_stream, "%s: pid = %ld\n", @@ -151,6 +163,7 @@ while (_argp_hang-- > 0) __sleep (1); break; +#endif default: return EBADKEY; Index: trunk/strcasecmp.c =================================================================== --- trunk/strcasecmp.c (revision 0) +++ trunk/strcasecmp.c (revision 3) @@ -0,0 +1,28 @@ +/* strcasecmp.c + * + */ + +/* Written by Niels Möller <nisse@lysator.liu.se> + * + * This file is hereby placed in the public domain. + */ + +#include <ctype.h> + +int strcasecmp(const char *s1, const char *s2) +{ + unsigned i; + + for (i = 0; s1[i] && s2[i]; i++) + { + unsigned char c1 = tolower( (unsigned char) s1[i]); + unsigned char c2 = tolower( (unsigned char) s2[i]); + + if (c1 < c2) + return -1; + else if (c1 > c2) + return 1; + } + + return !s2[i] - !s1[i]; +} Index: trunk/argp-test.c =================================================================== --- trunk/argp-test.c (revision 2) +++ trunk/argp-test.c (revision 3) @@ -1,5 +1,5 @@ /* Test program for argp argument parser - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 Index: trunk/argp-ba.c =================================================================== --- trunk/argp-ba.c (revision 2) +++ trunk/argp-ba.c (revision 3) @@ -1,5 +1,5 @@ /* Default definition for ARGP_PROGRAM_BUG_ADDRESS. - Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* If set by the user program, it should point to string that is the bug-reporting address for the program. It will be printed by argp_help if Property changes on: trunk/build-aux ___________________________________________________________________ Name: svn:ignore + depcomp missing config.guess ltmain.sh config.sub install-sh Index: trunk/argp-pv.c =================================================================== --- trunk/argp-pv.c (revision 2) +++ trunk/argp-pv.c (revision 3) @@ -1,5 +1,5 @@ /* Default definition for ARGP_PROGRAM_VERSION. - Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* If set by the user program to a non-zero value, then a default option --version is added (unless the ARGP_NO_HELP flag is used), which will Index: trunk/argp-help.c =================================================================== --- trunk/argp-help.c (revision 2) +++ trunk/argp-help.c (revision 3) @@ -1,5 +1,5 @@ /* Hierarchial argument parsing help output - Copyright (C) 1995,96,97,98,99,2000, 2003 Free Software Foundation, Inc. + Copyright (C) 96, 97, 98, 99, 1995, 2000, 2003, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifndef _GNU_SOURCE # define _GNU_SOURCE 1 @@ -47,8 +47,10 @@ #include <assert.h> #include <stdarg.h> #include <ctype.h> -/* Does any system still need malloc.h? If so, we'd need a configure - test. */ +#if HAVE_MALLOC_H +/* Needed, for alloca on windows */ +# include <malloc.h> +#endif #ifndef _ /* This is for other GNU distributions with internationalized messages. */ @@ -102,6 +104,10 @@ char *strchrnul(const char *s, int c); # endif /* !HAVE_STRCHRNUL */ +# if !HAVE_STRCASECMP +int strcasecmp(const char *s1, const char *s2); +#endif + #endif /* !_LIBC */ Index: trunk/argp-eexst.c =================================================================== --- trunk/argp-eexst.c (revision 2) +++ trunk/argp-eexst.c (revision 3) @@ -1,5 +1,5 @@ /* Default definition for ARGP_ERR_EXIT_STATUS - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,14 +15,18 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include <config.h> #endif +#if HAVE_SYSEXITS_H #include <sysexits.h> +#else +# define EX_USAGE 64 +#endif #include "argp.h" Index: trunk/configure.ac =================================================================== --- trunk/configure.ac (revision 2) +++ trunk/configure.ac (revision 3) @@ -3,8 +3,8 @@ dnl This configure.ac is only for building a standalone argp library. AC_PREREQ(2.54) AC_INIT(argp-ba.c) -AC_CONFIG_AUX_DIR([../build-aux]) -AM_INIT_AUTOMAKE(argp, standalone-1.3) +AC_CONFIG_AUX_DIR([build-aux]) +AM_INIT_AUTOMAKE(argp, standalone-1.4) AM_CONFIG_HEADER(config.h) # GNU libc defaults to supplying the ISO C library functions only. The @@ -20,14 +20,14 @@ AM_PROG_CC_STDC if test "x$am_cv_prog_cc_stdc" = xno ; then - AC_ERROR([the C compiler doesn't handle ANSI-C]) + AC_ERROR([the C compiler does not handle ANSI-C]) fi # Checks for libraries. # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(limits.h malloc.h unistd.h) +AC_CHECK_HEADERS(limits.h malloc.h unistd.h sysexits.h stdarg.h) # Checks for typedefs, structures, and compiler characteristics. AC_C_CONST @@ -39,16 +39,16 @@ # Checks for library functions. AC_FUNC_ALLOCA AC_FUNC_VPRINTF -AC_CHECK_FUNCS(strerror) +AC_CHECK_FUNCS(strerror sleep getpid snprintf) -AC_REPLACE_FUNCS(mempcpy strndup strchrnul) +AC_REPLACE_FUNCS(mempcpy strndup strchrnul strcasecmp vsnprintf) dnl ARGP_CHECK_FUNC(includes, function-call [, if-found [, if-not-found]]) AC_DEFUN([ARGP_CHECK_FUNC], [AS_VAR_PUSHDEF([ac_func], m4_substr([$2], 0, m4_index([$2], [(]))) AS_VAR_PUSHDEF([ac_var], [ac_cv_func_call_]ac_func) AH_TEMPLATE(AS_TR_CPP(HAVE_[]ac_func), - [Define to 1 if you have the `]ac_func[' function.]) + [Define to 1 if you have the ]ac_func[ function.]) AC_CACHE_CHECK([for $2], ac_var, [AC_TRY_LINK([$1], [$2], [AS_VAR_SET(ac_var, yes)], Index: trunk/argp-pvh.c =================================================================== --- trunk/argp-pvh.c (revision 2) +++ trunk/argp-pvh.c (revision 3) @@ -1,5 +1,5 @@ /* Default definition for ARGP_PROGRAM_VERSION_HOOK. - Copyright (C) 1996, 1997, 1999, 2004 Free Software Foundation, Inc. + Copyright (C) 1996, 1997, 1999, 2004, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #ifdef HAVE_CONFIG_H #include <config.h> Index: trunk/argp-namefrob.h =================================================================== --- trunk/argp-namefrob.h (revision 2) +++ trunk/argp-namefrob.h (revision 3) @@ -1,5 +1,5 @@ /* Name frobnication for compiling argp outside of glibc - Copyright (C) 1997 Free Software Foundation, Inc. + Copyright (C) 1997, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ #if !_LIBC /* This code is written for inclusion in gnu-libc, and uses names in the Index: trunk/Makefile.am =================================================================== --- trunk/Makefile.am (revision 2) +++ trunk/Makefile.am (revision 3) @@ -20,7 +20,7 @@ AUTOMAKE_OPTIONS = foreign SUBDIRS = . testsuite -ACLOCAL_AMFLAGS = -I ../build-aux +ACLOCAL_AMFLAGS = -I build-aux noinst_LTLIBRARIES = libargp.la noinst_PROGRAMS = argp-test @@ -28,7 +28,6 @@ EXTRA_DIST = mempcpy.c strchrnul.c strndup.c Versions -# Leaves out argp-fs-xinl.c and argp-xinl.c libargp_la_SOURCES = argp-ba.c argp-eexst.c argp-fmtstream.c \ argp-help.c argp-parse.c argp-pv.c \ argp-pvh.c Index: trunk/argp-fmtstream.c =================================================================== --- trunk/argp-fmtstream.c (revision 2) +++ trunk/argp-fmtstream.c (revision 3) @@ -1,5 +1,5 @@ /* Word-wrapping and line-truncating streams - Copyright (C) 1997, 1998, 1999, 2001 Free Software Foundation, Inc. + Copyright (C) 1997, 1998, 1999, 2001, 2007 Free Software Foundation, Inc. This file is part of the GNU C Library. Written by Miles Bader <miles@gnu.ai.mit.edu>. @@ -15,8 +15,8 @@ You should have received a copy of the GNU Library General Public License along with the GNU C Library; see the file COPYING.LIB. If not, - write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ + write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. */ /* This package emulates glibc `line_wrap_stream' semantics for systems that don't have that. */ Index: trunk/vsnprintf.c =================================================================== --- trunk/vsnprintf.c (revision 0) +++ trunk/vsnprintf.c (revision 3) @@ -0,0 +1,833 @@ +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell (papowell@astart.com) + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions + */ + +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long <blong@fiction.net> 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long <blong@fiction.net> 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler <roessler@guug.de> 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins <me@cs.hmc.edu> 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + * Andrew Tridgell (tridge@samba.org) Oct 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE + * + * Russ Allbery <rra@stanford.edu> 2000-08-26 + * fixed return value to comply with C99 + * fixed handling of snprintf(NULL, ...) + * + **************************************************************/ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +#include <string.h> +#include <ctype.h> +#include <sys/types.h> + +/* Define this as a fall through, HAVE_STDARG_H is probably already set */ + +#define HAVE_VARARGS_H + + +/* varargs declarations: */ + +#if defined(HAVE_STDARG_H) +# include <stdarg.h> +# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap, f) +# define VA_SHIFT(v,t) ; /* no-op for ANSI */ +# define VA_END va_end(ap) +#else +# if defined(HAVE_VARARGS_H) +# include <varargs.h> +# undef HAVE_STDARGS +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap) /* f is ignored! */ +# define VA_SHIFT(v,t) v = va_arg(ap,t) +# define VA_END va_end(ap) +# else +/*XX ** NO VARARGS ** XX*/ +# endif +#endif + +#ifdef HAVE_LONG_DOUBLE +#define LDOUBLE long double +#else +#define LDOUBLE double +#endif + +int snprintf (char *str, size_t count, const char *fmt, ...); +int vsnprintf (char *str, size_t count, const char *fmt, va_list arg); + +static int dopr (char *buffer, size_t maxlen, const char *format, + va_list args); +static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static int fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags); +static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags); +static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 + +#define char_to_int(p) (p - '0') +#define MAX(p,q) ((p >= q) ? p : q) +#define MIN(p,q) ((p <= q) ? p : q) + +static int dopr (char *buffer, size_t maxlen, const char *format, va_list args) +{ + unsigned char ch; + long value; + LDOUBLE fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + int total; + size_t currlen; + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; + ch = *format++; + total = 0; + + while (state != DP_S_DONE) + { + if (ch == '\0') + state = DP_S_DONE; + + switch(state) + { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + total += dopr_outch (buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) + { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit(ch)) + { + min = 10*min + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } + else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') + { + state = DP_S_MAX; + ch = *format++; + } + else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit(ch)) + { + if (max < 0) + max = 0; + max = 10*max + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } + else + state = DP_S_MOD; + break; + case DP_S_MOD: + /* Currently, we don't support Long Long, bummer */ + switch (ch) + { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) + { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = (short) va_arg (args, int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else + value = va_arg (args, int); + total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = (unsigned short) va_arg (args, unsigned); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + total += fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = (unsigned short) va_arg (args, unsigned); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + total += fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = (unsigned short) va_arg (args, unsigned); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + total += fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + /* um, floating point? */ + total += fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, LDOUBLE); + else + fvalue = va_arg (args, double); + break; + case 'c': + total += dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); + break; + case 's': + strvalue = va_arg (args, char *); + total += fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg (args, void *); + total += fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, + max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) + { + short int *num; + num = va_arg (args, short int *); + *num = currlen; + } + else if (cflags == DP_C_LONG) + { + long int *num; + num = va_arg (args, long int *); + *num = currlen; + } + else + { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; + case '%': + total += dopr_outch (buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (buffer != NULL) + { + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; + } + return total; +} + +static int fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + int total = 0; + + if (value == 0) + { + value = "<NULL>"; + } + + for (strln = 0; value[strln]; ++strln); /* strlen */ + if (max >= 0 && max < strln) + strln = max; + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while (padlen > 0) + { + total += dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + while (*value && ((max < 0) || (cnt < max))) + { + total += dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while (padlen < 0) + { + total += dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } + return total; +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static int fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags) +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + int total = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) + { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + } + + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < 20)); + if (place == 20) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; + if (flags & DP_F_ZERO) + { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place)); +#endif + + /* Spaces */ + while (spadlen > 0) + { + total += dopr_outch (buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + total += dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) + { + while (zpadlen > 0) + { + total += dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + total += dopr_outch (buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + total += dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } + + return total; +} + +static LDOUBLE abs_val (LDOUBLE value) +{ + LDOUBLE result = value; + + if (value < 0) + result = -value; + + return result; +} + +static LDOUBLE pow10 (int exp) +{ + LDOUBLE result = 1; + + while (exp) + { + result *= 10; + exp--; + } + + return result; +} + +static long round (LDOUBLE value) +{ + long intpart; + + intpart = value; + value = value - intpart; + if (value >= 0.5) + intpart++; + + return intpart; +} + +static int fmtfp (char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags) +{ + int signvalue = 0; + LDOUBLE ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + int total = 0; + long intpart; + long fracpart; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val (fvalue); + + if (fvalue < 0) + signvalue = '-'; + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + + intpart = ufvalue; + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + fracpart = round ((pow10 (max)) * (ufvalue - intpart)); + + if (fracpart >= pow10 (max)) + { + intpart++; + fracpart -= pow10 (max); + } + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); +#endif + + /* Convert integer part */ + do { + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) + { + if (signvalue) + { + total += dopr_outch (buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) + { + total += dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) + { + total += dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + total += dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + total += dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0) + { + total += dopr_outch (buffer, currlen, maxlen, '.'); + + while (fplace > 0) + total += dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + } + + while (zpadlen > 0) + { + total += dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) + { + total += dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } + + return total; +} + +static int dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen + 1 < maxlen) + buffer[(*currlen)++] = c; + return 1; +} + +#ifndef HAVE_VSNPRINTF +int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + if (str != NULL) + str[0] = 0; + return dopr(str, count, fmt, args); +} +#endif /* !HAVE_VSNPRINTF */ + +#ifndef HAVE_SNPRINTF +/* VARARGS3 */ +#ifdef HAVE_STDARGS +int snprintf (char *str,size_t count,const char *fmt,...) +#else +int snprintf (va_alist) va_dcl +#endif +{ +#ifndef HAVE_STDARGS + char *str; + size_t count; + char *fmt; +#endif + VA_LOCAL_DECL; + int total; + + VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t ); + VA_SHIFT (fmt, char *); + total = vsnprintf(str, count, fmt, ap); + VA_END; + return total; +} +#endif /* !HAVE_SNPRINTF */ + +#ifdef TEST_SNPRINTF +#ifndef LONG_STRING +#define LONG_STRING 1024 +#endif +int main (void) +{ + char buf1[LONG_STRING]; + char buf2[LONG_STRING]; + char *fp_fmt[] = { + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + "%.0f", + "%.1f", + NULL + }; + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; + int x, y; + int fail = 0; + int num = 0; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] != NULL ; x++) + for (y = 0; fp_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + fp_fmt[x], buf1, buf2); + fail++; + } + num++; + } + + for (x = 0; int_fmt[x] != NULL ; x++) + for (y = 0; int_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); + sprintf (buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + int_fmt[x], buf1, buf2); + fail++; + } + num++; + } + printf ("%d tests failed out of %d.\n", fail, num); +} +#endif /* SNPRINTF_TEST */ + +#endif /* !HAVE_SNPRINTF */ Index: trunk/bootstrap =================================================================== --- trunk/bootstrap (revision 0) +++ trunk/bootstrap (revision 3) @@ -0,0 +1,3 @@ +#! /bin/sh + +autoreconf --force --verbose --install Property changes on: trunk/bootstrap ___________________________________________________________________ Name: svn:eol-style + native Name: svn:executable + * Index: trunk/argp-xinl.c (deleted) =================================================================== Index: trunk/argp-fs-xinl.c (deleted) =================================================================== Property changes on: trunk ___________________________________________________________________ Name: svn:ignore + _build configure INSTALL COPYING config.h.in autom4te.cache aclocal.m4 -- SIGOURE Benoit aka Tsuna (SUSv3 compliant) _____ "On a long enough timeline, the survival rate /EPITA\ Promo 2008.CSI/ACU/YAKA for everyone drops to zero" -- Jack.
participants (1)
-
SIGOURE Benoit