Пример #1
0
size_t (mbstowcs)(wchar_t *wcs, const char *s, size_t n)
	{	/* translate multibyte string to wide char string */
	int i;
	wchar_t *pwc;
	_Mbsave state = {0};

	for (pwc = wcs; 0 < n; ++pwc, --n)
		{	/* make another wide character */
		i = _Mbtowc(pwc, s, MB_CUR_MAX, &state);
		if (i == -1)
			return (-1);
		else if (i == 0 || *pwc == 0)
			return (pwc - wcs);
		s += i;
		}
	return (pwc - wcs);
	}
Пример #2
0
_STD_BEGIN

wint_t (fgetwc)(FILE *str)
	{	/* get a wchar_t from wide stream */
	_Lockfileatomic(str);
	if (str->_WRback < str->_WBack
		 + sizeof (str->_WBack) / sizeof (wchar_t))
		{	/* deliver putback character */
		wint_t ch = *str->_WRback++;

		_Unlockfileatomic(str);
		return (ch);
		}

	for (; ; )
		{	/* loop until wide char built */
		int nc;
		size_t nbuf;
		size_t nback = str->_Back + sizeof (str->_Back) - str->_Rback;
		unsigned char *pbuf;
		wchar_t wc;

		if (0 < nback && (str->_Mode & _MWIDE) != 0)
			pbuf = str->_Rback, nbuf = nback;
		else if (str->_Next < str->_WRend || 0 < _WFrprep(str))
			pbuf = str->_Next, nbuf = str->_WRend - str->_Next;
		else
			{	/* nothing to read */
			_Unlockfileatomic(str);
			return (WEOF);
			}

		switch (nc = _Mbtowc(&wc, (const char *)pbuf, nbuf, &str->_Wstate))
			{	/* check completion code */
		case -2:	/* not done yet */
			if (sizeof (str->_Back) <= nbuf)
				nback = 0;	/* more chars won't help, signal failure */
			else if (nback == 0)
				{	/* set up buffer in str->_Back area */
				str->_Rback = str->_Back + sizeof (str->_Back) - nbuf;
				memcpy(str->_Rback, str->_Next, nbuf);
				str->_Next += nbuf;
				nback = nbuf;
				}

			if (nback == 0)
				;	/* report failure */
			else if (0 < _WFrprep(str))
				{	/* add chars to _Back buffer and retry */
				nbuf = str->_WRend - str->_Next;
				if (sizeof (str->_Back) - nback < nbuf)
					nbuf = sizeof (str->_Back) - nback;
				pbuf = ((str->_Back + sizeof (str->_Back)) - nbuf) - nback;
				memmove(pbuf, str->_Rback, nback);
				memcpy(pbuf + nback, str->_Next, nbuf);
				str->_Rback = pbuf;
				str->_Next += nbuf;
				break;
				}
			/* fall through */

		case -1:	/* bad multibyte character */
			str->_Mode |= _MERR;
			_Unlockfileatomic(str);
			return (WEOF);

		case 0:	/* may be null character */
			if (wc == L'\0')
				nc = strlen((const char *)pbuf) + 1;
			/* fall through */

		default:	/* got a wide character */
			if (nc == -3)
				nc = 0;	/* generated a wide character from state info */
			if (0 < nback)
				str->_Rback += nc;
			else
				str->_Next +=  nc;
			_Unlockfileatomic(str);
			return (wc);
			}
		}
	}
Пример #3
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;
		 }
		}
	}
Пример #4
0
_STD_BEGIN

#define NSTACK	3	/* depth of format nesting stack */

size_t _Wcsftime(wchar_t *buf, size_t bufsize,
	const char *fmt, size_t len, const struct tm *t)
	{	/* format and widen time information */
	const char *fmtsav[NSTACK] = { NULL };
	size_t lensav[NSTACK] = { 0 };
	size_t nstack = 0;
	wchar_t *ibuf = buf;
	_Mbstinit(mbst);

	while (0 < len || 0 < nstack)
		{	/* parse format string */
		int n;
		wchar_t wc = L'\0';

		if (len == 0)
			fmt = fmtsav[--nstack], len = lensav[nstack];
		if ((n = _Mbtowc(&wc, fmt, len, &mbst)) <= 0)
			n = *fmt == '\0' ? 0 : 1;	/* bad parse, eat one char */
		fmt += n, len -= n;
		if (wc == L'\0')
			;	/* discard any trailer */
		else if (bufsize == 0)
			return (0);	/* not enough room */
		else if (wc != L'%' || len == 0)
			*buf++ = wc, --bufsize;
		else
			{	/* do the conversion */
			char ac[20];
			char qual = (char)(*fmt == 'E' || *fmt == 'O' ? *fmt++ : '\0');
			int m;
			const char *p;

			p = _Gentime(t, _TLS_DATA_PTR(_Times), qual, *fmt, &m, ac);
			if (qual != '\0')
				--len;
			++fmt, --len;
			if (0 < m)
				{	/* parse conversion string */
				_Mbstinit(mbst2);

				for (; 0 < m; p += n, m -= n)
					if ((n = _Mbtowc(&wc, p, m, &mbst2)) <= 0)
						break;
					else if (bufsize == 0)
						return (0);
					else
						*buf++ = wc, --bufsize;
				}
			else if (len == 0 || NSTACK <= nstack)
				fmt = p, len = -m;	/* tail recursion or stack full */
			else
				{	/* add leftover format to stack */
				fmtsav[nstack] = fmt, fmt = p;
				lensav[nstack++] = len, len = -m;
				}
			}
		}
	return (buf - ibuf);
	}
Пример #5
0
int (mblen)(const char *s, size_t n)
{   /*	determine length of next multibyte code */
    return (_Mbtowc(NULL, s, n, &_Mbxlen));
}