Exemplo n.º 1
0
_STD_BEGIN

int _Getfld(_Sft *px)
	{	/* convert a field */
	px->stored = 0;
	switch (*px->s)
		{	/* switch on conversion specifier */
	case 'c':	/* convert an array of char */

 #if _HAS_FIXED_POINT
		if (px->qual == 'v')
			return (_Getcvec(px));
 #endif /* _HAS_FIXED_POINT */

		return (_Getstr(px, 0));

	case 'd': case 'i': case 'o':
	case 'u': case 'x': case 'X':

 #if _HAS_FIXED_POINT
		if (px->qual == 'v')
			return (_Geticvec(px));	/* v */
		else if (px->qual == 'w')
			return (_Getihvec(px));	/* hv or vh */
		else if (px->qual == 'W')
			return (_Getilvec(px));	/* hl or lh */
 #endif /* _HAS_FIXED_POINT */

	case 'p':	/* convert a pointer */
		return (_Getint(px, 0));	/* convert an integer */

	case 'e': case 'E':
	case 'g': case 'G':
	case 'f': case 'F':
	case 'a': case 'A':

 #if _HAS_FIXED_POINT
		if (px->qual == 'v')
			return (_Getfvec(px));
 #endif /* _HAS_FIXED_POINT */

		return (_Getfloat(px, 0));	/* convert a floating */

 #if _HAS_FIXED_POINT
	case 'k':	/* convert a fixed signed accumulator */
		return (_Fixed_get(px, FX_ACCUM));

	case 'K':	/* convert a fixed unsigned accumulator */
		return (_Fixed_get(px, FX_ACCUM | FX_UNSIGNED));

	case 'r':	/* convert a fixed signed fraction */
		return (_Fixed_get(px, 0));

	case 'R':	/* convert a fixed unsigned fraction */
		return (_Fixed_get(px, FX_UNSIGNED));
 #endif /* _HAS_FIXED_POINT */

	case 'n':	/* return input count */
		if (!px->noconv)
			switch (px->qual)
				{	/* store in specified integer type */
			case 'b':
				*va_arg(px->ap, signed char *) = (signed char)px->nchar;
				break;

			case 'q':
				*va_arg(px->ap, _Longlong *) = px->nchar;
				break;

			case 'j':
				*va_arg(px->ap, intmax_t *) = px->nchar;
				break;

			case 't':
				*va_arg(px->ap, ptrdiff_t *) = px->nchar;
				break;

			case 'z':
				*va_arg(px->ap, size_t *) = px->nchar;
				break;

			case 'h':
				*va_arg(px->ap, short *) = (short)px->nchar;
				break;

			case 'l':
				*va_arg(px->ap, long *) = px->nchar;
				break;

			default:
				*va_arg(px->ap, int *) = px->nchar;
				}
		return (1);

	case 'S':	/* convert a wide string -- nonstandard */
		px->qual = 'l';	/* fall through */

	case 's':	/* convert a string */
		return (_Getstr(px, 1));

	case '%':
		 {	/* match a '%' */
		int ch;

		if ((ch = GET(px)) == '%')
			return (1);
		UNGETN(px, ch);
		return (ch == EOF ? EOF : 0);
		 }

	case '[':	/* convert a scan set */
		return (_Getstr(px, -1));

	default:	/* undefined specifier, quit */
		return (0);
		}
		}
Exemplo n.º 2
0
int _Scanf(int (*pfn)(void *, int), void *arg,
	const char *fmt, va_list ap)
	{	/* read formatted */
	int nconv = 0;
	_Sft x;

	x.pfn = pfn;
	x.arg = arg;
	x.ap = ap;
	x.nchar = 0;
	for (x.s = fmt; ; ++x.s)
		{	/* parse format string */
		int ch;

		 {	/* match any literal or white-space */
		int n;
		wchar_t wc;
		_Mbsave state = {0};

		while (0 < (n = _Mbtowc(&wc, x.s, MB_CUR_MAX, &state)))
			{	/* check type of multibyte char */
			x.s += n;
			if (wc == '%')
				break;
			else if (wc <= UCHAR_MAX && isspace(wc))
				{	/* match any white-space */
				while (isspace(*x.s))
					++x.s;
				while (isspace(ch = GET(&x)))
					;
				UNGETN(&x, ch);
				}
			else	/* match literal text */
				for (x.s -= n; 0 <= --n; )
					if ((ch = GET(&x)) != *x.s++)
						{	/* bad match */
						UNGETN(&x, ch);
						return (nconv);
						}
			}
		if (*x.s == '\0')
			return (nconv);
		 }
		 {	/* process a conversion specifier */
		int code;

		x.noconv = *x.s == '*' ? *x.s++ : '\0';
		for (x.width = 0; isdigit(*x.s); ++x.s)
			if (x.width < _WMAX)
				x.width = x.width * 10 + *x.s - '0';
		x.qual = strchr("hlL", *x.s) ? *x.s++ : '\0';
		if (!strchr("cn[", *x.s))
			{	/* match leading white-space */
			while (isspace(ch = GET(&x)))
				;
			UNGETN(&x, ch);
			}
		if ((code = _Getfld(&x)) <= 0)
			return (nconv == 0 ? code : nconv);
		if (x.stored)
			++nconv;
		 }
		}
	}