⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 prprf.c

📁 Netscape NSPR库源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	if( nas[ cn ].type == TYPE_UNKNOWN ){	    if( l10n_debug )		printf( "unknown type \"%s\"\n", fmt );	    *rv = -1;	    break;	}    }    /*    ** third pass    ** fill the nas[cn].ap    */    if( *rv < 0 ){	if( nas != nasArray )	    PR_DELETE( nas );	return NULL;    }    cn = 0;    while( cn < number ){	if( nas[cn].type == TYPE_UNKNOWN ){	    cn++;	    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;	case TYPE_INT32:		(void)va_arg( ap, PRInt32 );		break;	case TYPE_UINT32:	(void)va_arg( ap, PRUint32 );	break;	case TYPE_INT64:	(void)va_arg( ap, PRInt64 );		break;	case TYPE_UINT64:	(void)va_arg( ap, PRUint64 );		break;	case TYPE_STRING:	(void)va_arg( ap, char* );		break;	case TYPE_INTSTR:	(void)va_arg( ap, PRIntn* );		break;	case TYPE_DOUBLE:	(void)va_arg( ap, double );		break;	default:	    if( nas != nasArray )		PR_DELETE( nas );	    *rv = -1;	    return NULL;	}	cn++;    }    return nas;}/*** The workhorse sprintf code.*/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;    } u;    const char *fmt0;    static char *hex = "0123456789abcdef";    static char *HEX = "0123456789ABCDEF";    char *hexp;    int rv, i;    struct NumArgState* nas = NULL;    struct NumArgState  nasArray[ NAS_DEFAULT_NUM ];    char  pattern[20];    const char* dolPt = NULL;  /* in "%4$.2f", dolPt will poiont to . */    /*    ** build an argument array, IF the fmt is numbered argument    ** list style, to contain the Numbered Argument list pointers    */    nas = BuildArgArray( fmt, ap, &rv, nasArray );    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 imporve error check later */		i = ( i * 10 ) + ( c - '0' );		c = *fmt++;	    }	    if( nas[i-1].type == TYPE_UNKNOWN ){		if( l10n_debug )		    printf( "numbered argument type unknown\n" );		if( nas && ( nas != nasArray ) )		    PR_DELETE( nas );		return -1;	    }	    ap = nas[i-1].ap;	    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 |= _LEFT;	    if (c == '+') flags |= _SIGNED;	    if (c == ' ') flags |= _SPACED;	    if (c == '0') flags |= _ZEROS;	    c = *fmt++;	}	if (flags & _SIGNED) flags &= ~_SPACED;	if (flags & _LEFT) flags &= ~_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++;	    }	}	/* 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 = va_arg(ap, int);		if (u.l < 0) {		    u.l = -u.l;		    flags |= _NEG;		}		goto do_long;	      case TYPE_UINT16:		u.l = va_arg(ap, int) & 0xffff;		goto do_long;	      case TYPE_INTN:		u.l = va_arg(ap, int);		if (u.l < 0) {		    u.l = -u.l;		    flags |= _NEG;		}		goto do_long;	      case TYPE_UINTN:		u.l = (long)va_arg(ap, unsigned int);		goto do_long;	      case TYPE_INT32:		u.l = va_arg(ap, PRInt32);		if (u.l < 0) {		    u.l = -u.l;		    flags |= _NEG;		}		goto do_long;	      case TYPE_UINT32:		u.l = (long)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 = va_arg(ap, PRInt64);		if (!LL_GE_ZERO(u.ll)) {		    LL_NEG(u.ll, u.ll);		    flags |= _NEG;		}		goto do_longlong;	      case TYPE_UINT64:		u.ll = 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 = 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 = va_arg(ap, int);            if ((flags & _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 & _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;#if 0	  case 'C':	  case 'S':	  case 'E':	  case 'G':	    /* XXX not supported I suppose */	    PR_ASSERT(0);	    break;#endif	  case 's':	    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 = 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);#endif	    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 );    }    return rv;}/************************************************************************/static int FuncStuff(SprintfState *ss, const char *sp, PRUint32 len){    int rv;    rv = (*ss->func)(ss->arg, sp, len);    if (rv < 0) {	return rv;    }    ss->maxlen += len;    return 0;}PR_IMPLEMENT(PRUint32) PR_sxprintf(PRStuffFunc func, void *arg,                                  const char *fmt, ...){    va_list ap;    int rv;    va_start(ap, fmt);    rv = PR_vsxprintf(func, arg, fmt, ap);    va_end(ap);    return rv;}PR_IMPLEMENT(PRUint32) PR_vsxprintf(PRStuffFunc func, void *arg,                                   const char *fmt, va_list ap){    SprintfState ss;    int rv;    ss.stuff = FuncStuff;    ss.func = func;    ss.arg = arg;    ss.maxlen = 0;    rv = dosprintf(&ss, fmt, ap);    return (rv < 0) ? (PRUint32)-1 : ss.maxlen;}/*** Stuff routine that automatically grows the malloc'd output buffer** before it overflows.*/static int GrowStuff(SprintfState *ss, const char *sp, PRUint32 len){    ptrdiff_t off;    char *newbase;    PRUint32 newlen;    off = ss->cur - ss->base;    if (off + len >= ss->maxlen) {	/* Grow the buffer */	newlen = ss->maxlen + ((len > 32) ? len : 32);	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++;    }    PR_ASSERT((PRUint32)(ss->cur - ss->base) <= ss->maxlen);    return 0;}/*** sprintf into a malloc'd buffer*/PR_IMPLEMENT(char *) PR_smprintf(const char *fmt, ...){    va_list ap;    char *rv;    va_start(ap, fmt);    rv = PR_vsmprintf(fmt, ap);    va_end(ap);    return rv;}/*** Free memory allocated, for the caller, by PR_smprintf*/PR_IMPLEMENT(void) PR_smprintf_free(char *mem){	PR_DELETE(mem);}PR_IMPLEMENT(char *) PR_vsmprintf(const char *fmt, va_list ap){    SprintfState ss;    int rv;    ss.stuff = GrowStuff;    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;    }    return ss.base;}/*** Stuff routine that discards overflow data*/static int LimitStuff(SprintfState *ss, const char *sp, PRUint32 len){    PRUint32 limit = ss->maxlen - (ss->cur - ss->base);    if (len > limit) {	len = limit;    }    while (len) {	--len;	*ss->cur++ = *sp++;    }    return 0;}/*** sprintf into a fixed size buffer. Make sure there is a NUL at the end** when finished.*/PR_IMPLEMENT(PRUint32) PR_snprintf(char *out, PRUint32 outlen, const char *fmt, ...){    va_list ap;    int rv;    PR_ASSERT((PRInt32)outlen > 0);    if ((PRInt32)outlen <= 0) {	return 0;    }    va_start(ap, fmt);    rv = PR_vsnprintf(out, outlen, fmt, ap);    va_end(ap);    return rv;}PR_IMPLEMENT(PRUint32) PR_vsnprintf(char *out, PRUint32 outlen,const char *fmt,                                  va_list ap){    SprintfState ss;    PRUint32 n;    PR_ASSERT((PRInt32)outlen > 0);    if ((PRInt32)outlen <= 0) {	return 0;    }    ss.stuff = LimitStuff;    ss.base = out;    ss.cur = out;    ss.maxlen = outlen;    (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') )        *(--ss.cur) = '\0';    n = ss.cur - ss.base;    return n ? n - 1 : n;}PR_IMPLEMENT(char *) PR_sprintf_append(char *last, const char *fmt, ...){    va_list ap;    char *rv;    va_start(ap, fmt);    rv = PR_vsprintf_append(last, fmt, ap);    va_end(ap);    return rv;}PR_IMPLEMENT(char *) PR_vsprintf_append(char *last, const char *fmt, va_list ap){    SprintfState ss;    int rv;    ss.stuff = GrowStuff;    if (last) {	int lastlen = strlen(last);	ss.base = last;	ss.cur = last + lastlen;	ss.maxlen = lastlen;    } else {	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;    }    return ss.base;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -