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

📄 vfprintf.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 4 页
字号:
			while (*template) {				if ((*template == '%') && (*++template != '%')) {					ppfs.fmtpos = template;					_ppfs_parsespec(&ppfs); /* Can't fail. */					template = ppfs.fmtpos; /* Update to one past spec end. */					if (ppfs.info.width == INT_MIN) {						++count;						if (n > 0) {							*argtypes++ = PA_INT;							--n;						}					}					if (ppfs.info.prec == INT_MIN) {						++count;						if (n > 0) {							*argtypes++ = PA_INT;							--n;						}					}					for (i = 0 ; i < ppfs.num_data_args ; i++) {						if ((ppfs.argtype[i]) != __PA_NOARG) {							++count;							if (n > 0) {								*argtypes++ = ppfs.argtype[i];								--n;							}						}					}				} else {					++template;				}			}#ifdef NL_ARGMAX		}#endif /* NL_ARGMAX */	}	return count;}#endif/**********************************************************************/#ifdef L__ppfs_initint _ppfs_init(register ppfs_t *ppfs, const char *fmt0){	int r;	/* First, zero out everything... argnumber[], argtype[], argptr[] */	memset(ppfs, 0, sizeof(ppfs_t)); /* TODO: nonportable???? */#ifdef NL_ARGMAX	--ppfs->maxposarg;			/* set to -1 */#endif /* NL_ARGMAX */	ppfs->fmtpos = fmt0;#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Make checking of the format string in C locale an option.#endif#ifdef __UCLIBC_HAS_LOCALE__	/* To support old programs, don't check mb validity if in C locale. */	if (((__UCLIBC_CURLOCALE_DATA).encoding) != __ctype_encoding_7_bit) {		/* ANSI/ISO C99 requires format string to be a valid multibyte string		 * beginning and ending in its initial shift state. */		static const char invalid_mbs[] = "Invalid multibyte format string.";		mbstate_t mbstate;		const char *p;		mbstate.__mask = 0;	/* Initialize the mbstate. */		p = fmt0;		if (mbsrtowcs(NULL, &p, SIZE_MAX, &mbstate) == ((size_t)(-1))) {			ppfs->fmtpos = invalid_mbs;			return -1;		}	}#endif /* __UCLIBC_HAS_LOCALE__ */	/* now set all argtypes to no-arg */	{#if 1		/* TODO - use memset here since already "paid for"? */		register int *p = ppfs->argtype;				r = MAX_ARGS;		do {			*p++ = __PA_NOARG;		} while (--r);#else		/* TODO -- get rid of this?? */		register char *p = (char *) ((MAX_ARGS-1) * sizeof(int));		do {			*((int *)(((char *)ppfs) + ((int)p) + offsetof(ppfs_t,argtype))) = __PA_NOARG;			p -= sizeof(int);		} while (p);#endif	}	/*	 * Run through the entire format string to validate it and initialize	 * the positional arg numbers (if any).	 */	{		register const char *fmt = fmt0;		while (*fmt) {			if ((*fmt == '%') && (*++fmt != '%')) {				ppfs->fmtpos = fmt; /* back up to the '%' */				if ((r = _ppfs_parsespec(ppfs)) < 0) {					return -1;				}				fmt = ppfs->fmtpos;	/* update to one past end of spec */			} else {				++fmt;			}		}		ppfs->fmtpos = fmt0;		/* rewind */	}#ifdef NL_MAX_ARG	/* If we have positional args, make sure we know all the types. */	{		register int *p = ppfs->argtype;		r = ppfs->maxposarg;		while (--r >= 0) {			if ( *p == __PA_NOARG ) { /* missing arg type!!! */				return -1;			}			++p;		}	}#endif /* NL_MAX_ARG */	return 0;}#endif/**********************************************************************/#ifdef L__ppfs_prepargsvoid _ppfs_prepargs(register ppfs_t *ppfs, va_list arg){	int i;	va_copy(ppfs->arg, arg);#ifdef NL_ARGMAX	if ((i = ppfs->maxposarg) > 0)  { /* init for positional args */		ppfs->num_data_args = i;		ppfs->info.width = ppfs->info.prec = ppfs->maxposarg = 0;		_ppfs_setargs(ppfs);		ppfs->maxposarg = i;	}#endif /* NL_ARGMAX */}#endif/**********************************************************************/#ifdef L__ppfs_setargsvoid _ppfs_setargs(register ppfs_t *ppfs){#ifdef __va_arg_ptr	register void **p = ppfs->argptr;#else	register argvalue_t *p = ppfs->argvalue;#endif	int i;#ifdef NL_ARGMAX	if (ppfs->maxposarg == 0) {	/* initing for or no pos args */#endif /* NL_ARGMAX */		if (ppfs->info.width == INT_MIN) {			ppfs->info.width =#ifdef __va_arg_ptr				*(int *)#endif				GET_VA_ARG(p,u,unsigned int,ppfs->arg);		} 		if (ppfs->info.prec == INT_MIN) {			ppfs->info.prec =#ifdef __va_arg_ptr				*(int *)#endif				GET_VA_ARG(p,u,unsigned int,ppfs->arg);		}		i = 0;		while (i < ppfs->num_data_args) {			switch(ppfs->argtype[i++]) {				case (PA_INT|PA_FLAG_LONG_LONG):#ifdef ULLONG_MAX					GET_VA_ARG(p,ull,unsigned long long,ppfs->arg);					break;#endif				case (PA_INT|PA_FLAG_LONG):#if ULONG_MAX != UINT_MAX					GET_VA_ARG(p,ul,unsigned long,ppfs->arg);					break;#endif				case PA_CHAR:	/* TODO - be careful */ 					/* ... users could use above and really want below!! */				case (PA_INT|__PA_FLAG_CHAR):/* TODO -- translate this!!! */				case (PA_INT|PA_FLAG_SHORT):				case PA_INT:					GET_VA_ARG(p,u,unsigned int,ppfs->arg);					break;				case PA_WCHAR:	/* TODO -- assume int? */					/* we're assuming wchar_t is at least an int */					GET_VA_ARG(p,wc,wchar_t,ppfs->arg);					break;#ifdef __STDIO_PRINTF_FLOAT					/* PA_FLOAT */				case PA_DOUBLE:					GET_VA_ARG(p,d,double,ppfs->arg);					break;				case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE):					GET_VA_ARG(p,ld,long double,ppfs->arg);					break;#else  /* __STDIO_PRINTF_FLOAT */				case PA_DOUBLE:				case (PA_DOUBLE|PA_FLAG_LONG_DOUBLE):					assert(0);					continue;#endif /* __STDIO_PRINTF_FLOAT */				default:					/* TODO -- really need to ensure this can't happen */					assert(ppfs->argtype[i-1] & PA_FLAG_PTR);				case PA_POINTER:				case PA_STRING:				case PA_WSTRING:					GET_VA_ARG(p,p,void *,ppfs->arg);					break;								case __PA_NOARG:					continue;			}			++p;		}#ifdef NL_ARGMAX	} else {		if (ppfs->info.width == INT_MIN) {			ppfs->info.width				= (int) GET_ARG_VALUE(p + ppfs->argnumber[0] - 1,u,unsigned int);		} 		if (ppfs->info.prec == INT_MIN) {			ppfs->info.prec				= (int) GET_ARG_VALUE(p + ppfs->argnumber[1] - 1,u,unsigned int);		}	}#endif /* NL_ARGMAX */	/* Now we know the width and precision. */	if (ppfs->info.width < 0) {		ppfs->info.width = -ppfs->info.width;		PRINT_INFO_SET_FLAG(&(ppfs->info),left);		PRINT_INFO_CLR_FLAG(&(ppfs->info),space);		ppfs->info.pad = ' ';	}#if 0	/* NOTE -- keep neg for now so float knows! */	if (ppfs->info.prec < 0) {	/* spec says treat as omitted. */		/* so use default prec... 1 for everything but floats and strings. */		ppfs->info.prec = 1;	}#endif}#endif/**********************************************************************/#ifdef L__ppfs_parsespec/* Notes: argtype differs from glibc for the following: *         mine              glibc *  lc     PA_WCHAR          PA_CHAR       the standard says %lc means %C *  ls     PA_WSTRING        PA_STRING     the standard says %ls means %S *  {*}n   {*}|PA_FLAG_PTR   PA_FLAG_PTR   size of n can be qualified *//* TODO: store positions of positional args *//* TODO -- WARNING -- assumes aligned on integer boundaries!!! *//* TODO -- disable if not using positional args!!! */#define _OVERLAPPING_DIFFERENT_ARGS/* TODO -- rethink this -- perhaps we should set to largest type??? */#ifdef _OVERLAPPING_DIFFERENT_ARGS #define PROMOTED_SIZE_OF(X)		((sizeof(X) + sizeof(int) - 1) / sizeof(X))static const short int type_codes[] = {	__PA_NOARG,					/* must be first entry */	PA_POINTER,	PA_STRING,	PA_WSTRING,	PA_CHAR,	PA_INT|PA_FLAG_SHORT,	PA_INT,	PA_INT|PA_FLAG_LONG,	PA_INT|PA_FLAG_LONG_LONG,	PA_WCHAR,#ifdef __STDIO_PRINTF_FLOAT	/* PA_FLOAT, */	PA_DOUBLE,	PA_DOUBLE|PA_FLAG_LONG_DOUBLE,#endif /* __STDIO_PRINTF_FLOAT */};static const unsigned char type_sizes[] = {	/* unknown type consumes no arg */	0,							/* must be first entry */	PROMOTED_SIZE_OF(void *),	PROMOTED_SIZE_OF(char *),	PROMOTED_SIZE_OF(wchar_t *),	PROMOTED_SIZE_OF(char),	PROMOTED_SIZE_OF(short),	PROMOTED_SIZE_OF(int),	PROMOTED_SIZE_OF(long),#ifdef ULLONG_MAX	PROMOTED_SIZE_OF(long long),#else	PROMOTED_SIZE_OF(long),		/* TODO -- is this correct? (above too) */#endif	PROMOTED_SIZE_OF(wchar_t),#ifdef __STDIO_PRINTF_FLOAT	/* PROMOTED_SIZE_OF(float), */	PROMOTED_SIZE_OF(double),	PROMOTED_SIZE_OF(long double),#endif /* __STDIO_PRINTF_FLOAT */};static int _promoted_size(int argtype){	register const short int *p;	/* note -- since any unrecognized type is treated as a pointer */	p = type_codes + sizeof(type_codes)/sizeof(type_codes[0]);	do {		if (*--p == argtype) {			break;		}	} while (p > type_codes);	return type_sizes[(int)(p - type_codes)];}static int _is_equal_or_bigger_arg(int curtype, int newtype){	/* Quick test */	if (newtype == __PA_NOARG) {		return 0;	}	if ((curtype == __PA_NOARG) || (curtype == newtype)) {		return 1;	}	/* Ok... slot is already filled and types are different in name. */	/* So, compare promoted sizes of curtype and newtype args. */	return _promoted_size(curtype) <= _promoted_size(newtype);}#else#define _is_equal_or_bigger_arg(C,N)	(((C) == __PA_NOARG) || ((C) == (N)))#endif#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__/* TODO - do this differently? */static char _bss_custom_printf_spec[MAX_USER_SPEC]; /* 0-init'd for us.  */char *_custom_printf_spec = _bss_custom_printf_spec;printf_arginfo_function *_custom_printf_arginfo[MAX_USER_SPEC];printf_function _custom_printf_handler[MAX_USER_SPEC];#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */extern int _ppfs_parsespec(ppfs_t *ppfs){	register const char *fmt;	register const char *p;	int preci;	int width;	int flags;	int dataargtype;	int i;	int dpoint;#ifdef NL_ARGMAX	int maxposarg;#endif /* NL_ARGMAX */	int p_m_spec_chars;	int n;	int argtype[MAX_ARGS_PER_SPEC+2];	int argnumber[3];			/* width, precision, 1st data arg */	static const char spec_flags[] = SPEC_FLAGS;	static const char spec_chars[] = SPEC_CHARS;/* TODO: b? */	static const char spec_ranges[] = SPEC_RANGES;	static const short spec_or_mask[] = SPEC_OR_MASK;	static const short spec_and_mask[] = SPEC_AND_MASK;	static const char qual_chars[] = QUAL_CHARS;#ifdef __UCLIBC_HAS_WCHAR__	char buf[32];#endif /* __UCLIBC_HAS_WCHAR__ */	/* WIDE note: we can test against '%' here since we don't allow */	/* WIDE note: other mappings of '%' in the wide char set. */	preci = -1;	argnumber[0] = 0;	argnumber[1] = 0;	argtype[0] = __PA_NOARG;	argtype[1] = __PA_NOARG;#ifdef NL_ARGMAX	maxposarg = ppfs->maxposarg;#endif /* NL_ARGMAX */#ifdef __UCLIBC_HAS_WCHAR__	/* This is somewhat lame, but saves a lot of code.  If we're dealing with	 * a wide stream, that means the format is a wchar string.  So, copy it	 * char-by-char into a normal char buffer for processing.  Make the buffer	 * (buf) big enough so that any reasonable format specifier will fit.	 * While there a legal specifiers that won't, the all involve duplicate	 * flags or outrageous field widths/precisions. */	width = dpoint = 0;	if ((flags = ppfs->info._flags & FLAG_WIDESTREAM) == 0) {		fmt = ppfs->fmtpos;	} else {		fmt = buf + 1;		i = 0;		do {			if ((buf[i] = (char) (((wchar_t *) ppfs->fmtpos)[i-1]))				!= (((wchar_t *) ppfs->fmtpos)[i-1])				) {				return -1;			}		} while (buf[i++]);		buf[sizeof(buf)-1] = 0;	}#else  /* __UCLIBC_HAS_WCHAR__ */	width = flags = dpoint = 0;	fmt = ppfs->fmtpos;#endif /* __UCLIBC_HAS_WCHAR__ */	assert(fmt[-1] == '%');	assert(fmt[0] != '%');	/* Process arg pos and/or flags and/or width and/or precision. */ width_precision:	p = fmt;	if (*fmt == '*') {		argtype[-dpoint] = PA_INT;		++fmt;	}	i = 0;	while (isdigit(*fmt)) {		if (i < MAX_FIELD_WIDTH) { /* Avoid overflow. */			i = (i * 10) + (*fmt - '0');		}		++fmt;	}	if (p[-1] == '%') { /* Check for a position. */		/* TODO: if val not in range, then error */#ifdef NL_ARGMAX		if ((*fmt == '$') && (i > 0)) {/* Positional spec. */			++fmt;			if (maxposarg == 0) {				return -1;			}			if ((argnumber[2] = i) > maxposarg) {				maxposarg = i;			}			/* Now fall through to check flags. */		} else {			if (maxposarg > 0) {#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Support prec and width for %m when positional args used				/* Actually, positional arg processing will fail in general				 * for specifiers that don't require an arg. */#endif /* __UCLIBC_MJN3_ONLY__ */				if (*fmt == 'm') {					goto PREC_WIDTH;				}#endif /* __UCLIBC_HAS_PRINTF_M_SPEC__ */				return -1;

⌨️ 快捷键说明

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