int mbsprint(const char *mbs, int print) { wchar_t wc; int len; /* length in bytes of UTF-8 encoded string */ int width; /* display width of a single Unicode char */ int total_width; /* display width of the whole string */ for (total_width = 0; *mbs != '\0'; mbs += len) { if ((len = mbtowc(&wc, mbs, MB_CUR_MAX)) == -1) { (void)mbtowc(NULL, NULL, MB_CUR_MAX); if (print) putchar(f_nonprint ? '?' : *mbs); total_width++; len = 1; } else if ((width = wcwidth(wc)) == -1) { if (print) { if (f_nonprint) putchar('?'); else fwrite(mbs, 1, len, stdout); } total_width++; } else { if (print) fwrite(mbs, 1, len, stdout); total_width += width; } } return total_width; }
wint_t my_getwc(FILE * s) { /* assuming no encoding ever consumes more than 16 bytes */ char i[MAX_ENC_BYTES]; int byte = 0; int convert; int x; wchar_t rval; while (1) { i[byte] = getc(s); if (i[byte] == EOF) { return WEOF; } byte++; errno = 0; mbtowc(NULL, NULL, 0); convert = mbtowc(&rval, i, byte); x = errno; if (convert > 0) { /* legal conversion */ return rval; } if (byte == MAX_ENC_BYTES) { while (byte > 1) { /* at least *try* to fix up */ ungetc(i[--byte], s); } errno = -EILSEQ; return WEOF; } } }
static int break_word(gchar *str, int width) { size_t i; int len = xstrlen(str); #if USE_UNICODE int sum = 0; mbtowc(NULL, NULL, 0); for (i = 0; i < len && sum<width; ) { wchar_t ch; int ch_len = mbtowc(&ch, &str[i], len - i); if (ch_len!=-1) { int wc_width = wcwidth(ch); if (wc_width == -1) wc_width = 1; if (sum + wc_width > width) break; sum += wc_width; i += ch_len; } else { i++; sum++; } } #else i = (len>=width ? width : len); #endif return i; }
static inline int xmbswidth(const char *s, size_t n) { #ifdef USE_UNICODE size_t i; int res = 0; mbtowc(NULL, NULL, 0); for (i = 0; i < n; ) { wchar_t ch; int ch_len; ch_len = mbtowc(&ch, &s[i], n - i); if (ch_len != -1) { int wc_width = wcwidth(ch); if (wc_width == -1) wc_width = 1; res += wc_width; i += ch_len; } else { i++; res++; } } return res; #else return n; #endif }
int main (void) { wchar_t wc; if (setlocale (LC_CTYPE, "de_DE.UTF-8") == NULL) { puts ("setlocale failed"); return 1; } if (mbtowc (&wc, "\xc3\xa1", MB_CUR_MAX) != 2 || wc != 0xE1) { puts ("1st mbtowc failed"); return 1; } if (mbtowc (&wc, "\xc3\xa1", SIZE_MAX) != 2 || wc != 0xE1) { puts ("2nd mbtowc failed"); return 1; } return 0; }
int getopt(int argc, char * const argv[], const char *optstring) { int i; wchar_t c, d; int k, l; char *optchar; if (!optind || __optreset) { __optreset = 0; __optpos = 0; optind = 1; } if (optind >= argc || !argv[optind] || argv[optind][0] != '-' || !argv[optind][1]) return -1; if (argv[optind][1] == '-' && !argv[optind][2]) return optind++, -1; if (!optpos) optpos++; if ((k = mbtowc(&c, argv[optind]+optpos, MB_LEN_MAX)) < 0) { k = 1; c = 0xfffd; /* replacement char */ } optchar = argv[optind]+optpos; optopt = c; optpos += k; if (!argv[optind][optpos]) { optind++; optpos = 0; } for (i=0; (l = mbtowc(&d, optstring+i, MB_LEN_MAX)) && d!=c; i+=l>0?l:1); if (d != c) { if (optstring[0] != ':' && opterr) { write(2, argv[0], strlen(argv[0])); write(2, ": illegal option: ", 18); write(2, optchar, k); write(2, "\n", 1); } return '?'; } if (optstring[i+1] == ':') { if (optind >= argc) { if (optstring[0] == ':') return ':'; if (opterr) { write(2, argv[0], strlen(argv[0])); write(2, ": option requires an argument: ", 31); write(2, optchar, k); write(2, "\n", 1); } return '?'; } optarg = argv[optind++] + optpos; optpos = 0; } return c; }
static void h_mbtowc(const char *locale, const char *illegal, const char *legal) { char buf[64]; size_t stateful, ret; char *str; ATF_REQUIRE_STREQ(setlocale(LC_ALL, "C"), "C"); #ifdef __NetBSD__ ATF_REQUIRE(setlocale(LC_CTYPE, locale) != NULL); #else if (setlocale(LC_CTYPE, locale) == NULL) { fprintf(stderr, "Locale %s not found.\n", locale); return; } #endif ATF_REQUIRE((str = setlocale(LC_ALL, NULL)) != NULL); (void)printf("Using locale: %s\n", str); stateful = wctomb(NULL, L'\0'); (void)printf("Locale is state-%sdependent\n", stateful ? "in" : ""); /* initialize internal state */ ret = mbtowc(NULL, NULL, 0); ATF_REQUIRE(stateful ? ret : !ret); (void)strvis(buf, illegal, VIS_WHITE | VIS_OCTAL); (void)printf("Checking illegal sequence: \"%s\"\n", buf); ret = mbtowc(NULL, illegal, strlen(illegal)); (void)printf("mbtowc() returned: %zd\n", ret); ATF_REQUIRE_EQ(ret, (size_t)-1); (void)printf("errno: %s\n", strerror(errno)); ATF_REQUIRE_EQ(errno, EILSEQ); /* if this is stateless encoding, this re-initialization is not required. */ if (stateful) { /* re-initialize internal state */ ret = mbtowc(NULL, NULL, 0); ATF_REQUIRE(stateful ? ret : !ret); } /* valid multibyte sequence case */ (void)strvis(buf, legal, VIS_WHITE | VIS_OCTAL); (void)printf("Checking legal sequence: \"%s\"\n", buf); errno = 0; ret = mbtowc(NULL, legal, strlen(legal)); (void)printf("mbtowc() returned: %zd\n", ret); ATF_REQUIRE(ret != (size_t)-1); (void)printf("errno: %s\n", strerror(errno)); ATF_REQUIRE_EQ(errno, 0); (void)printf("Ok.\n"); }
static int match_bracket(const char *p, int k, int kfold) { wchar_t wc; int inv = 0; p++; if (*p=='^' || *p=='!') { inv = 1; p++; } if (*p==']') { if (k==']') return !inv; p++; } else if (*p=='-') { if (k=='-') return !inv; p++; } wc = p[-1]; for (; *p != ']'; p++) { if (p[0]=='-' && p[1]!=']') { wchar_t wc2; int l = mbtowc(&wc2, p+1, 4); if (l < 0) return 0; if (wc <= wc2) if ((unsigned)k-wc <= wc2-wc || (unsigned)kfold-wc <= wc2-wc) return !inv; p += l-1; continue; } if (p[0]=='[' && (p[1]==':' || p[1]=='.' || p[1]=='=')) { const char *p0 = p+2; int z = p[1]; p+=3; while (p[-1]!=z || p[0]!=']') p++; if (z == ':' && p-1-p0 < 16) { char buf[16]; memcpy(buf, p0, p-1-p0); buf[p-1-p0] = 0; if (iswctype(k, wctype(buf)) || iswctype(kfold, wctype(buf))) return !inv; } continue; } if (*p < 128U) { wc = (unsigned char)*p; } else { int l = mbtowc(&wc, p, 4); if (l < 0) return 0; p += l-1; } if (wc==k || wc==kfold) return !inv; } return inv; }
int main(int argc, char **argv) { int i; int mb_consumed; char *mb_p; size_t mb_len; char *mb_buf; wchar_t wc; int wc_width; void (*dump)(FILE *fp, void *p_in, int size) = is_little_endian() ? dump_littleendian : dump_bigendian; if (argc < 2) { printf("Usage: %s STRING [...]\n", argv[0]); exit(1); } setlocale (LC_ALL, ""); mbtowc(NULL, NULL, 0); mb_buf = alloca(MB_CUR_MAX + 1); for (i = 1; i < argc; i++) { mb_p = argv[i]; mb_len = strlen(mb_p); while (mb_len > 0) { mb_consumed = mbtowc(&wc, mb_p, mb_len); if (mb_consumed == -1) { fprintf(stderr, "%s: ERROR: Invalid multibyte sequence: argv=%d, index=%d, bytes:", argv[0], i, (int)(mb_p - argv[i]) ); dump_bigendian(stderr, mb_p, mb_len); fputs("\n", stderr); exit(1); } wc_width = wcwidth(wc); strncpy(mb_buf, mb_p, mb_consumed); mb_buf[mb_consumed] = '\0'; printf("%d", wc_width); dump(stdout, &wc, sizeof(wchar_t)); printf("\t%s\n", mb_buf); mb_p += mb_consumed; mb_len -= mb_consumed; } } exit(0); }
int loadStrings() { const size_t tokenNum = 1 + STR_NUM * 2; jsmntok_t t[tokenNum]; char buf[8192]; jsmn_parser p; unsigned int i, j, k; const char *s; int l, r, len; File fd; sprintf(buf, "%s/%s", langPath, cfgs[CFG_LANG].val.s); if (!FileOpen(&fd, buf, 0)) return 1; len = FileGetSize(&fd); if (len > sizeof(buf)) return 1; FileRead(&fd, buf, len, 0); FileClose(&fd); jsmn_init(&p); r = jsmn_parse(&p, buf, len, t, tokenNum); if (r < 0) return r; for (i = 1; i < r; i++) { for (j = 0; j < STR_NUM; j++) { s = buf + t[i].start; len = t[i].end - t[i].start; if (!memcmp(s, keys[j], len) && !keys[j][len]) { i++; len = t[i].end - t[i].start; s = buf + t[i].start; for (k = 0; k + 1 < STR_MAX_LEN && len > 0; k++) { l = mbtowc(strings[j] + k, s, len); if (l < 0) break; len -= l; s += l; } strings[j][k] = 0; mbtowc(NULL, NULL, 0); break; } } } return 0; }
/* Returns the width of string S when output in font FONT. */ int bogl_metrics (const char *s, int n, const struct bogl_font *font) { int cx = 0; wchar_t wc; int k; mbtowc (0, 0, 0); for (; (k = mbtowc (&wc, s, n)) > 0; s += k, n -= k) cx += bogl_font_glyph (font, wc, NULL); return cx; }
/* Combine UTF-8 into Unicode. */ enum utf8_state utf8_combine(const struct utf8_data *ud, wchar_t *wc) { switch (mbtowc(wc, (const char *)ud->data, ud->size)) { case -1: mbtowc(NULL, NULL, MB_CUR_MAX); return (UTF8_ERROR); case 0: return (UTF8_ERROR); default: return (UTF8_DONE); } }
/* This function is equivalent to strncasecmp() for multibyte * strings. */ int mbstrncasecmp(const char *s1, const char *s2, size_t n) { #ifdef ENABLE_UTF8 if (use_utf8) { char *s1_mb, *s2_mb; wchar_t ws1, ws2; if (s1 == s2) return 0; assert(s1 != NULL && s2 != NULL); s1_mb = charalloc(MB_CUR_MAX); s2_mb = charalloc(MB_CUR_MAX); for (; *s1 != '\0' && *s2 != '\0' && n > 0; s1 += move_mbright(s1, 0), s2 += move_mbright(s2, 0), n--) { bool bad_s1_mb = FALSE, bad_s2_mb = FALSE; int s1_mb_len, s2_mb_len; s1_mb_len = parse_mbchar(s1, s1_mb, NULL); if (mbtowc(&ws1, s1_mb, s1_mb_len) < 0) { mbtowc_reset(); ws1 = (unsigned char)*s1_mb; bad_s1_mb = TRUE; } s2_mb_len = parse_mbchar(s2, s2_mb, NULL); if (mbtowc(&ws2, s2_mb, s2_mb_len) < 0) { mbtowc_reset(); ws2 = (unsigned char)*s2_mb; bad_s2_mb = TRUE; } if (bad_s1_mb != bad_s2_mb || towlower(ws1) != towlower(ws2)) break; } free(s1_mb); free(s2_mb); return (n > 0) ? towlower(ws1) - towlower(ws2) : 0; } else #endif return strncasecmp(s1, s2, n); }
static void sane(int not) { speed_t ispeed, ospeed; if (not) inval(); ispeed = cfgetispeed(&ts); ospeed = cfgetospeed(&ts); ts.c_cc[VINTR] = '\3'; ts.c_cc[VQUIT] = '\34'; ts.c_cc[VERASE] = '\10'; ts.c_cc[VKILL] = '\25'; ts.c_cc[VEOF] = '\4'; ts.c_cc[VEOL] = vdis; ts.c_cc[VEOL2] = vdis; #ifdef VSWTCH ts.c_cc[VSWTCH] = vdis; #endif ts.c_cc[VSTART] = '\21'; ts.c_cc[VSTOP] = '\23'; ts.c_cc[VSUSP] = '\32'; #ifdef VREPRINT ts.c_cc[VREPRINT] = '\22'; #endif #ifdef VDISCARD ts.c_cc[VDISCARD] = '\17'; #endif #ifdef VWERASE ts.c_cc[VWERASE] = '\27'; #endif ts.c_cc[VLNEXT] = '\26'; ts.c_cflag = CS8|CREAD; ts.c_lflag = ISIG|ICANON|ECHO|ECHOE|ECHOK|ECHOKE|IEXTEN; ts.c_iflag = BRKINT|IGNPAR|ICRNL|IXON|IMAXBEL; #ifdef IUTF8 if (MB_CUR_MAX > 1) { wchar_t wc; if (mbtowc(&wc, "\303\266", 2) == 2 && wc == 0xF6 && mbtowc(&wc, "\342\202\254", 3) == 3 && wc == 0x20AC) ts.c_iflag |= IUTF8; } #endif /* IUTF8 */ ts.c_oflag = OPOST|ONLCR; cfsetispeed(&ts, ispeed); cfsetospeed(&ts, ospeed); }
static void convertWithMBTOWC(struct OMRPortLibrary *portLibrary, const char *error, char *errBuf, uintptr_t bufLen) { char *out = errBuf; char *end = &errBuf[bufLen - 1]; const char *walk = error; wchar_t ch = '\0'; int ret = 0; /* reset the shift state */ ret = mbtowc(NULL, NULL, 0); while ('\0' != *walk) { ret = mbtowc(&ch, walk, MB_CUR_MAX); if (ret < 0) { ch = *walk++; } else if (0 == ret) { break; } else { walk += ret; } if ('\r' == ch) { continue; } if ('\n' == ch) { ch = ' '; } if (ch < 0x80) { if ((out + 1) > end) { break; } *out++ = (char)ch; } else if (ch < 0x800) { if ((out + 2) > end) { break; } *out++ = (char)(0xc0 | ((ch >> 6) & 0x1f)); *out++ = (char)(0x80 | (ch & 0x3f)); } else { if ((out + 3) > end) { break; } *out++ = (char)(0xe0 | ((ch >> 12) & 0x0f)); *out++ = (char)(0x80 | ((ch >> 6) & 0x3f)); *out++ = (char)(0x80 | (ch & 0x3f)); } }
static void putline(FILE *file, char *start, int num) { char *cp, *end; int i, len, d_col; wchar_t wc; cp = start; end = cp + num; while (cp < end) { if (isascii(*cp)) { (void) putc(*cp++, file); continue; } if ((len = end - cp) > MB_LEN_MAX) len = MB_LEN_MAX; if ((len = mbtowc(&wc, cp, len)) <= 0) { (void) putc(*cp++, file); continue; } if ((d_col = wcwidth(wc)) <= 0) d_col = len; if ((cp + d_col) > end) return; for (i = 0; i < len; i++) (void) putc(*cp++, file); } }
double* Signal::ReadFile(const char* name) { wchar_t ustr[_MAX_PATH] = L""; for (int i = 0; i < (int)strlen(name); i++) mbtowc(ustr + i, name + i, MB_CUR_MAX); return ReadFile(ustr); }
static size_t utf8len(char *text) { register size_t toffs=0; while (text[toffs]!='\0') { toffs+=mbtowc(NULL,&text[toffs],4); } return toffs; }
static pt_subst_t *get_nth_word_utf8(char *text, int idx) { // get nth word, return start (bytes) and length (bytes) // idx==0 for first word, etc register size_t toffs=0,xtoffs; gboolean isaspace=TRUE; pt_subst_t *subst=(pt_subst_t *)weed_malloc(sizeof(pt_subst_t)); subst->start=0; while (text[toffs]!='\0') { wchar_t pwc; xtoffs=mbtowc(&pwc,&text[toffs],4); if (iswspace(pwc)) { if (idx==-1) { subst->length=toffs-subst->start; return subst; } isaspace=TRUE; } else if (isaspace) { if (--idx==-1) subst->start=toffs; isaspace=FALSE; } toffs+=xtoffs; } subst->length=toffs-subst->start; return subst; }
void Console::error(char* str, ...) { if (g_hConsole != INVALID_HANDLE_VALUE) { char buf[1024]; va_list va; va_start(va, str); vsprintf(buf, str, va); va_end(va); #ifdef _UNICODE DWORD strLen = (DWORD)strlen(buf); wchar_t bufw[1024]; for (DWORD i=0; i<strLen; ++i) mbtowc(&bufw[i], &buf[i], 1); DWORD dwN; WriteConsole(g_hConsole, bufw, strLen, &dwN, 0); #else DWORD strLen = (DWORD)strlen(buf); WriteConsole(m_hConsole, buf, (DWORD)strlen(buf), &dwN, 0); #endif } else { va_list va; va_start(va, str); vprintf(str, va); va_end(va); } }
wchar_t str_wchar_at(char *p, int max) { wchar_t wc; if(mbtowc(&wc, p, max)>0) return wc; return 0; }
int GameClass::LoadStandardFont(char* name,int height,int flags,int italic) { HFONT hFont; StdFontBase=glGenLists(MAX_CHARS); size_t length=strlen(name); wchar_t* newStr = new wchar_t[length+1]; mbtowc(newStr,name,length+1); hFont=CreateFont( height,16,0,0, flags, italic, FALSE,FALSE, ANSI_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY, FF_DONTCARE|DEFAULT_PITCH, newStr); delete [] newStr; if(!hFont) return 0; hOldFont=(HFONT)SelectObject(GLWindow.Settings.hDC,hFont); wglUseFontBitmaps(GLWindow.Settings.hDC,0,MAX_CHARS-1,StdFontBase); return 1; }
int __m_wacs_cc(const cchar_t *acs, cchar_t *cc) { int i; unsigned char *acsc, mb[MB_LEN_MAX]; *cc = *acs; cc->_f = 1; /* Is it a single-byte character? */ if (!(acs->_at & WA_ALTCHARSET) || acs->_n != 1 || wctomb((char *) mb, acs->_wc[0]) != 1) /* No, just return the original character. */ return 0; /* Pick the acs mapping string to use. */ if (acs_chars == (char *) 0) { /* Use primary character set. */ acsc = acs_defaults; cc->_at &= ~A_ALTCHARSET; } else { acsc = (unsigned char *) acs_chars; } /* Assume that acsc is even in length. */ for (i = 0; acsc[i] != '\0'; i += 2) { if (acsc[i] == *mb) { (void) mbtowc(cc->_wc, (char *) &acsc[i+1], 1); cc->_at |= A_ALTCHARSET; break; } } return 0; }
/** * Upcase the first letter of the word. */ void upcase_utf8_str(char *to, const char * from, size_t usize) { wchar_t c; int i, nbl, nbh; char low[MB_LEN_MAX]; nbh = mbtowc (&c, from, 4); c = towupper(c); nbl = wctomb(low, c); /* Check for error on an in-place copy */ if ((nbh < nbl) && (to == from)) { /* I'm to lazy to fix this */ fprintf(stderr, "Error: can't upcase multi-byte string!\n"); return; } /* Upcase */ for (i=0; i<nbl; i++) { to[i] = low[i]; } if ((nbh == nbl) && (to == from)) return; from += nbh; to += nbl; safe_strcpy(to, from, usize-nbl); }
void Parser::parse(const char* src) { const char* ptr = src; mNodeStart = ptr; ERRNO(mbtowc(NULL, NULL, 0)); // reset shift state. while(*ptr) { // skip invalid utf-8 sequences. wchar_t w; int res = utf8towc(&w, ptr, 4); if(res <= 0) { if(res < 0) { printf("Invalid UTF-8 0x%x @ pos %" PRIuPTR "\n", (unsigned char)*ptr, ptr - src); } FLUSH; ptr++; mNodeStart = ptr; continue; } else if(res > 1) { // valid utf-8 beyond ascii ptr += res; continue; } if(STREQ(ptr, "http://")) { // unescaped link FLUSH; ptr = parseUnescapedUrl(ptr); mNodeStart = ptr; continue; } char c = *ptr; ptr++; if(c == '[') { // start tag while(*ptr == '[') { ptr++; } const char* endPtr = strchr(ptr, ']'); if(!endPtr) { break; } const char* newEndPtr = fixTag(ptr, endPtr); bool diff = newEndPtr != endPtr; endPtr = newEndPtr; flush(ptr-1); if(!diff) { mNodeStart = ptr; parseTag(ptr, endPtr - ptr); } ptr = endPtr; if(!diff) { ptr++; } mNodeStart = ptr; } else if(c == '\\' && *ptr == 'n') { flush(ptr-1); ptr++; mNodeStart = ptr; addLinebreakNode(); } } FLUSH; }
static int __read_wide_char( FILE *fp, wchar_t *wc ) /**************************************************/ { if( fp->_flag & _BINARY ) { /*** Read a wide character ***/ return( fread( wc, sizeof( wchar_t ), 1, fp ) ); } else { char mbc[MB_CUR_MAX]; wchar_t wcTemp; int rc; /*** Read the multibyte character ***/ if( !fread( &mbc[0], 1, 1, fp ) ) return( 0 ); if( _ismbblead( (unsigned char)mbc[0] ) ) { if( !fread( &mbc[1], 1, 1, fp ) ) return( 0 ); } /*** Convert it to wide form ***/ rc = mbtowc( &wcTemp, mbc, MB_CUR_MAX ); if( rc >= 0 ) { *wc = wcTemp; return( 1 ); } else { _RWD_errno = EILSEQ; return( 0 ); } } }
/* * Note: We should use wide-character for findng '\' character, * a directory separator on Windows, because some character-set have * been using the '\' character for a part of its multibyte character * code. */ static size_t dir_len(struct archive_entry *entry) { wchar_t wc; const char *path; const char *p, *rp; size_t al, l, size; path = tk_archive_entry_pathname(entry); al = l = -1; for (p = path; *p != '\0'; ++p) { if (*p == '\\') al = l = p - path; else if (*p == '/') al = p - path; } if (l == -1) goto alen; size = p - path; rp = p = path; while (*p != '\0') { l = mbtowc(&wc, p, size); if (l == -1) goto alen; if (l == 1 && (wc == L'/' || wc == L'\\')) rp = p; p += l; size -= l; } return (rp - path + 1); alen: if (al == -1) return (0); return (al + 1); }
static int theme_strlen(char *message, char end) { int len = 0; int i = 0; while ((message[i] != end) && (message[i] != 0)) { if (message[i] == '%') { i++; } else if (message[i] == '\\') { i++; len++; } else if ((unsigned char) message[i] > 0x7f) { wchar_t dest[2]; int bytes = mbtowc(dest, &message[i], 3) - 1; if (bytes >= 0) { int rwidth = wcwidth(dest[0]); if(rwidth < 0) rwidth = 1; i += bytes; len += rwidth; } else { i++; len += 1; } } else if (message[i] != '\n') len++; i++; } return len; }
static int putxy(WINDOW *win, int width, int *i, int *y, int *x, char *str) { if ((unsigned char) str[0] > 0x7F) { wchar_t dest[2]; int bytes = mbtowc(dest, &str[0], 3) - 1; if (bytes >= 0) { /* To deal with non-latin characters that can take up more than one character's alotted width, with offset x by wcwidth(character) rather than 1 */ /* Took me forever to find that function, thanks Andreas (newsbeuter) for that one. */ int rwidth = wcwidth(dest[0]); if (rwidth < 0) rwidth = 1; if (rwidth > (width - *x)) return 1; dest[1] = 0; mvwaddwstr(win, *y, *x, dest); *x += rwidth; *i += bytes; } } else mvwaddch(win, *y, (*x)++, str[0]); return 0; }
/* ** ** [func] - mbstowcs. ** [desc] - if s is a valid multibyte string then converts the multibyte ** string to a wide-character string and returns the length of ** the wide-character string. else returns -1. ** [entr] - wchar_t *ws; the destination wide-character string pointer. ** const char *s; the source multibyte string pointer. ** size_t n; the maximum number of characters to convert. ** [exit] - size_t; the length of the wide-character string. else -1. ** [prec] - ws is a valid wide-character string pointer and s is a valid ** string pointer. ** [post] - the memory pointed to by ws is modified. ** */ size_t mbstowcs(wchar_t *ws, const char *s, size_t n) { int len, shift; size_t ret = -1; /* convert the multibyte string to wide-character string. */ for (shift = __stdlib_mb_shift; *s != '\0'; ) { if (__isascii(*s) != 0) { /* multibyte character is ascii. */ *ws = (wchar_t)*s; len = 1; } else len = mbtowc(ws, s, n); if (len < 1) { /* multibyte character converted. */ ++ws; ++ret; s += len; n -= len; } else { /* error occured. */ ret = -1; break; } } /* append NULL terminator. */ if (n > 0) *ws = (wchar_t)'\0'; __stdlib_mb_shift = shift; return (ret); }