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

📄 fmt.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * The authors of this software are Rob Pike and Ken Thompson, * with contributions from Mike Burrows and Sean Dorward. * *     Copyright (c) 2002-2006 by Lucent Technologies. *     Portions Copyright (c) 2004 Google Inc. *  * Permission to use, copy, modify, and distribute this software for any * purpose without fee is hereby granted, provided that this entire notice * is included in all copies of any software which is or includes a copy * or modification of this software and in all copies of the supporting * documentation for such software. * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED * WARRANTY.  IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES  * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING  * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. */#include <stdio.h>#include <math.h>#include <float.h>#include <string.h>#include <stdlib.h>#include <errno.h>#include <stdarg.h>#include <assert.h>#include <ctype.h>#include <unistd.h>#include "u.h"#include "utf.h"#include "fmt.h"#define PLAN9PORT /* Get Plan 9 verbs *//* * compiler directive on Plan 9 */#ifndef USED#define USED(x) if(x);else#endif/* * nil cannot be ((void*)0) on ANSI C, * because it is used for function pointers */#undef	nil#define	nil	0#undef	nelem#define	nelem(x)	(sizeof (x)/sizeof (x)[0])/* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE *//* * dofmt -- format to a buffer * the number of characters formatted is returned, * or -1 if there was an error. * if the buffer is ever filled, flush is called. * it should reset the buffer and return whether formatting should continue. */typedef int (*Fmts)(Fmt*);typedef struct Quoteinfo Quoteinfo;struct Quoteinfo{	int	quoted;		/* if set, string must be quoted */	int	nrunesin;	/* number of input runes that can be accepted */	int	nbytesin;	/* number of input bytes that can be accepted */	int	nrunesout;	/* number of runes that will be generated */	int	nbytesout;	/* number of bytes that will be generated */};/* Edit .+1,/^$/ |cfn |grep -v static | grep __ */double       __Inf(int sign);double       __NaN(void);int          __badfmt(Fmt *f);int          __charfmt(Fmt *f);int          __countfmt(Fmt *f);int          __efgfmt(Fmt *fmt);int          __errfmt(Fmt *f);int          __flagfmt(Fmt *f);int          __fmtFdFlush(Fmt *f);int          __fmtcpy(Fmt *f, const void *vm, int n, int sz);void*        __fmtdispatch(Fmt *f, void *fmt, int isrunes);void *       __fmtflush(Fmt *f, void *t, int len);void         __fmtlock(void);int          __fmtpad(Fmt *f, int n);double       __fmtpow10(int n);int          __fmtrcpy(Fmt *f, const void *vm, int n);void         __fmtunlock(void);int          __ifmt(Fmt *f);int          __isInf(double d, int sign);int          __isNaN(double d);int          __needsep(int*, char**);int          __needsquotes(char *s, int *quotelenp);int          __percentfmt(Fmt *f);void         __quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout);int          __quotestrfmt(int runesin, Fmt *f);int          __rfmtpad(Fmt *f, int n);int          __runefmt(Fmt *f);int          __runeneedsquotes(Rune *r, int *quotelenp);int          __runesfmt(Fmt *f);int          __strfmt(Fmt *f);#define FMTCHAR(f, t, s, c)\	do{\	if(t + 1 > (char*)s){\		t = (char*)__fmtflush(f, t, 1);\		if(t != nil)\			s = (char*)f->stop;\		else\			return -1;\	}\	*t++ = c;\	}while(0)#define FMTRCHAR(f, t, s, c)\	do{\	if(t + 1 > (Rune*)s){\		t = (Rune*)__fmtflush(f, t, sizeof(Rune));\		if(t != nil)\			s = (Rune*)f->stop;\		else\			return -1;\	}\	*t++ = c;\	}while(0)#define FMTRUNE(f, t, s, r)\	do{\	Rune _rune;\	int _runelen;\	if(t + UTFmax > (char*)s && t + (_runelen = runelen(r)) > (char*)s){\		t = (char*)__fmtflush(f, t, _runelen);\		if(t != nil)\			s = (char*)f->stop;\		else\			return -1;\	}\	if(r < Runeself)\		*t++ = r;\	else{\		_rune = r;\		t += runetochar(t, &_rune);\	}\	}while(0)#ifdef va_copy#	define VA_COPY(a,b) va_copy(a,b)#	define VA_END(a) va_end(a)#else#	define VA_COPY(a,b) (a) = (b)#	define VA_END(a)#endif/* ---------- end preamble -------- *//* -------------- charstod.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* * Reads a floating-point number by interpreting successive characters * returned by (*f)(vp).  The last call it makes to f terminates the * scan, so is not a character in the number.  It may therefore be * necessary to back up the input stream up one byte after calling charstod. */doublefmtcharstod(int(*f)(void*), void *vp){	double num, dem;	int neg, eneg, dig, exp, c;	num = 0;	neg = 0;	dig = 0;	exp = 0;	eneg = 0;	c = (*f)(vp);	while(c == ' ' || c == '\t')		c = (*f)(vp);	if(c == '-' || c == '+'){		if(c == '-')			neg = 1;		c = (*f)(vp);	}	while(c >= '0' && c <= '9'){		num = num*10 + c-'0';		c = (*f)(vp);	}	if(c == '.')		c = (*f)(vp);	while(c >= '0' && c <= '9'){		num = num*10 + c-'0';		dig++;		c = (*f)(vp);	}	if(c == 'e' || c == 'E'){		c = (*f)(vp);		if(c == '-' || c == '+'){			if(c == '-'){				dig = -dig;				eneg = 1;			}			c = (*f)(vp);		}		while(c >= '0' && c <= '9'){			exp = exp*10 + c-'0';			c = (*f)(vp);		}	}	exp -= dig;	if(exp < 0){		exp = -exp;		eneg = !eneg;	}	dem = __fmtpow10(exp);	if(eneg)		num /= dem;	else		num *= dem;	if(neg)		return -num;	return num;}/* -------------- dofmt.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE *//* Copyright (c) 2004 Google Inc.; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* format the output into f->to and return the number of characters fmted  */intdofmt(Fmt *f, char *fmt){	Rune rune, *rt, *rs;	int r;	char *t, *s;	int n, nfmt;	nfmt = f->nfmt;	for(;;){		if(f->runes){			rt = (Rune*)f->to;			rs = (Rune*)f->stop;			while((r = *(uchar*)fmt) && r != '%'){				if(r < Runeself)					fmt++;				else{					fmt += chartorune(&rune, fmt);					r = rune;				}				FMTRCHAR(f, rt, rs, r);			}			fmt++;			f->nfmt += rt - (Rune *)f->to;			f->to = rt;			if(!r)				return f->nfmt - nfmt;			f->stop = rs;		}else{			t = (char*)f->to;			s = (char*)f->stop;			while((r = *(uchar*)fmt) && r != '%'){				if(r < Runeself){					FMTCHAR(f, t, s, r);					fmt++;				}else{					n = chartorune(&rune, fmt);					if(t + n > s){						t = (char*)__fmtflush(f, t, n);						if(t != nil)							s = (char*)f->stop;						else							return -1;					}					while(n--)						*t++ = *fmt++;				}			}			fmt++;			f->nfmt += t - (char *)f->to;			f->to = t;			if(!r)				return f->nfmt - nfmt;			f->stop = s;		}		fmt = (char*)__fmtdispatch(f, fmt, 0);		if(fmt == nil)			return -1;	}}void *__fmtflush(Fmt *f, void *t, int len){	if(f->runes)		f->nfmt += (Rune*)t - (Rune*)f->to;	else		f->nfmt += (char*)t - (char *)f->to;	f->to = t;	if(f->flush == 0 || (*f->flush)(f) == 0 || (char*)f->to + len > (char*)f->stop){		f->stop = f->to;		return nil;	}	return f->to;}/* * put a formatted block of memory sz bytes long of n runes into the output buffer, * left/right justified in a field of at least f->width characters (if FmtWidth is set) */int__fmtpad(Fmt *f, int n){	char *t, *s;	int i;	t = (char*)f->to;	s = (char*)f->stop;	for(i = 0; i < n; i++)		FMTCHAR(f, t, s, ' ');	f->nfmt += t - (char *)f->to;	f->to = t;	return 0;}int__rfmtpad(Fmt *f, int n){	Rune *t, *s;	int i;	t = (Rune*)f->to;	s = (Rune*)f->stop;	for(i = 0; i < n; i++)		FMTRCHAR(f, t, s, ' ');	f->nfmt += t - (Rune *)f->to;	f->to = t;	return 0;}int__fmtcpy(Fmt *f, const void *vm, int n, int sz){	Rune *rt, *rs, r;	char *t, *s, *m, *me;	ulong fl;	int nc, w;	m = (char*)vm;	me = m + sz;	fl = f->flags;	w = 0;	if(fl & FmtWidth)		w = f->width;	if((fl & FmtPrec) && n > f->prec)		n = f->prec;	if(f->runes){		if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)			return -1;		rt = (Rune*)f->to;		rs = (Rune*)f->stop;		for(nc = n; nc > 0; nc--){			r = *(uchar*)m;			if(r < Runeself)				m++;			else if((me - m) >= UTFmax || fullrune(m, me-m))				m += chartorune(&r, m);			else				break;			FMTRCHAR(f, rt, rs, r);		}		f->nfmt += rt - (Rune *)f->to;		f->to = rt;		if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)			return -1;	}else{		if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)			return -1;		t = (char*)f->to;		s = (char*)f->stop;		for(nc = n; nc > 0; nc--){			r = *(uchar*)m;			if(r < Runeself)				m++;			else if((me - m) >= UTFmax || fullrune(m, me-m))				m += chartorune(&r, m);			else				break;			FMTRUNE(f, t, s, r);		}		f->nfmt += t - (char *)f->to;		f->to = t;		if(fl & FmtLeft && __fmtpad(f, w - n) < 0)			return -1;	}	return 0;}int__fmtrcpy(Fmt *f, const void *vm, int n){	Rune r, *m, *me, *rt, *rs;	char *t, *s;	ulong fl;	int w;	m = (Rune*)vm;	fl = f->flags;	w = 0;	if(fl & FmtWidth)		w = f->width;	if((fl & FmtPrec) && n > f->prec)		n = f->prec;	if(f->runes){		if(!(fl & FmtLeft) && __rfmtpad(f, w - n) < 0)			return -1;		rt = (Rune*)f->to;		rs = (Rune*)f->stop;		for(me = m + n; m < me; m++)			FMTRCHAR(f, rt, rs, *m);		f->nfmt += rt - (Rune *)f->to;		f->to = rt;		if(fl & FmtLeft && __rfmtpad(f, w - n) < 0)			return -1;	}else{		if(!(fl & FmtLeft) && __fmtpad(f, w - n) < 0)			return -1;		t = (char*)f->to;		s = (char*)f->stop;		for(me = m + n; m < me; m++){			r = *m;			FMTRUNE(f, t, s, r);		}		f->nfmt += t - (char *)f->to;		f->to = t;		if(fl & FmtLeft && __fmtpad(f, w - n) < 0)			return -1;	}	return 0;}/* fmt out one character */int__charfmt(Fmt *f){	char x[1];	x[0] = va_arg(f->args, int);	f->prec = 1;	return __fmtcpy(f, (const char*)x, 1, 1);}/* fmt out one rune */int__runefmt(Fmt *f){	Rune x[1];	x[0] = va_arg(f->args, int);	return __fmtrcpy(f, (const void*)x, 1);}/* public helper routine: fmt out a null terminated string already in hand */intfmtstrcpy(Fmt *f, char *s){	int i, j;	if(!s)		return __fmtcpy(f, "<nil>", 5, 5);	/* if precision is specified, make sure we don't wander off the end */	if(f->flags & FmtPrec){#ifdef PLAN9PORT		Rune r;		i = 0;		for(j=0; j<f->prec && s[i]; j++)			i += chartorune(&r, s+i);#else		/* ANSI requires precision in bytes, not Runes */		for(i=0; i<f->prec; i++)			if(s[i] == 0)				break;		j = utfnlen(s, i);	/* won't print partial at end */#endif		return __fmtcpy(f, s, j, i);	}	return __fmtcpy(f, s, utflen(s), strlen(s));}/* fmt out a null terminated utf string */int__strfmt(Fmt *f){	char *s;	s = va_arg(f->args, char *);	return fmtstrcpy(f, s);}/* public helper routine: fmt out a null terminated rune string already in hand */intfmtrunestrcpy(Fmt *f, Rune *s){	Rune *e;	int n, p;	if(!s)		return __fmtcpy(f, "<nil>", 5, 5);	/* if precision is specified, make sure we don't wander off the end */	if(f->flags & FmtPrec){		p = f->prec;		for(n = 0; n < p; n++)			if(s[n] == 0)				break;	}else{		for(e = s; *e; e++)			;		n = e - s;	}	return __fmtrcpy(f, s, n);}/* fmt out a null terminated rune string */int__runesfmt(Fmt *f){	Rune *s;	s = va_arg(f->args, Rune *);	return fmtrunestrcpy(f, s);}/* fmt a % */int__percentfmt(Fmt *f){	Rune x[1];	x[0] = f->r;	f->prec = 1;	return __fmtrcpy(f, (const void*)x, 1);}/* fmt an integer */int__ifmt(Fmt *f){	char buf[140], *p, *conv;	/* 140: for 64 bits of binary + 3-byte sep every 4 digits */	uvlong vu;	ulong u;	int neg, base, i, n, fl, w, isv;	int ndig, len, excess, bytelen;	char *grouping;	char *thousands;	neg = 0;	fl = f->flags;	isv = 0;	vu = 0;	u = 0;#ifndef PLAN9PORT	/*	 * Unsigned verbs for ANSI C	 */	switch(f->r){	case 'o':	case 'p':	case 'u':	case 'x':	case 'X':		fl |= FmtUnsigned;		fl &= ~(FmtSign|FmtSpace);		break;	}#endif	if(f->r == 'p'){		u = (ulong)va_arg(f->args, void*);		f->r = 'x';		fl |= FmtUnsigned;	}else if(fl & FmtVLong){		isv = 1;		if(fl & FmtUnsigned)			vu = va_arg(f->args, uvlong);		else			vu = va_arg(f->args, vlong);	}else if(fl & FmtLong){		if(fl & FmtUnsigned)			u = va_arg(f->args, ulong);		else			u = va_arg(f->args, long);	}else if(fl & FmtByte){		if(fl & FmtUnsigned)			u = (uchar)va_arg(f->args, int);		else			u = (char)va_arg(f->args, int);	}else if(fl & FmtShort){		if(fl & FmtUnsigned)			u = (ushort)va_arg(f->args, int);		else			u = (short)va_arg(f->args, int);	}else{		if(fl & FmtUnsigned)			u = va_arg(f->args, uint);		else			u = va_arg(f->args, int);	}	conv = "0123456789abcdef";	grouping = "\4";	/* for hex, octal etc. (undefined by spec but nice) */	thousands = f->thousands;	switch(f->r){	case 'd':	case 'i':	case 'u':		base = 10;		grouping = f->grouping;		break;	case 'X':		conv = "0123456789ABCDEF";		/* fall through */	case 'x':		base = 16;		thousands = ":";		break;	case 'b':		base = 2;		thousands = ":";		break;	case 'o':		base = 8;		break;	default:		return -1;	}	if(!(fl & FmtUnsigned)){		if(isv && (vlong)vu < 0){			vu = -(vlong)vu;			neg = 1;		}else if(!isv && (long)u < 0){			u = -(long)u;			neg = 1;		}	}	p = buf + sizeof buf - 1;	n = 0;	/* in runes */	excess = 0;	/* number of bytes > number runes */	ndig = 0;	len = utflen(thousands);	bytelen = strlen(thousands);	if(isv){		while(vu){			i = vu % base;			vu /= base;			if((fl & FmtComma) && n % 4 == 3){				*p-- = ',';				n++;			}			if((fl & FmtApost) && __needsep(&ndig, &grouping)){				n += len;				excess += bytelen - len;				p -= bytelen;				memmove(p+1, thousands, bytelen);			}			*p-- = conv[i];			n++;		}	}else{		while(u){			i = u % base;			u /= base;			if((fl & FmtComma) && n % 4 == 3){				*p-- = ',';				n++;			}			if((fl & FmtApost) && __needsep(&ndig, &grouping)){				n += len;

⌨️ 快捷键说明

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