mirror of
https://github.com/fluencelabs/musl
synced 2025-06-05 11:01:37 +00:00
59 lines
1010 B
C
59 lines
1010 B
C
|
/*
|
||
|
* This code was written by Rich Felker in 2010; no copyright is claimed.
|
||
|
* This code is in the public domain. Attribution is appreciated but
|
||
|
* unnecessary.
|
||
|
*/
|
||
|
|
||
|
#include <stdlib.h>
|
||
|
#include <inttypes.h>
|
||
|
#include <wchar.h>
|
||
|
#include <errno.h>
|
||
|
|
||
|
#include "internal.h"
|
||
|
|
||
|
size_t wcsrtombs(char *s, const wchar_t **ws, size_t n, mbstate_t *st)
|
||
|
{
|
||
|
const wchar_t *ws2;
|
||
|
char buf[4];
|
||
|
size_t N = n, l;
|
||
|
if (!s) {
|
||
|
for (n=0, ws2=*ws; *ws2; ws2++) {
|
||
|
if (*ws2 >= 0x80) {
|
||
|
l = wcrtomb(buf, *ws2, 0);
|
||
|
if (!(l+1)) return -1;
|
||
|
n += l;
|
||
|
} else n++;
|
||
|
}
|
||
|
return n;
|
||
|
}
|
||
|
while (n>=4 && **ws) {
|
||
|
if (**ws >= 0x80) {
|
||
|
l = wcrtomb(s, **ws, 0);
|
||
|
if (!(l+1)) return -1;
|
||
|
s += l;
|
||
|
n -= l;
|
||
|
} else {
|
||
|
*s++ = **ws;
|
||
|
n--;
|
||
|
}
|
||
|
(*ws)++;
|
||
|
}
|
||
|
while (n && **ws) {
|
||
|
if (**ws >= 0x80) {
|
||
|
l = wcrtomb(buf, **ws, 0);
|
||
|
if (!(l+1)) return -1;
|
||
|
if (l>n) return N-n;
|
||
|
wcrtomb(s, **ws, 0);
|
||
|
s += l;
|
||
|
n -= l;
|
||
|
} else {
|
||
|
*s++ = **ws;
|
||
|
n--;
|
||
|
}
|
||
|
(*ws)++;
|
||
|
}
|
||
|
if (n) *s = 0;
|
||
|
*ws = 0;
|
||
|
return N-n;
|
||
|
}
|