diff options
Diffstat (limited to 'nsprpub/pr/src/io/prprf.c')
-rw-r--r-- | nsprpub/pr/src/io/prprf.c | 1486 |
1 files changed, 756 insertions, 730 deletions
diff --git a/nsprpub/pr/src/io/prprf.c b/nsprpub/pr/src/io/prprf.c index 8475c7713..9b6072e26 100644 --- a/nsprpub/pr/src/io/prprf.c +++ b/nsprpub/pr/src/io/prprf.c @@ -49,17 +49,17 @@ struct SprintfStateStr { struct NumArg { int type; /* type of the numbered argument */ union { /* the numbered argument */ - int i; - unsigned int ui; - PRInt32 i32; - PRUint32 ui32; - PRInt64 ll; - PRUint64 ull; - double d; - const char *s; - int *ip; + int i; + unsigned int ui; + PRInt32 i32; + PRUint32 ui32; + PRInt64 ll; + PRUint64 ull; + double d; + const char *s; + int *ip; #ifdef WIN32 - const WCHAR *ws; + const WCHAR *ws; #endif } u; }; @@ -71,63 +71,63 @@ struct NumArg { ** and their corresponding unsigned versions must have the subsequent ** odd value. */ -#define TYPE_INT16 0 -#define TYPE_UINT16 1 -#define TYPE_INTN 2 -#define TYPE_UINTN 3 -#define TYPE_INT32 4 -#define TYPE_UINT32 5 -#define TYPE_INT64 6 -#define TYPE_UINT64 7 -#define TYPE_STRING 8 -#define TYPE_DOUBLE 9 -#define TYPE_INTSTR 10 +#define TYPE_INT16 0 +#define TYPE_UINT16 1 +#define TYPE_INTN 2 +#define TYPE_UINTN 3 +#define TYPE_INT32 4 +#define TYPE_UINT32 5 +#define TYPE_INT64 6 +#define TYPE_UINT64 7 +#define TYPE_STRING 8 +#define TYPE_DOUBLE 9 +#define TYPE_INTSTR 10 #ifdef WIN32 -#define TYPE_WSTRING 11 +#define TYPE_WSTRING 11 #endif -#define TYPE_UNKNOWN 20 +#define TYPE_UNKNOWN 20 -#define FLAG_LEFT 0x1 -#define FLAG_SIGNED 0x2 -#define FLAG_SPACED 0x4 -#define FLAG_ZEROS 0x8 -#define FLAG_NEG 0x10 +#define FLAG_LEFT 0x1 +#define FLAG_SIGNED 0x2 +#define FLAG_SPACED 0x4 +#define FLAG_ZEROS 0x8 +#define FLAG_NEG 0x10 /* ** Fill into the buffer using the data in src */ static int fill2(SprintfState *ss, const char *src, int srclen, int width, - int flags) + int flags) { char space = ' '; int rv; width -= srclen; - if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */ - if (flags & FLAG_ZEROS) { - space = '0'; - } - while (--width >= 0) { - rv = (*ss->stuff)(ss, &space, 1); - if (rv < 0) { - return rv; - } - } + if ((width > 0) && ((flags & FLAG_LEFT) == 0)) { /* Right adjusting */ + if (flags & FLAG_ZEROS) { + space = '0'; + } + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } } /* Copy out the source data */ rv = (*ss->stuff)(ss, src, srclen); if (rv < 0) { - return rv; + return rv; } - if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */ - while (--width >= 0) { - rv = (*ss->stuff)(ss, &space, 1); - if (rv < 0) { - return rv; - } - } + if ((width > 0) && ((flags & FLAG_LEFT) != 0)) { /* Left adjusting */ + while (--width >= 0) { + rv = (*ss->stuff)(ss, &space, 1); + if (rv < 0) { + return rv; + } + } } return 0; } @@ -136,7 +136,7 @@ static int fill2(SprintfState *ss, const char *src, int srclen, int width, ** Fill a number. The order is: optional-sign zero-filling conversion-digits */ static int fill_n(SprintfState *ss, const char *src, int srclen, int width, - int prec, int type, int flags) + int prec, int type, int flags) { int zerowidth = 0; int precwidth = 0; @@ -148,77 +148,77 @@ static int fill_n(SprintfState *ss, const char *src, int srclen, int width, char sign; if ((type & 1) == 0) { - if (flags & FLAG_NEG) { - sign = '-'; - signwidth = 1; - } else if (flags & FLAG_SIGNED) { - sign = '+'; - signwidth = 1; - } else if (flags & FLAG_SPACED) { - sign = ' '; - signwidth = 1; - } + if (flags & FLAG_NEG) { + sign = '-'; + signwidth = 1; + } else if (flags & FLAG_SIGNED) { + sign = '+'; + signwidth = 1; + } else if (flags & FLAG_SPACED) { + sign = ' '; + signwidth = 1; + } } cvtwidth = signwidth + srclen; if (prec > 0) { - if (prec > srclen) { - precwidth = prec - srclen; /* Need zero filling */ - cvtwidth += precwidth; - } + if (prec > srclen) { + precwidth = prec - srclen; /* Need zero filling */ + cvtwidth += precwidth; + } } if ((flags & FLAG_ZEROS) && (prec < 0)) { - if (width > cvtwidth) { - zerowidth = width - cvtwidth; /* Zero filling */ - cvtwidth += zerowidth; - } + if (width > cvtwidth) { + zerowidth = width - cvtwidth; /* Zero filling */ + cvtwidth += zerowidth; + } } if (flags & FLAG_LEFT) { - if (width > cvtwidth) { - /* Space filling on the right (i.e. left adjusting) */ - rightspaces = width - cvtwidth; - } + if (width > cvtwidth) { + /* Space filling on the right (i.e. left adjusting) */ + rightspaces = width - cvtwidth; + } } else { - if (width > cvtwidth) { - /* Space filling on the left (i.e. right adjusting) */ - leftspaces = width - cvtwidth; - } + if (width > cvtwidth) { + /* Space filling on the left (i.e. right adjusting) */ + leftspaces = width - cvtwidth; + } } while (--leftspaces >= 0) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } } if (signwidth) { - rv = (*ss->stuff)(ss, &sign, 1); - if (rv < 0) { - return rv; - } + rv = (*ss->stuff)(ss, &sign, 1); + if (rv < 0) { + return rv; + } } while (--precwidth >= 0) { - rv = (*ss->stuff)(ss, "0", 1); - if (rv < 0) { - return rv; - } + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } } while (--zerowidth >= 0) { - rv = (*ss->stuff)(ss, "0", 1); - if (rv < 0) { - return rv; - } + rv = (*ss->stuff)(ss, "0", 1); + if (rv < 0) { + return rv; + } } rv = (*ss->stuff)(ss, src, srclen); if (rv < 0) { - return rv; + return rv; } while (--rightspaces >= 0) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } } return 0; } @@ -227,7 +227,7 @@ static int fill_n(SprintfState *ss, const char *src, int srclen, int width, ** Convert a long into its printable form */ static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, - int type, int flags, const char *hexp) + int type, int flags, const char *hexp) { char cvtbuf[100]; char *cvt; @@ -235,7 +235,7 @@ static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, /* according to the man page this needs to happen */ if ((prec == 0) && (num == 0)) { - return 0; + return 0; } /* @@ -246,14 +246,14 @@ static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, cvt = cvtbuf + sizeof(cvtbuf); digits = 0; while (num) { - int digit = (((unsigned long)num) % radix) & 0xF; - *--cvt = hexp[digit]; - digits++; - num = (long)(((unsigned long)num) / radix); + int digit = (((unsigned long)num) % radix) & 0xF; + *--cvt = hexp[digit]; + digits++; + num = (long)(((unsigned long)num) / radix); } if (digits == 0) { - *--cvt = '0'; - digits++; + *--cvt = '0'; + digits++; } /* @@ -267,7 +267,7 @@ static int cvt_l(SprintfState *ss, long num, int width, int prec, int radix, ** Convert a 64-bit integer into its printable form */ static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix, - int type, int flags, const char *hexp) + int type, int flags, const char *hexp) { char cvtbuf[100]; char *cvt; @@ -276,7 +276,7 @@ static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix, /* according to the man page this needs to happen */ if ((prec == 0) && (LL_IS_ZERO(num))) { - return 0; + return 0; } /* @@ -288,17 +288,17 @@ static int cvt_ll(SprintfState *ss, PRInt64 num, int width, int prec, int radix, cvt = cvtbuf + sizeof(cvtbuf); digits = 0; while (!LL_IS_ZERO(num)) { - PRInt32 digit; - PRInt64 quot, rem; - LL_UDIVMOD(", &rem, num, rad); - LL_L2I(digit, rem); - *--cvt = hexp[digit & 0xf]; - digits++; - num = quot; + PRInt32 digit; + PRInt64 quot, rem; + LL_UDIVMOD(", &rem, num, rad); + LL_L2I(digit, rem); + *--cvt = hexp[digit & 0xf]; + digits++; + num = quot; } if (digits == 0) { - *--cvt = '0'; - digits++; + *--cvt = '0'; + digits++; } /* @@ -321,8 +321,8 @@ static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) int amount = fmt1 - fmt0; if (amount <= 0 || amount >= sizeof(fin)) { - /* Totally bogus % command to snprintf. Just ignore it */ - return 0; + /* Totally bogus % command to snprintf. Just ignore it */ + return 0; } memcpy(fin, fmt0, amount); fin[amount] = 0; @@ -352,26 +352,27 @@ static int cvt_f(SprintfState *ss, double d, const char *fmt0, const char *fmt1) ** where -1 means until NUL. */ static int cvt_s(SprintfState *ss, const char *str, int width, int prec, - int flags) + int flags) { int slen; - if (prec == 0) - return 0; + if (prec == 0) { + return 0; + } /* Limit string length by precision value */ if (!str) { - str = "(null)"; - } + str = "(null)"; + } if (prec > 0) { - /* this is: slen = strnlen(str, prec); */ - register const char *s; + /* this is: slen = strnlen(str, prec); */ + register const char *s; - for(s = str; prec && *s; s++, prec-- ) - ; - slen = s - str; + for(s = str; prec && *s; s++, prec-- ) + ; + slen = s - str; } else { - slen = strlen(str); + slen = strlen(str); } /* and away we go */ @@ -381,7 +382,7 @@ static int cvt_s(SprintfState *ss, const char *str, int width, int prec, /* ** BuildArgArray stands for Numbered Argument list Sprintf ** for example, -** fmt = "%4$i, %2$d, %3s, %1d"; +** fmt = "%4$i, %2$d, %3s, %1d"; ** the number must start from 1, and no gap among them */ @@ -391,61 +392,63 @@ static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struc const char* p; char c; struct NumArg* nas; - + /* - ** first pass: - ** determine how many legal % I have got, then allocate space + ** first pass: + ** determine how many legal % I have got, then allocate space */ p = fmt; *rv = 0; i = 0; - while( ( c = *p++ ) != 0 ){ - if( c != '%' ) - continue; - if( ( c = *p++ ) == '%' ) /* skip %% case */ - continue; - - while( c != 0 ){ - if( c > '9' || c < '0' ){ - if( c == '$' ){ /* numbered argument case */ - if( i > 0 ){ - *rv = -1; - return NULL; - } - number++; - } else{ /* non-numbered argument case */ - if( number > 0 ){ - *rv = -1; - return NULL; - } - i = 1; - } - break; - } - - c = *p++; - } + while( ( c = *p++ ) != 0 ) { + if( c != '%' ) { + continue; + } + if( ( c = *p++ ) == '%' ) { /* skip %% case */ + continue; + } + + while( c != 0 ) { + if( c > '9' || c < '0' ) { + if( c == '$' ) { /* numbered argument case */ + if( i > 0 ) { + *rv = -1; + return NULL; + } + number++; + } else { /* non-numbered argument case */ + if( number > 0 ) { + *rv = -1; + return NULL; + } + i = 1; + } + break; + } + + c = *p++; + } } - if( number == 0 ){ - return NULL; + if( number == 0 ) { + return NULL; } - - if( number > NAS_DEFAULT_NUM ){ - nas = (struct NumArg*)PR_MALLOC( number * sizeof( struct NumArg ) ); - if( !nas ){ - *rv = -1; - return NULL; - } + + if( number > NAS_DEFAULT_NUM ) { + nas = (struct NumArg*)PR_MALLOC( number * sizeof( struct NumArg ) ); + if( !nas ) { + *rv = -1; + return NULL; + } } else { - nas = nasArray; + nas = nasArray; } - for( i = 0; i < number; i++ ){ - nas[i].type = TYPE_UNKNOWN; + for( i = 0; i < number; i++ ) { + nas[i].type = TYPE_UNKNOWN; } @@ -455,143 +458,148 @@ static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struc */ p = fmt; - while( ( c = *p++ ) != 0 ){ - if( c != '%' ) continue; - c = *p++; - if( c == '%' ) continue; - - cn = 0; - while( c && c != '$' ){ /* should improve error check later */ - cn = cn*10 + c - '0'; - c = *p++; - } - - if( !c || cn < 1 || cn > number ){ - *rv = -1; - break; + while( ( c = *p++ ) != 0 ) { + if( c != '%' ) { + continue; + } + c = *p++; + if( c == '%' ) { + continue; + } + + cn = 0; + while( c && c != '$' ) { /* should improve error check later */ + cn = cn*10 + c - '0'; + c = *p++; + } + + if( !c || cn < 1 || cn > number ) { + *rv = -1; + break; } - /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */ + /* nas[cn] starts from 0, and make sure nas[cn].type is not assigned */ cn--; - if( nas[cn].type != TYPE_UNKNOWN ) - continue; + if( nas[cn].type != TYPE_UNKNOWN ) { + continue; + } c = *p++; /* width */ if (c == '*') { - /* not supported feature, for the argument is not numbered */ - *rv = -1; - break; - } - - while ((c >= '0') && (c <= '9')) { - c = *p++; - } - - /* precision */ - if (c == '.') { - c = *p++; - if (c == '*') { - /* not supported feature, for the argument is not numbered */ - *rv = -1; - break; - } - - while ((c >= '0') && (c <= '9')) { - c = *p++; - } - } - - /* size */ - nas[cn].type = TYPE_INTN; - if (c == 'h') { - nas[cn].type = TYPE_INT16; - c = *p++; - } else if (c == 'L') { - /* XXX not quite sure here */ - nas[cn].type = TYPE_INT64; - c = *p++; - } else if (c == 'l') { - nas[cn].type = TYPE_INT32; - c = *p++; - if (c == 'l') { - nas[cn].type = TYPE_INT64; - c = *p++; - } - } else if (c == 'z') { - if (sizeof(size_t) == sizeof(PRInt32)) { - nas[ cn ].type = TYPE_INT32; - } else if (sizeof(size_t) == sizeof(PRInt64)) { - nas[ cn ].type = TYPE_INT64; - } else { - nas[ cn ].type = TYPE_UNKNOWN; - } - c = *p++; - } - - /* format */ - switch (c) { - case 'd': - case 'c': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': - break; - - case 'e': - case 'f': - case 'g': - nas[ cn ].type = TYPE_DOUBLE; - break; - - case 'p': - /* XXX should use cpp */ - if (sizeof(void *) == sizeof(PRInt32)) { - nas[ cn ].type = TYPE_UINT32; - } else if (sizeof(void *) == sizeof(PRInt64)) { - nas[ cn ].type = TYPE_UINT64; - } else if (sizeof(void *) == sizeof(PRIntn)) { - nas[ cn ].type = TYPE_UINTN; - } else { - nas[ cn ].type = TYPE_UNKNOWN; - } - break; - - case 'S': + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + + /* precision */ + if (c == '.') { + c = *p++; + if (c == '*') { + /* not supported feature, for the argument is not numbered */ + *rv = -1; + break; + } + + while ((c >= '0') && (c <= '9')) { + c = *p++; + } + } + + /* size */ + nas[cn].type = TYPE_INTN; + if (c == 'h') { + nas[cn].type = TYPE_INT16; + c = *p++; + } else if (c == 'L') { + /* XXX not quite sure here */ + nas[cn].type = TYPE_INT64; + c = *p++; + } else if (c == 'l') { + nas[cn].type = TYPE_INT32; + c = *p++; + if (c == 'l') { + nas[cn].type = TYPE_INT64; + c = *p++; + } + } else if (c == 'z') { + if (sizeof(size_t) == sizeof(PRInt32)) { + nas[ cn ].type = TYPE_INT32; + } else if (sizeof(size_t) == sizeof(PRInt64)) { + nas[ cn ].type = TYPE_INT64; + } else { + nas[ cn ].type = TYPE_UNKNOWN; + } + c = *p++; + } + + /* format */ + switch (c) { + case 'd': + case 'c': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': + break; + + case 'e': + case 'f': + case 'g': + nas[ cn ].type = TYPE_DOUBLE; + break; + + case 'p': + /* XXX should use cpp */ + if (sizeof(void *) == sizeof(PRInt32)) { + nas[ cn ].type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(PRInt64)) { + nas[ cn ].type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(PRIntn)) { + nas[ cn ].type = TYPE_UINTN; + } else { + nas[ cn ].type = TYPE_UNKNOWN; + } + break; + + case 'S': #ifdef WIN32 - nas[ cn ].type = TYPE_WSTRING; - break; + nas[ cn ].type = TYPE_WSTRING; + break; #endif - case 'C': - case 'E': - case 'G': - /* XXX not supported I suppose */ - PR_ASSERT(0); - nas[ cn ].type = TYPE_UNKNOWN; - break; - - case 's': - nas[ cn ].type = TYPE_STRING; - break; - - case 'n': - nas[ cn ].type = TYPE_INTSTR; - break; - - default: - PR_ASSERT(0); - nas[ cn ].type = TYPE_UNKNOWN; - break; - } - - /* get a legal para. */ - if( nas[ cn ].type == TYPE_UNKNOWN ){ - *rv = -1; - break; - } + case 'C': + case 'E': + case 'G': + /* XXX not supported I suppose */ + PR_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + + case 's': + nas[ cn ].type = TYPE_STRING; + break; + + case 'n': + nas[ cn ].type = TYPE_INTSTR; + break; + + default: + PR_ASSERT(0); + nas[ cn ].type = TYPE_UNKNOWN; + break; + } + + /* get a legal para. */ + if( nas[ cn ].type == TYPE_UNKNOWN ) { + *rv = -1; + break; + } } @@ -600,72 +608,74 @@ static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struc ** fill the nas[cn].ap */ - if( *rv < 0 ){ - if( nas != nasArray ) - PR_DELETE( nas ); - return NULL; + if( *rv < 0 ) { + if( nas != nasArray ) { + PR_DELETE( nas ); + } + return NULL; } cn = 0; - while( cn < number ){ - if( nas[cn].type == TYPE_UNKNOWN ){ - cn++; - continue; - } - - switch( nas[cn].type ){ - case TYPE_INT16: - case TYPE_UINT16: - case TYPE_INTN: - nas[cn].u.i = va_arg( ap, int ); - break; - - case TYPE_UINTN: - nas[cn].u.ui = va_arg( ap, unsigned int ); - break; - - case TYPE_INT32: - nas[cn].u.i32 = va_arg( ap, PRInt32 ); - break; - - case TYPE_UINT32: - nas[cn].u.ui32 = va_arg( ap, PRUint32 ); - break; - - case TYPE_INT64: - nas[cn].u.ll = va_arg( ap, PRInt64 ); - break; - - case TYPE_UINT64: - nas[cn].u.ull = va_arg( ap, PRUint64 ); - break; - - case TYPE_STRING: - nas[cn].u.s = va_arg( ap, char* ); - break; + while( cn < number ) { + if( nas[cn].type == TYPE_UNKNOWN ) { + cn++; + continue; + } + + switch( nas[cn].type ) { + case TYPE_INT16: + case TYPE_UINT16: + case TYPE_INTN: + nas[cn].u.i = va_arg( ap, int ); + break; + + case TYPE_UINTN: + nas[cn].u.ui = va_arg( ap, unsigned int ); + break; + + case TYPE_INT32: + nas[cn].u.i32 = va_arg( ap, PRInt32 ); + break; + + case TYPE_UINT32: + nas[cn].u.ui32 = va_arg( ap, PRUint32 ); + break; + + case TYPE_INT64: + nas[cn].u.ll = va_arg( ap, PRInt64 ); + break; + + case TYPE_UINT64: + nas[cn].u.ull = va_arg( ap, PRUint64 ); + break; + + case TYPE_STRING: + nas[cn].u.s = va_arg( ap, char* ); + break; #ifdef WIN32 - case TYPE_WSTRING: - nas[cn].u.ws = va_arg( ap, WCHAR* ); - break; + case TYPE_WSTRING: + nas[cn].u.ws = va_arg( ap, WCHAR* ); + break; #endif - case TYPE_INTSTR: - nas[cn].u.ip = va_arg( ap, int* ); - break; + case TYPE_INTSTR: + nas[cn].u.ip = va_arg( ap, int* ); + break; - case TYPE_DOUBLE: - nas[cn].u.d = va_arg( ap, double ); - break; + case TYPE_DOUBLE: + nas[cn].u.d = va_arg( ap, double ); + break; - default: - if( nas != nasArray ) - PR_DELETE( nas ); - *rv = -1; - return NULL; - } + default: + if( nas != nasArray ) { + PR_DELETE( nas ); + } + *rv = -1; + return NULL; + } - cn++; + cn++; } @@ -680,15 +690,15 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) char c; int flags, width, prec, radix, type; union { - char ch; - int i; - long l; - PRInt64 ll; - double d; - const char *s; - int *ip; + char ch; + int i; + long l; + PRInt64 ll; + double d; + const char *s; + int *ip; #ifdef WIN32 - const WCHAR *ws; + const WCHAR *ws; #endif } u; const char *fmt0; @@ -711,344 +721,359 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap) */ nas = BuildArgArray( fmt, ap, &rv, nasArray ); - if( rv < 0 ){ - /* the fmt contains error Numbered Argument format, jliu@netscape.com */ - PR_ASSERT(0); - return rv; + if( rv < 0 ) { + /* the fmt contains error Numbered Argument format, jliu@netscape.com */ + PR_ASSERT(0); + return rv; } while ((c = *fmt++) != 0) { - if (c != '%') { - rv = (*ss->stuff)(ss, fmt - 1, 1); - if (rv < 0) { - return rv; - } - continue; - } - fmt0 = fmt - 1; - - /* - ** Gobble up the % format string. Hopefully we have handled all - ** of the strange cases! - */ - flags = 0; - c = *fmt++; - if (c == '%') { - /* quoting a % with %% */ - rv = (*ss->stuff)(ss, fmt - 1, 1); - if (rv < 0) { - return rv; - } - continue; - } - - if( nas != NULL ){ - /* the fmt contains the Numbered Arguments feature */ - i = 0; - while( c && c != '$' ){ /* should improve error check later */ - i = ( i * 10 ) + ( c - '0' ); - c = *fmt++; - } - - if( nas[i-1].type == TYPE_UNKNOWN ){ - if( nas && ( nas != nasArray ) ) - PR_DELETE( nas ); - return -1; - } - - nap = &nas[i-1]; - dolPt = fmt; - c = *fmt++; - } - - /* - * Examine optional flags. Note that we do not implement the - * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is - * somewhat ambiguous and not ideal, which is perhaps why - * the various sprintf() implementations are inconsistent - * on this feature. - */ - while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { - if (c == '-') flags |= FLAG_LEFT; - if (c == '+') flags |= FLAG_SIGNED; - if (c == ' ') flags |= FLAG_SPACED; - if (c == '0') flags |= FLAG_ZEROS; - c = *fmt++; - } - if (flags & FLAG_SIGNED) flags &= ~FLAG_SPACED; - if (flags & FLAG_LEFT) flags &= ~FLAG_ZEROS; - - /* width */ - if (c == '*') { - c = *fmt++; - width = va_arg(ap, int); - } else { - width = 0; - while ((c >= '0') && (c <= '9')) { - width = (width * 10) + (c - '0'); - c = *fmt++; - } - } - - /* precision */ - prec = -1; - if (c == '.') { - c = *fmt++; - if (c == '*') { - c = *fmt++; - prec = va_arg(ap, int); - } else { - prec = 0; - while ((c >= '0') && (c <= '9')) { - prec = (prec * 10) + (c - '0'); - c = *fmt++; - } - } - } - - /* size */ - type = TYPE_INTN; - if (c == 'h') { - type = TYPE_INT16; - c = *fmt++; - } else if (c == 'L') { - /* XXX not quite sure here */ - type = TYPE_INT64; - c = *fmt++; - } else if (c == 'l') { - type = TYPE_INT32; - c = *fmt++; - if (c == 'l') { - type = TYPE_INT64; - c = *fmt++; - } - } else if (c == 'z') { - if (sizeof(size_t) == sizeof(PRInt32)) { - type = TYPE_INT32; - } else if (sizeof(size_t) == sizeof(PRInt64)) { - type = TYPE_INT64; - } - c = *fmt++; - } - - /* format */ - hexp = hex; - switch (c) { - case 'd': case 'i': /* decimal/integer */ - radix = 10; - goto fetch_and_convert; - - case 'o': /* octal */ - radix = 8; - type |= 1; - goto fetch_and_convert; - - case 'u': /* unsigned decimal */ - radix = 10; - type |= 1; - goto fetch_and_convert; - - case 'x': /* unsigned hex */ - radix = 16; - type |= 1; - goto fetch_and_convert; - - case 'X': /* unsigned HEX */ - radix = 16; - hexp = HEX; - type |= 1; - goto fetch_and_convert; - - fetch_and_convert: - switch (type) { - case TYPE_INT16: - u.l = nas ? nap->u.i : va_arg(ap, int); - if (u.l < 0) { - u.l = -u.l; - flags |= FLAG_NEG; - } - goto do_long; - case TYPE_UINT16: - u.l = (nas ? nap->u.i : va_arg(ap, int)) & 0xffff; - goto do_long; - case TYPE_INTN: - u.l = nas ? nap->u.i : va_arg(ap, int); - if (u.l < 0) { - u.l = -u.l; - flags |= FLAG_NEG; - } - goto do_long; - case TYPE_UINTN: - u.l = (long)(nas ? nap->u.ui : va_arg(ap, unsigned int)); - goto do_long; - - case TYPE_INT32: - u.l = nas ? nap->u.i32 : va_arg(ap, PRInt32); - if (u.l < 0) { - u.l = -u.l; - flags |= FLAG_NEG; - } - goto do_long; - case TYPE_UINT32: - u.l = (long)(nas ? nap->u.ui32 : va_arg(ap, PRUint32)); - do_long: - rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp); - if (rv < 0) { - return rv; - } - break; - - case TYPE_INT64: - u.ll = nas ? nap->u.ll : va_arg(ap, PRInt64); - if (!LL_GE_ZERO(u.ll)) { - LL_NEG(u.ll, u.ll); - flags |= FLAG_NEG; - } - goto do_longlong; - case TYPE_UINT64: - u.ll = nas ? nap->u.ull : va_arg(ap, PRUint64); - do_longlong: - rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp); - if (rv < 0) { - return rv; - } - break; - } - break; - - case 'e': - case 'E': - case 'f': - case 'g': - u.d = nas ? nap->u.d : va_arg(ap, double); - if( nas != NULL ){ - i = fmt - dolPt; - if( i < sizeof( pattern ) ){ - pattern[0] = '%'; - memcpy( &pattern[1], dolPt, i ); - rv = cvt_f(ss, u.d, pattern, &pattern[i+1] ); - } - } else - rv = cvt_f(ss, u.d, fmt0, fmt); - - if (rv < 0) { - return rv; - } - break; - - case 'c': - u.ch = nas ? nap->u.i : va_arg(ap, int); - if ((flags & FLAG_LEFT) == 0) { - while (width-- > 1) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } + if (c != '%') { + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + fmt0 = fmt - 1; + + /* + ** Gobble up the % format string. Hopefully we have handled all + ** of the strange cases! + */ + flags = 0; + c = *fmt++; + if (c == '%') { + /* quoting a % with %% */ + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + continue; + } + + if( nas != NULL ) { + /* the fmt contains the Numbered Arguments feature */ + i = 0; + while( c && c != '$' ) { /* should improve error check later */ + i = ( i * 10 ) + ( c - '0' ); + c = *fmt++; + } + + if( nas[i-1].type == TYPE_UNKNOWN ) { + if( nas && ( nas != nasArray ) ) { + PR_DELETE( nas ); } + return -1; } - rv = (*ss->stuff)(ss, &u.ch, 1); - if (rv < 0) { - return rv; - } - if (flags & FLAG_LEFT) { - while (width-- > 1) { - rv = (*ss->stuff)(ss, " ", 1); - if (rv < 0) { - return rv; - } + + nap = &nas[i-1]; + dolPt = fmt; + c = *fmt++; + } + + /* + * Examine optional flags. Note that we do not implement the + * '#' flag of sprintf(). The ANSI C spec. of the '#' flag is + * somewhat ambiguous and not ideal, which is perhaps why + * the various sprintf() implementations are inconsistent + * on this feature. + */ + while ((c == '-') || (c == '+') || (c == ' ') || (c == '0')) { + if (c == '-') { + flags |= FLAG_LEFT; + } + if (c == '+') { + flags |= FLAG_SIGNED; + } + if (c == ' ') { + flags |= FLAG_SPACED; + } + if (c == '0') { + flags |= FLAG_ZEROS; + } + c = *fmt++; + } + if (flags & FLAG_SIGNED) { + flags &= ~FLAG_SPACED; + } + if (flags & FLAG_LEFT) { + flags &= ~FLAG_ZEROS; + } + + /* width */ + if (c == '*') { + c = *fmt++; + width = va_arg(ap, int); + } else { + width = 0; + while ((c >= '0') && (c <= '9')) { + width = (width * 10) + (c - '0'); + c = *fmt++; + } + } + + /* precision */ + prec = -1; + if (c == '.') { + c = *fmt++; + if (c == '*') { + c = *fmt++; + prec = va_arg(ap, int); + } else { + prec = 0; + while ((c >= '0') && (c <= '9')) { + prec = (prec * 10) + (c - '0'); + c = *fmt++; } } - break; - - case 'p': - if (sizeof(void *) == sizeof(PRInt32)) { - type = TYPE_UINT32; - } else if (sizeof(void *) == sizeof(PRInt64)) { - type = TYPE_UINT64; - } else if (sizeof(void *) == sizeof(int)) { - type = TYPE_UINTN; - } else { - PR_ASSERT(0); - break; - } - radix = 16; - goto fetch_and_convert; + } + + /* size */ + type = TYPE_INTN; + if (c == 'h') { + type = TYPE_INT16; + c = *fmt++; + } else if (c == 'L') { + /* XXX not quite sure here */ + type = TYPE_INT64; + c = *fmt++; + } else if (c == 'l') { + type = TYPE_INT32; + c = *fmt++; + if (c == 'l') { + type = TYPE_INT64; + c = *fmt++; + } + } else if (c == 'z') { + if (sizeof(size_t) == sizeof(PRInt32)) { + type = TYPE_INT32; + } else if (sizeof(size_t) == sizeof(PRInt64)) { + type = TYPE_INT64; + } + c = *fmt++; + } + + /* format */ + hexp = hex; + switch (c) { + case 'd': case 'i': /* decimal/integer */ + radix = 10; + goto fetch_and_convert; + + case 'o': /* octal */ + radix = 8; + type |= 1; + goto fetch_and_convert; + + case 'u': /* unsigned decimal */ + radix = 10; + type |= 1; + goto fetch_and_convert; + + case 'x': /* unsigned hex */ + radix = 16; + type |= 1; + goto fetch_and_convert; + + case 'X': /* unsigned HEX */ + radix = 16; + hexp = HEX; + type |= 1; + goto fetch_and_convert; + +fetch_and_convert: + switch (type) { + case TYPE_INT16: + u.l = nas ? nap->u.i : va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT16: + u.l = (nas ? nap->u.i : va_arg(ap, int)) & 0xffff; + goto do_long; + case TYPE_INTN: + u.l = nas ? nap->u.i : va_arg(ap, int); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINTN: + u.l = (long)(nas ? nap->u.ui : va_arg(ap, unsigned int)); + goto do_long; + + case TYPE_INT32: + u.l = nas ? nap->u.i32 : va_arg(ap, PRInt32); + if (u.l < 0) { + u.l = -u.l; + flags |= FLAG_NEG; + } + goto do_long; + case TYPE_UINT32: + u.l = (long)(nas ? nap->u.ui32 : va_arg(ap, PRUint32)); +do_long: + rv = cvt_l(ss, u.l, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + + case TYPE_INT64: + u.ll = nas ? nap->u.ll : va_arg(ap, PRInt64); + if (!LL_GE_ZERO(u.ll)) { + LL_NEG(u.ll, u.ll); + flags |= FLAG_NEG; + } + goto do_longlong; + case TYPE_UINT64: + u.ll = nas ? nap->u.ull : va_arg(ap, PRUint64); +do_longlong: + rv = cvt_ll(ss, u.ll, width, prec, radix, type, flags, hexp); + if (rv < 0) { + return rv; + } + break; + } + break; + + case 'e': + case 'E': + case 'f': + case 'g': + u.d = nas ? nap->u.d : va_arg(ap, double); + if( nas != NULL ) { + i = fmt - dolPt; + if( i < sizeof( pattern ) ) { + pattern[0] = '%'; + memcpy( &pattern[1], dolPt, i ); + rv = cvt_f(ss, u.d, pattern, &pattern[i+1] ); + } + } else { + rv = cvt_f(ss, u.d, fmt0, fmt); + } + + if (rv < 0) { + return rv; + } + break; + + case 'c': + u.ch = nas ? nap->u.i : va_arg(ap, int); + if ((flags & FLAG_LEFT) == 0) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + rv = (*ss->stuff)(ss, &u.ch, 1); + if (rv < 0) { + return rv; + } + if (flags & FLAG_LEFT) { + while (width-- > 1) { + rv = (*ss->stuff)(ss, " ", 1); + if (rv < 0) { + return rv; + } + } + } + break; + + case 'p': + if (sizeof(void *) == sizeof(PRInt32)) { + type = TYPE_UINT32; + } else if (sizeof(void *) == sizeof(PRInt64)) { + type = TYPE_UINT64; + } else if (sizeof(void *) == sizeof(int)) { + type = TYPE_UINTN; + } else { + PR_ASSERT(0); + break; + } + radix = 16; + goto fetch_and_convert; #ifndef WIN32 - case 'S': - /* XXX not supported I suppose */ - PR_ASSERT(0); - break; + case 'S': + /* XXX not supported I suppose */ + PR_ASSERT(0); + break; #endif #if 0 - case 'C': - case 'E': - case 'G': - /* XXX not supported I suppose */ - PR_ASSERT(0); - break; + case 'C': + case 'E': + case 'G': + /* XXX not supported I suppose */ + PR_ASSERT(0); + break; #endif #ifdef WIN32 - case 'S': - u.ws = nas ? nap->u.ws : va_arg(ap, const WCHAR*); - - /* Get the required size in rv */ - rv = WideCharToMultiByte(CP_ACP, 0, u.ws, -1, NULL, 0, NULL, NULL); - if (rv == 0) - rv = 1; - pBuf = PR_MALLOC(rv); - WideCharToMultiByte(CP_ACP, 0, u.ws, -1, pBuf, (int)rv, NULL, NULL); - pBuf[rv-1] = '\0'; - - rv = cvt_s(ss, pBuf, width, prec, flags); - - /* We don't need the allocated buffer anymore */ - PR_Free(pBuf); - if (rv < 0) { - return rv; - } - break; + case 'S': + u.ws = nas ? nap->u.ws : va_arg(ap, const WCHAR*); + + /* Get the required size in rv */ + rv = WideCharToMultiByte(CP_ACP, 0, u.ws, -1, NULL, 0, NULL, NULL); + if (rv == 0) { + rv = 1; + } + pBuf = PR_MALLOC(rv); + WideCharToMultiByte(CP_ACP, 0, u.ws, -1, pBuf, (int)rv, NULL, NULL); + pBuf[rv-1] = '\0'; + + rv = cvt_s(ss, pBuf, width, prec, flags); + + /* We don't need the allocated buffer anymore */ + PR_Free(pBuf); + if (rv < 0) { + return rv; + } + break; #endif - case 's': - u.s = nas ? nap->u.s : va_arg(ap, const char*); - rv = cvt_s(ss, u.s, width, prec, flags); - if (rv < 0) { - return rv; - } - break; - - case 'n': - u.ip = nas ? nap->u.ip : va_arg(ap, int*); - if (u.ip) { - *u.ip = ss->cur - ss->base; - } - break; - - default: - /* Not a % token after all... skip it */ + case 's': + u.s = nas ? nap->u.s : va_arg(ap, const char*); + rv = cvt_s(ss, u.s, width, prec, flags); + if (rv < 0) { + return rv; + } + break; + + case 'n': + u.ip = nas ? nap->u.ip : va_arg(ap, int*); + if (u.ip) { + *u.ip = ss->cur - ss->base; + } + break; + + default: + /* Not a % token after all... skip it */ #if 0 - PR_ASSERT(0); + PR_ASSERT(0); #endif - rv = (*ss->stuff)(ss, "%", 1); - if (rv < 0) { - return rv; - } - rv = (*ss->stuff)(ss, fmt - 1, 1); - if (rv < 0) { - return rv; - } - } + rv = (*ss->stuff)(ss, "%", 1); + if (rv < 0) { + return rv; + } + rv = (*ss->stuff)(ss, fmt - 1, 1); + if (rv < 0) { + return rv; + } + } } /* Stuff trailing NUL */ rv = (*ss->stuff)(ss, "\0", 1); - if( nas && ( nas != nasArray ) ){ - PR_DELETE( nas ); + if( nas && ( nas != nasArray ) ) { + PR_DELETE( nas ); } return rv; @@ -1065,18 +1090,18 @@ static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len) ** if ss->maxlen + len would overflow or be greater than PR_INT32_MAX. */ if (PR_UINT32_MAX - ss->maxlen < len || ss->maxlen + len > PR_INT32_MAX) { - return -1; + return -1; } rv = (*ss->func)(ss->arg, sp, len); if (rv < 0) { - return rv; + return rv; } ss->maxlen += len; return 0; } -PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, - const char *fmt, ...) +PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, + const char *fmt, ...) { va_list ap; PRUint32 rv; @@ -1087,8 +1112,8 @@ PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg, return rv; } -PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg, - const char *fmt, va_list ap) +PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg, + const char *fmt, va_list ap) { SprintfState ss; int rv; @@ -1113,38 +1138,38 @@ static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len) off = ss->cur - ss->base; if (PR_UINT32_MAX - len < off) { - /* off + len would be too big. */ - return -1; + /* off + len would be too big. */ + return -1; } if (off + len >= ss->maxlen) { - /* Grow the buffer */ - PRUint32 increment = (len > 32) ? len : 32; - if (PR_UINT32_MAX - ss->maxlen < increment) { - /* ss->maxlen + increment would overflow. */ - return -1; - } - newlen = ss->maxlen + increment; - if (newlen > PR_INT32_MAX) { - return -1; - } - if (ss->base) { - newbase = (char*) PR_REALLOC(ss->base, newlen); - } else { - newbase = (char*) PR_MALLOC(newlen); - } - if (!newbase) { - /* Ran out of memory */ - return -1; - } - ss->base = newbase; - ss->maxlen = newlen; - ss->cur = ss->base + off; + /* Grow the buffer */ + PRUint32 increment = (len > 32) ? len : 32; + if (PR_UINT32_MAX - ss->maxlen < increment) { + /* ss->maxlen + increment would overflow. */ + return -1; + } + newlen = ss->maxlen + increment; + if (newlen > PR_INT32_MAX) { + return -1; + } + if (ss->base) { + newbase = (char*) PR_REALLOC(ss->base, newlen); + } else { + newbase = (char*) PR_MALLOC(newlen); + } + if (!newbase) { + /* Ran out of memory */ + return -1; + } + ss->base = newbase; + ss->maxlen = newlen; + ss->cur = ss->base + off; } /* Copy data */ while (len) { - --len; - *ss->cur++ = *sp++; + --len; + *ss->cur++ = *sp++; } PR_ASSERT((PRUint32)(ss->cur - ss->base) <= ss->maxlen); return 0; @@ -1169,7 +1194,7 @@ PR_IMPLEMENT(char *) PR_smprintf(const char *fmt, ...) */ PR_IMPLEMENT(void) PR_smprintf_free(char *mem) { - PR_DELETE(mem); + PR_DELETE(mem); } PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap) @@ -1183,10 +1208,10 @@ PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap) ss.maxlen = 0; rv = dosprintf(&ss, fmt, ap); if (rv < 0) { - if (ss.base) { - PR_DELETE(ss.base); - } - return 0; + if (ss.base) { + PR_DELETE(ss.base); + } + return 0; } return ss.base; } @@ -1199,11 +1224,11 @@ static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len) PRUint32 limit = ss->maxlen - (ss->cur - ss->base); if (len > limit) { - len = limit; + len = limit; } while (len) { - --len; - *ss->cur++ = *sp++; + --len; + *ss->cur++ = *sp++; } return 0; } @@ -1224,14 +1249,14 @@ PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, } PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, - va_list ap) + va_list ap) { SprintfState ss; PRUint32 n; PR_ASSERT(outlen != 0 && outlen <= PR_INT32_MAX); if (outlen == 0 || outlen > PR_INT32_MAX) { - return 0; + return 0; } ss.stuff = LimitStuff; @@ -1241,8 +1266,9 @@ PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt, (void) dosprintf(&ss, fmt, ap); /* If we added chars, and we didn't append a null, do it now. */ - if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') ) + if( (ss.cur != ss.base) && (*(ss.cur - 1) != '\0') ) { *(ss.cur - 1) = '\0'; + } n = ss.cur - ss.base; return n ? n - 1 : n; @@ -1266,24 +1292,24 @@ PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap) ss.stuff = GrowStuff; if (last) { - size_t lastlen = strlen(last); - if (lastlen > PR_INT32_MAX) { - return 0; - } - ss.base = last; - ss.cur = last + lastlen; - ss.maxlen = lastlen; + size_t lastlen = strlen(last); + if (lastlen > PR_INT32_MAX) { + return 0; + } + ss.base = last; + ss.cur = last + lastlen; + ss.maxlen = lastlen; } else { - ss.base = 0; - ss.cur = 0; - ss.maxlen = 0; + ss.base = 0; + ss.cur = 0; + ss.maxlen = 0; } rv = dosprintf(&ss, fmt, ap); if (rv < 0) { - if (ss.base) { - PR_DELETE(ss.base); - } - return 0; + if (ss.base) { + PR_DELETE(ss.base); + } + return 0; } return ss.base; } |