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

📄 vfprintf.c

📁 Axis 221 camera embedded programing interface
💻 C
📖 第 1 页 / 共 4 页
字号:
	static const wchar_t prefix[] = L"+\0-\0 \0000x\0000X";#endif /* L_vfprintf */	enum {		PREFIX_PLUS = 0,		PREFIX_MINUS = 2,		PREFIX_SPACE = 4,		PREFIX_LWR_X = 6,		PREFIX_UPR_X = 9,		PREFIX_NONE = 11	};#ifdef __va_arg_ptr	const void * const *argptr;#else	const void * argptr[MAX_ARGS_PER_SPEC];#endif	int *argtype;#ifdef __UCLIBC_HAS_WCHAR__	const wchar_t *ws = NULL;	mbstate_t mbstate;#endif /* __UCLIBC_HAS_WCHAR__ */	size_t slen;#ifdef L_vfprintf#define SLEN slen#else	size_t SLEN;	wchar_t wbuf[2];#endif	int base;	int numpad;	int alphacase;	int numfill = 0;			/* TODO: fix */	int prefix_num = PREFIX_NONE;	char padchar = ' ';#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Determine appropriate buf size.#endif /* __UCLIBC_MJN3_ONLY__ */	/* TODO: buf needs to be big enough for any possible error return strings	 * and also for any locale-grouped long long integer strings generated.	 * This should be large enough for any of the current archs/locales, but	 * eventually this should be handled robustly. */	char buf[128];#ifdef NDEBUG	_ppfs_parsespec(ppfs);#else	if (_ppfs_parsespec(ppfs) < 0) { /* TODO: just for debugging */		abort();	}#endif	_ppfs_setargs(ppfs);	argtype = ppfs->argtype + ppfs->argnumber[2] - 1;	/* Deal with the argptr vs argvalue issue. */#ifdef __va_arg_ptr	argptr = (const void * const *) ppfs->argptr;#ifdef NL_ARGMAX	if (ppfs->maxposarg > 0) {	/* Using positional args... */		argptr += ppfs->argnumber[2] - 1;	}#endif /* NL_ARGMAX */#else	/* Need to build a local copy... */	{		register argvalue_t *p = ppfs->argvalue;		int i;#ifdef NL_ARGMAX		if (ppfs->maxposarg > 0) {	/* Using positional args... */			p += ppfs->argnumber[2] - 1;		}#endif /* NL_ARGMAX */		for (i = 0 ; i < ppfs->num_data_args ; i++ ) {			argptr[i] = (void *) p++;		}	}#endif	{		register char *s = NULL; /* TODO: Should s be unsigned char * ? */		if (ppfs->conv_num == CONV_n) {			_store_inttype(*(void **)*argptr,						   ppfs->info._flags & __PA_INTMASK,						   (intmax_t) (*count));			return 0;		}		if (ppfs->conv_num <= CONV_i) {	/* pointer or (un)signed int */			alphacase = __UIM_LOWER;#ifdef __UCLIBC_MJN3_ONLY__#ifdef L_vfprintf#warning CONSIDER: Should we ignore these flags if stub locale?  What about custom specs?#endif#endif /* __UCLIBC_MJN3_ONLY__ */			if ((base = spec_base[(int)(ppfs->conv_num - CONV_p)]) == 10) {				if (PRINT_INFO_FLAG_VAL(&(ppfs->info),group)) {					alphacase = __UIM_GROUP;				}				if (PRINT_INFO_FLAG_VAL(&(ppfs->info),i18n)) {					alphacase |= 0x80;				}			}			if (ppfs->conv_num <= CONV_u) { /* pointer or unsigned int */				if (ppfs->conv_num == CONV_X) {					alphacase = __UIM_UPPER;				}				if (ppfs->conv_num == CONV_p) { /* pointer */					prefix_num = PREFIX_LWR_X;				} else {		/* unsigned int */				}			} else {			/* signed int */				base = -base;			}			if (ppfs->info.prec < 0) { /* Ignore '0' flag if prec specified. */				padchar = ppfs->info.pad;			}#ifdef __UCLIBC_MJN3_ONLY__#ifdef L_vfprintf#warning CONSIDER: If using outdigits and/or grouping, how should we interpret precision?#endif#endif /* __UCLIBC_MJN3_ONLY__ */			s = _uintmaxtostr(buf + sizeof(buf) - 1,							  (uintmax_t)							  _load_inttype(*argtype & __PA_INTMASK,											*argptr, base), base, alphacase);			if (ppfs->conv_num > CONV_u) { /* signed int */				if (*s == '-') {					PRINT_INFO_SET_FLAG(&(ppfs->info),showsign);					++s;		/* handle '-' in the prefix string */					prefix_num = PREFIX_MINUS;				} else if (PRINT_INFO_FLAG_VAL(&(ppfs->info),showsign)) {					prefix_num = PREFIX_PLUS;				} else if (PRINT_INFO_FLAG_VAL(&(ppfs->info),space)) {					prefix_num = PREFIX_SPACE;				}			}			slen = (char *)(buf + sizeof(buf) - 1) - s;#ifdef L_vfwprintf			{				const char *q = s;				mbstate.__mask = 0; /* Initialize the mbstate. */				SLEN = mbsrtowcs(NULL, &q, 0, &mbstate);			}#endif			numfill = ((ppfs->info.prec < 0) ? 1 : ppfs->info.prec);			if (PRINT_INFO_FLAG_VAL(&(ppfs->info),alt)) {				if (ppfs->conv_num <= CONV_x) {	/* x or p */					prefix_num = PREFIX_LWR_X;				}				if (ppfs->conv_num == CONV_X) {					prefix_num = PREFIX_UPR_X;				}				if ((ppfs->conv_num == CONV_o) && (numfill <= SLEN)) {					numfill = ((*s == '0') ? 1 : SLEN + 1);				}			}			if (*s == '0') {				if (prefix_num >= PREFIX_LWR_X) {					prefix_num = PREFIX_NONE;				}				if (ppfs->conv_num == CONV_p) {/* null pointer */					s = "(nil)";#ifdef L_vfwprintf					SLEN =#endif					slen = 5;					numfill = 0;				} else if (numfill == 0) {	/* if precision 0, no output */#ifdef L_vfwprintf					SLEN =#endif					slen = 0;				}			}			numfill = ((numfill > SLEN) ? numfill - SLEN : 0);		} else if (ppfs->conv_num <= CONV_A) {	/* floating point */#ifdef __STDIO_PRINTF_FLOAT			*count +=				_fpmaxtostr(stream,							(__fpmax_t)							(PRINT_INFO_FLAG_VAL(&(ppfs->info),is_long_double)							 ? *(long double *) *argptr							 : (long double) (* (double *) *argptr)),							&ppfs->info, FP_OUT );			return 0;#else  /* __STDIO_PRINTF_FLOAT */			return -1;			/* TODO -- try to continue? */#endif /* __STDIO_PRINTF_FLOAT */		} else if (ppfs->conv_num <= CONV_S) {	/* wide char or string */#ifdef L_vfprintf#ifdef __UCLIBC_HAS_WCHAR__			mbstate.__mask = 0;	/* Initialize the mbstate. */			if (ppfs->conv_num == CONV_S) { /* wide string */				if (!(ws = *((const wchar_t **) *argptr))) {					goto NULL_STRING;				}				/* We use an awful uClibc-specific hack here, passing				 * (char*) &ws as the conversion destination.  This signals				 * uClibc's wcsrtombs that we want a "restricted" length				 * such that the mbs fits in a buffer of the specified				 * size with no partial conversions. */				if ((slen = wcsrtombs((char *) &ws, &ws, /* Use awful hack! */									  ((ppfs->info.prec >= 0)									   ? ppfs->info.prec									   : SIZE_MAX), &mbstate))					== ((size_t)-1)					) {					return -1;	/* EILSEQ */				}			} else {			/* wide char */				s = buf;				slen = wcrtomb(s, (*((const wchar_t *) *argptr)), &mbstate);				if (slen == ((size_t)-1)) {					return -1;	/* EILSEQ */				}				s[slen] = 0;	/* TODO - Is this necessary? */			}#else  /* __UCLIBC_HAS_WCHAR__ */			return -1;#endif /* __UCLIBC_HAS_WCHAR__ */		} else if (ppfs->conv_num <= CONV_s) {	/* char or string */			if (ppfs->conv_num == CONV_s) { /* string */				s = *((char **) (*argptr));				if (s) {#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__				SET_STRING_LEN:#endif					slen = strnlen(s, ((ppfs->info.prec >= 0)									   ? ppfs->info.prec : SIZE_MAX));				} else {#ifdef __UCLIBC_HAS_WCHAR__				NULL_STRING:#endif					s = "(null)";					slen = 6;				}			} else {			/* char */				s = buf;				*s = (unsigned char)(*((const int *) *argptr));				s[1] = 0;				slen = 1;			}#else  /* L_vfprintf */			if (ppfs->conv_num == CONV_S) { /* wide string */				ws = *((wchar_t **) (*argptr));				if (!ws) {					goto NULL_STRING;				}				SLEN = wcsnlen(ws, ((ppfs->info.prec >= 0)									? ppfs->info.prec : SIZE_MAX));			} else {			/* wide char */				*wbuf = (wchar_t)(*((const wint_t *) *argptr));			CHAR_CASE:				ws = wbuf;				wbuf[1] = 0;				SLEN = 1;			}		} else if (ppfs->conv_num <= CONV_s) {	/* char or string */			if (ppfs->conv_num == CONV_s) { /* string */#ifdef __UCLIBC_MJN3_ONLY__#warning TODO: Fix %s for vfwprintf... output upto illegal sequence?#endif /* __UCLIBC_MJN3_ONLY__ */				s = *((char **) (*argptr));				if (s) {#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__				SET_STRING_LEN:#endif					/* We use an awful uClibc-specific hack here, passing					 * (wchar_t*) &mbstate as the conversion destination.					 *  This signals uClibc's mbsrtowcs that we want a					 * "restricted" length such that the mbs fits in a buffer					 * of the specified size with no partial conversions. */					{						const char *q = s;						mbstate.__mask = 0;	/* Initialize the mbstate. */						SLEN = mbsrtowcs((wchar_t *) &mbstate, &q,										 ((ppfs->info.prec >= 0)										  ? ppfs->info.prec : SIZE_MAX),										 &mbstate);					}					if (SLEN == ((size_t)(-1))) {						return -1;	/* EILSEQ */					}				} else {				NULL_STRING:					s = "(null)";					SLEN = slen = 6;				}			} else {			/* char */				*wbuf = btowc( (unsigned char)(*((const int *) *argptr)) );				goto CHAR_CASE;			}#endif /* L_vfprintf */#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__		} else if (ppfs->conv_num == CONV_m) {			s = _glibc_strerror_r(errno, buf, sizeof(buf));			goto SET_STRING_LEN;#endif		} else {#ifdef __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__			assert(ppfs->conv_num == CONV_custom0);			s = _custom_printf_spec;			do {				if (*s == ppfs->info.spec) {					int rv;					/* TODO -- check return value for sanity? */					rv = (*_custom_printf_handler						  [(int)(s-_custom_printf_spec)])						(stream, &ppfs->info, argptr);					if (rv < 0) {						return -1;					}					*count += rv;					return 0;				}			} while (++s < (_custom_printf_spec + MAX_USER_SPEC));#endif /* __UCLIBC_HAS_GLIBC_CUSTOM_PRINTF__ */			assert(0);			return -1;		}#ifdef __UCLIBC_MJN3_ONLY__#ifdef L_vfprintf#warning CONSIDER: If using outdigits and/or grouping, how should we pad?#endif#endif /* __UCLIBC_MJN3_ONLY__ */		{			size_t t;			t = SLEN + numfill;			if (prefix_num != PREFIX_NONE) {				t += ((prefix_num < PREFIX_LWR_X) ? 1 : 2);			}			numpad = ((ppfs->info.width > t) ? (ppfs->info.width - t) : 0);			*count += t + numpad;		}		if (padchar == '0') { /* TODO: check this */			numfill += numpad;			numpad = 0;		}		/* Now handle the output itself. */		if (!PRINT_INFO_FLAG_VAL(&(ppfs->info),left)) {			_charpad(stream, ' ', numpad);			numpad = 0;		}		OUTPUT(stream, prefix + prefix_num);		_charpad(stream, '0', numfill);#ifdef L_vfprintf#ifdef __UCLIBC_HAS_WCHAR__		if (!ws) {			assert(s);			_outnstr(stream, s, slen);		} else {				/* wide string */			size_t t;			mbstate.__mask = 0;	/* Initialize the mbstate. */			while (slen) {				t = (slen <= sizeof(buf)) ? slen : sizeof(buf);				t = wcsrtombs(buf, &ws, t, &mbstate);				assert (t != ((size_t)(-1)));				_outnstr(stream, buf, t);				slen -= t;			}		}#else  /* __UCLIBC_HAS_WCHAR__ */		_outnstr(stream, s, slen);#endif /* __UCLIBC_HAS_WCHAR__ */#else  /* L_vfprintf */		if (!ws) {			assert(s);			_outnstr(stream, s, SLEN);		} else {			_outnwcs(stream, ws, SLEN);		}#endif /* L_vfprintf */		_charpad(stream, ' ', numpad);	}	return 0;}int VFPRINTF (FILE * __restrict stream,			  register const FMT_TYPE * __restrict format,			  va_list arg){	ppfs_t ppfs;	int count, r;	register const FMT_TYPE *s;	__STDIO_AUTO_THREADLOCK_VAR;	__STDIO_AUTO_THREADLOCK(stream);	count = 0;	s = format;	if #ifdef L_vfprintf	(!__STDIO_STREAM_IS_NARROW_WRITING(stream)	 && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_NARROW))#else	(!__STDIO_STREAM_IS_WIDE_WRITING(stream)	 && __STDIO_STREAM_TRANS_TO_WRITE(stream, __FLAG_WIDE))#endif	{		count = -1;	} else if (_PPFS_init(&ppfs, format) < 0) {	/* Bad format string. */		OUTNSTR(stream, (const FMT_TYPE *) ppfs.fmtpos,				STRLEN((const FMT_TYPE *)(ppfs.fmtpos)));#if defined(L_vfprintf) && !defined(NDEBUG)		fprintf(stderr,"\nIMbS: \"%s\"\n\n", format);#endif		count = -1;	} else {		_ppfs_prepargs(&ppfs, arg);	/* This did a va_copy!!! */		do {			while (*format && (*format != '%')) {				++format;			}			if (format-s) {		/* output any literal text in format string */				if ( (r = OUTNSTR(stream, s, format-s)) < 0) {					count = -1;					break;				}				count += r;			}			if (!*format) {			/* we're done */				break;			}					if (format[1] != '%') {	/* if we get here, *format == '%' */				/* TODO: _do_one_spec needs to know what the output funcs are!!! */				ppfs.fmtpos = (const char *)(++format);				/* TODO: check -- should only fail on stream error */				if ( (r = _do_one_spec(stream, &ppfs, &count)) < 0) {					count = -1;					break;				}				s = format = (const FMT_TYPE *) ppfs.fmtpos;			} else {			/* %% means literal %, so start new string */				s = ++format;				++format;			}		} while (1);		va_end(ppfs.arg);		/* Need to clean up after va_copy! */	}/* #if defined(L_vfprintf) && defined(__UCLIBC_HAS_WCHAR__) *//*  DONE: *//* #endif */	__STDIO_AUTO_THREADUNLOCK(stream);	return count;}#endif/**********************************************************************/

⌨️ 快捷键说明

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