pkgsrc-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[pkgsrc/trunk]: pkgsrc/pkgtools/libnbcompat/files Replace "poor man's printf"...



details:   https://anonhg.NetBSD.org/pkgsrc/rev/bc5975d725e4
branches:  trunk
changeset: 531095:bc5975d725e4
user:      tnn <tnn%pkgsrc.org@localhost>
date:      Thu Jul 19 22:06:43 2007 +0000

description:
Replace "poor man's printf" implementation of (v)snprintf with an
imlementation using vfprintf. The advantage is that format strings behave
like other *printf functions on the host, the drawback is that it is slower.

diffstat:

 pkgtools/libnbcompat/files/snprintf.c |  839 ++-------------------------------
 1 files changed, 72 insertions(+), 767 deletions(-)

diffs (truncated from 866 to 300 lines):

diff -r 63c8c42d74cf -r bc5975d725e4 pkgtools/libnbcompat/files/snprintf.c
--- a/pkgtools/libnbcompat/files/snprintf.c     Thu Jul 19 21:58:17 2007 +0000
+++ b/pkgtools/libnbcompat/files/snprintf.c     Thu Jul 19 22:06:43 2007 +0000
@@ -1,790 +1,95 @@
-/*     $NetBSD: snprintf.c,v 1.3 2004/08/23 03:32:12 jlam Exp $        */
+/*     $NetBSD: snprintf.c,v 1.4 2007/07/19 22:06:43 tnn Exp $ */
 
-/*
- * Copyright Patrick Powell 1995
- * This code is based on code written by Patrick Powell (papowell%astart.com@localhost)
- * It may be used for any purpose as long as this notice remains intact
- * on all source code distributions
+/*-
+ * Copyright (c) 2007 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Tobias Nygren.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by the NetBSD
+ *        Foundation, Inc. and its contributors.
+ * 4. Neither the name of The NetBSD Foundation nor the names of its
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
  */
 
-/**************************************************************
- * 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@localhost> 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@localhost> 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@localhost> 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@localhost> 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@localhost) Oct 1998
- *    fixed handling of %.0f
- *    added test for HAVE_LONG_DOUBLE
- *
- *  Luke Mewburn <lukem%netbsd.org@localhost>, Thu Sep 30 23:28:21 EST 1999
- *     cleaned up formatting, autoconf tests
- *     added long long support
- *
- **************************************************************/
+#include <nbcompat.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
 
-#include <nbcompat.h>
 #if HAVE_STDARG_H
 #include <stdarg.h>
 #endif
 
-#if HAVE_LONG_DOUBLE
-#define LDOUBLE long double
-#else
-#define LDOUBLE double
-#endif
-
-#if HAVE_LONG_LONG
-#define LLONG long long
-#else
-#define LLONG long
-#endif
-
-static void dopr(char *buffer, size_t maxlen, size_t *retlen,
-                   const char *format, va_list args);
-static void fmtstr(char *buffer, size_t * currlen, size_t maxlen,
-                   char *value, int min, int max, int flags);
-static void fmtint(char *buffer, size_t * currlen, size_t maxlen,
-                   LLONG value, int base, int min, int max, int flags);
-static void fmtfp(char *buffer, size_t * currlen, size_t maxlen,
-                   LDOUBLE fvalue, int min, int max, int flags);
-static void dopr_outch(char *buffer, size_t * currlen, size_t maxlen, int 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 DP_C_LLONG     4
-
-#define char_to_int(p) (p - '0')
-
-static void
-dopr(char *buffer, size_t maxlen, size_t *retlen, const char *format,
-       va_list args)
+int
+snprintf(char *str, size_t size, const char *format, ...)
 {
-       char     ch;
-       LLONG    value;
-       LDOUBLE  fvalue;
-       char    *strvalue;
-       int      min;
-       int      max;
-       int      state;
-       int      flags;
-       int      cflags;
-       size_t   currlen;
-
-       state = DP_S_DEFAULT;
-       flags = currlen = cflags = min = 0;
-       max = -1;
-       ch = *format++;
-
-       while (state != DP_S_DONE) {
-               if ((ch == '\0') || (currlen >= maxlen))
-                       state = DP_S_DONE;
+       va_list ap;
+       int len;
 
-               switch (state) {
-               case DP_S_DEFAULT:
-                       if (ch == '%')
-                               state = DP_S_FLAGS;
-                       else
-                               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((unsigned char) 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((unsigned char) 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:
-                       switch (ch) {
-                       case 'h':
-                               cflags = DP_C_SHORT;
-                               ch = *format++;
-                               break;
-                       case 'l':
-                               if (*format == 'l') {
-                                       cflags = DP_C_LLONG;
-                                       format++;
-                               } else
-                                       cflags = DP_C_LONG;
-                               ch = *format++;
-                               break;
-                       case 'q':
-                               cflags = DP_C_LLONG;
-                               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':
-                               switch (cflags) {
-                               case DP_C_SHORT:
-                                       value = va_arg(args, int);
-                                       break;
-                               case DP_C_LONG:
-                                       value = va_arg(args, long int);
-                                       break;
-                               case DP_C_LLONG:
-                                       value = va_arg(args, LLONG);
-                                       break;
-                               default:
-                                       value = va_arg(args, int);
-                                       break;
-                               }
-                               fmtint(buffer, &currlen, maxlen, value, 10,



Home | Main Index | Thread Index | Old Index