xref: /illumos-gate/usr/src/lib/libc/port/locale/mbftowc.c (revision 5aec55eb)
15ffa97faSGarrett D'Amore /*
26b5e5868SGarrett D'Amore  * This file and its contents are supplied under the terms of the
36b5e5868SGarrett D'Amore  * Common Development and Distribution License ("CDDL"), version 1.0.
4*5aec55ebSGarrett D'Amore  * You may only use this file in accordance with the terms of version
56b5e5868SGarrett D'Amore  * 1.0 of the CDDL.
65ffa97faSGarrett D'Amore  *
76b5e5868SGarrett D'Amore  * A full copy of the text of the CDDL should have accompanied this
8*5aec55ebSGarrett D'Amore  * source.  A copy of the CDDL is also available via the Internet at
9*5aec55ebSGarrett D'Amore  * http://www.illumos.org/license/CDDL.
106b5e5868SGarrett D'Amore  */
116b5e5868SGarrett D'Amore 
126b5e5868SGarrett D'Amore /*
136b5e5868SGarrett D'Amore  * Copyright 2010 Nexenta Systems, Inc.  All rights reserved.
145ffa97faSGarrett D'Amore  */
155ffa97faSGarrett D'Amore 
165ffa97faSGarrett D'Amore #include "lint.h"
175ffa97faSGarrett D'Amore #include <stdlib.h>
185ffa97faSGarrett D'Amore #include <string.h>
195ffa97faSGarrett D'Amore #include <wchar.h>
205ffa97faSGarrett D'Amore 
215ffa97faSGarrett D'Amore /*
225ffa97faSGarrett D'Amore  * This function is apparently referenced by parts of ON.  It is
235ffa97faSGarrett D'Amore  * not intended for public API usage -- and it is not documented.
245ffa97faSGarrett D'Amore  *
255ffa97faSGarrett D'Amore  * The usage appears to be to consume bytes until a character is
265ffa97faSGarrett D'Amore  * gathered, using a supplied function.   It reads exactly one
275ffa97faSGarrett D'Amore  * character and returns the number of bytes in the multibyte string
285ffa97faSGarrett D'Amore  * that were consumed.
295ffa97faSGarrett D'Amore  *
305ffa97faSGarrett D'Amore  * The string "s" is storage for the multibyte string, the
315ffa97faSGarrett D'Amore  * wc will receive the interpreted character, the peek function
325ffa97faSGarrett D'Amore  * obtains the next character (as an int so we can get EOF),
335ffa97faSGarrett D'Amore  * and errorc is stuffed with the character that is responsible
345ffa97faSGarrett D'Amore  * for a parse error, if any.
355ffa97faSGarrett D'Amore  */
365ffa97faSGarrett D'Amore 
375ffa97faSGarrett D'Amore int
_mbftowc(char * s,wchar_t * wc,int (* peek)(void),int * errorc)385ffa97faSGarrett D'Amore _mbftowc(char *s, wchar_t *wc, int (*peek)(void), int *errorc)
395ffa97faSGarrett D'Amore {
405ffa97faSGarrett D'Amore 	int		c;
415ffa97faSGarrett D'Amore 	mbstate_t	mbs;
425ffa97faSGarrett D'Amore 	char		*start = s;
43eda71b4aSGarrett D'Amore 	size_t		cons = 0;
445ffa97faSGarrett D'Amore 
455ffa97faSGarrett D'Amore 	for (;;) {
465ffa97faSGarrett D'Amore 		c = peek();
475ffa97faSGarrett D'Amore 		if (c < 0) {
485ffa97faSGarrett D'Amore 			/* No bytes returned? */
495ffa97faSGarrett D'Amore 			return (s - start);
505ffa97faSGarrett D'Amore 		}
515ffa97faSGarrett D'Amore 
525ffa97faSGarrett D'Amore 		*s = (char)c;
535ffa97faSGarrett D'Amore 		s++;
545ffa97faSGarrett D'Amore 
555ffa97faSGarrett D'Amore 		(void) memset(&mbs, 0, sizeof (mbs));
565ffa97faSGarrett D'Amore 		cons = mbrtowc(wc, start, s - start, &mbs);
57eda71b4aSGarrett D'Amore 		if ((int)cons >= 0) {
585ffa97faSGarrett D'Amore 			/* fully translated character */
595ffa97faSGarrett D'Amore 			return (cons);
605ffa97faSGarrett D'Amore 		}
61eda71b4aSGarrett D'Amore 		if (cons == (size_t)-2) {
625ffa97faSGarrett D'Amore 			/* incomplete, recycle */
635ffa97faSGarrett D'Amore 			continue;
645ffa97faSGarrett D'Amore 		}
655ffa97faSGarrett D'Amore 
665ffa97faSGarrett D'Amore 		/*
675ffa97faSGarrett D'Amore 		 * Parse error, don't consider the first character part
685ffa97faSGarrett D'Amore 		 * of the error.
695ffa97faSGarrett D'Amore 		 */
705ffa97faSGarrett D'Amore 		s--;
715ffa97faSGarrett D'Amore 		cons = (s - start);
725ffa97faSGarrett D'Amore 		*errorc = c >= 0 ?  c : 0;
735ffa97faSGarrett D'Amore 		break;
745ffa97faSGarrett D'Amore 	}
755ffa97faSGarrett D'Amore 
765ffa97faSGarrett D'Amore 	return (cons);
775ffa97faSGarrett D'Amore }
78