X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=ngircd-alex.git;a=blobdiff_plain;f=src%2Fportab%2Fvsnprintf.c;h=39a6c5fae903ba717c2af15eba44f74c5902a7ed;hp=8620164ff7e24d38a3fd7f2b9dee7119be68850f;hb=3de972e0bdbb5da7b13db5628e5373e3ec57cf51;hpb=679565603aebc3880fe640301ac8216811da5d32 diff --git a/src/portab/vsnprintf.c b/src/portab/vsnprintf.c index 8620164f..39a6c5fa 100644 --- a/src/portab/vsnprintf.c +++ b/src/portab/vsnprintf.c @@ -2,24 +2,19 @@ * ngIRCd -- The Next Generation IRC Daemon * Copyright (c)2001,2002 by Alexander Barton (alex@barton.de) * - * Dieses Programm ist freie Software. Sie koennen es unter den Bedingungen - * der GNU General Public License (GPL), wie von der Free Software Foundation - * herausgegeben, weitergeben und/oder modifizieren, entweder unter Version 2 - * der Lizenz oder (wenn Sie es wuenschen) jeder spaeteren Version. - * Naehere Informationen entnehmen Sie bitter der Datei COPYING. Eine Liste - * der an ngIRCd beteiligten Autoren finden Sie in der Datei AUTHORS. - * - * $Id: vsnprintf.c,v 1.1 2002/05/19 01:17:40 alex Exp $ - * - * vsnprintf.c: vsnprintf()-Ersatz + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * Please read the file COPYING, README and AUTHORS for more information. */ - #include "portab.h" -#include "imp.h" - -#include "exp.h" +/** + * @file + * snprintf() and vsnprintf() replacement functions + */ /* * snprintf.c: Copyright Patrick Powell 1995 @@ -45,36 +40,38 @@ * 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 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. + * Brandon Long 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 01/27/98 for mutt 0.89i - * The PGP code was using unsigned hexadecimal formats. - * Unfortunately, unsigned formats simply didn't work. + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. * - * Michael Elkins 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. + * Michael Elkins 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 + * Andrew Tridgell , October 1998 + * fixed handling of %.0f + * added test for HAVE_LONG_DOUBLE * * tridge@samba.org, idra@samba.org, April 2001 - * got rid of fcvt code (twas buggy and made testing harder) - * added C99 semantics + * got rid of fcvt code (twas buggy and made testing harder) + * added C99 semantics + * + * Alexander Barton, , 2002-05-19 + * removed [v]asprintf() and C99 tests: not needed by ngIRCd. */ - #ifdef HAVE_STRING_H #include #endif @@ -90,11 +87,12 @@ #include #endif -#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) && defined(HAVE_C99_VSNPRINTF) +#if defined(HAVE_SNPRINTF) && defined(HAVE_VSNPRINTF) /* only include stdio.h if we are not re-defining snprintf or vsnprintf */ #include - /* make the compiler happy with an empty file */ - void dummy_snprintf(void) {} +/* make the compiler happy with an empty file */ +void dummy_snprintf PARAMS(( void )); +void dummy_snprintf PARAMS(( void )) { } #else #ifdef HAVE_LONG_DOUBLE @@ -109,15 +107,16 @@ #define LLONG long #endif -static size_t dopr(char *buffer, size_t maxlen, const char *format, - va_list args); -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max); -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - long 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, char c); +static size_t dopr PARAMS((char *buffer, size_t maxlen, const char *format, + va_list args)); +static void fmtstr PARAMS((char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max)); +static void fmtint PARAMS((char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags)); +static void fmtfp PARAMS((char *buffer, size_t *currlen, size_t maxlen, + LDOUBLE fvalue, int min, int max, int flags)); +static void dopr_outch PARAMS((char *buffer, size_t *currlen, size_t maxlen, + char c)); /* * dopr(): poor man's version of doprintf @@ -153,7 +152,8 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c); #define MAX(p,q) (((p) >= (q)) ? (p) : (q)) #endif -static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args) +static size_t +dopr(char *buffer, size_t maxlen, const char *format, va_list args) { char ch; LLONG value; @@ -410,8 +410,9 @@ static size_t dopr(char *buffer, size_t maxlen, const char *format, va_list args return currlen; } -static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, - char *value, int flags, int min, int max) +static void +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; @@ -448,8 +449,9 @@ static void fmtstr(char *buffer, size_t *currlen, size_t maxlen, /* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ -static void fmtint(char *buffer, size_t *currlen, size_t maxlen, - long value, int base, int min, int max, int flags) +static void +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; @@ -532,7 +534,8 @@ static void fmtint(char *buffer, size_t *currlen, size_t maxlen, } } -static LDOUBLE abs_val(LDOUBLE value) +static LDOUBLE +abs_val(LDOUBLE value) { LDOUBLE result = value; @@ -542,7 +545,8 @@ static LDOUBLE abs_val(LDOUBLE value) return result; } -static LDOUBLE POW10(int exp) +static LDOUBLE +POW10(int exp) { LDOUBLE result = 1; @@ -554,7 +558,8 @@ static LDOUBLE POW10(int exp) return result; } -static LLONG ROUND(LDOUBLE value) +static LLONG +ROUND(LDOUBLE value) { LLONG intpart; @@ -567,7 +572,8 @@ static LLONG ROUND(LDOUBLE value) /* a replacement for modf that doesn't need the math library. Should be portable, but slow */ -static double my_modf(double x0, double *iptr) +static double +my_modf(double x0, double *iptr) { int i; long l; @@ -601,8 +607,9 @@ static double my_modf(double x0, double *iptr) } -static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, - LDOUBLE fvalue, 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) { int signvalue = 0; double ufvalue; @@ -638,14 +645,6 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, } } -#if 0 - if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ -#endif - -#if 0 - if (max == 0) ufvalue += 0.5; /* if max = 0 we must round */ -#endif - /* * Sorry, we only support 16 digits past the decimal because of our * conversion method @@ -755,7 +754,8 @@ static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, } } -static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) +static void +dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) { if (*currlen < maxlen) { buffer[(*currlen)] = c; @@ -763,15 +763,26 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) (*currlen)++; } -#if !defined(HAVE_VSNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +#if !defined(HAVE_VSNPRINTF) +int +vsnprintf (char *str, size_t count, const char *fmt, va_list args) { return dopr(str, count, fmt, args); } #endif -#if !defined(HAVE_SNPRINTF) || !defined(HAVE_C99_VSNPRINTF) - int snprintf(char *str,size_t count,const char *fmt,...) +#if !defined(HAVE_SNPRINTF) +#ifdef PROTOTYPES +int +snprintf(char *str, size_t count, const char *fmt, ...) +#else +int +snprintf(str, count, fmt, va_alist) +char *str; +size_t count; +const char *fmt; +va_dcl +#endif { size_t ret; va_list ap; @@ -783,170 +794,6 @@ static void dopr_outch(char *buffer, size_t *currlen, size_t maxlen, char c) } #endif -#endif - -#ifndef HAVE_VASPRINTF - int vasprintf(char **ptr, const char *format, va_list ap) -{ - int ret; - - ret = vsnprintf(NULL, 0, format, ap); - if (ret <= 0) return ret; - - (*ptr) = (char *)malloc(ret+1); - if (!*ptr) return -1; - ret = vsnprintf(*ptr, ret+1, format, ap); - - return ret; -} -#endif - - -#ifndef HAVE_ASPRINTF - int asprintf(char **ptr, const char *format, ...) -{ - va_list ap; - int ret; - - va_start(ap, format); - ret = vasprintf(ptr, format, ap); - va_end(ap); - - return ret; -} #endif -#ifdef TEST_SNPRINTF -int sprintf(char *str,const char *fmt,...); -int main (void) -{ - char buf1[1024]; - char buf2[1024]; - char *fp_fmt[] = { - "%1.1f", - "%-1.5f", - "%1.5f", - "%123.9f", - "%10.5f", - "% 10.5f", - "%+22.9f", - "%+4.9f", - "%01.3f", - "%4f", - "%3.1f", - "%3.2f", - "%.0f", - "%f", - "-16.16f", - NULL - }; - double fp_nums[] = { 6442452944.1234, -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", - "%d", - NULL - }; - long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; - char *str_fmt[] = { - "10.5s", - "5.10s", - "10.1s", - "0.10s", - "10.0s", - "1.10s", - "%s", - "%.1s", - "%.10s", - "%10s", - NULL - }; - char *str_vals[] = {"hello", "a", "", "a longer string", NULL}; - int x, y; - int fail = 0; - int num = 0; - - printf ("Testing snprintf format codes against system sprintf...\n"); - - for (x = 0; fp_fmt[x] ; x++) { - for (y = 0; fp_nums[y] != 0 ; y++) { - int l1 = snprintf(NULL, 0, fp_fmt[x], fp_nums[y]); - int l2 = 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\t sprintf = [%s]\n", - fp_fmt[x], buf1, buf2); - fail++; - } - if (l1 != l2) { - printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, fp_fmt[x]); - fail++; - } - num++; - } - } - - for (x = 0; int_fmt[x] ; x++) { - for (y = 0; int_nums[y] != 0 ; y++) { - int l1 = snprintf(NULL, 0, int_fmt[x], int_nums[y]); - int l2 = 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\t sprintf = [%s]\n", - int_fmt[x], buf1, buf2); - fail++; - } - if (l1 != l2) { - printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, int_fmt[x]); - fail++; - } - num++; - } - } - - for (x = 0; str_fmt[x] ; x++) { - for (y = 0; str_vals[y] != 0 ; y++) { - int l1 = snprintf(NULL, 0, str_fmt[x], str_vals[y]); - int l2 = snprintf(buf1, sizeof(buf1), str_fmt[x], str_vals[y]); - sprintf (buf2, str_fmt[x], str_vals[y]); - if (strcmp (buf1, buf2)) { - printf("snprintf doesn't match Format: %s\n\tsnprintf = [%s]\n\t sprintf = [%s]\n", - str_fmt[x], buf1, buf2); - fail++; - } - if (l1 != l2) { - printf("snprintf l1 != l2 (%d %d) %s\n", l1, l2, str_fmt[x]); - fail++; - } - num++; - } - } - - printf ("%d tests failed out of %d.\n", fail, num); - - printf("seeing how many digits we support\n"); - { - double v0 = 0.12345678901234567890123456789012345678901; - for (x=0; x<100; x++) { - snprintf(buf1, sizeof(buf1), "%1.1f", v0*pow(10, x)); - sprintf(buf2, "%1.1f", v0*pow(10, x)); - if (strcmp(buf1, buf2)) { - printf("we seem to support %d digits\n", x-1); - break; - } - } - } - return 0; -} -#endif /* SNPRINTF_TEST */ - - /* -eof- */