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

📄 sftable.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       */#include	"sfhdr.h"#include	"FEATURE/float"/*	Dealing with $ argument addressing stuffs.****	Written by Kiem-Phong Vo.*/#if __STD_Cstatic char* sffmtint(const char* str, int* v)#elsestatic char* sffmtint(str, v)char*	str;int*	v;#endif{		for(*v = 0; isdigit(*str); ++str)		*v = *v * 10 + (*str - '0');	*v -= 1;	return (char*)str;}#if __STD_Cstatic Fmtpos_t* sffmtpos(Sfio_t* f,const char* form,va_list args,Sffmt_t* ft,int type)#elsestatic Fmtpos_t* sffmtpos(f,form,args,ft,type)Sfio_t*		f;char*		form;va_list		args;Sffmt_t*	ft;int		type;	/* >0: scanf, =0: printf, -1: internal	*/#endif{	int		base, fmt, flags, dot, width, precis;	ssize_t		n_str, size;	char		*t_str, *sp;	int		v, n, skip, dollar, decimal, thousand;	Sffmt_t		savft;	Fmtpos_t*	fp;	/* position array of arguments	*/	int		argp, argn, maxp, need[FP_INDEX];#if _has_multibyte	SFMBDCL(fmbs)#endif	if(type < 0)		fp = NIL(Fmtpos_t*);	else if(!(fp = sffmtpos(f,form,args,ft,-1)) )		return NIL(Fmtpos_t*);	dollar = decimal = thousand = 0; argn = maxp = -1;	SFMBCLR(&fmbs);	while((n = *form) )	{	if(n != '%') /* collect the non-pattern chars */		{	sp = (char*)form;			for(;;)			{	form += SFMBLEN(form, &fmbs);				if(*form == 0 || *form == '%')					break;			}			continue;		}		else	form += 1;		if(*form == 0)			break;		else if(*form == '%')		{	form += 1;			continue;		}		if(*form == '*' && type > 0) /* skip in scanning */		{	skip = 1;			form += 1;			argp = -1;		}		else /* get the position of this argument */		{	skip = 0;			sp = sffmtint(form,&argp);			if(*sp == '$')			{	dollar = 1;				form = sp+1;			}			else	argp = -1;		}		flags = dot = 0;		t_str = NIL(char*); n_str = 0;		size = width = precis = base = -1;		for(n = 0; n < FP_INDEX; ++n)			need[n] = -1;	loop_flags:	/* LOOP FOR \0, %, FLAGS, WIDTH, PRECISION, BASE, TYPE */		switch((fmt = *form++) )		{		case LEFTP : /* get the type enclosed in balanced parens */			t_str = (char*)form;			for(v = 1;;)			{	switch(*form++)				{				case 0 :	/* not balancable, retract */					form = t_str;					t_str = NIL(char*);					n_str = 0;					goto loop_flags;				case LEFTP :	/* increasing nested level */					v += 1;					continue;				case RIGHTP :	/* decreasing nested level */					if((v -= 1) != 0)						continue;					n_str = form-t_str;					if(*t_str == '*')					{	t_str = sffmtint(t_str+1,&n);						if(*t_str == '$')							dollar = 1;						else	n = -1;						if((n = FP_SET(n,argn)) > maxp)							maxp = n;						if(fp && fp[n].ft.fmt == 0)						{	fp[n].ft.fmt = LEFTP;							fp[n].ft.form = (char*)form;						}						need[FP_STR] = n;					}					goto loop_flags;				}			}		case '-' :			flags |= SFFMT_LEFT;			flags &= ~SFFMT_ZERO;			goto loop_flags;		case '0' :			if(!(flags&SFFMT_LEFT) )				flags |= SFFMT_ZERO;			goto loop_flags;		case ' ' :			if(!(flags&SFFMT_SIGN) )				flags |= SFFMT_BLANK;			goto loop_flags;		case '+' :			flags |= SFFMT_SIGN;			flags &= ~SFFMT_BLANK;			goto loop_flags;		case '#' :			flags |= SFFMT_ALTER;			goto loop_flags;		case QUOTE:			SFSETLOCALE(&decimal,&thousand);			if(thousand > 0)				flags |= SFFMT_THOUSAND;			goto loop_flags;		case '.' :			if((dot += 1) == 2)				base = 0; /* for %s,%c */			if(isdigit(*form))			{	fmt = *form++;				goto dot_size;			}			else if(*form != '*')				goto loop_flags;			else	form += 1; /* drop thru below */		case '*' :			form = sffmtint(form,&n);			if(*form == '$' )			{	dollar = 1;				form += 1;			}			else	n = -1;			if((n = FP_SET(n,argn)) > maxp)				maxp = n;			if(fp && fp[n].ft.fmt == 0)			{	fp[n].ft.fmt = '.';				fp[n].ft.size = dot;				fp[n].ft.form = (char*)form;			}			if(dot <= 2)				need[dot] = n;			goto loop_flags;		case '1' : case '2' : case '3' :		case '4' : case '5' : case '6' :		case '7' : case '8' : case '9' :		dot_size :			for(v = fmt - '0', fmt = *form; isdigit(fmt); fmt = *++form)				v = v*10 + (fmt - '0');			if(dot == 0)				width = v;			else if(dot == 1)				precis = v;			else if(dot == 2)				base = v;			goto loop_flags;		case 'I' : /* object length */			size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_IFLAG;			if(isdigit(*form) )			{	for(size = 0, n = *form; isdigit(n); n = *++form)					size = size*10 + (n - '0');			}			else if(*form == '*')			{	form = sffmtint(form+1,&n);				if(*form == '$' )				{	dollar = 1;					form += 1;				}				else	n = -1;				if((n = FP_SET(n,argn)) > maxp)					maxp = n;				if(fp && fp[n].ft.fmt == 0)				{	fp[n].ft.fmt = 'I';					fp[n].ft.size = sizeof(int);					fp[n].ft.form = (char*)form;				}				need[FP_SIZE] = n;			}			goto loop_flags;		case 'l' :			size = -1; flags &= ~SFFMT_TYPES;			if(*form == 'l')			{	form += 1;				flags |= SFFMT_LLONG;			}			else	flags |= SFFMT_LONG;			goto loop_flags;		case 'h' :			size = -1; flags &= ~SFFMT_TYPES;			if(*form == 'h')			{	form += 1;				flags |= SFFMT_SSHORT;			}			else	flags |= SFFMT_SHORT;			goto loop_flags;		case 'L' :			size = -1; flags = (flags & ~SFFMT_TYPES) | SFFMT_LDOUBLE;			goto loop_flags;		}		/* set object size for scalars */		if(flags & SFFMT_TYPES)		{	if((_Sftype[fmt]&(SFFMT_INT|SFFMT_UINT)) || fmt == 'n')			{	if(flags&SFFMT_LONG)					size = sizeof(long);				else if(flags&SFFMT_SHORT)					size = sizeof(short);				else if(flags&SFFMT_SSHORT)					size = sizeof(char);				else if(flags&SFFMT_TFLAG)					size = sizeof(ptrdiff_t);				else if(flags&SFFMT_ZFLAG) 					size = sizeof(size_t);				else if(flags&(SFFMT_LLONG|SFFMT_JFLAG) )					size = sizeof(Sflong_t);				else if(flags&SFFMT_IFLAG)				{	if(size <= 0 ||					   size == sizeof(Sflong_t)*CHAR_BIT )						size = sizeof(Sflong_t);				}				else if(size < 0)					size = sizeof(int);			}			else if(_Sftype[fmt]&SFFMT_FLOAT)			{	if(flags&(SFFMT_LONG|SFFMT_LLONG))					size = sizeof(double);				else if(flags&SFFMT_LDOUBLE)					size = sizeof(Sfdouble_t);				else if(flags&SFFMT_IFLAG)				{	if(size <= 0)						size = sizeof(Sfdouble_t);				}				else if(size < 0)					size = sizeof(float);			}			else if(_Sftype[fmt]&SFFMT_CHAR)			{#if _has_multibyte				if((flags&SFFMT_LONG) || fmt == 'C')				{	size = sizeof(wchar_t) > sizeof(int) ?						sizeof(wchar_t) : sizeof(int);				} else#endif				if(size < 0)					size = sizeof(int);			}		}		if(skip)			continue;		if((argp = FP_SET(argp,argn)) > maxp)			maxp = argp;		if(dollar && fmt == '!')			return NIL(Fmtpos_t*);		if(fp && fp[argp].ft.fmt == 0)		{	fp[argp].ft.form = (char*)form;			fp[argp].ft.fmt = fp[argp].fmt = fmt;			fp[argp].ft.size = size;			fp[argp].ft.flags = flags;			fp[argp].ft.width = width;			fp[argp].ft.precis = precis;			fp[argp].ft.base = base;			fp[argp].ft.t_str = t_str;			fp[argp].ft.n_str = n_str;			for(n = 0; n < FP_INDEX; ++n)				fp[argp].need[n] = need[n];		}	}	if(!fp) /* constructing position array only */	{	if(!dollar || !(fp = (Fmtpos_t*)malloc((maxp+1)*sizeof(Fmtpos_t))) )			return NIL(Fmtpos_t*);		for(n = 0; n <= maxp; ++n)			fp[n].ft.fmt = 0;		return fp;	}	/* get value for positions */	for(n = 0; n <= maxp; ++n)	{	if(fp[n].ft.fmt == 0) /* gap: pretend it's a 'd' pattern */		{	fp[n].ft.fmt = 'd';			fp[n].ft.width = 0;			fp[n].ft.precis = 0;			fp[n].ft.base = 0;			fp[n].ft.size = 0;			fp[n].ft.t_str = 0;			fp[n].ft.n_str = 0;			fp[n].ft.flags = 0;			for(v = 0; v < FP_INDEX; ++v)				fp[n].need[v] = -1;		}		if(ft && ft->extf)		{	fp[n].ft.version = ft->version;			fp[n].ft.extf = ft->extf;			fp[n].ft.eventf = ft->eventf;			if((v = fp[n].need[FP_WIDTH]) >= 0 && v < n)				fp[n].ft.width = fp[v].argv.i;			if((v = fp[n].need[FP_PRECIS]) >= 0 && v < n)				fp[n].ft.precis = fp[v].argv.i;			if((v = fp[n].need[FP_BASE]) >= 0 && v < n)				fp[n].ft.base = fp[v].argv.i;			if((v = fp[n].need[FP_STR]) >= 0 && v < n)				fp[n].ft.t_str = fp[v].argv.s;			if((v = fp[n].need[FP_SIZE]) >= 0 && v < n)				fp[n].ft.size = fp[v].argv.i;			memcpy(ft,&fp[n].ft,sizeof(Sffmt_t));			va_copy(ft->args,args);			ft->flags |= SFFMT_ARGPOS;			v = (*ft->extf)(f, (Void_t*)(&fp[n].argv), ft);			va_copy(args,ft->args);			memcpy(&fp[n].ft,ft,sizeof(Sffmt_t));			if(v < 0)			{	memcpy(ft,&savft,sizeof(Sffmt_t));				ft = NIL(Sffmt_t*);			}			if(!(fp[n].ft.flags&SFFMT_VALUE) )				goto arg_list;			else if(_Sftype[fp[n].ft.fmt]&(SFFMT_INT|SFFMT_UINT) )			{	if(fp[n].ft.size == sizeof(short))				{	if(_Sftype[fp[n].ft.fmt]&SFFMT_INT)						fp[n].argv.i = fp[n].argv.h;					else	fp[n].argv.i = fp[n].argv.uh;				}				else if(fp[n].ft.size == sizeof(char))				{	if(_Sftype[fp[n].ft.fmt]&SFFMT_INT)						fp[n].argv.i = fp[n].argv.c;					else	fp[n].argv.i = fp[n].argv.uc;				}			}			else if(_Sftype[fp[n].ft.fmt]&SFFMT_FLOAT )			{	if(fp[n].ft.size == sizeof(float) )					fp[n].argv.d = fp[n].argv.f;			}		}		else		{ arg_list:			if(fp[n].ft.fmt == LEFTP)			{	fp[n].argv.s = va_arg(args, char*);				fp[n].ft.size = strlen(fp[n].argv.s);			}			else if(fp[n].ft.fmt == '.' || fp[n].ft.fmt == 'I')				fp[n].argv.i = va_arg(args, int);			else if(fp[n].ft.fmt == '!')			{	if(ft)					memcpy(ft,&savft,sizeof(Sffmt_t));				fp[n].argv.ft = ft = va_arg(args, Sffmt_t*);				if(ft->form)					ft = NIL(Sffmt_t*);				if(ft)					memcpy(&savft,ft,sizeof(Sffmt_t));			}			else if(type > 0) /* from sfvscanf */				fp[n].argv.vp = va_arg(args, Void_t*);			else switch(_Sftype[fp[n].ft.fmt])			{ case SFFMT_INT:			  case SFFMT_UINT:#if !_ast_intmax_long				if(size == sizeof(Sflong_t) )					fp[n].argv.ll = va_arg(args, Sflong_t);				else#endif				if(size == sizeof(long) )					fp[n].argv.l = va_arg(args, long);				else	fp[n].argv.i = va_arg(args, int);				break;			  case SFFMT_FLOAT:#if !_ast_fltmax_double				if(size == sizeof(Sfdouble_t) )					fp[n].argv.ld = va_arg(args,Sfdouble_t);				else#endif					fp[n].argv.d  = va_arg(args,double);				break;	 		  case SFFMT_POINTER:					fp[n].argv.vp = va_arg(args,Void_t*);				break;			  case SFFMT_CHAR:				if(fp[n].ft.base >= 0)					fp[n].argv.s = va_arg(args,char*);#if _has_multibyte				else if((fp[n].ft.flags & SFFMT_LONG) ||					fp[n].ft.fmt == 'C' )				{	if(sizeof(wchar_t) <= sizeof(int) )					     fp[n].argv.wc = (wchar_t)va_arg(args,int);					else fp[n].argv.wc = va_arg(args,wchar_t);				}#endif					/* observe promotion rule */				else	fp[n].argv.i = va_arg(args,int);				break;			  default: /* unknown pattern */				break;			}		}	}	if(ft)		memcpy(ft,&savft,sizeof(Sffmt_t));	return fp;}static const unsigned char	flt_nan[] = { _ast_flt_nan_init };static const unsigned char	dbl_nan[] = { _ast_dbl_nan_init };#ifdef _ast_ldbl_nan_initstatic const unsigned char	ldbl_nan[] = { _ast_ldbl_nan_init };#endif/* function to initialize conversion tables */static int sfcvinit(){	reg int		d, l;	for(d = 0; d <= SF_MAXCHAR; ++d)	{	_Sfcv36[d] = SF_RADIX;		_Sfcv64[d] = SF_RADIX;	}	/* [0-9] */	for(d = 0; d < 10; ++d)	{	_Sfcv36[(uchar)_Sfdigits[d]] = d;		_Sfcv64[(uchar)_Sfdigits[d]] = d;	}	/* [a-z] */	for(; d < 36; ++d)	{	_Sfcv36[(uchar)_Sfdigits[d]] = d;		_Sfcv64[(uchar)_Sfdigits[d]] = d;	}	/* [A-Z] */	for(l = 10; d < 62; ++l, ++d)	{	_Sfcv36[(uchar)_Sfdigits[d]] = l;		_Sfcv64[(uchar)_Sfdigits[d]] = d;	}	/* remaining digits */	for(; d < SF_RADIX; ++d)	{	_Sfcv36[(uchar)_Sfdigits[d]] = d;		_Sfcv64[(uchar)_Sfdigits[d]] = d;	}	_Sftype['d'] = _Sftype['i'] = SFFMT_INT;	_Sftype['u'] = _Sftype['o'] = _Sftype['x'] = _Sftype['X'] = SFFMT_UINT;	_Sftype['e'] = _Sftype['E'] = _Sftype['a'] = _Sftype['A'] =	_Sftype['g'] = _Sftype['G'] = _Sftype['f'] = SFFMT_FLOAT;	_Sftype['s'] = _Sftype['n'] = _Sftype['p'] = _Sftype['!'] = SFFMT_POINTER;	_Sftype['c'] = SFFMT_CHAR;	_Sftype['['] = SFFMT_CLASS;#if _has_multibyte	_Sftype['S'] = SFFMT_POINTER;	_Sftype['C'] = SFFMT_CHAR;#endif	/* floating point huge values */	memcpy((char*)&_Sffhuge, (char*)flt_nan, sizeof(_Sffhuge));	memcpy((char*)&_Sfdhuge, (char*)dbl_nan, sizeof(_Sfdhuge));#ifdef _ast_ldbl_nan_init	memcpy((char*)&_Sflhuge, (char*)ldbl_nan, sizeof(_Sflhuge));#else	memcpy((char*)&_Sflhuge, (char*)dbl_nan, sizeof(_Sfdhuge));#endif	return 1;}/* table for floating point and integer conversions */#include	"FEATURE/sfinit"

⌨️ 快捷键说明

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