summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwchang0222%aol.com <devnull@localhost>2004-04-12 23:59:24 +0000
committerwchang0222%aol.com <devnull@localhost>2004-04-12 23:59:24 +0000
commit29db57ee264c9ed5fa184961d30721928495407f (patch)
tree8193f67b16de5e1fa00cd0af27bdcc5a8de9b06a
parent2d8416ab6610034cf6de845a88e6f485bc783185 (diff)
downloadnspr-hg-29db57ee264c9ed5fa184961d30721928495407f.tar.gz
Bugzilla bug 238842: avoid the copying of va_list (the VARARGS_ASSIGN
macro) because it is not portable. r=jgmyers. sr=darin. Tag: NSPRPUB_PRE_4_2_CLIENT_BRANCH
-rw-r--r--pr/src/io/prprf.c117
1 files changed, 64 insertions, 53 deletions
diff --git a/pr/src/io/prprf.c b/pr/src/io/prprf.c
index 5f4de6f4..00440cf9 100644
--- a/pr/src/io/prprf.c
+++ b/pr/src/io/prprf.c
@@ -1,4 +1,4 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
@@ -48,23 +48,6 @@
#include "prmem.h"
/*
-** Note: on some platforms va_list is defined as an array,
-** and requires array notation.
-*/
-#if (defined(LINUX) && defined(__x86_64__))
-#define VARARGS_ASSIGN(foo, bar) __va_copy((foo), (bar))
-#elif (defined(LINUX) && defined(__powerpc__)) || \
- (defined(LINUX) && defined(__s390__)) || \
- (defined(LINUX) && defined(__s390x__)) || \
- defined(WIN16) || defined(QNX) || \
- (defined(__NetBSD__) && defined(__powerpc__) && \
- __NetBSD_Version__ < 105000000)
-#define VARARGS_ASSIGN(foo, bar) foo[0] = bar[0]
-#else
-#define VARARGS_ASSIGN(foo, bar) (foo) = (bar)
-#endif
-
-/*
** WARNING: This code may *NOT* call PR_LOG (because PR_LOG calls it)
*/
@@ -86,14 +69,24 @@ struct SprintfStateStr {
};
/*
-** Numbered Arguement State
+** Numbered Argument
*/
-struct NumArgState{
- int type; /* type of the current ap */
- va_list ap; /* point to the corresponding position on ap */
+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;
+ } u;
};
-#define NAS_DEFAULT_NUM 20 /* default number of NumberedArgumentState array */
+#define NAS_DEFAULT_NUM 20 /* default number of NumberedArgument array */
#define TYPE_INT16 0
@@ -404,12 +397,12 @@ static int cvt_s(SprintfState *ss, const char *s, int width, int prec,
** the number must start from 1, and no gap among them
*/
-static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArgState* nasArray )
+static struct NumArg* BuildArgArray( const char *fmt, va_list ap, int* rv, struct NumArg* nasArray )
{
int number = 0, cn = 0, i;
const char* p;
char c;
- struct NumArgState* nas;
+ struct NumArg* nas;
/*
@@ -428,7 +421,7 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv,
while( c != 0 ){
if( c > '9' || c < '0' ){
- if( c == '$' ){ /* numbered argument csae */
+ if( c == '$' ){ /* numbered argument case */
if( i > 0 ){
*rv = -1;
return NULL;
@@ -454,7 +447,7 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv,
if( number > NAS_DEFAULT_NUM ){
- nas = (struct NumArgState*)PR_MALLOC( number * sizeof( struct NumArgState ) );
+ nas = (struct NumArg*)PR_MALLOC( number * sizeof( struct NumArg ) );
if( !nas ){
*rv = -1;
return NULL;
@@ -619,27 +612,44 @@ static struct NumArgState* BuildArgArray( const char *fmt, va_list ap, int* rv,
continue;
}
- VARARGS_ASSIGN(nas[cn].ap, ap);
-
switch( nas[cn].type ){
case TYPE_INT16:
case TYPE_UINT16:
case TYPE_INTN:
- case TYPE_UINTN: (void)va_arg( ap, PRIntn ); break;
+ nas[cn].u.i = va_arg( ap, int );
+ break;
- case TYPE_INT32: (void)va_arg( ap, PRInt32 ); break;
+ case TYPE_UINTN:
+ nas[cn].u.ui = va_arg( ap, unsigned int );
+ break;
- case TYPE_UINT32: (void)va_arg( ap, PRUint32 ); 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: (void)va_arg( ap, PRInt64 ); break;
+ case TYPE_INT64:
+ nas[cn].u.ll = va_arg( ap, PRInt64 );
+ break;
- case TYPE_UINT64: (void)va_arg( ap, PRUint64 ); break;
+ case TYPE_UINT64:
+ nas[cn].u.ull = va_arg( ap, PRUint64 );
+ break;
- case TYPE_STRING: (void)va_arg( ap, char* ); break;
+ case TYPE_STRING:
+ nas[cn].u.s = va_arg( ap, char* );
+ break;
- case TYPE_INTSTR: (void)va_arg( ap, PRIntn* ); break;
+ case TYPE_INTSTR:
+ nas[cn].u.ip = va_arg( ap, int* );
+ break;
- case TYPE_DOUBLE: (void)va_arg( ap, double ); break;
+ case TYPE_DOUBLE:
+ nas[cn].u.d = va_arg( ap, double );
+ break;
default:
if( nas != nasArray )
@@ -676,10 +686,11 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
static char *HEX = "0123456789ABCDEF";
char *hexp;
int rv, i;
- struct NumArgState* nas = NULL;
- struct NumArgState nasArray[ NAS_DEFAULT_NUM ];
+ struct NumArg* nas = NULL;
+ struct NumArg* nap;
+ struct NumArg nasArray[ NAS_DEFAULT_NUM ];
char pattern[20];
- const char* dolPt = NULL; /* in "%4$.2f", dolPt will poiont to . */
+ const char* dolPt = NULL; /* in "%4$.2f", dolPt will point to . */
/*
@@ -733,7 +744,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
return -1;
}
- ap = nas[i-1].ap;
+ nap = &nas[i-1];
dolPt = fmt;
c = *fmt++;
}
@@ -832,35 +843,35 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
fetch_and_convert:
switch (type) {
case TYPE_INT16:
- u.l = va_arg(ap, int);
+ 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 = va_arg(ap, int) & 0xffff;
+ u.l = (nas ? nap->u.i : va_arg(ap, int)) & 0xffff;
goto do_long;
case TYPE_INTN:
- u.l = va_arg(ap, int);
+ 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)va_arg(ap, unsigned int);
+ u.l = (long)(nas ? nap->u.ui : va_arg(ap, unsigned int));
goto do_long;
case TYPE_INT32:
- u.l = va_arg(ap, PRInt32);
+ 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)va_arg(ap, PRUint32);
+ 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) {
@@ -869,14 +880,14 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
break;
case TYPE_INT64:
- u.ll = va_arg(ap, PRInt64);
+ 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 = va_arg(ap, PRUint64);
+ 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) {
@@ -890,7 +901,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
case 'E':
case 'f':
case 'g':
- u.d = va_arg(ap, double);
+ u.d = nas ? nap->u.d : va_arg(ap, double);
if( nas != NULL ){
i = fmt - dolPt;
if( i < sizeof( pattern ) ){
@@ -907,7 +918,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
break;
case 'c':
- u.ch = va_arg(ap, int);
+ u.ch = nas ? nap->u.i : va_arg(ap, int);
if ((flags & FLAG_LEFT) == 0) {
while (width-- > 1) {
rv = (*ss->stuff)(ss, " ", 1);
@@ -955,7 +966,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
#endif
case 's':
- u.s = va_arg(ap, const char*);
+ 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;
@@ -963,7 +974,7 @@ static int dosprintf(SprintfState *ss, const char *fmt, va_list ap)
break;
case 'n':
- u.ip = va_arg(ap, int*);
+ u.ip = nas ? nap->u.ip : va_arg(ap, int*);
if (u.ip) {
*u.ip = ss->cur - ss->base;
}