X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=sbr%2Fsnprintf.c;h=1dd4a65cf8ea7f371de8e70748a85fc3f6353b1f;hb=ced6090a330d3d83d0bce709f756aa3d7d65fea4;hp=efb6df061c063a25637245c1fe076a39ffc50b27;hpb=1691e80890e5d8ba258c51c214a3e91880e1db2b;p=mmh
diff --git a/sbr/snprintf.c b/sbr/snprintf.c
index efb6df0..1dd4a65 100644
--- a/sbr/snprintf.c
+++ b/sbr/snprintf.c
@@ -1,70 +1,70 @@
/*
- * snprintf.c -- formatted output to a string
- *
- * This is an implementation of snprintf() and vsnprintf()
- * taken from the Apache web server. This is only used on
- * systems which do not have a native version.
- */
+** snprintf.c -- formatted output to a string
+**
+** This is an implementation of snprintf() and vsnprintf()
+** taken from the Apache web server. This is only used on
+** systems which do not have a native version.
+*/
/* ====================================================================
- * Copyright (c) 1995-1999 The Apache Group. All rights reserved.
- *
- * 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 acknowledgment:
- * "This product includes software developed by the Apache Group
- * for use in the Apache HTTP server project (http://www.apache.org/)."
- *
- * 4. The names "Apache Server" and "Apache Group" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission. For written permission, please contact
- * apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache"
- * nor may "Apache" appear in their names without prior written
- * permission of the Apache Group.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by the Apache Group
- * for use in the Apache HTTP server project (http://www.apache.org/)."
- *
- * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
- * EXPRESSED 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 APACHE GROUP OR
- * ITS 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.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Group and was originally based
- * on public domain software written at the National Center for
- * Supercomputing Applications, University of Illinois, Urbana-Champaign.
- * For more information on the Apache Group and the Apache HTTP server
- * project, please see .
- *
- * This code is based on, and used with the permission of, the
- * SIO stdio-replacement strx_* functions by Panos Tsirigotis
- * for xinetd.
- */
+** Copyright (c) 1995-1999 The Apache Group. All rights reserved.
+**
+** 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 acknowledgment:
+** "This product includes software developed by the Apache Group
+** for use in the Apache HTTP server project (http://www.apache.org/)."
+**
+** 4. The names "Apache Server" and "Apache Group" must not be used to
+** endorse or promote products derived from this software without
+** prior written permission. For written permission, please contact
+** apache@apache.org.
+**
+** 5. Products derived from this software may not be called "Apache"
+** nor may "Apache" appear in their names without prior written
+** permission of the Apache Group.
+**
+** 6. Redistributions of any form whatsoever must retain the following
+** acknowledgment:
+** "This product includes software developed by the Apache Group
+** for use in the Apache HTTP server project (http://www.apache.org/)."
+**
+** THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
+** EXPRESSED 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 APACHE GROUP OR
+** ITS 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.
+** ====================================================================
+**
+** This software consists of voluntary contributions made by many
+** individuals on behalf of the Apache Group and was originally based
+** on public domain software written at the National Center for
+** Supercomputing Applications, University of Illinois, Urbana-Champaign.
+** For more information on the Apache Group and the Apache HTTP server
+** project, please see .
+**
+** This code is based on, and used with the permission of, the
+** SIO stdio-replacement strx_* functions by Panos Tsirigotis
+** for xinetd.
+*/
#include
#include
@@ -76,970 +76,981 @@
#include
typedef enum {
- NO = 0, YES = 1
+ NO = 0, YES = 1
} boolean_e;
#ifndef FALSE
-#define FALSE 0
+# define FALSE 0
#endif
#ifndef TRUE
-#define TRUE 1
+# define TRUE 1
#endif
-#define NUL '\0'
-#define INT_NULL ((int *)0)
-#define WIDE_INT long
+#define NUL '\0'
+#define INT_NULL ((int *)0)
+#define WIDE_INT long
typedef struct {
- char *curpos;
- char *endpos;
+ char *curpos;
+ char *endpos;
} ap_vformatter_buff;
typedef WIDE_INT wide_int;
typedef unsigned WIDE_INT u_wide_int;
typedef int bool_int;
-#define S_NULL "(null)"
-#define S_NULL_LEN 6
+#define S_NULL "(null)"
+#define S_NULL_LEN 6
-#define FLOAT_DIGITS 6
-#define EXPONENT_LENGTH 10
+#define FLOAT_DIGITS 6
+#define EXPONENT_LENGTH 10
-/* These macros allow correct support of 8-bit characters on systems which
- * support 8-bit characters. Pretty dumb how the cast is required, but
- * that's legacy libc for ya. These new macros do not support EOF like
- * the standard macros do. Tough.
- */
+/*
+** These macros allow correct support of 8-bit characters on systems which
+** support 8-bit characters. Pretty dumb how the cast is required, but
+** that's legacy libc for ya. These new macros do not support EOF like
+** the standard macros do. Tough.
+*/
#define ap_isalpha(c) (isalpha(((unsigned char)(c))))
#define ap_isdigit(c) (isdigit(((unsigned char)(c))))
#define ap_islower(c) (islower(((unsigned char)(c))))
/*
- * NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
- *
- * XXX: this is a magic number; do not decrease it
- */
-#define NUM_BUF_SIZE 512
+** NUM_BUF_SIZE is the size of the buffer used for arithmetic conversions
+**
+** XXX: this is a magic number; do not decrease it
+*/
+#define NUM_BUF_SIZE 512
/*
- * cvt.c - IEEE floating point formatting routines for FreeBSD
- * from GNU libc-4.6.27. Modified to be thread safe.
- */
+** cvt.c - IEEE floating point formatting routines for FreeBSD
+** from GNU libc-4.6.27. Modified to be thread safe.
+*/
/*
- * ap_ecvt converts to decimal
- * the number of digits is specified by ndigit
- * decpt is set to the position of the decimal point
- * sign is set to 0 for positive, 1 for negative
- */
+** ap_ecvt converts to decimal
+** the number of digits is specified by ndigit
+** decpt is set to the position of the decimal point
+** sign is set to 0 for positive, 1 for negative
+*/
-#define NDIG 80
+#define NDIG 80
/* buf must have at least NDIG bytes */
-static char *ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf)
+static char *
+ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf)
{
- register int r2;
- double fi, fj;
- register char *p, *p1;
-
- if (ndigits >= NDIG - 1)
- ndigits = NDIG - 2;
- r2 = 0;
- *sign = 0;
- p = &buf[0];
- if (arg < 0) {
- *sign = 1;
- arg = -arg;
- }
- arg = modf(arg, &fi);
- p1 = &buf[NDIG];
- /*
- * Do integer part
- */
- if (fi != 0) {
+ register int r2;
+ double fi, fj;
+ register char *p, *p1;
+
+ if (ndigits >= NDIG - 1)
+ ndigits = NDIG - 2;
+ r2 = 0;
+ *sign = 0;
+ p = &buf[0];
+ if (arg < 0) {
+ *sign = 1;
+ arg = -arg;
+ }
+ arg = modf(arg, &fi);
p1 = &buf[NDIG];
- while (fi != 0) {
- fj = modf(fi / 10, &fi);
- *--p1 = (int) ((fj + .03) * 10) + '0';
- r2++;
+ /*
+ ** Do integer part
+ */
+ if (fi != 0) {
+ p1 = &buf[NDIG];
+ while (fi != 0) {
+ fj = modf(fi / 10, &fi);
+ *--p1 = (int) ((fj + .03) * 10) + '0';
+ r2++;
+ }
+ while (p1 < &buf[NDIG])
+ *p++ = *p1++;
+ } else if (arg > 0) {
+ while ((fj = arg * 10) < 1) {
+ arg = fj;
+ r2--;
+ }
}
- while (p1 < &buf[NDIG])
- *p++ = *p1++;
- }
- else if (arg > 0) {
- while ((fj = arg * 10) < 1) {
- arg = fj;
- r2--;
+ p1 = &buf[ndigits];
+ if (eflag == 0)
+ p1 += r2;
+ *decpt = r2;
+ if (p1 < &buf[0]) {
+ buf[0] = '\0';
+ return (buf);
}
- }
- p1 = &buf[ndigits];
- if (eflag == 0)
- p1 += r2;
- *decpt = r2;
- if (p1 < &buf[0]) {
- buf[0] = '\0';
- return (buf);
- }
- while (p <= p1 && p < &buf[NDIG]) {
- arg *= 10;
- arg = modf(arg, &fj);
- *p++ = (int) fj + '0';
- }
- if (p1 >= &buf[NDIG]) {
- buf[NDIG - 1] = '\0';
- return (buf);
- }
- p = p1;
- *p1 += 5;
- while (*p1 > '9') {
- *p1 = '0';
- if (p1 > buf)
- ++ * --p1;
- else {
- *p1 = '1';
- (*decpt)++;
- if (eflag == 0) {
- if (p > buf)
- *p = '0';
- p++;
- }
+ while (p <= p1 && p < &buf[NDIG]) {
+ arg *= 10;
+ arg = modf(arg, &fj);
+ *p++ = (int) fj + '0';
+ }
+ if (p1 >= &buf[NDIG]) {
+ buf[NDIG - 1] = '\0';
+ return (buf);
+ }
+ p = p1;
+ *p1 += 5;
+ while (*p1 > '9') {
+ *p1 = '0';
+ if (p1 > buf)
+ ++ * --p1;
+ else {
+ *p1 = '1';
+ (*decpt)++;
+ if (eflag == 0) {
+ if (p > buf)
+ *p = '0';
+ p++;
+ }
+ }
}
- }
- *p = '\0';
- return (buf);
+ *p = '\0';
+ return (buf);
}
-static char *ap_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
+static char *
+ap_ecvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
{
- return (ap_cvt(arg, ndigits, decpt, sign, 1, buf));
+ return (ap_cvt(arg, ndigits, decpt, sign, 1, buf));
}
-static char *ap_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
+static char *
+ap_fcvt(double arg, int ndigits, int *decpt, int *sign, char *buf)
{
- return (ap_cvt(arg, ndigits, decpt, sign, 0, buf));
+ return (ap_cvt(arg, ndigits, decpt, sign, 0, buf));
}
/*
- * ap_gcvt - Floating output conversion to
- * minimal length string
- */
+** ap_gcvt - Floating output conversion to
+** minimal length string
+*/
-static char *ap_gcvt(double number, int ndigit, char *buf, boolean_e altform)
+static char *
+ap_gcvt(double number, int ndigit, char *buf, boolean_e altform)
{
- int sign, decpt;
- register char *p1, *p2;
- register int i;
- char buf1[NDIG];
-
- p1 = ap_ecvt(number, ndigit, &decpt, &sign, buf1);
- p2 = buf;
- if (sign)
- *p2++ = '-';
- for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
- ndigit--;
- if ((decpt >= 0 && decpt - ndigit > 4)
- || (decpt < 0 && decpt < -3)) { /* use E-style */
- decpt--;
- *p2++ = *p1++;
- *p2++ = '.';
- for (i = 1; i < ndigit; i++)
- *p2++ = *p1++;
- *p2++ = 'e';
- if (decpt < 0) {
- decpt = -decpt;
- *p2++ = '-';
- }
- else
- *p2++ = '+';
- if (decpt / 100 > 0)
- *p2++ = decpt / 100 + '0';
- if (decpt / 10 > 0)
- *p2++ = (decpt % 100) / 10 + '0';
- *p2++ = decpt % 10 + '0';
- }
- else {
- if (decpt <= 0) {
- if (*p1 != '0')
- *p2++ = '.';
- while (decpt < 0) {
- decpt++;
- *p2++ = '0';
- }
- }
- for (i = 1; i <= ndigit; i++) {
- *p2++ = *p1++;
- if (i == decpt)
+ int sign, decpt;
+ register char *p1, *p2;
+ register int i;
+ char buf1[NDIG];
+
+ p1 = ap_ecvt(number, ndigit, &decpt, &sign, buf1);
+ p2 = buf;
+ if (sign)
+ *p2++ = '-';
+ for (i = ndigit - 1; i > 0 && p1[i] == '0'; i--)
+ ndigit--;
+ if ((decpt >= 0 && decpt - ndigit > 4)
+ || (decpt < 0 && decpt < -3)) { /* use E-style */
+ decpt--;
+ *p2++ = *p1++;
*p2++ = '.';
+ for (i = 1; i < ndigit; i++)
+ *p2++ = *p1++;
+ *p2++ = 'e';
+ if (decpt < 0) {
+ decpt = -decpt;
+ *p2++ = '-';
+ } else
+ *p2++ = '+';
+ if (decpt / 100 > 0)
+ *p2++ = decpt / 100 + '0';
+ if (decpt / 10 > 0)
+ *p2++ = (decpt % 100) / 10 + '0';
+ *p2++ = decpt % 10 + '0';
+ } else {
+ if (decpt <= 0) {
+ if (*p1 != '0')
+ *p2++ = '.';
+ while (decpt < 0) {
+ decpt++;
+ *p2++ = '0';
+ }
+ }
+ for (i = 1; i <= ndigit; i++) {
+ *p2++ = *p1++;
+ if (i == decpt)
+ *p2++ = '.';
+ }
+ if (ndigit < decpt) {
+ while (ndigit++ < decpt)
+ *p2++ = '0';
+ *p2++ = '.';
+ }
}
- if (ndigit < decpt) {
- while (ndigit++ < decpt)
- *p2++ = '0';
- *p2++ = '.';
- }
- }
- if (p2[-1] == '.' && !altform)
- p2--;
- *p2 = '\0';
- return (buf);
+ if (p2[-1] == '.' && !altform)
+ p2--;
+ *p2 = '\0';
+ return (buf);
}
/*
- * The INS_CHAR macro inserts a character in the buffer and writes
- * the buffer back to disk if necessary
- * It uses the char pointers sp and bep:
- * sp points to the next available character in the buffer
- * bep points to the end-of-buffer+1
- * While using this macro, note that the nextb pointer is NOT updated.
- *
- * NOTE: Evaluation of the c argument should not have any side-effects
- */
-#define INS_CHAR(c, sp, bep, cc) \
- { \
- if (sp >= bep) { \
- vbuff->curpos = sp; \
- if (flush_func(vbuff)) \
- return -1; \
- sp = vbuff->curpos; \
- bep = vbuff->endpos; \
- } \
- *sp++ = (c); \
- cc++; \
- }
-
-#define NUM( c ) ( c - '0' )
-
-#define STR_TO_DEC( str, num ) \
- num = NUM( *str++ ) ; \
- while ( ap_isdigit( *str ) ) \
- { \
- num *= 10 ; \
- num += NUM( *str++ ) ; \
- }
+** The INS_CHAR macro inserts a character in the buffer and writes
+** the buffer back to disk if necessary
+** It uses the char pointers sp and bep:
+** sp points to the next available character in the buffer
+** bep points to the end-of-buffer+1
+** While using this macro, note that the nextb pointer is NOT updated.
+**
+** NOTE: Evaluation of the c argument should not have any side-effects
+*/
+#define INS_CHAR(c, sp, bep, cc) \
+ { \
+ if (sp >= bep) { \
+ vbuff->curpos = sp; \
+ if (flush_func(vbuff)) \
+ return -1; \
+ sp = vbuff->curpos; \
+ bep = vbuff->endpos; \
+ } \
+ *sp++ = (c); \
+ cc++; \
+ }
-/*
- * This macro does zero padding so that the precision
- * requirement is satisfied. The padding is done by
- * adding '0's to the left of the string that is going
- * to be printed.
- */
-#define FIX_PRECISION( adjust, precision, s, s_len ) \
- if ( adjust ) \
- while ( s_len < precision ) \
- { \
- *--s = '0' ; \
- s_len++ ; \
+#define NUM( c ) ( c - '0' )
+
+#define STR_TO_DEC( str, num ) \
+ num = NUM( *str++ ) ; \
+ while ( ap_isdigit( *str ) ) \
+ { \
+ num *= 10 ; \
+ num += NUM( *str++ ) ; \
}
/*
- * Macro that does padding. The padding is done by printing
- * the character ch.
- */
-#define PAD( width, len, ch ) do \
- { \
- INS_CHAR( ch, sp, bep, cc ) ; \
- width-- ; \
- } \
+** This macro does zero padding so that the precision
+** requirement is satisfied. The padding is done by
+** adding '0's to the left of the string that is going
+** to be printed.
+*/
+#define FIX_PRECISION( adjust, precision, s, s_len ) \
+ if ( adjust ) \
+ while ( s_len < precision ) \
+ { \
+ *--s = '0' ; \
+ s_len++ ; \
+ }
+
+/*
+** Macro that does padding. The padding is done by printing
+** the character ch.
+*/
+#define PAD( width, len, ch ) do \
+ { \
+ INS_CHAR( ch, sp, bep, cc ) ; \
+ width-- ; \
+ } \
while ( width > len )
/*
- * Prefix the character ch to the string str
- * Increase length
- * Set the has_prefix flag
- */
-#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES
+** Prefix the character ch to the string str
+** Increase length
+** Set the has_prefix flag
+*/
+#define PREFIX( str, length, ch ) *--str = ch ; length++ ; has_prefix = YES
/*
- * Convert num to its decimal format.
- * Return value:
- * - a pointer to a string containing the number (no sign)
- * - len contains the length of the string
- * - is_negative is set to TRUE or FALSE depending on the sign
- * of the number (always set to FALSE if is_unsigned is TRUE)
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *conv_10(register wide_int num, register bool_int is_unsigned,
- register bool_int *is_negative, char *buf_end,
- register int *len)
+** Convert num to its decimal format.
+** Return value:
+** - a pointer to a string containing the number (no sign)
+** - len contains the length of the string
+** - is_negative is set to TRUE or FALSE depending on the sign
+** of the number (always set to FALSE if is_unsigned is TRUE)
+**
+** The caller provides a buffer for the string: that is the buf_end argument
+** which is a pointer to the END of the buffer + 1 (i.e. if the buffer
+** is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
+*/
+static char *
+conv_10(register wide_int num, register bool_int is_unsigned,
+ register bool_int *is_negative, char *buf_end,
+ register int *len)
{
- register char *p = buf_end;
- register u_wide_int magnitude;
+ register char *p = buf_end;
+ register u_wide_int magnitude;
+
+ if (is_unsigned) {
+ magnitude = (u_wide_int) num;
+ *is_negative = FALSE;
+ } else {
+ *is_negative = (num < 0);
- if (is_unsigned) {
- magnitude = (u_wide_int) num;
- *is_negative = FALSE;
- }
- else {
- *is_negative = (num < 0);
+ /*
+ ** On a 2's complement machine, negating the most negative
+ ** integer results in a number that cannot be represented
+ ** as a signed integer.
+ ** Here is what we do to obtain the number's magnitude:
+ ** a. add 1 to the number
+ ** b. negate it (becomes positive)
+ ** c. convert it to unsigned
+ ** d. add 1
+ */
+ if (*is_negative) {
+ wide_int t = num + 1;
+
+ magnitude = ((u_wide_int) -t) + 1;
+ } else
+ magnitude = (u_wide_int) num;
+ }
/*
- * On a 2's complement machine, negating the most negative integer
- * results in a number that cannot be represented as a signed integer.
- * Here is what we do to obtain the number's magnitude:
- * a. add 1 to the number
- * b. negate it (becomes positive)
- * c. convert it to unsigned
- * d. add 1
- */
- if (*is_negative) {
- wide_int t = num + 1;
-
- magnitude = ((u_wide_int) -t) + 1;
+ ** We use a do-while loop so that we write at least 1 digit
+ */
+ do {
+ register u_wide_int new_magnitude = magnitude / 10;
+
+ *--p = (char) (magnitude - new_magnitude * 10 + '0');
+ magnitude = new_magnitude;
}
- else
- magnitude = (u_wide_int) num;
- }
-
- /*
- * We use a do-while loop so that we write at least 1 digit
- */
- do {
- register u_wide_int new_magnitude = magnitude / 10;
-
- *--p = (char) (magnitude - new_magnitude * 10 + '0');
- magnitude = new_magnitude;
- }
- while (magnitude);
-
- *len = buf_end - p;
- return (p);
+ while (magnitude);
+
+ *len = buf_end - p;
+ return (p);
}
-static char *conv_in_addr(struct in_addr *ia, char *buf_end, int *len)
+static char *
+conv_in_addr(struct in_addr *ia, char *buf_end, int *len)
{
- unsigned addr = ntohl(ia->s_addr);
- char *p = buf_end;
- bool_int is_negative;
- int sub_len;
-
- p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len);
- *--p = '.';
- p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len);
- *--p = '.';
- p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len);
- *--p = '.';
- p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len);
-
- *len = buf_end - p;
- return (p);
+ unsigned addr = ntohl(ia->s_addr);
+ char *p = buf_end;
+ bool_int is_negative;
+ int sub_len;
+
+ p = conv_10((addr & 0x000000FF) , TRUE, &is_negative, p, &sub_len);
+ *--p = '.';
+ p = conv_10((addr & 0x0000FF00) >> 8, TRUE, &is_negative, p, &sub_len);
+ *--p = '.';
+ p = conv_10((addr & 0x00FF0000) >> 16, TRUE, &is_negative, p, &sub_len);
+ *--p = '.';
+ p = conv_10((addr & 0xFF000000) >> 24, TRUE, &is_negative, p, &sub_len);
+
+ *len = buf_end - p;
+ return (p);
}
-static char *conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, int *len)
+static char *
+conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, int *len)
{
- char *p = buf_end;
- bool_int is_negative;
- int sub_len;
+ char *p = buf_end;
+ bool_int is_negative;
+ int sub_len;
- p = conv_10(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len);
- *--p = ':';
- p = conv_in_addr(&si->sin_addr, p, &sub_len);
+ p = conv_10(ntohs(si->sin_port), TRUE, &is_negative, p, &sub_len);
+ *--p = ':';
+ p = conv_in_addr(&si->sin_addr, p, &sub_len);
- *len = buf_end - p;
- return (p);
+ *len = buf_end - p;
+ return (p);
}
/*
- * Convert a floating point number to a string formats 'f', 'e' or 'E'.
- * The result is placed in buf, and len denotes the length of the string
- * The sign is returned in the is_negative argument (and is not placed
- * in buf).
- */
-static char *conv_fp(register char format, register double num,
- boolean_e add_dp, int precision, bool_int *is_negative,
- char *buf, int *len)
+** Convert a floating point number to a string formats 'f', 'e' or 'E'.
+** The result is placed in buf, and len denotes the length of the string
+** The sign is returned in the is_negative argument (and is not placed
+** in buf).
+*/
+static char *
+conv_fp(register char format, register double num,
+ boolean_e add_dp, int precision, bool_int *is_negative,
+ char *buf, int *len)
{
- register char *s = buf;
- register char *p;
- int decimal_point;
- char buf1[NDIG];
-
- if (format == 'f')
- p = ap_fcvt(num, precision, &decimal_point, is_negative, buf1);
- else /* either e or E format */
- p = ap_ecvt(num, precision + 1, &decimal_point, is_negative, buf1);
-
- /*
- * Check for Infinity and NaN
- */
- if (ap_isalpha(*p)) {
- *len = strlen(strcpy(buf, p));
- *is_negative = FALSE;
- return (buf);
- }
-
- if (format == 'f') {
- if (decimal_point <= 0) {
- *s++ = '0';
- if (precision > 0) {
- *s++ = '.';
- while (decimal_point++ < 0)
- *s++ = '0';
- }
- else if (add_dp)
- *s++ = '.';
+ register char *s = buf;
+ register char *p;
+ int decimal_point;
+ char buf1[NDIG];
+
+ if (format == 'f')
+ p = ap_fcvt(num, precision, &decimal_point, is_negative, buf1);
+ else /* either e or E format */
+ p = ap_ecvt(num, precision + 1, &decimal_point, is_negative, buf1);
+
+ /*
+ ** Check for Infinity and NaN
+ */
+ if (ap_isalpha(*p)) {
+ *len = strlen(strcpy(buf, p));
+ *is_negative = FALSE;
+ return (buf);
}
- else {
- while (decimal_point-- > 0)
+
+ if (format == 'f') {
+ if (decimal_point <= 0) {
+ *s++ = '0';
+ if (precision > 0) {
+ *s++ = '.';
+ while (decimal_point++ < 0)
+ *s++ = '0';
+ } else if (add_dp)
+ *s++ = '.';
+ } else {
+ while (decimal_point-- > 0)
+ *s++ = *p++;
+ if (precision > 0 || add_dp)
+ *s++ = '.';
+ }
+ } else {
*s++ = *p++;
- if (precision > 0 || add_dp)
- *s++ = '.';
+ if (precision > 0 || add_dp)
+ *s++ = '.';
}
- }
- else {
- *s++ = *p++;
- if (precision > 0 || add_dp)
- *s++ = '.';
- }
-
- /*
- * copy the rest of p, the NUL is NOT copied
- */
- while (*p)
- *s++ = *p++;
-
- if (format != 'f') {
- char temp[EXPONENT_LENGTH]; /* for exponent conversion */
- int t_len;
- bool_int exponent_is_negative;
-
- *s++ = format; /* either e or E */
- decimal_point--;
- if (decimal_point != 0) {
- p = conv_10((wide_int) decimal_point, FALSE, &exponent_is_negative,
- &temp[EXPONENT_LENGTH], &t_len);
- *s++ = exponent_is_negative ? '-' : '+';
-
- /*
- * Make sure the exponent has at least 2 digits
- */
- if (t_len == 1)
- *s++ = '0';
- while (t_len--)
+
+ /*
+ ** copy the rest of p, the NUL is NOT copied
+ */
+ while (*p)
*s++ = *p++;
+
+ if (format != 'f') {
+ char temp[EXPONENT_LENGTH]; /* for exponent conversion */
+ int t_len;
+ bool_int exponent_is_negative;
+
+ *s++ = format; /* either e or E */
+ decimal_point--;
+ if (decimal_point != 0) {
+ p = conv_10((wide_int) decimal_point, FALSE,
+ &exponent_is_negative, &temp[EXPONENT_LENGTH],
+ &t_len);
+ *s++ = exponent_is_negative ? '-' : '+';
+
+ /*
+ ** Make sure the exponent has at least 2 digits
+ */
+ if (t_len == 1)
+ *s++ = '0';
+ while (t_len--)
+ *s++ = *p++;
+ } else {
+ *s++ = '+';
+ *s++ = '0';
+ *s++ = '0';
+ }
}
- else {
- *s++ = '+';
- *s++ = '0';
- *s++ = '0';
- }
- }
- *len = s - buf;
- return (buf);
+ *len = s - buf;
+ return (buf);
}
/*
- * Convert num to a base X number where X is a power of 2. nbits determines X.
- * For example, if nbits is 3, we do base 8 conversion
- * Return value:
- * a pointer to a string containing the number
- *
- * The caller provides a buffer for the string: that is the buf_end argument
- * which is a pointer to the END of the buffer + 1 (i.e. if the buffer
- * is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
- */
-static char *conv_p2(register u_wide_int num, register int nbits,
- char format, char *buf_end, register int *len)
+** Convert num to a base X number where X is a power of 2. nbits determines X.
+** For example, if nbits is 3, we do base 8 conversion
+** Return value:
+** a pointer to a string containing the number
+**
+** The caller provides a buffer for the string: that is the buf_end argument
+** which is a pointer to the END of the buffer + 1 (i.e. if the buffer
+** is declared as buf[ 100 ], buf_end should be &buf[ 100 ])
+*/
+static char *
+conv_p2(register u_wide_int num, register int nbits,
+ char format, char *buf_end, register int *len)
{
- register int mask = (1 << nbits) - 1;
- register char *p = buf_end;
- static const char low_digits[] = "0123456789abcdef";
- static const char upper_digits[] = "0123456789ABCDEF";
- register const char *digits = (format == 'X') ? upper_digits : low_digits;
-
- do {
- *--p = digits[num & mask];
- num >>= nbits;
- }
- while (num);
-
- *len = buf_end - p;
- return (p);
+ register int mask = (1 << nbits) - 1;
+ register char *p = buf_end;
+ static const char low_digits[] = "0123456789abcdef";
+ static const char upper_digits[] = "0123456789ABCDEF";
+ register const char *digits = (format == 'X') ? upper_digits : low_digits;
+
+ do {
+ *--p = digits[num & mask];
+ num >>= nbits;
+ }
+ while (num);
+
+ *len = buf_end - p;
+ return (p);
}
/*
- * Do format conversion placing the output in buffer
- */
-int ap_vformatter(int (*flush_func)(ap_vformatter_buff *),
- ap_vformatter_buff *vbuff, const char *fmt, va_list ap)
+** Do format conversion placing the output in buffer
+*/
+static int
+ap_vformatter(int (*flush_func)(ap_vformatter_buff *),
+ ap_vformatter_buff *vbuff, const char *fmt, va_list ap)
{
- register char *sp;
- register char *bep;
- register int cc = 0;
- register int i;
-
- register char *s = NULL;
- char *q;
- int s_len;
-
- register int min_width = 0;
- int precision = 0;
- enum {
- LEFT, RIGHT
- } adjust;
- char pad_char;
- char prefix_char;
-
- double fp_num;
- wide_int i_num = (wide_int) 0;
- u_wide_int ui_num;
-
- char num_buf[NUM_BUF_SIZE];
- char char_buf[2]; /* for printing %% and % */
-
- /*
- * Flag variables
- */
- boolean_e is_long;
- boolean_e alternate_form;
- boolean_e print_sign;
- boolean_e print_blank;
- boolean_e adjust_precision;
- boolean_e adjust_width;
- bool_int is_negative;
-
- sp = vbuff->curpos;
- bep = vbuff->endpos;
-
- while (*fmt) {
- if (*fmt != '%') {
- INS_CHAR(*fmt, sp, bep, cc);
- }
- else {
- /*
- * Default variable settings
- */
- adjust = RIGHT;
- alternate_form = print_sign = print_blank = NO;
- pad_char = ' ';
- prefix_char = NUL;
-
- fmt++;
-
- /*
- * Try to avoid checking for flags, width or precision
- */
- if (!ap_islower(*fmt)) {
- /*
- * Recognize flags: -, #, BLANK, +
- */
- for (;; fmt++) {
- if (*fmt == '-')
- adjust = LEFT;
- else if (*fmt == '+')
- print_sign = YES;
- else if (*fmt == '#')
- alternate_form = YES;
- else if (*fmt == ' ')
- print_blank = YES;
- else if (*fmt == '0')
- pad_char = '0';
- else
- break;
- }
+ register char *sp;
+ register char *bep;
+ register int cc = 0;
+ register int i;
+
+ register char *s = NULL;
+ char *q;
+ int s_len;
+
+ register int min_width = 0;
+ int precision = 0;
+ enum {
+ LEFT, RIGHT
+ } adjust;
+ char pad_char;
+ char prefix_char;
+
+ double fp_num;
+ wide_int i_num = (wide_int) 0;
+ u_wide_int ui_num;
+
+ char num_buf[NUM_BUF_SIZE];
+ char char_buf[2]; /* for printing %% and % */
- /*
- * Check if a width was specified
- */
- if (ap_isdigit(*fmt)) {
- STR_TO_DEC(fmt, min_width);
- adjust_width = YES;
- }
- else if (*fmt == '*') {
- min_width = va_arg(ap, int);
- fmt++;
- adjust_width = YES;
- if (min_width < 0) {
- adjust = LEFT;
- min_width = -min_width;
- }
- }
- else
- adjust_width = NO;
+ /*
+ ** Flag variables
+ */
+ boolean_e is_long;
+ boolean_e alternate_form;
+ boolean_e print_sign;
+ boolean_e print_blank;
+ boolean_e adjust_precision;
+ boolean_e adjust_width;
+ bool_int is_negative;
+
+ sp = vbuff->curpos;
+ bep = vbuff->endpos;
+
+ while (*fmt) {
+ if (*fmt != '%') {
+ INS_CHAR(*fmt, sp, bep, cc);
+ } else {
+ /*
+ ** Default variable settings
+ */
+ adjust = RIGHT;
+ alternate_form = print_sign = print_blank = NO;
+ pad_char = ' ';
+ prefix_char = NUL;
- /*
- * Check if a precision was specified
- *
- * XXX: an unreasonable amount of precision may be specified
- * resulting in overflow of num_buf. Currently we
- * ignore this possibility.
- */
- if (*fmt == '.') {
- adjust_precision = YES;
- fmt++;
- if (ap_isdigit(*fmt)) {
- STR_TO_DEC(fmt, precision);
- }
- else if (*fmt == '*') {
- precision = va_arg(ap, int);
fmt++;
- if (precision < 0)
- precision = 0;
- }
- else
- precision = 0;
- }
- else
- adjust_precision = NO;
- }
- else
- adjust_precision = adjust_width = NO;
-
- /*
- * Modifier check
- */
- if (*fmt == 'l') {
- is_long = YES;
- fmt++;
- }
- else {
- if (*fmt == 'h') /* "short" backward compatibility */
- ++fmt;
- is_long = NO;
- }
-
- /*
- * Argument extraction and printing.
- * First we determine the argument type.
- * Then, we convert the argument to a string.
- * On exit from the switch, s points to the string that
- * must be printed, s_len has the length of the string
- * The precision requirements, if any, are reflected in s_len.
- *
- * NOTE: pad_char may be set to '0' because of the 0 flag.
- * It is reset to ' ' by non-numeric formats
- */
- switch (*fmt) {
- case 'u':
- if (is_long)
- i_num = va_arg(ap, u_wide_int);
- else
- i_num = (wide_int) va_arg(ap, unsigned int);
- s = conv_10(i_num, 1, &is_negative,
- &num_buf[NUM_BUF_SIZE], &s_len);
- FIX_PRECISION(adjust_precision, precision, s, s_len);
- break;
-
- case 'd':
- case 'i':
- if (is_long)
- i_num = va_arg(ap, wide_int);
- else
- i_num = (wide_int) va_arg(ap, int);
- s = conv_10(i_num, 0, &is_negative,
- &num_buf[NUM_BUF_SIZE], &s_len);
- FIX_PRECISION(adjust_precision, precision, s, s_len);
-
- if (is_negative)
- prefix_char = '-';
- else if (print_sign)
- prefix_char = '+';
- else if (print_blank)
- prefix_char = ' ';
- break;
-
-
- case 'o':
- if (is_long)
- ui_num = va_arg(ap, u_wide_int);
- else
- ui_num = (u_wide_int) va_arg(ap, unsigned int);
- s = conv_p2(ui_num, 3, *fmt,
- &num_buf[NUM_BUF_SIZE], &s_len);
- FIX_PRECISION(adjust_precision, precision, s, s_len);
- if (alternate_form && *s != '0') {
- *--s = '0';
- s_len++;
- }
- break;
-
-
- case 'x':
- case 'X':
- if (is_long)
- ui_num = (u_wide_int) va_arg(ap, u_wide_int);
- else
- ui_num = (u_wide_int) va_arg(ap, unsigned int);
- s = conv_p2(ui_num, 4, *fmt,
- &num_buf[NUM_BUF_SIZE], &s_len);
- FIX_PRECISION(adjust_precision, precision, s, s_len);
- if (alternate_form && i_num != 0) {
- *--s = *fmt; /* 'x' or 'X' */
- *--s = '0';
- s_len += 2;
- }
- break;
-
- case 's':
- s = va_arg(ap, char *);
- if (s != NULL) {
- s_len = strlen(s);
- if (adjust_precision && precision < s_len)
- s_len = precision;
- }
- else {
- s = S_NULL;
- s_len = S_NULL_LEN;
- }
- pad_char = ' ';
- break;
-
-
- case 'f':
- case 'e':
- case 'E':
- fp_num = va_arg(ap, double);
- /*
- * * We use &num_buf[ 1 ], so that we have room for the sign
- */
- s = conv_fp(*fmt, fp_num, alternate_form,
- (adjust_precision == NO) ? FLOAT_DIGITS : precision,
- &is_negative, &num_buf[1], &s_len);
- if (is_negative)
- prefix_char = '-';
- else if (print_sign)
- prefix_char = '+';
- else if (print_blank)
- prefix_char = ' ';
- break;
-
-
- case 'g':
- case 'G':
- if (adjust_precision == NO)
- precision = FLOAT_DIGITS;
- else if (precision == 0)
- precision = 1;
- /*
- * * We use &num_buf[ 1 ], so that we have room for the sign
- */
- s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1],
- alternate_form);
- if (*s == '-')
- prefix_char = *s++;
- else if (print_sign)
- prefix_char = '+';
- else if (print_blank)
- prefix_char = ' ';
-
- s_len = strlen(s);
-
- if (alternate_form && (q = strchr(s, '.')) == NULL) {
- s[s_len++] = '.';
- s[s_len] = '\0'; /* delimit for following strchr() */
- }
- if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
- *q = 'E';
- break;
-
-
- case 'c':
- char_buf[0] = (char) (va_arg(ap, int));
- s = &char_buf[0];
- s_len = 1;
- pad_char = ' ';
- break;
-
-
- case '%':
- char_buf[0] = '%';
- s = &char_buf[0];
- s_len = 1;
- pad_char = ' ';
- break;
-
-
- case 'n':
- *(va_arg(ap, int *)) = cc;
- break;
-
- /*
- * This is where we extend the printf format, with a second
- * type specifier
- */
- case 'p':
- switch(*++fmt) {
- /*
- * If the pointer size is equal to the size of an unsigned
- * integer we convert the pointer to a hex number, otherwise
- * we print "%p" to indicate that we don't handle "%p".
- */
- case 'p':
- ui_num = (u_wide_int) va_arg(ap, void *);
-
- if (sizeof(char *) <= sizeof(u_wide_int))
- s = conv_p2(ui_num, 4, 'x',
- &num_buf[NUM_BUF_SIZE], &s_len);
- else {
- s = "%p";
- s_len = 2;
- prefix_char = NUL;
- }
- pad_char = ' ';
- break;
-
- /* print a struct sockaddr_in as a.b.c.d:port */
- case 'I':
- {
- struct sockaddr_in *si;
-
- si = va_arg(ap, struct sockaddr_in *);
- if (si != NULL) {
- s = conv_sockaddr_in(si, &num_buf[NUM_BUF_SIZE], &s_len);
- if (adjust_precision && precision < s_len)
- s_len = precision;
- }
- else {
- s = S_NULL;
- s_len = S_NULL_LEN;
+ /*
+ ** Try to avoid checking for flags, width or precision
+ */
+ if (!ap_islower(*fmt)) {
+ /*
+ ** Recognize flags: -, #, BLANK, +
+ */
+ for (;; fmt++) {
+ if (*fmt == '-')
+ adjust = LEFT;
+ else if (*fmt == '+')
+ print_sign = YES;
+ else if (*fmt == '#')
+ alternate_form = YES;
+ else if (*fmt == ' ')
+ print_blank = YES;
+ else if (*fmt == '0')
+ pad_char = '0';
+ else
+ break;
+ }
+
+ /*
+ ** Check if a width was specified
+ */
+ if (ap_isdigit(*fmt)) {
+ STR_TO_DEC(fmt, min_width);
+ adjust_width = YES;
+ } else if (*fmt == '*') {
+ min_width = va_arg(ap, int);
+ fmt++;
+ adjust_width = YES;
+ if (min_width < 0) {
+ adjust = LEFT;
+ min_width = -min_width;
+ }
+ } else
+ adjust_width = NO;
+
+ /*
+ ** Check if a precision was specified
+ **
+ ** XXX: an unreasonable amount of precision
+ ** may be specified resulting in overflow of
+ ** num_buf. Currently we ignore this
+ ** possibility.
+ */
+ if (*fmt == '.') {
+ adjust_precision = YES;
+ fmt++;
+ if (ap_isdigit(*fmt)) {
+ STR_TO_DEC(fmt, precision);
+ } else if (*fmt == '*') {
+ precision = va_arg(ap, int);
+ fmt++;
+ if (precision < 0)
+ precision = 0;
+ } else
+ precision = 0;
+ } else
+ adjust_precision = NO;
+ } else
+ adjust_precision = adjust_width = NO;
+
+ /*
+ ** Modifier check
+ */
+ if (*fmt == 'l') {
+ is_long = YES;
+ fmt++;
+ } else {
+ if (*fmt == 'h') /* "short" backward compatibility */
+ ++fmt;
+ is_long = NO;
}
- pad_char = ' ';
- }
- break;
-
- /* print a struct in_addr as a.b.c.d */
- case 'A':
- {
- struct in_addr *ia;
-
- ia = va_arg(ap, struct in_addr *);
- if (ia != NULL) {
- s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len);
- if (adjust_precision && precision < s_len)
- s_len = precision;
+
+ /*
+ ** Argument extraction and printing.
+ ** First we determine the argument type.
+ ** Then, we convert the argument to a string.
+ ** On exit from the switch, s points to the string that
+ ** must be printed, s_len has the length of the string
+ ** The precision requirements, if any, are reflected
+ ** in s_len.
+ **
+ ** NOTE: pad_char may be set to '0' because of the
+ ** 0 flag.
+ ** It is reset to ' ' by non-numeric formats
+ */
+ switch (*fmt) {
+ case 'u':
+ if (is_long)
+ i_num = va_arg(ap, u_wide_int);
+ else
+ i_num = (wide_int) va_arg(ap, unsigned int);
+ s = conv_10(i_num, 1, &is_negative,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ break;
+
+ case 'd':
+ case 'i':
+ if (is_long)
+ i_num = va_arg(ap, wide_int);
+ else
+ i_num = (wide_int) va_arg(ap, int);
+ s = conv_10(i_num, 0, &is_negative,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+
+ if (is_negative)
+ prefix_char = '-';
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
+ break;
+
+
+ case 'o':
+ if (is_long)
+ ui_num = va_arg(ap, u_wide_int);
+ else
+ ui_num = (u_wide_int) va_arg(ap, unsigned int);
+ s = conv_p2(ui_num, 3, *fmt,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ if (alternate_form && *s != '0') {
+ *--s = '0';
+ s_len++;
+ }
+ break;
+
+
+ case 'x':
+ case 'X':
+ if (is_long)
+ ui_num = (u_wide_int) va_arg(ap, u_wide_int);
+ else
+ ui_num = (u_wide_int) va_arg(ap, unsigned int);
+ s = conv_p2(ui_num, 4, *fmt,
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ FIX_PRECISION(adjust_precision, precision, s, s_len);
+ if (alternate_form && i_num != 0) {
+ *--s = *fmt; /* 'x' or 'X' */
+ *--s = '0';
+ s_len += 2;
+ }
+ break;
+
+
+ case 's':
+ s = va_arg(ap, char *);
+ if (s != NULL) {
+ s_len = strlen(s);
+ if (adjust_precision && precision < s_len)
+ s_len = precision;
+ }
+ else {
+ s = S_NULL;
+ s_len = S_NULL_LEN;
+ }
+ pad_char = ' ';
+ break;
+
+
+ case 'f':
+ case 'e':
+ case 'E':
+ fp_num = va_arg(ap, double);
+ /*
+ ** We use &num_buf[ 1 ], so that we have
+ ** room for the sign
+ */
+ s = conv_fp(*fmt, fp_num, alternate_form,
+ (adjust_precision == NO) ? FLOAT_DIGITS : precision,
+ &is_negative, &num_buf[1], &s_len);
+ if (is_negative)
+ prefix_char = '-';
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
+ break;
+
+
+ case 'g':
+ case 'G':
+ if (adjust_precision == NO)
+ precision = FLOAT_DIGITS;
+ else if (precision == 0)
+ precision = 1;
+ /*
+ ** We use &num_buf[ 1 ], so that we have
+ ** room for the sign
+ */
+ s = ap_gcvt(va_arg(ap, double), precision, &num_buf[1],
+ alternate_form);
+ if (*s == '-')
+ prefix_char = *s++;
+ else if (print_sign)
+ prefix_char = '+';
+ else if (print_blank)
+ prefix_char = ' ';
+
+ s_len = strlen(s);
+
+ if (alternate_form && (q = strchr(s, '.')) == NULL) {
+ s[s_len++] = '.';
+ s[s_len] = '\0'; /* delimit for following strchr() */
+ }
+ if (*fmt == 'G' && (q = strchr(s, 'e')) != NULL)
+ *q = 'E';
+ break;
+
+
+ case 'c':
+ char_buf[0] = (char) (va_arg(ap, int));
+ s = &char_buf[0];
+ s_len = 1;
+ pad_char = ' ';
+ break;
+
+
+ case '%':
+ char_buf[0] = '%';
+ s = &char_buf[0];
+ s_len = 1;
+ pad_char = ' ';
+ break;
+
+
+ case 'n':
+ *(va_arg(ap, int *)) = cc;
+ break;
+
+ /*
+ ** This is where we extend the printf format,
+ ** with a second type specifier
+ */
+ case 'p':
+ switch(*++fmt) {
+ /*
+ ** If the pointer size is equal to
+ ** the size of an unsigned integer
+ ** we convert the pointer to a hex
+ ** number, otherwise we print "%p"
+ ** to indicate that we don't handle
+ ** "%p".
+ */
+ case 'p':
+ ui_num = (u_wide_int) va_arg(ap, void *);
+
+ if (sizeof(char *) <= sizeof(u_wide_int))
+ s = conv_p2(ui_num, 4, 'x',
+ &num_buf[NUM_BUF_SIZE], &s_len);
+ else {
+ s = "%p";
+ s_len = 2;
+ prefix_char = NUL;
+ }
+ pad_char = ' ';
+ break;
+
+ /*
+ ** print a struct sockaddr_in as
+ ** a.b.c.d:port
+ */
+ case 'I':
+ {
+ struct sockaddr_in *si;
+
+ si = va_arg(ap, struct sockaddr_in *);
+ if (si != NULL) {
+ s = conv_sockaddr_in(si, &num_buf[NUM_BUF_SIZE], &s_len);
+ if (adjust_precision && precision < s_len)
+ s_len = precision;
+ } else {
+ s = S_NULL;
+ s_len = S_NULL_LEN;
+ }
+ pad_char = ' ';
+ }
+ break;
+
+ /* print a struct in_addr as a.b.c.d */
+ case 'A':
+ {
+ struct in_addr *ia;
+
+ ia = va_arg(ap, struct in_addr *);
+ if (ia != NULL) {
+ s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len);
+ if (adjust_precision && precision < s_len)
+ s_len = precision;
+ } else {
+ s = S_NULL;
+ s_len = S_NULL_LEN;
+ }
+ pad_char = ' ';
+ }
+ break;
+
+ case NUL:
+ /* if %p ends the string, oh well ignore it */
+ continue;
+
+ default:
+ s = "bogus %p";
+ s_len = 8;
+ prefix_char = NUL;
+ break;
+ }
+ break;
+
+ case NUL:
+ /*
+ ** The last character of the format string
+ ** was %. We ignore it.
+ */
+ continue;
+
+
+ /*
+ ** The default case is for unrecognized %'s.
+ ** We print % to help the user identify
+ ** what option is not understood. This is
+ ** also useful in case the user wants to
+ ** pass the output of format_converter
+ ** to another function that understands
+ ** some other % (like syslog).
+ ** Note that we can't point s inside fmt
+ ** because the unknown could be
+ ** preceded by width etc.
+ */
+ default:
+ char_buf[0] = '%';
+ char_buf[1] = *fmt;
+ s = char_buf;
+ s_len = 2;
+ pad_char = ' ';
+ break;
}
- else {
- s = S_NULL;
- s_len = S_NULL_LEN;
+
+ if (prefix_char != NUL && s != S_NULL && s != char_buf) {
+ *--s = prefix_char;
+ s_len++;
}
- pad_char = ' ';
- }
- break;
-
- case NUL:
- /* if %p ends the string, oh well ignore it */
- continue;
-
- default:
- s = "bogus %p";
- s_len = 8;
- prefix_char = NUL;
- break;
- }
- break;
- case NUL:
- /*
- * The last character of the format string was %.
- * We ignore it.
- */
- continue;
+ if (adjust_width && adjust == RIGHT && min_width > s_len) {
+ if (pad_char == '0' && prefix_char != NUL) {
+ INS_CHAR(*s, sp, bep, cc);
+ s++;
+ s_len--;
+ min_width--;
+ }
+ PAD(min_width, s_len, pad_char);
+ }
+ /*
+ ** Print the string s.
+ */
+ for (i = s_len; i != 0; i--) {
+ INS_CHAR(*s, sp, bep, cc);
+ s++;
+ }
- /*
- * The default case is for unrecognized %'s.
- * We print % to help the user identify what
- * option is not understood.
- * This is also useful in case the user wants to pass
- * the output of format_converter to another function
- * that understands some other % (like syslog).
- * Note that we can't point s inside fmt because the
- * unknown could be preceded by width etc.
- */
- default:
- char_buf[0] = '%';
- char_buf[1] = *fmt;
- s = char_buf;
- s_len = 2;
- pad_char = ' ';
- break;
- }
-
- if (prefix_char != NUL && s != S_NULL && s != char_buf) {
- *--s = prefix_char;
- s_len++;
- }
-
- if (adjust_width && adjust == RIGHT && min_width > s_len) {
- if (pad_char == '0' && prefix_char != NUL) {
- INS_CHAR(*s, sp, bep, cc);
- s++;
- s_len--;
- min_width--;
+ if (adjust_width && adjust == LEFT && min_width > s_len)
+ PAD(min_width, s_len, pad_char);
}
- PAD(min_width, s_len, pad_char);
- }
-
- /*
- * Print the string s.
- */
- for (i = s_len; i != 0; i--) {
- INS_CHAR(*s, sp, bep, cc);
- s++;
- }
-
- if (adjust_width && adjust == LEFT && min_width > s_len)
- PAD(min_width, s_len, pad_char);
+ fmt++;
}
- fmt++;
- }
- vbuff->curpos = sp;
- return cc;
+ vbuff->curpos = sp;
+ return cc;
}
-static int snprintf_flush(ap_vformatter_buff *vbuff)
+static int
+snprintf_flush(ap_vformatter_buff *vbuff)
{
- /* if the buffer fills we have to abort immediately, there is no way
- * to "flush" a snprintf... there's nowhere to flush it to.
- */
- return -1;
+ /*
+ ** if the buffer fills we have to abort immediately, there is no way
+ ** to "flush" a snprintf... there's nowhere to flush it to.
+ */
+ return -1;
}
-int snprintf(char *buf, size_t len, const char *format,...)
+int
+snprintf(char *buf, size_t len, const char *format,...)
{
- int cc;
- va_list ap;
- ap_vformatter_buff vbuff;
-
- if (len == 0)
- return 0;
-
- /* save one byte for nul terminator */
- vbuff.curpos = buf;
- vbuff.endpos = buf + len - 1;
- va_start(ap, format);
- cc = ap_vformatter(snprintf_flush, &vbuff, format, ap);
- va_end(ap);
- *vbuff.curpos = '\0';
- return (cc == -1) ? len : cc;
+ int cc;
+ va_list ap;
+ ap_vformatter_buff vbuff;
+
+ if (len == 0)
+ return 0;
+
+ /* save one byte for nul terminator */
+ vbuff.curpos = buf;
+ vbuff.endpos = buf + len - 1;
+ va_start(ap, format);
+ cc = ap_vformatter(snprintf_flush, &vbuff, format, ap);
+ va_end(ap);
+ *vbuff.curpos = '\0';
+ return (cc == -1) ? len : cc;
}
-int vsnprintf(char *buf, size_t len, const char *format, va_list ap)
+int
+vsnprintf(char *buf, size_t len, const char *format, va_list ap)
{
- int cc;
- ap_vformatter_buff vbuff;
-
- if (len == 0)
- return 0;
-
- /* save one byte for nul terminator */
- vbuff.curpos = buf;
- vbuff.endpos = buf + len - 1;
- cc = ap_vformatter(snprintf_flush, &vbuff, format, ap);
- *vbuff.curpos = '\0';
- return (cc == -1) ? len : cc;
+ int cc;
+ ap_vformatter_buff vbuff;
+
+ if (len == 0)
+ return 0;
+
+ /* save one byte for nul terminator */
+ vbuff.curpos = buf;
+ vbuff.endpos = buf + len - 1;
+ cc = ap_vformatter(snprintf_flush, &vbuff, format, ap);
+ *vbuff.curpos = '\0';
+ return (cc == -1) ? len : cc;
}