X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Fsnprintf.c;h=1dd4a65cf8ea7f371de8e70748a85fc3f6353b1f;hp=2b198811aa740030699e1150c78c6cf0767e8fa9;hb=ced6090a330d3d83d0bce709f756aa3d7d65fea4;hpb=337338b404931f06f0db2119c9e145e8ca5a9860 diff --git a/sbr/snprintf.c b/sbr/snprintf.c index 2b19881..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 @@ -104,33 +104,34 @@ typedef int bool_int; #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 - */ +** 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 @@ -154,8 +155,8 @@ ap_cvt(double arg, int ndigits, int *decpt, int *sign, int eflag, char *buf) arg = modf(arg, &fi); p1 = &buf[NDIG]; /* - * Do integer part - */ + ** Do integer part + */ if (fi != 0) { p1 = &buf[NDIG]; while (fi != 0) { @@ -221,9 +222,9 @@ ap_fcvt(double arg, int ndigits, int *decpt, int *sign, char *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) @@ -284,15 +285,15 @@ ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) } /* - * 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 - */ +** 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) { \ @@ -317,11 +318,11 @@ ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) } /* - * 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. - */ +** 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 ) \ @@ -331,9 +332,9 @@ ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) } /* - * Macro that does padding. The padding is done by printing - * the character ch. - */ +** 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 ) ; \ @@ -342,25 +343,25 @@ ap_gcvt(double number, int ndigit, char *buf, boolean_e altform) while ( width > len ) /* - * Prefix the character ch to the string str - * Increase length - * Set the has_prefix flag - */ +** 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 ]) - */ +** 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, @@ -376,14 +377,15 @@ conv_10(register wide_int num, register bool_int is_unsigned, *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 - */ + ** 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; @@ -393,8 +395,8 @@ conv_10(register wide_int num, register bool_int is_unsigned, } /* - * We use a do-while loop so that we write at least 1 digit - */ + ** We use a do-while loop so that we write at least 1 digit + */ do { register u_wide_int new_magnitude = magnitude / 10; @@ -449,11 +451,11 @@ conv_sockaddr_in(struct sockaddr_in *si, char *buf_end, 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). - */ +** 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, @@ -470,8 +472,8 @@ conv_fp(register char format, register double num, p = ap_ecvt(num, precision + 1, &decimal_point, is_negative, buf1); /* - * Check for Infinity and NaN - */ + ** Check for Infinity and NaN + */ if (ap_isalpha(*p)) { *len = strlen(strcpy(buf, p)); *is_negative = FALSE; @@ -500,8 +502,8 @@ conv_fp(register char format, register double num, } /* - * copy the rest of p, the NUL is NOT copied - */ + ** copy the rest of p, the NUL is NOT copied + */ while (*p) *s++ = *p++; @@ -519,8 +521,8 @@ conv_fp(register char format, register double num, *s++ = exponent_is_negative ? '-' : '+'; /* - * Make sure the exponent has at least 2 digits - */ + ** Make sure the exponent has at least 2 digits + */ if (t_len == 1) *s++ = '0'; while (t_len--) @@ -538,15 +540,15 @@ conv_fp(register char format, register double num, /* - * 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 ]) - */ +** 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) @@ -569,8 +571,8 @@ conv_p2(register u_wide_int num, register int nbits, /* - * Do format conversion placing the output in buffer - */ +** 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) @@ -600,8 +602,8 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), char char_buf[2]; /* for printing %% and % */ /* - * Flag variables - */ + ** Flag variables + */ boolean_e is_long; boolean_e alternate_form; boolean_e print_sign; @@ -618,8 +620,8 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), INS_CHAR(*fmt, sp, bep, cc); } else { /* - * Default variable settings - */ + ** Default variable settings + */ adjust = RIGHT; alternate_form = print_sign = print_blank = NO; pad_char = ' '; @@ -628,12 +630,12 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), fmt++; /* - * Try to avoid checking for flags, width or precision - */ + ** Try to avoid checking for flags, width or precision + */ if (!ap_islower(*fmt)) { /* - * Recognize flags: -, #, BLANK, + - */ + ** Recognize flags: -, #, BLANK, + + */ for (;; fmt++) { if (*fmt == '-') adjust = LEFT; @@ -650,8 +652,8 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), } /* - * Check if a width was specified - */ + ** Check if a width was specified + */ if (ap_isdigit(*fmt)) { STR_TO_DEC(fmt, min_width); adjust_width = YES; @@ -667,12 +669,13 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), 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. - */ + ** 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++; @@ -691,8 +694,8 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), adjust_precision = adjust_width = NO; /* - * Modifier check - */ + ** Modifier check + */ if (*fmt == 'l') { is_long = YES; fmt++; @@ -703,16 +706,18 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), } /* - * 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 - */ + ** 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) @@ -795,8 +800,9 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), case 'E': fp_num = va_arg(ap, double); /* - * * We use &num_buf[ 1 ], so that we have room for the sign - */ + ** 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); @@ -816,8 +822,9 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), else if (precision == 0) precision = 1; /* - * * We use &num_buf[ 1 ], so that we have room for the sign - */ + ** 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 == '-') @@ -859,16 +866,19 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), break; /* - * This is where we extend the printf format, with a second - * type specifier - */ + ** 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". - */ + ** 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 *); @@ -883,7 +893,10 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), pad_char = ' '; break; - /* print a struct sockaddr_in as a.b.c.d:port */ + /* + ** print a struct sockaddr_in as + ** a.b.c.d:port + */ case 'I': { struct sockaddr_in *si; @@ -893,8 +906,7 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), s = conv_sockaddr_in(si, &num_buf[NUM_BUF_SIZE], &s_len); if (adjust_precision && precision < s_len) s_len = precision; - } - else { + } else { s = S_NULL; s_len = S_NULL_LEN; } @@ -912,8 +924,7 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), s = conv_in_addr(ia, &num_buf[NUM_BUF_SIZE], &s_len); if (adjust_precision && precision < s_len) s_len = precision; - } - else { + } else { s = S_NULL; s_len = S_NULL_LEN; } @@ -935,22 +946,24 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), case NUL: /* - * The last character of the format string was %. - * We ignore it. - */ + ** 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. - */ + ** 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; @@ -976,8 +989,8 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), } /* - * Print the string s. - */ + ** Print the string s. + */ for (i = s_len; i != 0; i--) { INS_CHAR(*s, sp, bep, cc); s++; @@ -996,9 +1009,10 @@ ap_vformatter(int (*flush_func)(ap_vformatter_buff *), 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. - */ + /* + ** 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; }