mbftowc.c revision 6b5e5868e7ebf1aff3a5abd7d0c4ef0e5fbf3648
/*
* This file and its contents are supplied under the terms of the
* Common Development and Distribution License ("CDDL"), version 1.0.
* You may only use this file in accordance with the terms version
* 1.0 of the CDDL.
*
* A full copy of the text of the CDDL should have accompanied this
* source. A copy is of the CDDL is also available via the Internet
* at http://www.illumos.org/license/CDDL.
*/
/*
* Copyright 2010 Nexenta Systems, Inc. All rights reserved.
*/
#include "lint.h"
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
/*
* This function is apparently referenced by parts of ON. It is
* not intended for public API usage -- and it is not documented.
*
* The usage appears to be to consume bytes until a character is
* gathered, using a supplied function. It reads exactly one
* character and returns the number of bytes in the multibyte string
* that were consumed.
*
* The string "s" is storage for the multibyte string, the
* wc will receive the interpreted character, the peek function
* obtains the next character (as an int so we can get EOF),
* and errorc is stuffed with the character that is responsible
* for a parse error, if any.
*/
int
_mbftowc(char *s, wchar_t *wc, int (*peek)(void), int *errorc)
{
int c;
mbstate_t mbs;
char *start = s;
size_t cons = 0;
for (;;) {
c = peek();
if (c < 0) {
/* No bytes returned? */
return (s - start);
}
*s = (char)c;
s++;
(void) memset(&mbs, 0, sizeof (mbs));
cons = mbrtowc(wc, start, s - start, &mbs);
if ((int)cons >= 0) {
/* fully translated character */
return (cons);
}
if (cons == (size_t)-2) {
/* incomplete, recycle */
continue;
}
/*
* Parse error, don't consider the first character part
* of the error.
*/
s--;
cons = (s - start);
*errorc = c >= 0 ? c : 0;
break;
}
return (cons);
}