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

📄 fmt.c

📁 在x86平台上运行不可信任代码的sandbox。
💻 C
📖 第 1 页 / 共 5 页
字号:
				 * account for new digit				 */				if(z1)	/* 0.099 => 0.100 or 0.99 => 1.00*/					z1--;				else	/* 9.99 => 10.00 */					point++;			}			z2 = 0;			ndigits = newndigits;		}			sufwid = 0;		break;	}		/*	 * if %g is given without FmtSharp, remove trailing zeros.	 * must do after truncation, so that e.g. print %.3g 1.001	 * produces 1, not 1.00.  sorry, but them's the rules.	 */	if(realchr == 'g' && !(fl & FmtSharp)) {		if(z1+ndigits+z2 >= point) {			if(z1+ndigits < point)				z2 = point - (z1+ndigits);			else{				z2 = 0;				while(z1+ndigits > point && digits[ndigits-1] == '0')					ndigits--;			}		}	}	/*	 * compute width of all digits and decimal point and suffix if any	 */	wid = z1+ndigits+z2;	if(wid > point)		wid += dotwid;	else if(wid == point){		if(fl & FmtSharp)			wid += dotwid;		else			point++;	/* do not print any decimal point */	}	wid += sufwid;	/*	 * determine sign	 */	sign = 0;	if(neg)		sign = '-';	else if(fl & FmtSign)		sign = '+';	else if(fl & FmtSpace)		sign = ' ';	if(sign)		wid++;	/*	 * compute padding	 */	pad = 0;	if((fl & FmtWidth) && fmt->width > wid)		pad = fmt->width - wid;	if(pad && !(fl & FmtLeft) && (fl & FmtZero)){		z1 += pad;		point += pad;		pad = 0;	}	/*	 * format the actual field.  too bad about doing this twice.	 */	if(fmt->runes){		if(pad && !(fl & FmtLeft) && __rfmtpad(fmt, pad) < 0)			return -1;		rt = (Rune*)fmt->to;		rs = (Rune*)fmt->stop;		if(sign)			FMTRCHAR(fmt, rt, rs, sign);		while(z1>0 || ndigits>0 || z2>0) {			if(z1 > 0){				z1--;				c = '0';			}else if(ndigits > 0){				ndigits--;				c = *digits++;			}else{				z2--;				c = '0';			}			FMTRCHAR(fmt, rt, rs, c);			if(--point == 0) {				for(p = dot; *p; ){					p += chartorune(&r, p);					FMTRCHAR(fmt, rt, rs, r);				}			}		}		fmt->nfmt += rt - (Rune*)fmt->to;		fmt->to = rt;		if(sufwid && __fmtcpy(fmt, suf, sufwid, sufwid) < 0)			return -1;		if(pad && (fl & FmtLeft) && __rfmtpad(fmt, pad) < 0)			return -1;	}else{		if(pad && !(fl & FmtLeft) && __fmtpad(fmt, pad) < 0)			return -1;		t = (char*)fmt->to;		s = (char*)fmt->stop;		if(sign)			FMTCHAR(fmt, t, s, sign);		while(z1>0 || ndigits>0 || z2>0) {			if(z1 > 0){				z1--;				c = '0';			}else if(ndigits > 0){				ndigits--;				c = *digits++;			}else{				z2--;				c = '0';			}			FMTCHAR(fmt, t, s, c);			if(--point == 0)				for(p=dot; *p; p++)					FMTCHAR(fmt, t, s, *p);		}		fmt->nfmt += t - (char*)fmt->to;		fmt->to = t;		if(sufwid && __fmtcpy(fmt, suf, sufwid, sufwid) < 0)			return -1;		if(pad && (fl & FmtLeft) && __fmtpad(fmt, pad) < 0)			return -1;	}	return 0;}/* -------------- fmt.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"enum{	Maxfmt = 64};typedef struct Convfmt Convfmt;struct Convfmt{	int	c;	volatile	Fmts	fmt;	/* for spin lock in fmtfmt; avoids race due to write order */};static struct{	/* lock by calling __fmtlock, __fmtunlock */	int	nfmt;	Convfmt	fmt[Maxfmt];} fmtalloc;static Convfmt knownfmt[] = {	{ ' ',	__flagfmt },	{ '#',	__flagfmt },	{ '%',	__percentfmt },	{ '\'',	__flagfmt },	{ '+',	__flagfmt },	{ ',',	__flagfmt },	{ '-',	__flagfmt },	{ 'C',	__runefmt },	/* Plan 9 addition */	{ 'E',	__efgfmt },#ifndef PLAN9PORT	{ 'F',	__efgfmt },	/* ANSI only */#endif	{ 'G',	__efgfmt },#ifndef PLAN9PORT	{ 'L',	__flagfmt },	/* ANSI only */#endif	{ 'S',	__runesfmt },	/* Plan 9 addition */	{ 'X',	__ifmt },	{ 'b',	__ifmt },		/* Plan 9 addition */	{ 'c',	__charfmt },	{ 'd',	__ifmt },	{ 'e',	__efgfmt },	{ 'f',	__efgfmt },	{ 'g',	__efgfmt },	{ 'h',	__flagfmt },#ifndef PLAN9PORT	{ 'i',	__ifmt },		/* ANSI only */#endif	{ 'l',	__flagfmt },	{ 'n',	__countfmt },	{ 'o',	__ifmt },	{ 'p',	__ifmt },	{ 'r',	__errfmt },	{ 's',	__strfmt },#ifdef PLAN9PORT	{ 'u',	__flagfmt },#else	{ 'u',	__ifmt },#endif	{ 'x',	__ifmt },	{ 0,	nil }};int	(*fmtdoquote)(int);/* * __fmtlock() must be set */static int__fmtinstall(int c, Fmts f){	Convfmt *p, *ep;	if(c<=0 || c>=65536)		return -1;	if(!f)		f = __badfmt;	ep = &fmtalloc.fmt[fmtalloc.nfmt];	for(p=fmtalloc.fmt; p<ep; p++)		if(p->c == c)			break;	if(p == &fmtalloc.fmt[Maxfmt])		return -1;	p->fmt = f;	if(p == ep){	/* installing a new format character */		fmtalloc.nfmt++;		p->c = c;	}	return 0;}intfmtinstall(int c, int (*f)(Fmt*)){	int ret;	__fmtlock();	ret = __fmtinstall(c, f);	__fmtunlock();	return ret;}static Fmtsfmtfmt(int c){	Convfmt *p, *ep;	ep = &fmtalloc.fmt[fmtalloc.nfmt];	for(p=fmtalloc.fmt; p<ep; p++)		if(p->c == c){			while(p->fmt == nil)	/* loop until value is updated */				;			return p->fmt;		}	/* is this a predefined format char? */	__fmtlock();	for(p=knownfmt; p->c; p++)		if(p->c == c){			__fmtinstall(p->c, p->fmt);			__fmtunlock();			return p->fmt;		}	__fmtunlock();	return __badfmt;}void*__fmtdispatch(Fmt *f, void *fmt, int isrunes){	Rune rune, r;	int i, n;	f->flags = 0;	f->width = f->prec = 0;	for(;;){		if(isrunes){			r = *(Rune*)fmt;			fmt = (Rune*)fmt + 1;		}else{			fmt = (char*)fmt + chartorune(&rune, (char*)fmt);			r = rune;		}		f->r = r;		switch(r){		case '\0':			return nil;		case '.':			f->flags |= FmtWidth|FmtPrec;			continue;		case '0':			if(!(f->flags & FmtWidth)){				f->flags |= FmtZero;				continue;			}			/* fall through */		case '1': case '2': case '3': case '4':		case '5': case '6': case '7': case '8': case '9':			i = 0;			while(r >= '0' && r <= '9'){				i = i * 10 + r - '0';				if(isrunes){					r = *(Rune*)fmt;					fmt = (Rune*)fmt + 1;				}else{					r = *(char*)fmt;					fmt = (char*)fmt + 1;				}			}			if(isrunes)				fmt = (Rune*)fmt - 1;			else				fmt = (char*)fmt - 1;		numflag:			if(f->flags & FmtWidth){				f->flags |= FmtPrec;				f->prec = i;			}else{				f->flags |= FmtWidth;				f->width = i;			}			continue;		case '*':			i = va_arg(f->args, int);			if(i < 0){				/*				 * negative precision =>				 * ignore the precision.				 */				if(f->flags & FmtPrec){					f->flags &= ~FmtPrec;					f->prec = 0;					continue;				}				i = -i;				f->flags |= FmtLeft;			}			goto numflag;		}		n = (*fmtfmt(r))(f);		if(n < 0)			return nil;		if(n == 0)			return fmt;	}}/* -------------- fmtfd.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* * public routine for final flush of a formatting buffer * to a file descriptor; returns total char count. */intfmtfdflush(Fmt *f){	if(__fmtFdFlush(f) <= 0)		return -1;	return f->nfmt;}/* * initialize an output buffer for buffered printing */intfmtfdinit(Fmt *f, int fd, char *buf, int size){	f->runes = 0;	f->start = buf;	f->to = buf;	f->stop = buf + size;	f->flush = __fmtFdFlush;	f->farg = (void*)(uintptr_t)fd;	f->flags = 0;	f->nfmt = 0;	fmtlocaleinit(f, nil, nil, nil);	return 0;}/* -------------- fmtfdflush.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */// #include <stdarg.h>// #include <unistd.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* * generic routine for flushing a formatting buffer * to a file descriptor */int__fmtFdFlush(Fmt *f){	int n;	n = (char*)f->to - (char*)f->start;	if(n && write((uintptr)f->farg, f->start, n) != n)		return 0;	f->to = f->start;	return 1;}/* -------------- fmtlocale.c --------------- *//* Copyright (c) 2004 Google Inc.; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* * Fill in the internationalization stuff in the State structure. * For nil arguments, provide the sensible defaults: *	decimal is a period *	thousands separator is a comma *	thousands are marked every three digits */voidfmtlocaleinit(Fmt *f, char *decimal, char *thousands, char *grouping){	if(decimal == nil || decimal[0] == '\0')		decimal = ".";	if(thousands == nil)		thousands = ",";	if(grouping == nil)		grouping = "\3";	f->decimal = decimal;	f->thousands = thousands;	f->grouping = grouping;}/* * We are about to emit a digit in e.g. %'d.  If that digit would * overflow a thousands (e.g.) grouping, tell the caller to emit * the thousands separator.  Always advance the digit counter * and pointer into the grouping descriptor. */int__needsep(int *ndig, char **grouping){	int group;		(*ndig)++;	group = *(unsigned char*)*grouping;	/* CHAR_MAX means no further grouping. \0 means we got the empty string */	if(group == 0xFF || group == 0x7f || group == 0x00)		return 0;	if(*ndig > group){		/* if we're at end of string, continue with this grouping; else advance */		if((*grouping)[1] != '\0')			(*grouping)++;		*ndig = 1;		return 1;	}	return 0;}/* -------------- fmtlock.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */// #include <stdarg.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"void__fmtlock(void){}void__fmtunlock(void){}/* -------------- fmtnull.c --------------- *//* Copyright (c) 2004 Google Inc.; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* * Absorb output without using resources. */static Rune nullbuf[32];static int__fmtnullflush(Fmt *f){	f->to = nullbuf;	f->nfmt = 0;	return 0;}intfmtnullinit(Fmt *f){	memset(&f, 0, sizeof *f);	f->runes = 1;	f->start = nullbuf;	f->to = nullbuf;	f->stop = nullbuf+nelem(nullbuf);	f->flush = __fmtnullflush;	fmtlocaleinit(f, nil, nil, nil);	return 0;}/* -------------- fmtprint.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* * format a string into the output buffer * designed for formats which themselves call fmt, * but ignore any width flags */intfmtprint(Fmt *f, char *fmt, ...){	va_list va;	int n;	f->flags = 0;	f->width = 0;	f->prec = 0;	VA_COPY(va, f->args);	VA_END(f->args);	va_start(f->args, fmt);	n = dofmt(f, fmt);	va_end(f->args);	f->flags = 0;	f->width = 0;	f->prec = 0;	VA_COPY(f->args,va);	VA_END(va);	if(n >= 0)		return 0;	return n;}/* -------------- fmtquote.c --------------- *//* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */// #include <stdarg.h>// #include <string.h>// #include "plan9.h"// #include "fmt.h"// #include "fmtdef.h"/* * How many bytes of output UTF will be produced by quoting (if necessary) this string? * How many runes? How much of the input will be consumed? * The parameter q is filled in by __quotesetup. * The string may be UTF or Runes (s or r). * Return count does not include NUL. * Terminate the scan at the first of: *	NUL in input *	count exceeded in input *	count exceeded on output * *ninp is set to number of input bytes accepted. * nin may be <0 initially, to avoid checking input by count. */void__quotesetup(char *s, Rune *r, int nin, int nout, Quoteinfo *q, int sharp, int runesout){	int w;	Rune c;	q->quoted = 0;	q->nbytesout = 0;	q->nrunesout = 0;	q->nbytesin = 0;	q->nrunesin = 0;	if(sharp || nin==0 || (s && *s=='\0') || (r && *r=='\0')){		if(nout < 2)			return;		q->quoted = 1;		q->nbytesout = 2;		q->nrunesout = 2;	}	for(; nin!=0; nin--){		if(s)			w = chartorune(&c, s);		else{			c = *r;			w = runelen(c);		}		if(c == '\0')			break;		if(runesout){			if(q->nrunesout+1 > nout)				break;		}else{			if(q->nbytesout+w > nout)				break;		}		if((c <= L' ') || (c == L'\'') || (fmtdoquote!=nil && fmtdoquote(c))){			if(!q->quoted){				if(runesout){					if(1+q->nrunesout+1+1 > nout)	/* no room for quotes */						break;				}else{					if(1+q->nbytesout+w+1 > nout)	/* no room for quotes */						break;				}				q->nrunesout += 2;	/* include quotes */				q->nbytesout += 2;	/* include quotes */				q->quoted = 1;			}			if(c == '\'')	{				if(runesout){					if(1+q->nrunesout+1 > nout)	/* no room for quotes */						break;				}else{					if(1+q->nbytesout+w > nout)	/* no room for quotes */						break;				}				q->nbytesout++;				q->nrunesout++;	/* quotes reproduce as two characters */			}		}		/* advance input */		if(s)			s += w;		else			r++;		q->nbytesin += w;		q->nrunesin++;		/* advance output */		q->nbytesout += w;		q->nrunesout++;#ifndef PLAN9PORT		/* ANSI requires precision in bytes, not Runes. */		nin-= w-1;	/* and then n-- in the loop */#endif	}}static intqstrfmt(char *sin, Rune *rin, Quoteinfo *q, Fmt *f){	Rune r, *rm, *rme;	char *t, *s, *m, *me;	Rune *rt, *rs;	ulong fl;	int nc, w;	m = sin;	me = m + q->nbytesin;	rm = rin;	rme = rm + q->nrunesin;	fl = f->flags;	w = 0;	if(fl & FmtWidth)		w = f->width;	if(f->runes){		if(!(fl & FmtLeft) && __rfmtpad(f, w - q->nrunesout) < 0)			return -1;	}else{		if(!(fl & FmtLeft) && __fmtpad(f, w - q->nbytesout) < 0)			return -1;	}	t = (char*)f->to;

⌨️ 快捷键说明

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