mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-19 09:00:31 +00:00
Update Musl Libc code
We now have implement all of Musl's localization code, the same way that Musl implements localization. You may need setlocale(LC_ALL, "C.UTF-8"), just in case anything stops working as expected.
This commit is contained in:
parent
d0360bf4bd
commit
bb815eafaf
116 changed files with 6525 additions and 5523 deletions
3
third_party/musl/BUILD.mk
vendored
3
third_party/musl/BUILD.mk
vendored
|
@ -30,7 +30,8 @@ THIRD_PARTY_MUSL_A_DIRECTDEPS = \
|
|||
LIBC_STR \
|
||||
LIBC_SYSV \
|
||||
LIBC_THREAD \
|
||||
THIRD_PARTY_ZLIB
|
||||
THIRD_PARTY_TZ \
|
||||
THIRD_PARTY_ZLIB \
|
||||
|
||||
THIRD_PARTY_MUSL_A_DEPS := \
|
||||
$(call uniq,$(foreach x,$(THIRD_PARTY_MUSL_A_DIRECTDEPS),$($(x))))
|
||||
|
|
72
third_party/musl/__mo_lookup.c
vendored
Normal file
72
third_party/musl/__mo_lookup.c
vendored
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
static inline uint32_t swapc(uint32_t x, int c)
|
||||
{
|
||||
return c ? x>>24 | x>>8&0xff00 | x<<8&0xff0000 | x<<24 : x;
|
||||
}
|
||||
|
||||
const char *__mo_lookup(const void *p, size_t size, const char *s)
|
||||
{
|
||||
const uint32_t *mo = p;
|
||||
int sw = *mo - 0x950412de;
|
||||
uint32_t b = 0, n = swapc(mo[2], sw);
|
||||
uint32_t o = swapc(mo[3], sw);
|
||||
uint32_t t = swapc(mo[4], sw);
|
||||
if (n>=size/4 || o>=size-4*n || t>=size-4*n || ((o|t)%4))
|
||||
return 0;
|
||||
o/=4;
|
||||
t/=4;
|
||||
for (;;) {
|
||||
uint32_t ol = swapc(mo[o+2*(b+n/2)], sw);
|
||||
uint32_t os = swapc(mo[o+2*(b+n/2)+1], sw);
|
||||
if (os >= size || ol >= size-os || ((char *)p)[os+ol])
|
||||
return 0;
|
||||
int sign = strcmp(s, (char *)p + os);
|
||||
if (!sign) {
|
||||
uint32_t tl = swapc(mo[t+2*(b+n/2)], sw);
|
||||
uint32_t ts = swapc(mo[t+2*(b+n/2)+1], sw);
|
||||
if (ts >= size || tl >= size-ts || ((char *)p)[ts+tl])
|
||||
return 0;
|
||||
return (char *)p + ts;
|
||||
}
|
||||
else if (n == 1) return 0;
|
||||
else if (sign < 0)
|
||||
n /= 2;
|
||||
else {
|
||||
b += n/2;
|
||||
n -= n/2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
10
third_party/musl/__month_to_secs.c
vendored
Normal file
10
third_party/musl/__month_to_secs.c
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
int __month_to_secs(int month, int is_leap)
|
||||
{
|
||||
static const int secs_through_month[] = {
|
||||
0, 31*86400, 59*86400, 90*86400,
|
||||
120*86400, 151*86400, 181*86400, 212*86400,
|
||||
243*86400, 273*86400, 304*86400, 334*86400 };
|
||||
int t = secs_through_month[month];
|
||||
if (is_leap && month >= 2) t+=86400;
|
||||
return t;
|
||||
}
|
82
third_party/musl/__secs_to_tm.c
vendored
Normal file
82
third_party/musl/__secs_to_tm.c
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
#include "time_impl.h"
|
||||
#include <limits.h>
|
||||
|
||||
/* 2000-03-01 (mod 400 year, immediately after feb29 */
|
||||
#define LEAPOCH (946684800LL + 86400*(31+29))
|
||||
|
||||
#define DAYS_PER_400Y (365*400 + 97)
|
||||
#define DAYS_PER_100Y (365*100 + 24)
|
||||
#define DAYS_PER_4Y (365*4 + 1)
|
||||
|
||||
int __secs_to_tm(long long t, struct tm *tm)
|
||||
{
|
||||
long long days, secs, years;
|
||||
int remdays, remsecs, remyears;
|
||||
int qc_cycles, c_cycles, q_cycles;
|
||||
int months;
|
||||
int wday, yday, leap;
|
||||
static const char days_in_month[] = {31,30,31,30,31,31,30,31,30,31,31,29};
|
||||
|
||||
/* Reject time_t values whose year would overflow int */
|
||||
if (t < INT_MIN * 31622400LL || t > INT_MAX * 31622400LL)
|
||||
return -1;
|
||||
|
||||
secs = t - LEAPOCH;
|
||||
days = secs / 86400;
|
||||
remsecs = secs % 86400;
|
||||
if (remsecs < 0) {
|
||||
remsecs += 86400;
|
||||
days--;
|
||||
}
|
||||
|
||||
wday = (3+days)%7;
|
||||
if (wday < 0) wday += 7;
|
||||
|
||||
qc_cycles = days / DAYS_PER_400Y;
|
||||
remdays = days % DAYS_PER_400Y;
|
||||
if (remdays < 0) {
|
||||
remdays += DAYS_PER_400Y;
|
||||
qc_cycles--;
|
||||
}
|
||||
|
||||
c_cycles = remdays / DAYS_PER_100Y;
|
||||
if (c_cycles == 4) c_cycles--;
|
||||
remdays -= c_cycles * DAYS_PER_100Y;
|
||||
|
||||
q_cycles = remdays / DAYS_PER_4Y;
|
||||
if (q_cycles == 25) q_cycles--;
|
||||
remdays -= q_cycles * DAYS_PER_4Y;
|
||||
|
||||
remyears = remdays / 365;
|
||||
if (remyears == 4) remyears--;
|
||||
remdays -= remyears * 365;
|
||||
|
||||
leap = !remyears && (q_cycles || !c_cycles);
|
||||
yday = remdays + 31 + 28 + leap;
|
||||
if (yday >= 365+leap) yday -= 365+leap;
|
||||
|
||||
years = remyears + 4*q_cycles + 100*c_cycles + 400LL*qc_cycles;
|
||||
|
||||
for (months=0; days_in_month[months] <= remdays; months++)
|
||||
remdays -= days_in_month[months];
|
||||
|
||||
if (months >= 10) {
|
||||
months -= 12;
|
||||
years++;
|
||||
}
|
||||
|
||||
if (years+100 > INT_MAX || years+100 < INT_MIN)
|
||||
return -1;
|
||||
|
||||
tm->tm_year = years + 100;
|
||||
tm->tm_mon = months + 2;
|
||||
tm->tm_mday = remdays + 1;
|
||||
tm->tm_wday = wday;
|
||||
tm->tm_yday = yday;
|
||||
|
||||
tm->tm_hour = remsecs / 3600;
|
||||
tm->tm_min = remsecs / 60 % 60;
|
||||
tm->tm_sec = remsecs % 60;
|
||||
|
||||
return 0;
|
||||
}
|
24
third_party/musl/__tm_to_secs.c
vendored
Normal file
24
third_party/musl/__tm_to_secs.c
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "time_impl.h"
|
||||
|
||||
long long __tm_to_secs(const struct tm *tm)
|
||||
{
|
||||
int is_leap;
|
||||
long long year = tm->tm_year;
|
||||
int month = tm->tm_mon;
|
||||
if (month >= 12 || month < 0) {
|
||||
int adj = month / 12;
|
||||
month %= 12;
|
||||
if (month < 0) {
|
||||
adj--;
|
||||
month += 12;
|
||||
}
|
||||
year += adj;
|
||||
}
|
||||
long long t = __year_to_secs(year, &is_leap);
|
||||
t += __month_to_secs(month, is_leap);
|
||||
t += 86400LL * (tm->tm_mday-1);
|
||||
t += 3600LL * tm->tm_hour;
|
||||
t += 60LL * tm->tm_min;
|
||||
t += tm->tm_sec;
|
||||
return t;
|
||||
}
|
47
third_party/musl/__year_to_secs.c
vendored
Normal file
47
third_party/musl/__year_to_secs.c
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
long long __year_to_secs(long long year, int *is_leap)
|
||||
{
|
||||
if (year-2ULL <= 136) {
|
||||
int y = year;
|
||||
int leaps = (y-68)>>2;
|
||||
if (!((y-68)&3)) {
|
||||
leaps--;
|
||||
if (is_leap) *is_leap = 1;
|
||||
} else if (is_leap) *is_leap = 0;
|
||||
return 31536000*(y-70) + 86400*leaps;
|
||||
}
|
||||
|
||||
int cycles, centuries, leaps, rem, dummy;
|
||||
|
||||
if (!is_leap) is_leap = &dummy;
|
||||
cycles = (year-100) / 400;
|
||||
rem = (year-100) % 400;
|
||||
if (rem < 0) {
|
||||
cycles--;
|
||||
rem += 400;
|
||||
}
|
||||
if (!rem) {
|
||||
*is_leap = 1;
|
||||
centuries = 0;
|
||||
leaps = 0;
|
||||
} else {
|
||||
if (rem >= 200) {
|
||||
if (rem >= 300) centuries = 3, rem -= 300;
|
||||
else centuries = 2, rem -= 200;
|
||||
} else {
|
||||
if (rem >= 100) centuries = 1, rem -= 100;
|
||||
else centuries = 0;
|
||||
}
|
||||
if (!rem) {
|
||||
*is_leap = 0;
|
||||
leaps = 0;
|
||||
} else {
|
||||
leaps = rem / 4U;
|
||||
rem %= 4U;
|
||||
*is_leap = !rem;
|
||||
}
|
||||
}
|
||||
|
||||
leaps += 97*cycles + 24*centuries - *is_leap;
|
||||
|
||||
return (year-100) * 31536000LL + leaps * 86400LL + 946684800 + 86400;
|
||||
}
|
10
third_party/musl/asctime.c
vendored
Normal file
10
third_party/musl/asctime.c
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/time.h"
|
||||
|
||||
char *asctime(const struct tm *tm)
|
||||
{
|
||||
static char buf[26];
|
||||
return asctime_r(tm, buf);
|
||||
}
|
52
third_party/musl/asctime_r.c
vendored
Normal file
52
third_party/musl/asctime_r.c
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/langinfo.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
char *asctime_r(const struct tm *tm, char *buf)
|
||||
{
|
||||
if (snprintf(buf, 26, "%.3s %.3s%3d %.2d:%.2d:%.2d %d\n",
|
||||
nl_langinfo_l(ABDAY_1+tm->tm_wday, C_LOCALE),
|
||||
nl_langinfo_l(ABMON_1+tm->tm_mon, C_LOCALE),
|
||||
tm->tm_mday, tm->tm_hour,
|
||||
tm->tm_min, tm->tm_sec,
|
||||
1900 + tm->tm_year) >= 26)
|
||||
{
|
||||
/* ISO C requires us to use the above format string,
|
||||
* even if it will not fit in the buffer. Thus asctime_r
|
||||
* is _supposed_ to crash if the fields in tm are too large.
|
||||
* We follow this behavior and crash "gracefully" to warn
|
||||
* application developers that they may not be so lucky
|
||||
* on other implementations (e.g. stack smashing..).
|
||||
*/
|
||||
__builtin_trap();
|
||||
}
|
||||
return buf;
|
||||
}
|
38
third_party/musl/btowc.c
vendored
Normal file
38
third_party/musl/btowc.c
vendored
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include <stdlib.h>
|
||||
#include "multibyte.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
wint_t btowc(int c)
|
||||
{
|
||||
int b = (unsigned char)c;
|
||||
return b<128U ? b : (MB_CUR_MAX==1 && c!=EOF) ? CODEUNIT(c) : WEOF;
|
||||
}
|
65
third_party/musl/c16rtomb.c
vendored
Normal file
65
third_party/musl/c16rtomb.c
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <uchar.h>
|
||||
#include <errno.h>
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
size_t c16rtomb(char *restrict s, char16_t c16, mbstate_t *restrict ps)
|
||||
{
|
||||
static unsigned internal_state;
|
||||
if (!ps) ps = (void *)&internal_state;
|
||||
unsigned *x = (unsigned *)ps;
|
||||
wchar_t wc;
|
||||
|
||||
if (!s) {
|
||||
if (*x) goto ilseq;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!*x && c16 - 0xd800u < 0x400) {
|
||||
*x = c16 - 0xd7c0 << 10;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (*x) {
|
||||
if (c16 - 0xdc00u >= 0x400) goto ilseq;
|
||||
else wc = *x + c16 - 0xdc00;
|
||||
*x = 0;
|
||||
} else {
|
||||
wc = c16;
|
||||
}
|
||||
return wcrtomb(s, wc, 0);
|
||||
|
||||
ilseq:
|
||||
*x = 0;
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
35
third_party/musl/c32rtomb.c
vendored
Normal file
35
third_party/musl/c32rtomb.c
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <uchar.h>
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t c32rtomb(char *restrict s, char32_t c32, mbstate_t *restrict ps)
|
||||
{
|
||||
return wcrtomb(s, c32, ps);
|
||||
}
|
1
third_party/musl/catclose.c
vendored
1
third_party/musl/catclose.c
vendored
|
@ -30,6 +30,7 @@
|
|||
#include <stdint.h>
|
||||
#include <endian.h>
|
||||
#include <sys/mman.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define V(p) be32toh(*(uint32_t *)(p))
|
||||
|
||||
|
|
1
third_party/musl/catgets.c
vendored
1
third_party/musl/catgets.c
vendored
|
@ -31,6 +31,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <errno.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define V(p) be32toh(*(uint32_t *)(p))
|
||||
|
||||
|
|
1
third_party/musl/catopen.c
vendored
1
third_party/musl/catopen.c
vendored
|
@ -35,6 +35,7 @@
|
|||
#include <locale.h>
|
||||
#include "third_party/musl/mapfile.internal.h"
|
||||
#include <sys/mman.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define V(p) be32toh(*(uint32_t *)(p))
|
||||
|
||||
|
|
22
third_party/musl/ctime.c
vendored
Normal file
22
third_party/musl/ctime.c
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/time.h"
|
||||
|
||||
/**
|
||||
* Represents time as string.
|
||||
* @threadunsafe
|
||||
*/
|
||||
char *
|
||||
ctime(const time_t *timep)
|
||||
{
|
||||
/*
|
||||
** Section 4.12.3.2 of X3.159-1989 requires that
|
||||
** The ctime function converts the calendar time pointed to by timer
|
||||
** to local time in the form of a string. It is equivalent to
|
||||
** asctime(localtime(timer))
|
||||
*/
|
||||
struct tm *tmp = localtime(timep);
|
||||
return tmp ? asctime(tmp) : NULL;
|
||||
}
|
13
third_party/musl/ctime_r.c
vendored
Normal file
13
third_party/musl/ctime_r.c
vendored
Normal file
|
@ -0,0 +1,13 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/time.h"
|
||||
|
||||
char *
|
||||
ctime_r(const time_t *timep, char *buf)
|
||||
{
|
||||
struct tm mytm;
|
||||
struct tm *tmp = localtime_r(timep, &mytm);
|
||||
return tmp ? asctime_r(tmp, buf) : NULL;
|
||||
}
|
45
third_party/musl/duplocale.c
vendored
Normal file
45
third_party/musl/duplocale.c
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define malloc _mapanon
|
||||
#define calloc undef
|
||||
#define realloc undef
|
||||
#define free undef
|
||||
|
||||
locale_t duplocale(locale_t old)
|
||||
{
|
||||
locale_t new = malloc(sizeof *new);
|
||||
if (!new) return 0;
|
||||
if (old == LC_GLOBAL_LOCALE) old = &__global_locale;
|
||||
*new = *old;
|
||||
return new;
|
||||
}
|
567
third_party/musl/fnmatch.c
vendored
567
third_party/musl/fnmatch.c
vendored
|
@ -25,10 +25,12 @@
|
|||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/limits.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/wctype.h"
|
||||
#include "third_party/musl/fnmatch.h"
|
||||
#include <string.h>
|
||||
#include <fnmatch.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
/*
|
||||
|
@ -46,284 +48,279 @@ __static_yoink("musl_libc_notice");
|
|||
* - Rich Felker, April 2012
|
||||
*/
|
||||
|
||||
#define END 0
|
||||
#define END 0
|
||||
#define UNMATCHABLE -2
|
||||
#define BRACKET -3
|
||||
#define QUESTION -4
|
||||
#define STAR -5
|
||||
#define BRACKET -3
|
||||
#define QUESTION -4
|
||||
#define STAR -5
|
||||
|
||||
static int FnmatchNextString(const char *str, size_t n, size_t *step) {
|
||||
if (!n) {
|
||||
*step = 0;
|
||||
return 0;
|
||||
}
|
||||
if (str[0] >= 128U) {
|
||||
wchar_t wc;
|
||||
int k = mbtowc(&wc, str, n);
|
||||
if (k < 0) {
|
||||
*step = 1;
|
||||
return -1;
|
||||
}
|
||||
*step = k;
|
||||
return wc;
|
||||
}
|
||||
*step = 1;
|
||||
return str[0];
|
||||
static int str_next(const char *str, size_t n, size_t *step)
|
||||
{
|
||||
if (!n) {
|
||||
*step = 0;
|
||||
return 0;
|
||||
}
|
||||
if (str[0] >= 128U) {
|
||||
wchar_t wc;
|
||||
int k = mbtowc(&wc, str, n);
|
||||
if (k<0) {
|
||||
*step = 1;
|
||||
return -1;
|
||||
}
|
||||
*step = k;
|
||||
return wc;
|
||||
}
|
||||
*step = 1;
|
||||
return str[0];
|
||||
}
|
||||
|
||||
static int FnmatchNextPattern(const char *pat, size_t m, size_t *step,
|
||||
int flags) {
|
||||
int esc = 0;
|
||||
if (!m || !*pat) {
|
||||
*step = 0;
|
||||
return END;
|
||||
}
|
||||
*step = 1;
|
||||
if (pat[0] == '\\' && pat[1] && !(flags & FNM_NOESCAPE)) {
|
||||
*step = 2;
|
||||
pat++;
|
||||
esc = 1;
|
||||
goto escaped;
|
||||
}
|
||||
if (pat[0] == '[') {
|
||||
size_t k = 1;
|
||||
if (k < m)
|
||||
if (pat[k] == '^' || pat[k] == '!') k++;
|
||||
if (k < m)
|
||||
if (pat[k] == ']') k++;
|
||||
for (; k < m && pat[k] && pat[k] != ']'; k++) {
|
||||
if (k + 1 < m && pat[k + 1] && pat[k] == '[' &&
|
||||
(pat[k + 1] == ':' || pat[k + 1] == '.' || pat[k + 1] == '=')) {
|
||||
int z = pat[k + 1];
|
||||
k += 2;
|
||||
if (k < m && pat[k]) k++;
|
||||
while (k < m && pat[k] && (pat[k - 1] != z || pat[k] != ']')) k++;
|
||||
if (k == m || !pat[k]) break;
|
||||
}
|
||||
}
|
||||
if (k == m || !pat[k]) {
|
||||
*step = 1;
|
||||
return '[';
|
||||
}
|
||||
*step = k + 1;
|
||||
return BRACKET;
|
||||
}
|
||||
if (pat[0] == '*') return STAR;
|
||||
if (pat[0] == '?') return QUESTION;
|
||||
static int pat_next(const char *pat, size_t m, size_t *step, int flags)
|
||||
{
|
||||
int esc = 0;
|
||||
if (!m || !*pat) {
|
||||
*step = 0;
|
||||
return END;
|
||||
}
|
||||
*step = 1;
|
||||
if (pat[0]=='\\' && pat[1] && !(flags & FNM_NOESCAPE)) {
|
||||
*step = 2;
|
||||
pat++;
|
||||
esc = 1;
|
||||
goto escaped;
|
||||
}
|
||||
if (pat[0]=='[') {
|
||||
size_t k = 1;
|
||||
if (k<m) if (pat[k] == '^' || pat[k] == '!') k++;
|
||||
if (k<m) if (pat[k] == ']') k++;
|
||||
for (; k<m && pat[k] && pat[k]!=']'; k++) {
|
||||
if (k+1<m && pat[k+1] && pat[k]=='[' && (pat[k+1]==':' || pat[k+1]=='.' || pat[k+1]=='=')) {
|
||||
int z = pat[k+1];
|
||||
k+=2;
|
||||
if (k<m && pat[k]) k++;
|
||||
while (k<m && pat[k] && (pat[k-1]!=z || pat[k]!=']')) k++;
|
||||
if (k==m || !pat[k]) break;
|
||||
}
|
||||
}
|
||||
if (k==m || !pat[k]) {
|
||||
*step = 1;
|
||||
return '[';
|
||||
}
|
||||
*step = k+1;
|
||||
return BRACKET;
|
||||
}
|
||||
if (pat[0] == '*')
|
||||
return STAR;
|
||||
if (pat[0] == '?')
|
||||
return QUESTION;
|
||||
escaped:
|
||||
if (pat[0] >= 128U) {
|
||||
wchar_t wc;
|
||||
int k = mbtowc(&wc, pat, m);
|
||||
if (k < 0) {
|
||||
*step = 0;
|
||||
return UNMATCHABLE;
|
||||
}
|
||||
*step = k + esc;
|
||||
return wc;
|
||||
}
|
||||
return pat[0];
|
||||
if (pat[0] >= 128U) {
|
||||
wchar_t wc;
|
||||
int k = mbtowc(&wc, pat, m);
|
||||
if (k<0) {
|
||||
*step = 0;
|
||||
return UNMATCHABLE;
|
||||
}
|
||||
*step = k + esc;
|
||||
return wc;
|
||||
}
|
||||
return pat[0];
|
||||
}
|
||||
|
||||
static int FnmatchCaseFold(int k) {
|
||||
int c = towupper(k);
|
||||
return c == k ? towlower(k) : c;
|
||||
static int casefold(int k)
|
||||
{
|
||||
int c = towupper(k);
|
||||
return c == k ? towlower(k) : c;
|
||||
}
|
||||
|
||||
static int FnmatchBracket(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;
|
||||
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;
|
||||
}
|
||||
|
||||
static int FnmatchPerform(const char *pat, size_t m, const char *str, size_t n,
|
||||
int flags) {
|
||||
const char *p, *ptail, *endpat;
|
||||
const char *s, *stail, *endstr;
|
||||
size_t pinc, sinc, tailcnt = 0;
|
||||
int c, k, kfold;
|
||||
static int fnmatch_internal(const char *pat, size_t m, const char *str, size_t n, int flags)
|
||||
{
|
||||
const char *p, *ptail, *endpat;
|
||||
const char *s, *stail, *endstr;
|
||||
size_t pinc, sinc, tailcnt=0;
|
||||
int c, k, kfold;
|
||||
|
||||
if (flags & FNM_PERIOD) {
|
||||
if (*str == '.' && *pat != '.') {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
}
|
||||
if (flags & FNM_PERIOD) {
|
||||
if (*str == '.' && *pat != '.')
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
for (;;) {
|
||||
switch ((c = pat_next(pat, m, &pinc, flags))) {
|
||||
case UNMATCHABLE:
|
||||
return FNM_NOMATCH;
|
||||
case STAR:
|
||||
pat++;
|
||||
m--;
|
||||
break;
|
||||
default:
|
||||
k = str_next(str, n, &sinc);
|
||||
if (k <= 0)
|
||||
return (c==END) ? 0 : FNM_NOMATCH;
|
||||
str += sinc;
|
||||
n -= sinc;
|
||||
kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
|
||||
if (c == BRACKET) {
|
||||
if (!match_bracket(pat, k, kfold))
|
||||
return FNM_NOMATCH;
|
||||
} else if (c != QUESTION && k != c && kfold != c) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
pat+=pinc;
|
||||
m-=pinc;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
switch ((c = FnmatchNextPattern(pat, m, &pinc, flags))) {
|
||||
case UNMATCHABLE:
|
||||
return FNM_NOMATCH;
|
||||
case STAR:
|
||||
pat++;
|
||||
m--;
|
||||
break;
|
||||
default:
|
||||
k = FnmatchNextString(str, n, &sinc);
|
||||
if (k <= 0) return (c == END) ? 0 : FNM_NOMATCH;
|
||||
str += sinc;
|
||||
n -= sinc;
|
||||
kfold = flags & FNM_CASEFOLD ? FnmatchCaseFold(k) : k;
|
||||
if (c == BRACKET) {
|
||||
if (!FnmatchBracket(pat, k, kfold)) return FNM_NOMATCH;
|
||||
} else if (c != QUESTION && k != c && kfold != c) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
pat += pinc;
|
||||
m -= pinc;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Compute real pat length if it was initially unknown/-1 */
|
||||
m = strnlen(pat, m);
|
||||
endpat = pat + m;
|
||||
|
||||
/* Compute real pat length if it was initially unknown/-1 */
|
||||
m = strnlen(pat, m);
|
||||
endpat = pat + m;
|
||||
/* Find the last * in pat and count chars needed after it */
|
||||
for (p=ptail=pat; p<endpat; p+=pinc) {
|
||||
switch (pat_next(p, endpat-p, &pinc, flags)) {
|
||||
case UNMATCHABLE:
|
||||
return FNM_NOMATCH;
|
||||
case STAR:
|
||||
tailcnt=0;
|
||||
ptail = p+1;
|
||||
break;
|
||||
default:
|
||||
tailcnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the last * in pat and count chars needed after it */
|
||||
for (p = ptail = pat; p < endpat; p += pinc) {
|
||||
switch (FnmatchNextPattern(p, endpat - p, &pinc, flags)) {
|
||||
case UNMATCHABLE:
|
||||
return FNM_NOMATCH;
|
||||
case STAR:
|
||||
tailcnt = 0;
|
||||
ptail = p + 1;
|
||||
break;
|
||||
default:
|
||||
tailcnt++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Past this point we need not check for UNMATCHABLE in pat,
|
||||
* because all of pat has already been parsed once. */
|
||||
|
||||
/* Past this point we need not check for UNMATCHABLE in pat,
|
||||
* because all of pat has already been parsed once. */
|
||||
/* Compute real str length if it was initially unknown/-1 */
|
||||
n = strnlen(str, n);
|
||||
endstr = str + n;
|
||||
if (n < tailcnt) return FNM_NOMATCH;
|
||||
|
||||
/* Compute real str length if it was initially unknown/-1 */
|
||||
n = strnlen(str, n);
|
||||
endstr = str + n;
|
||||
if (n < tailcnt) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
/* Find the final tailcnt chars of str, accounting for UTF-8.
|
||||
* On illegal sequences we may get it wrong, but in that case
|
||||
* we necessarily have a matching failure anyway. */
|
||||
for (s=endstr; s>str && tailcnt; tailcnt--) {
|
||||
if (s[-1] < 128U || MB_CUR_MAX==1) s--;
|
||||
else while ((unsigned char)*--s-0x80U<0x40 && s>str);
|
||||
}
|
||||
if (tailcnt) return FNM_NOMATCH;
|
||||
stail = s;
|
||||
|
||||
/* Find the final tailcnt chars of str, accounting for UTF-8.
|
||||
* On illegal sequences we may get it wrong, but in that case
|
||||
* we necessarily have a matching failure anyway. */
|
||||
for (s = endstr; s > str && tailcnt; tailcnt--) {
|
||||
if (s[-1] < 128U || MB_CUR_MAX == 1) {
|
||||
s--;
|
||||
} else {
|
||||
while ((unsigned char)*--s - 0x80U < 0x40 && s > str)
|
||||
;
|
||||
}
|
||||
}
|
||||
if (tailcnt) return FNM_NOMATCH;
|
||||
stail = s;
|
||||
/* Check that the pat and str tails match */
|
||||
p = ptail;
|
||||
for (;;) {
|
||||
c = pat_next(p, endpat-p, &pinc, flags);
|
||||
p += pinc;
|
||||
if ((k = str_next(s, endstr-s, &sinc)) <= 0) {
|
||||
if (c != END) return FNM_NOMATCH;
|
||||
break;
|
||||
}
|
||||
s += sinc;
|
||||
kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
|
||||
if (c == BRACKET) {
|
||||
if (!match_bracket(p-pinc, k, kfold))
|
||||
return FNM_NOMATCH;
|
||||
} else if (c != QUESTION && k != c && kfold != c) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the pat and str tails match */
|
||||
p = ptail;
|
||||
for (;;) {
|
||||
c = FnmatchNextPattern(p, endpat - p, &pinc, flags);
|
||||
p += pinc;
|
||||
if ((k = FnmatchNextString(s, endstr - s, &sinc)) <= 0) {
|
||||
if (c != END) return FNM_NOMATCH;
|
||||
break;
|
||||
}
|
||||
s += sinc;
|
||||
kfold = flags & FNM_CASEFOLD ? FnmatchCaseFold(k) : k;
|
||||
if (c == BRACKET) {
|
||||
if (!FnmatchBracket(p - pinc, k, kfold)) return FNM_NOMATCH;
|
||||
} else if (c != QUESTION && k != c && kfold != c) {
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
}
|
||||
/* We're all done with the tails now, so throw them out */
|
||||
endstr = stail;
|
||||
endpat = ptail;
|
||||
|
||||
/* We're all done with the tails now, so throw them out */
|
||||
endstr = stail;
|
||||
endpat = ptail;
|
||||
/* Match pattern components until there are none left */
|
||||
while (pat<endpat) {
|
||||
p = pat;
|
||||
s = str;
|
||||
for (;;) {
|
||||
c = pat_next(p, endpat-p, &pinc, flags);
|
||||
p += pinc;
|
||||
/* Encountering * completes/commits a component */
|
||||
if (c == STAR) {
|
||||
pat = p;
|
||||
str = s;
|
||||
break;
|
||||
}
|
||||
k = str_next(s, endstr-s, &sinc);
|
||||
if (!k)
|
||||
return FNM_NOMATCH;
|
||||
kfold = flags & FNM_CASEFOLD ? casefold(k) : k;
|
||||
if (c == BRACKET) {
|
||||
if (!match_bracket(p-pinc, k, kfold))
|
||||
break;
|
||||
} else if (c != QUESTION && k != c && kfold != c) {
|
||||
break;
|
||||
}
|
||||
s += sinc;
|
||||
}
|
||||
if (c == STAR) continue;
|
||||
/* If we failed, advance str, by 1 char if it's a valid
|
||||
* char, or past all invalid bytes otherwise. */
|
||||
k = str_next(str, endstr-str, &sinc);
|
||||
if (k > 0) str += sinc;
|
||||
else for (str++; str_next(str, endstr-str, &sinc)<0; str++);
|
||||
}
|
||||
|
||||
/* Match pattern components until there are none left */
|
||||
while (pat < endpat) {
|
||||
p = pat;
|
||||
s = str;
|
||||
for (;;) {
|
||||
c = FnmatchNextPattern(p, endpat - p, &pinc, flags);
|
||||
p += pinc;
|
||||
/* Encountering * completes/commits a component */
|
||||
if (c == STAR) {
|
||||
pat = p;
|
||||
str = s;
|
||||
break;
|
||||
}
|
||||
k = FnmatchNextString(s, endstr - s, &sinc);
|
||||
if (!k) return FNM_NOMATCH;
|
||||
kfold = flags & FNM_CASEFOLD ? FnmatchCaseFold(k) : k;
|
||||
if (c == BRACKET) {
|
||||
if (!FnmatchBracket(p - pinc, k, kfold)) break;
|
||||
} else if (c != QUESTION && k != c && kfold != c) {
|
||||
break;
|
||||
}
|
||||
s += sinc;
|
||||
}
|
||||
if (c == STAR) continue;
|
||||
/* If we failed, advance str, by 1 char if it's a valid
|
||||
* char, or past all invalid bytes otherwise. */
|
||||
k = FnmatchNextString(str, endstr - str, &sinc);
|
||||
if (k > 0) {
|
||||
str += sinc;
|
||||
} else {
|
||||
str++;
|
||||
while (FnmatchNextString(str, endstr - str, &sinc) < 0) {
|
||||
str++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -337,29 +334,27 @@ static int FnmatchPerform(const char *pat, size_t m, const char *str, size_t n,
|
|||
*
|
||||
* @see glob()
|
||||
*/
|
||||
int fnmatch(const char *pat, const char *str, int flags) {
|
||||
const char *s, *p;
|
||||
size_t inc;
|
||||
int c;
|
||||
if (flags & FNM_PATHNAME) {
|
||||
for (;;) {
|
||||
for (s = str; *s && *s != '/'; s++)
|
||||
;
|
||||
for (p = pat;
|
||||
(c = FnmatchNextPattern(p, -1, &inc, flags)) != END && c != '/';
|
||||
p += inc)
|
||||
;
|
||||
if (c != *s && (!*s || !(flags & FNM_LEADING_DIR))) return FNM_NOMATCH;
|
||||
if (FnmatchPerform(pat, p - pat, str, s - str, flags)) return FNM_NOMATCH;
|
||||
if (!c) return 0;
|
||||
str = s + 1;
|
||||
pat = p + inc;
|
||||
}
|
||||
} else if (flags & FNM_LEADING_DIR) {
|
||||
for (s = str; *s; s++) {
|
||||
if (*s != '/') continue;
|
||||
if (!FnmatchPerform(pat, -1, str, s - str, flags)) return 0;
|
||||
}
|
||||
}
|
||||
return FnmatchPerform(pat, -1, str, -1, flags);
|
||||
int fnmatch(const char *pat, const char *str, int flags)
|
||||
{
|
||||
const char *s, *p;
|
||||
size_t inc;
|
||||
int c;
|
||||
if (flags & FNM_PATHNAME) for (;;) {
|
||||
for (s=str; *s && *s!='/'; s++);
|
||||
for (p=pat; (c=pat_next(p, -1, &inc, flags))!=END && c!='/'; p+=inc);
|
||||
if (c!=*s && (!*s || !(flags & FNM_LEADING_DIR)))
|
||||
return FNM_NOMATCH;
|
||||
if (fnmatch_internal(pat, p-pat, str, s-str, flags))
|
||||
return FNM_NOMATCH;
|
||||
if (!c) return 0;
|
||||
str = s+1;
|
||||
pat = p+inc;
|
||||
} else if (flags & FNM_LEADING_DIR) {
|
||||
for (s=str; *s; s++) {
|
||||
if (*s != '/') continue;
|
||||
if (!fnmatch_internal(pat, -1, str, s-str, flags))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return fnmatch_internal(pat, -1, str, -1, flags);
|
||||
}
|
||||
|
|
41
third_party/musl/freelocale.c
vendored
Normal file
41
third_party/musl/freelocale.c
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define malloc undef
|
||||
#define calloc undef
|
||||
#define realloc undef
|
||||
#define free(p) munmap(p, sizeof(struct __locale_struct))
|
||||
|
||||
void freelocale(locale_t l)
|
||||
{
|
||||
if (__loc_is_allocated(l)) free(l);
|
||||
}
|
528
third_party/musl/glob.c
vendored
528
third_party/musl/glob.c
vendored
|
@ -35,190 +35,227 @@
|
|||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/dt.h"
|
||||
#include "libc/sysv/consts/s.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "third_party/musl/passwd.h"
|
||||
#include "third_party/musl/fnmatch.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define MAXPATH 1024
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
struct GlobList {
|
||||
struct GlobList *next;
|
||||
char name[];
|
||||
struct match
|
||||
{
|
||||
struct match *next;
|
||||
char name[];
|
||||
};
|
||||
|
||||
static int AppendGlob(struct GlobList **tail, const char *name, size_t len,
|
||||
int mark) {
|
||||
struct GlobList *new;
|
||||
if ((new = malloc(sizeof(struct GlobList) + len + 2))) {
|
||||
(*tail)->next = new;
|
||||
new->next = NULL;
|
||||
memcpy(new->name, name, len + 1);
|
||||
if (mark && len && name[len - 1] != '/') {
|
||||
new->name[len] = '/';
|
||||
new->name[len + 1] = 0;
|
||||
}
|
||||
*tail = new;
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
static int append(struct match **tail, const char *name, size_t len, int mark)
|
||||
{
|
||||
struct match *new = malloc(sizeof(struct match) + len + 2);
|
||||
if (!new) return -1;
|
||||
(*tail)->next = new;
|
||||
new->next = NULL;
|
||||
memcpy(new->name, name, len+1);
|
||||
if (mark && len && name[len-1]!='/') {
|
||||
new->name[len] = '/';
|
||||
new->name[len+1] = 0;
|
||||
}
|
||||
*tail = new;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int PerformGlob(char *buf, size_t pos, int type, char *pat, int flags,
|
||||
int (*errfunc)(const char *path, int err),
|
||||
struct GlobList **tail) {
|
||||
DIR *dir;
|
||||
size_t l;
|
||||
char *p, *p2;
|
||||
char saved_sep;
|
||||
ptrdiff_t i, j;
|
||||
struct stat st;
|
||||
struct dirent *de;
|
||||
int r, readerr, in_bracket, overflow, old_errno, fnm_flags;
|
||||
/* If GLOB_MARK is unused, we don't care about type. */
|
||||
if (!type && !(flags & GLOB_MARK)) type = DT_REG;
|
||||
/* Special-case the remaining pattern being all slashes, in
|
||||
* which case we can use caller-passed type if it's a dir. */
|
||||
if (*pat && type != DT_DIR) type = 0;
|
||||
while (pos + 1 < MAXPATH && *pat == '/') {
|
||||
buf[pos++] = *pat++;
|
||||
}
|
||||
/* Consume maximal [escaped-]literal prefix of pattern, copying
|
||||
* and un-escaping it to the running buffer as we go. */
|
||||
i = 0;
|
||||
j = 0;
|
||||
overflow = 0;
|
||||
in_bracket = 0;
|
||||
for (; pat[i] != '*' && pat[i] != '?' && (!in_bracket || pat[i] != ']');
|
||||
i++) {
|
||||
if (!pat[i]) {
|
||||
if (overflow) return 0;
|
||||
pat += i;
|
||||
pos += j;
|
||||
i = j = 0;
|
||||
break;
|
||||
} else if (pat[i] == '[') {
|
||||
in_bracket = 1;
|
||||
} else if (pat[i] == '\\' && !(flags & GLOB_NOESCAPE)) {
|
||||
/* Backslashes inside a bracket are (at least by
|
||||
* our interpretation) non-special, so if next
|
||||
* char is ']' we have a complete expression. */
|
||||
if (in_bracket && pat[i + 1] == ']') break;
|
||||
/* Unpaired final backslash never matches. */
|
||||
if (!pat[i + 1]) return 0;
|
||||
i++;
|
||||
}
|
||||
if (pat[i] == '/') {
|
||||
if (overflow) return 0;
|
||||
in_bracket = 0;
|
||||
pat += i + 1;
|
||||
i = -1;
|
||||
pos += j + 1;
|
||||
j = -1;
|
||||
}
|
||||
/* Only store a character if it fits in the buffer, but if
|
||||
* a potential bracket expression is open, the overflow
|
||||
* must be remembered and handled later only if the bracket
|
||||
* is unterminated (and thereby a literal), so as not to
|
||||
* disallow long bracket expressions with short matches. */
|
||||
if (pos + (j + 1) < MAXPATH) {
|
||||
buf[pos + j++] = pat[i];
|
||||
} else if (in_bracket) {
|
||||
overflow = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
/* If we consume any new components, the caller-passed type
|
||||
* or dummy type from above is no longer valid. */
|
||||
type = 0;
|
||||
}
|
||||
buf[pos] = 0;
|
||||
if (!*pat) {
|
||||
/* If we consumed any components above, or if GLOB_MARK is
|
||||
* requested and we don't yet know if the match is a dir,
|
||||
* we must call stat to confirm the file exists and/or
|
||||
* determine its type. */
|
||||
if ((flags & GLOB_MARK) && type == DT_LNK) type = 0;
|
||||
if (!type && stat(buf, &st)) {
|
||||
if (errno != ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR))) {
|
||||
return GLOB_ABORTED;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!type && S_ISDIR(st.st_mode)) type = DT_DIR;
|
||||
if (AppendGlob(tail, buf, pos, (flags & GLOB_MARK) && type == DT_DIR)) {
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
p2 = strchr(pat, '/');
|
||||
saved_sep = '/';
|
||||
/* Check if the '/' was escaped and, if so, remove the escape char
|
||||
* so that it will not be unpaired when passed to fnmatch. */
|
||||
if (p2 && !(flags & GLOB_NOESCAPE)) {
|
||||
for (p = p2; p > pat && p[-1] == '\\'; p--)
|
||||
;
|
||||
if ((p2 - p) % 2) {
|
||||
p2--;
|
||||
saved_sep = '\\';
|
||||
}
|
||||
}
|
||||
dir = opendir(pos ? buf : ".");
|
||||
if (!dir) {
|
||||
if (errfunc(buf, errno) || (flags & GLOB_ERR)) return GLOB_ABORTED;
|
||||
return 0;
|
||||
}
|
||||
old_errno = errno;
|
||||
while (errno = 0, de = readdir(dir)) {
|
||||
/* Quickly skip non-directories when there's pattern left. */
|
||||
if (p2 && de->d_type && de->d_type != DT_DIR && de->d_type != DT_LNK) {
|
||||
continue;
|
||||
}
|
||||
l = strlen(de->d_name);
|
||||
if (l >= MAXPATH - pos) continue;
|
||||
if (p2) *p2 = 0;
|
||||
fnm_flags = ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0) |
|
||||
((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0);
|
||||
if (fnmatch(pat, de->d_name, fnm_flags)) continue;
|
||||
/* With GLOB_PERIOD don't allow matching . or .. unless fnmatch()
|
||||
* would match them with FNM_PERIOD rules in effect. */
|
||||
if (p2 && (flags & GLOB_PERIOD) && de->d_name[0] == '.' &&
|
||||
(!de->d_name[1] || (de->d_name[1] == '.' && !de->d_name[2])) &&
|
||||
fnmatch(pat, de->d_name, fnm_flags | FNM_PERIOD)) {
|
||||
continue;
|
||||
}
|
||||
memcpy(buf + pos, de->d_name, l + 1);
|
||||
if (p2) *p2 = saved_sep;
|
||||
r = PerformGlob(buf, pos + l, de->d_type, p2 ? p2 : "", flags, errfunc,
|
||||
tail);
|
||||
if (r) {
|
||||
closedir(dir);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
readerr = errno;
|
||||
if (p2) *p2 = saved_sep;
|
||||
closedir(dir);
|
||||
if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR))) {
|
||||
return GLOB_ABORTED;
|
||||
}
|
||||
errno = old_errno;
|
||||
return 0;
|
||||
static int do_glob(char *buf, size_t pos, int type, char *pat, int flags, int (*errfunc)(const char *path, int err), struct match **tail)
|
||||
{
|
||||
/* If GLOB_MARK is unused, we don't care about type. */
|
||||
if (!type && !(flags & GLOB_MARK)) type = DT_REG;
|
||||
|
||||
/* Special-case the remaining pattern being all slashes, in
|
||||
* which case we can use caller-passed type if it's a dir. */
|
||||
if (*pat && type!=DT_DIR) type = 0;
|
||||
while (pos+1 < PATH_MAX && *pat=='/') buf[pos++] = *pat++;
|
||||
|
||||
/* Consume maximal [escaped-]literal prefix of pattern, copying
|
||||
* and un-escaping it to the running buffer as we go. */
|
||||
ptrdiff_t i=0, j=0;
|
||||
int in_bracket = 0, overflow = 0;
|
||||
for (; pat[i]!='*' && pat[i]!='?' && (!in_bracket || pat[i]!=']'); i++) {
|
||||
if (!pat[i]) {
|
||||
if (overflow) return 0;
|
||||
pat += i;
|
||||
pos += j;
|
||||
i = j = 0;
|
||||
break;
|
||||
} else if (pat[i] == '[') {
|
||||
in_bracket = 1;
|
||||
} else if (pat[i] == '\\' && !(flags & GLOB_NOESCAPE)) {
|
||||
/* Backslashes inside a bracket are (at least by
|
||||
* our interpretation) non-special, so if next
|
||||
* char is ']' we have a complete expression. */
|
||||
if (in_bracket && pat[i+1]==']') break;
|
||||
/* Unpaired final backslash never matches. */
|
||||
if (!pat[i+1]) return 0;
|
||||
i++;
|
||||
}
|
||||
if (pat[i] == '/') {
|
||||
if (overflow) return 0;
|
||||
in_bracket = 0;
|
||||
pat += i+1;
|
||||
i = -1;
|
||||
pos += j+1;
|
||||
j = -1;
|
||||
}
|
||||
/* Only store a character if it fits in the buffer, but if
|
||||
* a potential bracket expression is open, the overflow
|
||||
* must be remembered and handled later only if the bracket
|
||||
* is unterminated (and thereby a literal), so as not to
|
||||
* disallow long bracket expressions with short matches. */
|
||||
if (pos+(j+1) < PATH_MAX) {
|
||||
buf[pos+j++] = pat[i];
|
||||
} else if (in_bracket) {
|
||||
overflow = 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
/* If we consume any new components, the caller-passed type
|
||||
* or dummy type from above is no longer valid. */
|
||||
type = 0;
|
||||
}
|
||||
buf[pos] = 0;
|
||||
if (!*pat) {
|
||||
/* If we consumed any components above, or if GLOB_MARK is
|
||||
* requested and we don't yet know if the match is a dir,
|
||||
* we must confirm the file exists and/or determine its type.
|
||||
*
|
||||
* If marking dirs, symlink type is inconclusive; we need the
|
||||
* type for the symlink target, and therefore must try stat
|
||||
* first unless type is known not to be a symlink. Otherwise,
|
||||
* or if that fails, use lstat for determining existence to
|
||||
* avoid false negatives in the case of broken symlinks. */
|
||||
struct stat st;
|
||||
if ((flags & GLOB_MARK) && (!type||type==DT_LNK) && !stat(buf, &st)) {
|
||||
if (S_ISDIR(st.st_mode)) type = DT_DIR;
|
||||
else type = DT_REG;
|
||||
}
|
||||
if (!type && lstat(buf, &st)) {
|
||||
if (errno!=ENOENT && (errfunc(buf, errno) || (flags & GLOB_ERR)))
|
||||
return GLOB_ABORTED;
|
||||
return 0;
|
||||
}
|
||||
if (append(tail, buf, pos, (flags & GLOB_MARK) && type==DT_DIR))
|
||||
return GLOB_NOSPACE;
|
||||
return 0;
|
||||
}
|
||||
char *p2 = strchr(pat, '/'), saved_sep = '/';
|
||||
/* Check if the '/' was escaped and, if so, remove the escape char
|
||||
* so that it will not be unpaired when passed to fnmatch. */
|
||||
if (p2 && !(flags & GLOB_NOESCAPE)) {
|
||||
char *p;
|
||||
for (p=p2; p>pat && p[-1]=='\\'; p--);
|
||||
if ((p2-p)%2) {
|
||||
p2--;
|
||||
saved_sep = '\\';
|
||||
}
|
||||
}
|
||||
DIR *dir = opendir(pos ? buf : ".");
|
||||
if (!dir) {
|
||||
if (errfunc(buf, errno) || (flags & GLOB_ERR))
|
||||
return GLOB_ABORTED;
|
||||
return 0;
|
||||
}
|
||||
int old_errno = errno;
|
||||
struct dirent *de;
|
||||
while (errno=0, de=readdir(dir)) {
|
||||
/* Quickly skip non-directories when there's pattern left. */
|
||||
if (p2 && de->d_type && de->d_type!=DT_DIR && de->d_type!=DT_LNK)
|
||||
continue;
|
||||
|
||||
size_t l = strlen(de->d_name);
|
||||
if (l >= PATH_MAX-pos) continue;
|
||||
|
||||
if (p2) *p2 = 0;
|
||||
|
||||
int fnm_flags= ((flags & GLOB_NOESCAPE) ? FNM_NOESCAPE : 0)
|
||||
| ((!(flags & GLOB_PERIOD)) ? FNM_PERIOD : 0);
|
||||
|
||||
if (fnmatch(pat, de->d_name, fnm_flags))
|
||||
continue;
|
||||
|
||||
/* With GLOB_PERIOD, don't allow matching . or .. unless
|
||||
* fnmatch would match them with FNM_PERIOD rules in effect. */
|
||||
if (p2 && (flags & GLOB_PERIOD) && de->d_name[0]=='.'
|
||||
&& (!de->d_name[1] || de->d_name[1]=='.' && !de->d_name[2])
|
||||
&& fnmatch(pat, de->d_name, fnm_flags | FNM_PERIOD))
|
||||
continue;
|
||||
|
||||
memcpy(buf+pos, de->d_name, l+1);
|
||||
if (p2) *p2 = saved_sep;
|
||||
int r = do_glob(buf, pos+l, de->d_type, p2 ? p2 : "", flags, errfunc, tail);
|
||||
if (r) {
|
||||
closedir(dir);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
int readerr = errno;
|
||||
if (p2) *p2 = saved_sep;
|
||||
closedir(dir);
|
||||
if (readerr && (errfunc(buf, errno) || (flags & GLOB_ERR)))
|
||||
return GLOB_ABORTED;
|
||||
errno = old_errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int IgnoreGlobError(const char *path, int err) {
|
||||
return 0;
|
||||
static int ignore_err(const char *path, int err)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void FreeGlobList(struct GlobList *head) {
|
||||
struct GlobList *match, *next;
|
||||
for (match = head->next; match; match = next) {
|
||||
next = match->next;
|
||||
free(match);
|
||||
}
|
||||
static void freelist(struct match *head)
|
||||
{
|
||||
struct match *match, *next;
|
||||
for (match=head->next; match; match=next) {
|
||||
next = match->next;
|
||||
free(match);
|
||||
}
|
||||
}
|
||||
|
||||
static int GlobPredicate(const void *a, const void *b) {
|
||||
return strcmp(*(const char **)a, *(const char **)b);
|
||||
static int sort(const void *a, const void *b)
|
||||
{
|
||||
return strcmp(*(const char **)a, *(const char **)b);
|
||||
}
|
||||
|
||||
static int expand_tilde(char **pat, char *buf, size_t *pos)
|
||||
{
|
||||
char *p = *pat + 1;
|
||||
size_t i = 0;
|
||||
|
||||
char delim, *name_end = strchrnul(p, '/');
|
||||
if ((delim = *name_end)) *name_end++ = 0;
|
||||
*pat = name_end;
|
||||
|
||||
char *home = *p ? NULL : getenv("HOME");
|
||||
if (!home) {
|
||||
struct passwd pw, *res;
|
||||
int e = *p ? getpwnam_r(p, &pw, buf, PATH_MAX, &res)
|
||||
: getpwuid_r(getuid(), &pw, buf, PATH_MAX, &res);
|
||||
if (e == ENOMEM) {
|
||||
return GLOB_NOSPACE;
|
||||
} else if (e == 0) {
|
||||
if (!res)
|
||||
return GLOB_NOMATCH;
|
||||
} else {
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
home = pw.pw_dir;
|
||||
}
|
||||
while (i < PATH_MAX - 2 && *home)
|
||||
buf[i++] = *home++;
|
||||
if (*home)
|
||||
return GLOB_NOMATCH;
|
||||
if ((buf[i] = delim))
|
||||
buf[++i] = 0;
|
||||
*pos = i;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -239,81 +276,88 @@ static int GlobPredicate(const void *a, const void *b) {
|
|||
* @return 0 on success or GLOB_NOMATCH, GLOB_NOSPACE on OOM, or
|
||||
* GLOB_ABORTED on read error
|
||||
*/
|
||||
int glob(const char *pat, int flags, int errfunc(const char *path, int err),
|
||||
glob_t *g) {
|
||||
int error = 0;
|
||||
size_t cnt, i;
|
||||
char **pathv, buf[MAXPATH];
|
||||
struct GlobList head = {.next = NULL}, *tail = &head;
|
||||
size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
|
||||
if (!errfunc) errfunc = IgnoreGlobError;
|
||||
if (!(flags & GLOB_APPEND)) {
|
||||
g->gl_offs = offs;
|
||||
g->gl_pathc = 0;
|
||||
g->gl_pathv = NULL;
|
||||
}
|
||||
if (*pat) {
|
||||
char *p = strdup(pat);
|
||||
if (!p) return GLOB_NOSPACE;
|
||||
buf[0] = 0;
|
||||
error = PerformGlob(buf, 0, 0, p, flags, errfunc, &tail);
|
||||
free(p);
|
||||
}
|
||||
if (error == GLOB_NOSPACE) {
|
||||
FreeGlobList(&head);
|
||||
return error;
|
||||
}
|
||||
for (cnt = 0, tail = head.next; tail; tail = tail->next, cnt++)
|
||||
;
|
||||
if (!cnt) {
|
||||
if (flags & GLOB_NOCHECK) {
|
||||
tail = &head;
|
||||
if (AppendGlob(&tail, pat, strlen(pat), 0)) {
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
cnt++;
|
||||
} else
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
if (flags & GLOB_APPEND) {
|
||||
pathv =
|
||||
realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
|
||||
if (!pathv) {
|
||||
FreeGlobList(&head);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
g->gl_pathv = pathv;
|
||||
offs += g->gl_pathc;
|
||||
} else {
|
||||
g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
|
||||
if (!g->gl_pathv) {
|
||||
FreeGlobList(&head);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
for (i = 0; i < offs; i++) {
|
||||
g->gl_pathv[i] = NULL;
|
||||
}
|
||||
}
|
||||
for (i = 0, tail = head.next; i < cnt; tail = tail->next, i++) {
|
||||
g->gl_pathv[offs + i] = tail->name;
|
||||
}
|
||||
g->gl_pathv[offs + i] = NULL;
|
||||
g->gl_pathc += cnt;
|
||||
if (!(flags & GLOB_NOSORT)) {
|
||||
qsort(g->gl_pathv + offs, cnt, sizeof(char *), GlobPredicate);
|
||||
}
|
||||
return error;
|
||||
int glob(const char *restrict pat, int flags, int (*errfunc)(const char *path, int err), glob_t *restrict g)
|
||||
{
|
||||
struct match head = { .next = NULL }, *tail = &head;
|
||||
size_t cnt, i;
|
||||
size_t offs = (flags & GLOB_DOOFFS) ? g->gl_offs : 0;
|
||||
int error = 0;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
if (!errfunc) errfunc = ignore_err;
|
||||
|
||||
if (!(flags & GLOB_APPEND)) {
|
||||
g->gl_offs = offs;
|
||||
g->gl_pathc = 0;
|
||||
g->gl_pathv = NULL;
|
||||
}
|
||||
|
||||
if (*pat) {
|
||||
char *p = strdup(pat);
|
||||
if (!p) return GLOB_NOSPACE;
|
||||
buf[0] = 0;
|
||||
size_t pos = 0;
|
||||
char *s = p;
|
||||
if ((flags & (GLOB_TILDE | GLOB_TILDE_CHECK)) && *p == '~')
|
||||
error = expand_tilde(&s, buf, &pos);
|
||||
if (!error)
|
||||
error = do_glob(buf, pos, 0, s, flags, errfunc, &tail);
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (error == GLOB_NOSPACE) {
|
||||
freelist(&head);
|
||||
return error;
|
||||
}
|
||||
|
||||
for (cnt=0, tail=head.next; tail; tail=tail->next, cnt++);
|
||||
if (!cnt) {
|
||||
if (flags & GLOB_NOCHECK) {
|
||||
tail = &head;
|
||||
if (append(&tail, pat, strlen(pat), 0))
|
||||
return GLOB_NOSPACE;
|
||||
cnt++;
|
||||
} else if (!error)
|
||||
return GLOB_NOMATCH;
|
||||
}
|
||||
|
||||
if (flags & GLOB_APPEND) {
|
||||
char **pathv = realloc(g->gl_pathv, (offs + g->gl_pathc + cnt + 1) * sizeof(char *));
|
||||
if (!pathv) {
|
||||
freelist(&head);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
g->gl_pathv = pathv;
|
||||
offs += g->gl_pathc;
|
||||
} else {
|
||||
g->gl_pathv = malloc((offs + cnt + 1) * sizeof(char *));
|
||||
if (!g->gl_pathv) {
|
||||
freelist(&head);
|
||||
return GLOB_NOSPACE;
|
||||
}
|
||||
for (i=0; i<offs; i++)
|
||||
g->gl_pathv[i] = NULL;
|
||||
}
|
||||
for (i=0, tail=head.next; i<cnt; tail=tail->next, i++)
|
||||
g->gl_pathv[offs + i] = tail->name;
|
||||
g->gl_pathv[offs + i] = NULL;
|
||||
g->gl_pathc += cnt;
|
||||
|
||||
if (!(flags & GLOB_NOSORT))
|
||||
qsort(g->gl_pathv+offs, cnt, sizeof(char *), sort);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Frees entries allocated by glob().
|
||||
*/
|
||||
void globfree(glob_t *g) {
|
||||
size_t i;
|
||||
for (i = 0; i < g->gl_pathc; i++) {
|
||||
free(g->gl_pathv[g->gl_offs + i] - offsetof(struct GlobList, name));
|
||||
}
|
||||
free(g->gl_pathv);
|
||||
g->gl_pathc = 0;
|
||||
g->gl_pathv = NULL;
|
||||
void globfree(glob_t *g)
|
||||
{
|
||||
size_t i;
|
||||
for (i=0; i<g->gl_pathc; i++)
|
||||
free(g->gl_pathv[g->gl_offs + i] - offsetof(struct match, name));
|
||||
free(g->gl_pathv);
|
||||
g->gl_pathc = 0;
|
||||
g->gl_pathv = NULL;
|
||||
}
|
||||
|
|
727
third_party/musl/iconv.c
vendored
Normal file
727
third_party/musl/iconv.c
vendored
Normal file
|
@ -0,0 +1,727 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/stdio/iconv.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/locale.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/thread/tls.h"
|
||||
// clang-format off
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define UTF_32BE 0300
|
||||
#define UTF_16LE 0301
|
||||
#define UTF_16BE 0302
|
||||
#define UTF_32LE 0303
|
||||
#define UCS2BE 0304
|
||||
#define UCS2LE 0305
|
||||
#define WCHAR_T 0306
|
||||
#define US_ASCII 0307
|
||||
#define UTF_8 0310
|
||||
#define UTF_16 0312
|
||||
#define UTF_32 0313
|
||||
#define UCS2 0314
|
||||
#define EUC_JP 0320
|
||||
#define SHIFT_JIS 0321
|
||||
#define ISO2022_JP 0322
|
||||
#define GB18030 0330
|
||||
#define GBK 0331
|
||||
#define GB2312 0332
|
||||
#define BIG5 0340
|
||||
#define EUC_KR 0350
|
||||
|
||||
/* Definitions of charmaps. Each charmap consists of:
|
||||
* 1. Empty-string-terminated list of null-terminated aliases.
|
||||
* 2. Special type code or number of elided quads of entries.
|
||||
* 3. Character table (size determined by field 2), consisting
|
||||
* of 5 bytes for every 4 characters, interpreted as 10-bit
|
||||
* indices into the legacy_chars table. */
|
||||
|
||||
static const unsigned char charmaps[] =
|
||||
"utf8\0char\0\0\310"
|
||||
"wchart\0\0\306"
|
||||
"ucs2be\0\0\304"
|
||||
"ucs2le\0\0\305"
|
||||
"utf16be\0\0\302"
|
||||
"utf16le\0\0\301"
|
||||
"ucs4be\0utf32be\0\0\300"
|
||||
"ucs4le\0utf32le\0\0\303"
|
||||
"ascii\0usascii\0iso646\0iso646us\0\0\307"
|
||||
"utf16\0\0\312"
|
||||
"ucs4\0utf32\0\0\313"
|
||||
"ucs2\0\0\314"
|
||||
"eucjp\0\0\320"
|
||||
"shiftjis\0sjis\0cp932\0\0\321"
|
||||
"iso2022jp\0\0\322"
|
||||
"gb18030\0\0\330"
|
||||
"gbk\0cp936\0windows936\0\0\331"
|
||||
"gb2312\0\0\332"
|
||||
"big5\0bigfive\0cp950\0big5hkscs\0\0\340"
|
||||
"euckr\0ksc5601\0ksx1001\0cp949\0\0\350"
|
||||
#include "libc/stdio/codepages.inc"
|
||||
;
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wmissing-braces"
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
/* Table of characters that appear in legacy 8-bit codepages,
|
||||
* limited to 1024 slots (10 bit indices). The first 256 entries
|
||||
* are elided since those characters are obviously all included. */
|
||||
static const unsigned short legacy_chars[] = {
|
||||
#include "libc/stdio/legacychars.inc"
|
||||
};
|
||||
|
||||
static const unsigned short jis0208[84][94] = {
|
||||
#include "libc/stdio/jis0208.inc"
|
||||
};
|
||||
|
||||
static const unsigned short gb18030[126][190] = {
|
||||
#include "libc/stdio/gb18030.inc"
|
||||
};
|
||||
|
||||
static const unsigned short big5[89][157] = {
|
||||
#include "libc/stdio/big5.inc"
|
||||
};
|
||||
|
||||
static const unsigned short hkscs[] = {
|
||||
#include "libc/stdio/hkscs.inc"
|
||||
};
|
||||
|
||||
static const unsigned short ksc[93][94] = {
|
||||
#include "libc/stdio/ksc.inc"
|
||||
};
|
||||
|
||||
static const unsigned short rev_jis[] = {
|
||||
#include "libc/stdio/revjis.inc"
|
||||
};
|
||||
|
||||
static int fuzzycmp(const unsigned char *a, const unsigned char *b)
|
||||
{
|
||||
for (; *a && *b; a++, b++) {
|
||||
while (*a && (*a|32U)-'a'>26 && *a-'0'>10U) a++;
|
||||
if ((*a|32U) != *b) return 1;
|
||||
}
|
||||
return *a != *b;
|
||||
}
|
||||
|
||||
static size_t find_charmap(const void *name)
|
||||
{
|
||||
const unsigned char *s;
|
||||
if (!*(char *)name) name=charmaps; /* "utf8" */
|
||||
for (s=charmaps; *s; ) {
|
||||
if (!fuzzycmp(name, s)) {
|
||||
for (; *s; s+=strlen((void *)s)+1);
|
||||
return s+1-charmaps;
|
||||
}
|
||||
s += strlen((void *)s)+1;
|
||||
if (!*s) {
|
||||
if (s[1] > 0200) s+=2;
|
||||
else s+=2+(64U-s[1])*5;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct stateful_cd {
|
||||
iconv_t base_cd;
|
||||
unsigned state;
|
||||
};
|
||||
|
||||
static iconv_t combine_to_from(size_t t, size_t f)
|
||||
{
|
||||
return (void *)(f<<16 | t<<1 | 1);
|
||||
}
|
||||
|
||||
static size_t extract_from(iconv_t cd)
|
||||
{
|
||||
return (size_t)cd >> 16;
|
||||
}
|
||||
|
||||
static size_t extract_to(iconv_t cd)
|
||||
{
|
||||
return (size_t)cd >> 1 & 0x7fff;
|
||||
}
|
||||
|
||||
iconv_t iconv_open(const char *to, const char *from)
|
||||
{
|
||||
size_t f, t;
|
||||
struct stateful_cd *scd;
|
||||
|
||||
if ((t = find_charmap(to))==-1
|
||||
|| (f = find_charmap(from))==-1
|
||||
|| (charmaps[t] >= 0330)) {
|
||||
errno = EINVAL;
|
||||
return (iconv_t)-1;
|
||||
}
|
||||
iconv_t cd = combine_to_from(t, f);
|
||||
|
||||
switch (charmaps[f]) {
|
||||
case UTF_16:
|
||||
case UTF_32:
|
||||
case UCS2:
|
||||
case ISO2022_JP:
|
||||
scd = malloc(sizeof *scd);
|
||||
if (!scd) return (iconv_t)-1;
|
||||
scd->base_cd = cd;
|
||||
scd->state = 0;
|
||||
cd = (iconv_t)scd;
|
||||
}
|
||||
|
||||
return cd;
|
||||
}
|
||||
|
||||
int iconv_close(iconv_t cd)
|
||||
{
|
||||
if (!((size_t)cd & 1)) free((void *)cd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned get_16(const unsigned char *s, int e)
|
||||
{
|
||||
e &= 1;
|
||||
return s[e]<<8 | s[1-e];
|
||||
}
|
||||
|
||||
static void put_16(unsigned char *s, unsigned c, int e)
|
||||
{
|
||||
e &= 1;
|
||||
s[e] = c>>8;
|
||||
s[1-e] = c;
|
||||
}
|
||||
|
||||
static unsigned get_32(const unsigned char *s, int e)
|
||||
{
|
||||
e &= 3;
|
||||
return (s[e]+0U)<<24 | s[e^1]<<16 | s[e^2]<<8 | s[e^3];
|
||||
}
|
||||
|
||||
static void put_32(unsigned char *s, unsigned c, int e)
|
||||
{
|
||||
e &= 3;
|
||||
s[e^0] = c>>24;
|
||||
s[e^1] = c>>16;
|
||||
s[e^2] = c>>8;
|
||||
s[e^3] = c;
|
||||
}
|
||||
|
||||
/* Adapt as needed */
|
||||
#define mbrtowc_utf8 mbrtowc
|
||||
#define wctomb_utf8 wctomb
|
||||
|
||||
static unsigned legacy_map(const unsigned char *map, unsigned c)
|
||||
{
|
||||
if (c < 4*map[-1]) return c;
|
||||
unsigned x = c - 4*map[-1];
|
||||
x = map[x*5/4]>>2*x%8 | map[x*5/4+1]<<8-2*x%8 & 1023;
|
||||
return x < 256 ? x : legacy_chars[x-256];
|
||||
}
|
||||
|
||||
static unsigned uni_to_jis(unsigned c)
|
||||
{
|
||||
unsigned nel = sizeof rev_jis / sizeof *rev_jis;
|
||||
unsigned d, j, i, b = 0;
|
||||
for (;;) {
|
||||
i = nel/2;
|
||||
j = rev_jis[b+i];
|
||||
d = jis0208[j/256][j%256];
|
||||
if (d==c) return j + 0x2121;
|
||||
else if (nel == 1) return 0;
|
||||
else if (c < d)
|
||||
nel /= 2;
|
||||
else {
|
||||
b += i;
|
||||
nel -= nel/2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t iconv(iconv_t cd, char **restrict in, size_t *restrict inb, char **restrict out, size_t *restrict outb)
|
||||
{
|
||||
size_t x=0;
|
||||
struct stateful_cd *scd=0;
|
||||
if (!((size_t)cd & 1)) {
|
||||
scd = (void *)cd;
|
||||
cd = scd->base_cd;
|
||||
}
|
||||
unsigned to = extract_to(cd);
|
||||
unsigned from = extract_from(cd);
|
||||
const unsigned char *map = charmaps+from+1;
|
||||
const unsigned char *tomap = charmaps+to+1;
|
||||
mbstate_t st = {0};
|
||||
wchar_t wc;
|
||||
unsigned c, d;
|
||||
size_t k, l;
|
||||
int err;
|
||||
unsigned char type = map[-1];
|
||||
unsigned char totype = tomap[-1];
|
||||
locale_t *ploc = &CURRENT_LOCALE, loc = *ploc;
|
||||
|
||||
if (!in || !*in || !*inb) return 0;
|
||||
|
||||
*ploc = UTF8_LOCALE;
|
||||
|
||||
for (; *inb; *in+=l, *inb-=l) {
|
||||
c = *(unsigned char *)*in;
|
||||
l = 1;
|
||||
|
||||
switch (type) {
|
||||
case UTF_8:
|
||||
if (c < 128) break;
|
||||
l = mbrtowc_utf8(&wc, *in, *inb, &st);
|
||||
if (l == (size_t)-1) goto ilseq;
|
||||
if (l == (size_t)-2) goto starved;
|
||||
c = wc;
|
||||
break;
|
||||
case US_ASCII:
|
||||
if (c >= 128) goto ilseq;
|
||||
break;
|
||||
case WCHAR_T:
|
||||
l = sizeof(wchar_t);
|
||||
if (*inb < l) goto starved;
|
||||
c = *(wchar_t *)*in;
|
||||
if (0) {
|
||||
case UTF_32BE:
|
||||
case UTF_32LE:
|
||||
l = 4;
|
||||
if (*inb < 4) goto starved;
|
||||
c = get_32((void *)*in, type);
|
||||
}
|
||||
if (c-0xd800u < 0x800u || c >= 0x110000u) goto ilseq;
|
||||
break;
|
||||
case UCS2BE:
|
||||
case UCS2LE:
|
||||
case UTF_16BE:
|
||||
case UTF_16LE:
|
||||
l = 2;
|
||||
if (*inb < 2) goto starved;
|
||||
c = get_16((void *)*in, type);
|
||||
if ((unsigned)(c-0xdc00) < 0x400) goto ilseq;
|
||||
if ((unsigned)(c-0xd800) < 0x400) {
|
||||
if (type-UCS2BE < 2U) goto ilseq;
|
||||
l = 4;
|
||||
if (*inb < 4) goto starved;
|
||||
d = get_16((void *)(*in + 2), type);
|
||||
if ((unsigned)(d-0xdc00) >= 0x400) goto ilseq;
|
||||
c = ((c-0xd7c0)<<10) + (d-0xdc00);
|
||||
}
|
||||
break;
|
||||
case UCS2:
|
||||
case UTF_16:
|
||||
l = 0;
|
||||
if (!scd->state) {
|
||||
if (*inb < 2) goto starved;
|
||||
c = get_16((void *)*in, 0);
|
||||
scd->state = type==UCS2
|
||||
? c==0xfffe ? UCS2LE : UCS2BE
|
||||
: c==0xfffe ? UTF_16LE : UTF_16BE;
|
||||
if (c == 0xfffe || c == 0xfeff)
|
||||
l = 2;
|
||||
}
|
||||
type = scd->state;
|
||||
continue;
|
||||
case UTF_32:
|
||||
l = 0;
|
||||
if (!scd->state) {
|
||||
if (*inb < 4) goto starved;
|
||||
c = get_32((void *)*in, 0);
|
||||
scd->state = c==0xfffe0000 ? UTF_32LE : UTF_32BE;
|
||||
if (c == 0xfffe0000 || c == 0xfeff)
|
||||
l = 4;
|
||||
}
|
||||
type = scd->state;
|
||||
continue;
|
||||
case SHIFT_JIS:
|
||||
if (c < 128) break;
|
||||
if (c-0xa1 <= 0xdf-0xa1) {
|
||||
c += 0xff61-0xa1;
|
||||
break;
|
||||
}
|
||||
l = 2;
|
||||
if (*inb < 2) goto starved;
|
||||
d = *((unsigned char *)*in + 1);
|
||||
if (c-129 <= 159-129) c -= 129;
|
||||
else if (c-224 <= 239-224) c -= 193;
|
||||
else goto ilseq;
|
||||
c *= 2;
|
||||
if (d-64 <= 158-64) {
|
||||
if (d==127) goto ilseq;
|
||||
if (d>127) d--;
|
||||
d -= 64;
|
||||
} else if (d-159 <= 252-159) {
|
||||
c++;
|
||||
d -= 159;
|
||||
}
|
||||
if (c>=84) goto ilseq;
|
||||
c = jis0208[c][d];
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
case EUC_JP:
|
||||
if (c < 128) break;
|
||||
l = 2;
|
||||
if (*inb < 2) goto starved;
|
||||
d = *((unsigned char *)*in + 1);
|
||||
if (c==0x8e) {
|
||||
c = d;
|
||||
if (c-0xa1 > 0xdf-0xa1) goto ilseq;
|
||||
c += 0xff61 - 0xa1;
|
||||
break;
|
||||
}
|
||||
c -= 0xa1;
|
||||
d -= 0xa1;
|
||||
if (c >= 84 || d >= 94) goto ilseq;
|
||||
c = jis0208[c][d];
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
case ISO2022_JP:
|
||||
if (c >= 128) goto ilseq;
|
||||
if (c == '\033') {
|
||||
l = 3;
|
||||
if (*inb < 3) goto starved;
|
||||
c = *((unsigned char *)*in + 1);
|
||||
d = *((unsigned char *)*in + 2);
|
||||
if (c != '(' && c != '$') goto ilseq;
|
||||
switch (128*(c=='$') + d) {
|
||||
case 'B': scd->state=0; continue;
|
||||
case 'J': scd->state=1; continue;
|
||||
case 'I': scd->state=4; continue;
|
||||
case 128+'@': scd->state=2; continue;
|
||||
case 128+'B': scd->state=3; continue;
|
||||
}
|
||||
goto ilseq;
|
||||
}
|
||||
switch (scd->state) {
|
||||
case 1:
|
||||
if (c=='\\') c = 0xa5;
|
||||
if (c=='~') c = 0x203e;
|
||||
break;
|
||||
case 2:
|
||||
case 3:
|
||||
l = 2;
|
||||
if (*inb < 2) goto starved;
|
||||
d = *((unsigned char *)*in + 1);
|
||||
c -= 0x21;
|
||||
d -= 0x21;
|
||||
if (c >= 84 || d >= 94) goto ilseq;
|
||||
c = jis0208[c][d];
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
case 4:
|
||||
if (c-0x60 < 0x1f) goto ilseq;
|
||||
if (c-0x21 < 0x5e) c += 0xff61-0x21;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GB2312:
|
||||
if (c < 128) break;
|
||||
if (c < 0xa1) goto ilseq;
|
||||
case GBK:
|
||||
if (c == 128) {
|
||||
c = 0x20ac;
|
||||
break;
|
||||
}
|
||||
case GB18030:
|
||||
if (c < 128) break;
|
||||
c -= 0x81;
|
||||
if (c >= 126) goto ilseq;
|
||||
l = 2;
|
||||
if (*inb < 2) goto starved;
|
||||
d = *((unsigned char *)*in + 1);
|
||||
if (d < 0xa1 && type == GB2312) goto ilseq;
|
||||
if (d-0x40>=191 || d==127) {
|
||||
if (d-'0'>9 || type != GB18030)
|
||||
goto ilseq;
|
||||
l = 4;
|
||||
if (*inb < 4) goto starved;
|
||||
c = (10*c + d-'0') * 1260;
|
||||
d = *((unsigned char *)*in + 2);
|
||||
if (d-0x81>126) goto ilseq;
|
||||
c += 10*(d-0x81);
|
||||
d = *((unsigned char *)*in + 3);
|
||||
if (d-'0'>9) goto ilseq;
|
||||
c += d-'0';
|
||||
c += 128;
|
||||
for (d=0; d<=c; ) {
|
||||
k = 0;
|
||||
for (int i=0; i<126; i++)
|
||||
for (int j=0; j<190; j++)
|
||||
if (gb18030[i][j]-d <= c-d)
|
||||
k++;
|
||||
d = c+1;
|
||||
c += k;
|
||||
}
|
||||
break;
|
||||
}
|
||||
d -= 0x40;
|
||||
if (d>63) d--;
|
||||
c = gb18030[c][d];
|
||||
break;
|
||||
case BIG5:
|
||||
if (c < 128) break;
|
||||
l = 2;
|
||||
if (*inb < 2) goto starved;
|
||||
d = *((unsigned char *)*in + 1);
|
||||
if (d-0x40>=0xff-0x40 || d-0x7f<0xa1-0x7f) goto ilseq;
|
||||
d -= 0x40;
|
||||
if (d > 0x3e) d -= 0x22;
|
||||
if (c-0xa1>=0xfa-0xa1) {
|
||||
if (c-0x87>=0xff-0x87) goto ilseq;
|
||||
if (c < 0xa1) c -= 0x87;
|
||||
else c -= 0x87 + (0xfa-0xa1);
|
||||
c = (hkscs[4867+(c*157+d)/16]>>(c*157+d)%16)%2<<17
|
||||
| hkscs[c*157+d];
|
||||
/* A few HKSCS characters map to pairs of UCS
|
||||
* characters. These are mapped to surrogate
|
||||
* range in the hkscs table then hard-coded
|
||||
* here. Ugly, yes. */
|
||||
if (c/256 == 0xdc) {
|
||||
union {
|
||||
char c[8];
|
||||
wchar_t wc[2];
|
||||
} tmp;
|
||||
char *ptmp = tmp.c;
|
||||
size_t tmpx = iconv(combine_to_from(to, find_charmap("utf8")),
|
||||
&(char *){"\303\212\314\204"
|
||||
"\303\212\314\214"
|
||||
"\303\252\314\204"
|
||||
"\303\252\314\214"
|
||||
+c%256}, &(size_t){4},
|
||||
&ptmp, &(size_t){sizeof tmp});
|
||||
size_t tmplen = ptmp - tmp.c;
|
||||
if (tmplen > *outb) goto toobig;
|
||||
if (tmpx) x++;
|
||||
memcpy(*out, &tmp, tmplen);
|
||||
*out += tmplen;
|
||||
*outb -= tmplen;
|
||||
continue;
|
||||
}
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
}
|
||||
c -= 0xa1;
|
||||
c = big5[c][d]|(c==0x27&&(d==0x3a||d==0x3c||d==0x42))<<17;
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
case EUC_KR:
|
||||
if (c < 128) break;
|
||||
l = 2;
|
||||
if (*inb < 2) goto starved;
|
||||
d = *((unsigned char *)*in + 1);
|
||||
c -= 0xa1;
|
||||
d -= 0xa1;
|
||||
if (c >= 93 || d >= 94) {
|
||||
c += (0xa1-0x81);
|
||||
d += 0xa1;
|
||||
if (c >= 93 || c>=0xc6-0x81 && d>0x52)
|
||||
goto ilseq;
|
||||
if (d-'A'<26) d = d-'A';
|
||||
else if (d-'a'<26) d = d-'a'+26;
|
||||
else if (d-0x81<0xff-0x81) d = d-0x81+52;
|
||||
else goto ilseq;
|
||||
if (c < 0x20) c = 178*c + d;
|
||||
else c = 178*0x20 + 84*(c-0x20) + d;
|
||||
c += 0xac00;
|
||||
for (d=0xac00; d<=c; ) {
|
||||
k = 0;
|
||||
for (int i=0; i<93; i++)
|
||||
for (int j=0; j<94; j++)
|
||||
if (ksc[i][j]-d <= c-d)
|
||||
k++;
|
||||
d = c+1;
|
||||
c += k;
|
||||
}
|
||||
break;
|
||||
}
|
||||
c = ksc[c][d];
|
||||
if (!c) goto ilseq;
|
||||
break;
|
||||
default:
|
||||
if (!c) break;
|
||||
c = legacy_map(map, c);
|
||||
if (!c) goto ilseq;
|
||||
}
|
||||
|
||||
switch (totype) {
|
||||
case WCHAR_T:
|
||||
if (*outb < sizeof(wchar_t)) goto toobig;
|
||||
*(wchar_t *)*out = c;
|
||||
*out += sizeof(wchar_t);
|
||||
*outb -= sizeof(wchar_t);
|
||||
break;
|
||||
case UTF_8:
|
||||
if (*outb < 4) {
|
||||
char tmp[4];
|
||||
k = wctomb_utf8(tmp, c);
|
||||
if (*outb < k) goto toobig;
|
||||
memcpy(*out, tmp, k);
|
||||
} else k = wctomb_utf8(*out, c);
|
||||
*out += k;
|
||||
*outb -= k;
|
||||
break;
|
||||
case US_ASCII:
|
||||
if (c > 0x7f) subst: x++, c='*';
|
||||
default:
|
||||
if (*outb < 1) goto toobig;
|
||||
if (c<256 && c==legacy_map(tomap, c)) {
|
||||
revout:
|
||||
if (*outb < 1) goto toobig;
|
||||
*(*out)++ = c;
|
||||
*outb -= 1;
|
||||
break;
|
||||
}
|
||||
d = c;
|
||||
for (c=4*totype; c<256; c++) {
|
||||
if (d == legacy_map(tomap, c)) {
|
||||
goto revout;
|
||||
}
|
||||
}
|
||||
goto subst;
|
||||
case SHIFT_JIS:
|
||||
if (c < 128) goto revout;
|
||||
if (c == 0xa5) {
|
||||
x++;
|
||||
c = '\\';
|
||||
goto revout;
|
||||
}
|
||||
if (c == 0x203e) {
|
||||
x++;
|
||||
c = '~';
|
||||
goto revout;
|
||||
}
|
||||
if (c-0xff61 <= 0xdf-0xa1) {
|
||||
c += 0xa1 - 0xff61;
|
||||
goto revout;
|
||||
}
|
||||
c = uni_to_jis(c);
|
||||
if (!c) goto subst;
|
||||
if (*outb < 2) goto toobig;
|
||||
d = c%256;
|
||||
c = c/256;
|
||||
*(*out)++ = (c+1)/2 + (c<95 ? 112 : 176);
|
||||
*(*out)++ = c%2 ? d + 31 + d/96 : d + 126;
|
||||
*outb -= 2;
|
||||
break;
|
||||
case EUC_JP:
|
||||
if (c < 128) goto revout;
|
||||
if (c-0xff61 <= 0xdf-0xa1) {
|
||||
c += 0x0e00 + 0x21 - 0xff61;
|
||||
} else {
|
||||
c = uni_to_jis(c);
|
||||
}
|
||||
if (!c) goto subst;
|
||||
if (*outb < 2) goto toobig;
|
||||
*(*out)++ = c/256 + 0x80;
|
||||
*(*out)++ = c%256 + 0x80;
|
||||
*outb -= 2;
|
||||
break;
|
||||
case ISO2022_JP:
|
||||
if (c < 128) goto revout;
|
||||
if (c-0xff61 <= 0xdf-0xa1 || c==0xa5 || c==0x203e) {
|
||||
if (*outb < 7) goto toobig;
|
||||
*(*out)++ = '\033';
|
||||
*(*out)++ = '(';
|
||||
if (c==0xa5) {
|
||||
*(*out)++ = 'J';
|
||||
*(*out)++ = '\\';
|
||||
} else if (c==0x203e) {
|
||||
*(*out)++ = 'J';
|
||||
*(*out)++ = '~';
|
||||
} else {
|
||||
*(*out)++ = 'I';
|
||||
*(*out)++ = c-0xff61+0x21;
|
||||
}
|
||||
*(*out)++ = '\033';
|
||||
*(*out)++ = '(';
|
||||
*(*out)++ = 'B';
|
||||
*outb -= 7;
|
||||
break;
|
||||
}
|
||||
c = uni_to_jis(c);
|
||||
if (!c) goto subst;
|
||||
if (*outb < 8) goto toobig;
|
||||
*(*out)++ = '\033';
|
||||
*(*out)++ = '$';
|
||||
*(*out)++ = 'B';
|
||||
*(*out)++ = c/256;
|
||||
*(*out)++ = c%256;
|
||||
*(*out)++ = '\033';
|
||||
*(*out)++ = '(';
|
||||
*(*out)++ = 'B';
|
||||
*outb -= 8;
|
||||
break;
|
||||
case UCS2:
|
||||
totype = UCS2BE;
|
||||
case UCS2BE:
|
||||
case UCS2LE:
|
||||
case UTF_16:
|
||||
case UTF_16BE:
|
||||
case UTF_16LE:
|
||||
if (c < 0x10000 || totype-UCS2BE < 2U) {
|
||||
if (c >= 0x10000) c = 0xFFFD;
|
||||
if (*outb < 2) goto toobig;
|
||||
put_16((void *)*out, c, totype);
|
||||
*out += 2;
|
||||
*outb -= 2;
|
||||
break;
|
||||
}
|
||||
if (*outb < 4) goto toobig;
|
||||
c -= 0x10000;
|
||||
put_16((void *)*out, (c>>10)|0xd800, totype);
|
||||
put_16((void *)(*out + 2), (c&0x3ff)|0xdc00, totype);
|
||||
*out += 4;
|
||||
*outb -= 4;
|
||||
break;
|
||||
case UTF_32:
|
||||
totype = UTF_32BE;
|
||||
case UTF_32BE:
|
||||
case UTF_32LE:
|
||||
if (*outb < 4) goto toobig;
|
||||
put_32((void *)*out, c, totype);
|
||||
*out += 4;
|
||||
*outb -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*ploc = loc;
|
||||
return x;
|
||||
ilseq:
|
||||
err = EILSEQ;
|
||||
x = -1;
|
||||
goto end;
|
||||
toobig:
|
||||
err = E2BIG;
|
||||
x = -1;
|
||||
goto end;
|
||||
starved:
|
||||
err = EINVAL;
|
||||
x = -1;
|
||||
end:
|
||||
errno = err;
|
||||
*ploc = loc;
|
||||
return x;
|
||||
}
|
99
third_party/musl/langinfo.c
vendored
Normal file
99
third_party/musl/langinfo.c
vendored
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
static const char c_time[] =
|
||||
"Sun\0" "Mon\0" "Tue\0" "Wed\0" "Thu\0" "Fri\0" "Sat\0"
|
||||
"Sunday\0" "Monday\0" "Tuesday\0" "Wednesday\0"
|
||||
"Thursday\0" "Friday\0" "Saturday\0"
|
||||
"Jan\0" "Feb\0" "Mar\0" "Apr\0" "May\0" "Jun\0"
|
||||
"Jul\0" "Aug\0" "Sep\0" "Oct\0" "Nov\0" "Dec\0"
|
||||
"January\0" "February\0" "March\0" "April\0"
|
||||
"May\0" "June\0" "July\0" "August\0"
|
||||
"September\0" "October\0" "November\0" "December\0"
|
||||
"AM\0" "PM\0"
|
||||
"%a %b %e %T %Y\0"
|
||||
"%m/%d/%y\0"
|
||||
"%H:%M:%S\0"
|
||||
"%I:%M:%S %p\0"
|
||||
"\0"
|
||||
"\0"
|
||||
"%m/%d/%y\0"
|
||||
"0123456789\0"
|
||||
"%a %b %e %T %Y\0"
|
||||
"%H:%M:%S";
|
||||
|
||||
static const char c_messages[] = "^[yY]\0" "^[nN]\0" "yes\0" "no";
|
||||
static const char c_numeric[] = ".\0" "";
|
||||
|
||||
char *nl_langinfo_l(nl_item item, locale_t loc)
|
||||
{
|
||||
int cat = item >> 16;
|
||||
int idx = item & 65535;
|
||||
const char *str;
|
||||
|
||||
if (item == CODESET) return loc->cat[LC_CTYPE] ? "UTF-8" : "ASCII";
|
||||
|
||||
/* _NL_LOCALE_NAME extension */
|
||||
if (idx == 65535 && cat < LC_ALL)
|
||||
return loc->cat[cat] ? (char *)loc->cat[cat]->name : "C";
|
||||
|
||||
switch (cat) {
|
||||
case LC_NUMERIC:
|
||||
if (idx > 1) return "";
|
||||
str = c_numeric;
|
||||
break;
|
||||
case LC_TIME:
|
||||
if (idx > 0x31) return "";
|
||||
str = c_time;
|
||||
break;
|
||||
case LC_MONETARY:
|
||||
if (idx > 0) return "";
|
||||
str = "";
|
||||
break;
|
||||
case LC_MESSAGES:
|
||||
if (idx > 3) return "";
|
||||
str = c_messages;
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
||||
for (; idx; idx--, str++) for (; *str; str++);
|
||||
if (cat != LC_NUMERIC && *str) str = LCTRANS(str, cat, loc);
|
||||
return (char *)str;
|
||||
}
|
||||
|
||||
char *nl_langinfo(nl_item item)
|
||||
{
|
||||
return nl_langinfo_l(item, CURRENT_LOCALE);
|
||||
}
|
46
third_party/musl/lctrans.c
vendored
Normal file
46
third_party/musl/lctrans.c
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
const char *__lctrans_dummy(const char *msg, const struct __locale_map *lm)
|
||||
{
|
||||
return msg;
|
||||
}
|
||||
|
||||
__weak_reference(__lctrans_dummy, __lctrans_impl);
|
||||
|
||||
const char *__lctrans(const char *msg, const struct __locale_map *lm)
|
||||
{
|
||||
return __lctrans_impl(msg, lm);
|
||||
}
|
||||
|
||||
const char *__lctrans_cur(const char *msg)
|
||||
{
|
||||
return __lctrans_impl(msg, CURRENT_LOCALE->cat[LC_MESSAGES]);
|
||||
}
|
137
third_party/musl/locale_map.c
vendored
Normal file
137
third_party/musl/locale_map.c
vendored
Normal file
|
@ -0,0 +1,137 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "third_party/musl/mapfile.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define malloc _mapanon
|
||||
#define calloc undef
|
||||
#define realloc undef
|
||||
#define free undef
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
const char *__lctrans_impl(const char *msg, const struct __locale_map *lm)
|
||||
{
|
||||
const char *trans = 0;
|
||||
if (lm) trans = __mo_lookup(lm->map, lm->map_size, msg);
|
||||
return trans ? trans : msg;
|
||||
}
|
||||
|
||||
static const char envvars[][12] = {
|
||||
"LC_CTYPE",
|
||||
"LC_NUMERIC",
|
||||
"LC_TIME",
|
||||
"LC_COLLATE",
|
||||
"LC_MONETARY",
|
||||
"LC_MESSAGES",
|
||||
};
|
||||
|
||||
const struct __locale_map *__get_locale(int cat, const char *val)
|
||||
{
|
||||
static void *volatile loc_head;
|
||||
const struct __locale_map *p;
|
||||
struct __locale_map *new = 0;
|
||||
const char *path = 0, *z;
|
||||
char buf[256];
|
||||
size_t l, n;
|
||||
|
||||
if (!*val) {
|
||||
(val = getenv("LC_ALL")) && *val ||
|
||||
(val = getenv(envvars[cat])) && *val ||
|
||||
(val = getenv("LANG")) && *val ||
|
||||
(val = "C.UTF-8");
|
||||
}
|
||||
|
||||
/* Limit name length and forbid leading dot or any slashes. */
|
||||
for (n=0; n<LOCALE_NAME_MAX && val[n] && val[n]!='/'; n++);
|
||||
if (val[0]=='.' || val[n]) val = "C.UTF-8";
|
||||
int builtin = (val[0]=='C' && !val[1])
|
||||
|| !strcmp(val, "C.UTF-8")
|
||||
|| !strcmp(val, "POSIX");
|
||||
|
||||
if (builtin) {
|
||||
if (cat == LC_CTYPE && val[1]=='.')
|
||||
return (void *)&__c_dot_utf8;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p=loc_head; p; p=p->next)
|
||||
if (!strcmp(val, p->name)) return p;
|
||||
|
||||
path = secure_getenv("MUSL_LOCPATH");
|
||||
/* FIXME: add a default path? */
|
||||
|
||||
if (path) for (; *path; path=z+!!*z) {
|
||||
z = strchrnul(path, ':');
|
||||
l = z - path;
|
||||
if (l >= sizeof buf - n - 2) continue;
|
||||
memcpy(buf, path, l);
|
||||
buf[l] = '/';
|
||||
memcpy(buf+l+1, val, n);
|
||||
buf[l+1+n] = 0;
|
||||
size_t map_size;
|
||||
const void *map = __map_file(buf, &map_size);
|
||||
if (map) {
|
||||
new = malloc(sizeof *new);
|
||||
if (!new) {
|
||||
munmap((void *)map, map_size);
|
||||
break;
|
||||
}
|
||||
new->map = map;
|
||||
new->map_size = map_size;
|
||||
memcpy(new->name, val, n);
|
||||
new->name[n] = 0;
|
||||
new->next = loc_head;
|
||||
loc_head = new;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* If no locale definition was found, make a locale map
|
||||
* object anyway to store the name, which is kept for the
|
||||
* sake of being able to do message translations at the
|
||||
* application level. */
|
||||
if (!new && (new = malloc(sizeof *new))) {
|
||||
new->map = __c_dot_utf8.map;
|
||||
new->map_size = __c_dot_utf8.map_size;
|
||||
memcpy(new->name, val, n);
|
||||
new->name[n] = 0;
|
||||
new->next = loc_head;
|
||||
loc_head = new;
|
||||
}
|
||||
|
||||
/* For LC_CTYPE, never return a null pointer unless the
|
||||
* requested name was "C" or "POSIX". */
|
||||
if (!new && cat == LC_CTYPE) new = (void *)&__c_dot_utf8;
|
||||
|
||||
return new;
|
||||
}
|
34
third_party/musl/mblen.c
vendored
Normal file
34
third_party/musl/mblen.c
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdlib.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
int mblen(const char *s, size_t n)
|
||||
{
|
||||
return mbtowc(0, s, n);
|
||||
}
|
35
third_party/musl/mbrlen.c
vendored
Normal file
35
third_party/musl/mbrlen.c
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t mbrlen(const char *restrict s, size_t n, mbstate_t *restrict st)
|
||||
{
|
||||
static unsigned internal;
|
||||
return mbrtowc(0, s, n, st ? st : (mbstate_t *)&internal);
|
||||
}
|
58
third_party/musl/mbrtoc16.c
vendored
Normal file
58
third_party/musl/mbrtoc16.c
vendored
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <uchar.h>
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t mbrtoc16(char16_t *restrict pc16, const char *restrict s, size_t n, mbstate_t *restrict ps)
|
||||
{
|
||||
static unsigned internal_state;
|
||||
if (!ps) ps = (void *)&internal_state;
|
||||
unsigned *pending = (unsigned *)ps;
|
||||
|
||||
if (!s) return mbrtoc16(0, "", 1, ps);
|
||||
|
||||
/* mbrtowc states for partial UTF-8 characters have the high bit set;
|
||||
* we use nonzero states without high bit for pending surrogates. */
|
||||
if ((int)*pending > 0) {
|
||||
if (pc16) *pc16 = *pending;
|
||||
*pending = 0;
|
||||
return -3;
|
||||
}
|
||||
|
||||
wchar_t wc;
|
||||
size_t ret = mbrtowc(&wc, s, n, ps);
|
||||
if (ret <= 4) {
|
||||
if (wc >= 0x10000) {
|
||||
*pending = (wc & 0x3ff) + 0xdc00;
|
||||
wc = 0xd7c0 + (wc >> 10);
|
||||
}
|
||||
if (pc16) *pc16 = wc;
|
||||
}
|
||||
return ret;
|
||||
}
|
41
third_party/musl/mbrtoc32.c
vendored
Normal file
41
third_party/musl/mbrtoc32.c
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <uchar.h>
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t mbrtoc32(char32_t *restrict pc32, const char *restrict s, size_t n, mbstate_t *restrict ps)
|
||||
{
|
||||
static unsigned internal_state;
|
||||
if (!ps) ps = (void *)&internal_state;
|
||||
if (!s) return mbrtoc32(0, "", 1, ps);
|
||||
wchar_t wc;
|
||||
size_t ret = mbrtowc(&wc, s, n, ps);
|
||||
if (ret <= 4 && pc32) *pc32 = wc;
|
||||
return ret;
|
||||
}
|
81
third_party/musl/mbrtowc.c
vendored
Normal file
81
third_party/musl/mbrtowc.c
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
#include "multibyte.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
size_t mbrtowc(wchar_t *restrict wc, const char *restrict src, size_t n, mbstate_t *restrict st)
|
||||
{
|
||||
static unsigned internal_state;
|
||||
unsigned c;
|
||||
const unsigned char *s = (const void *)src;
|
||||
const size_t N = n;
|
||||
wchar_t dummy;
|
||||
|
||||
if (!st) st = (void *)&internal_state;
|
||||
c = *(unsigned *)st;
|
||||
|
||||
if (!s) {
|
||||
if (c) goto ilseq;
|
||||
return 0;
|
||||
} else if (!wc) wc = &dummy;
|
||||
|
||||
if (!n) return -2;
|
||||
if (!c) {
|
||||
if (*s < 0x80) return !!(*wc = *s);
|
||||
if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
|
||||
if (*s-SA > SB-SA) goto ilseq;
|
||||
c = bittab[*s++-SA]; n--;
|
||||
}
|
||||
|
||||
if (n) {
|
||||
if (OOB(c,*s)) goto ilseq;
|
||||
loop:
|
||||
c = c<<6 | *s++-0x80; n--;
|
||||
if (!(c&(1U<<31))) {
|
||||
*(unsigned *)st = 0;
|
||||
*wc = c;
|
||||
return N-n;
|
||||
}
|
||||
if (n) {
|
||||
if (*s-0x80u >= 0x40) goto ilseq;
|
||||
goto loop;
|
||||
}
|
||||
}
|
||||
|
||||
*(unsigned *)st = c;
|
||||
return -2;
|
||||
ilseq:
|
||||
*(unsigned *)st = 0;
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
34
third_party/musl/mbsinit.c
vendored
Normal file
34
third_party/musl/mbsinit.c
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
int mbsinit(const mbstate_t *st)
|
||||
{
|
||||
return !st || !*(unsigned *)st;
|
||||
}
|
83
third_party/musl/mbsnrtowcs.c
vendored
Normal file
83
third_party/musl/mbsnrtowcs.c
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t mbsnrtowcs(wchar_t *restrict wcs, const char **restrict src, size_t n, size_t wn, mbstate_t *restrict st)
|
||||
{
|
||||
size_t l, cnt=0, n2;
|
||||
wchar_t *ws, wbuf[256];
|
||||
const char *s = *src;
|
||||
const char *tmp_s;
|
||||
|
||||
if (!wcs) ws = wbuf, wn = sizeof wbuf / sizeof *wbuf;
|
||||
else ws = wcs;
|
||||
|
||||
/* making sure output buffer size is at most n/4 will ensure
|
||||
* that mbsrtowcs never reads more than n input bytes. thus
|
||||
* we can use mbsrtowcs as long as it's practical.. */
|
||||
|
||||
while ( s && wn && ( (n2=n/4)>=wn || n2>32 ) ) {
|
||||
if (n2>=wn) n2=wn;
|
||||
tmp_s = s;
|
||||
l = mbsrtowcs(ws, &s, n2, st);
|
||||
if (!(l+1)) {
|
||||
cnt = l;
|
||||
wn = 0;
|
||||
break;
|
||||
}
|
||||
if (ws != wbuf) {
|
||||
ws += l;
|
||||
wn -= l;
|
||||
}
|
||||
n = s ? n - (s - tmp_s) : 0;
|
||||
cnt += l;
|
||||
}
|
||||
if (s) while (wn && n) {
|
||||
l = mbrtowc(ws, s, n, st);
|
||||
if (l+2<=2) {
|
||||
if (!(l+1)) {
|
||||
cnt = l;
|
||||
break;
|
||||
}
|
||||
if (!l) {
|
||||
s = 0;
|
||||
break;
|
||||
}
|
||||
/* have to roll back partial character */
|
||||
*(unsigned *)st = 0;
|
||||
break;
|
||||
}
|
||||
s += l; n -= l;
|
||||
/* safe - this loop runs fewer than sizeof(wbuf)/8 times */
|
||||
ws++; wn--;
|
||||
cnt++;
|
||||
}
|
||||
if (wcs) *src = s;
|
||||
return cnt;
|
||||
}
|
150
third_party/musl/mbsrtowcs.c
vendored
Normal file
150
third_party/musl/mbsrtowcs.c
vendored
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdint.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "multibyte.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
size_t mbsrtowcs(wchar_t *restrict ws, const char **restrict src, size_t wn, mbstate_t *restrict st)
|
||||
{
|
||||
const unsigned char *s = (const void *)*src;
|
||||
size_t wn0 = wn;
|
||||
unsigned c = 0;
|
||||
|
||||
if (st && (c = *(unsigned *)st)) {
|
||||
if (ws) {
|
||||
*(unsigned *)st = 0;
|
||||
goto resume;
|
||||
} else {
|
||||
goto resume0;
|
||||
}
|
||||
}
|
||||
|
||||
if (MB_CUR_MAX==1) {
|
||||
if (!ws) return strlen((const char *)s);
|
||||
for (;;) {
|
||||
if (!wn) {
|
||||
*src = (const void *)s;
|
||||
return wn0;
|
||||
}
|
||||
if (!*s) break;
|
||||
c = *s++;
|
||||
*ws++ = CODEUNIT(c);
|
||||
wn--;
|
||||
}
|
||||
*ws = 0;
|
||||
*src = 0;
|
||||
return wn0-wn;
|
||||
}
|
||||
|
||||
if (!ws) for (;;) {
|
||||
#ifdef __GNUC__
|
||||
typedef uint32_t __attribute__((__may_alias__)) w32;
|
||||
if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
|
||||
while (!(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) {
|
||||
s += 4;
|
||||
wn -= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (*s-1u < 0x7f) {
|
||||
s++;
|
||||
wn--;
|
||||
continue;
|
||||
}
|
||||
if (*s-SA > SB-SA) break;
|
||||
c = bittab[*s++-SA];
|
||||
resume0:
|
||||
if (OOB(c,*s)) { s--; break; }
|
||||
s++;
|
||||
if (c&(1U<<25)) {
|
||||
if (*s-0x80u >= 0x40) { s-=2; break; }
|
||||
s++;
|
||||
if (c&(1U<<19)) {
|
||||
if (*s-0x80u >= 0x40) { s-=3; break; }
|
||||
s++;
|
||||
}
|
||||
}
|
||||
wn--;
|
||||
c = 0;
|
||||
} else for (;;) {
|
||||
if (!wn) {
|
||||
*src = (const void *)s;
|
||||
return wn0;
|
||||
}
|
||||
#ifdef __GNUC__
|
||||
typedef uint32_t __attribute__((__may_alias__)) w32;
|
||||
if (*s-1u < 0x7f && (uintptr_t)s%4 == 0) {
|
||||
while (wn>=5 && !(( *(w32*)s | *(w32*)s-0x01010101) & 0x80808080)) {
|
||||
*ws++ = *s++;
|
||||
*ws++ = *s++;
|
||||
*ws++ = *s++;
|
||||
*ws++ = *s++;
|
||||
wn -= 4;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (*s-1u < 0x7f) {
|
||||
*ws++ = *s++;
|
||||
wn--;
|
||||
continue;
|
||||
}
|
||||
if (*s-SA > SB-SA) break;
|
||||
c = bittab[*s++-SA];
|
||||
resume:
|
||||
if (OOB(c,*s)) { s--; break; }
|
||||
c = (c<<6) | *s++-0x80;
|
||||
if (c&(1U<<31)) {
|
||||
if (*s-0x80u >= 0x40) { s-=2; break; }
|
||||
c = (c<<6) | *s++-0x80;
|
||||
if (c&(1U<<31)) {
|
||||
if (*s-0x80u >= 0x40) { s-=3; break; }
|
||||
c = (c<<6) | *s++-0x80;
|
||||
}
|
||||
}
|
||||
*ws++ = c;
|
||||
wn--;
|
||||
c = 0;
|
||||
}
|
||||
|
||||
if (!c && !*s) {
|
||||
if (ws) {
|
||||
*ws = 0;
|
||||
*src = 0;
|
||||
}
|
||||
return wn0-wn;
|
||||
}
|
||||
errno = EILSEQ;
|
||||
if (ws) *src = (const void *)s;
|
||||
return -1;
|
||||
}
|
35
third_party/musl/mbstowcs.c
vendored
Normal file
35
third_party/musl/mbstowcs.c
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t mbstowcs(wchar_t *restrict ws, const char *restrict s, size_t wn)
|
||||
{
|
||||
return mbsrtowcs(ws, (void*)&s, wn, 0);
|
||||
}
|
77
third_party/musl/mbtowc.c
vendored
Normal file
77
third_party/musl/mbtowc.c
vendored
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
#include "multibyte.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wparentheses"
|
||||
|
||||
int mbtowc(wchar_t *restrict wc, const char *restrict src, size_t n)
|
||||
{
|
||||
unsigned c;
|
||||
const unsigned char *s = (const void *)src;
|
||||
wchar_t dummy;
|
||||
|
||||
if (!s) return 0;
|
||||
if (!n) goto ilseq;
|
||||
if (!wc) wc = &dummy;
|
||||
|
||||
if (*s < 0x80) return !!(*wc = *s);
|
||||
if (MB_CUR_MAX==1) return (*wc = CODEUNIT(*s)), 1;
|
||||
if (*s-SA > SB-SA) goto ilseq;
|
||||
c = bittab[*s++-SA];
|
||||
|
||||
/* Avoid excessive checks against n: If shifting the state n-1
|
||||
* times does not clear the high bit, then the value of n is
|
||||
* insufficient to read a character */
|
||||
if (n<4 && ((c<<(6*n-6)) & (1U<<31))) goto ilseq;
|
||||
|
||||
if (OOB(c,*s)) goto ilseq;
|
||||
c = c<<6 | *s++-0x80;
|
||||
if (!(c&(1U<<31))) {
|
||||
*wc = c;
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (*s-0x80u >= 0x40) goto ilseq;
|
||||
c = c<<6 | *s++-0x80;
|
||||
if (!(c&(1U<<31))) {
|
||||
*wc = c;
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (*s-0x80u >= 0x40) goto ilseq;
|
||||
*wc = c<<6 | *s++-0x80;
|
||||
return 4;
|
||||
|
||||
ilseq:
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
53
third_party/musl/multibyte.c
vendored
Normal file
53
third_party/musl/multibyte.c
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "multibyte.h"
|
||||
|
||||
#define C(x) ( x<2 ? -1 : ( R(0x80,0xc0) | x ) )
|
||||
#define D(x) C((x+16))
|
||||
#define E(x) ( ( x==0 ? R(0xa0,0xc0) : \
|
||||
x==0xd ? R(0x80,0xa0) : \
|
||||
R(0x80,0xc0) ) \
|
||||
| ( R(0x80,0xc0) >> 6 ) \
|
||||
| x )
|
||||
#define F(x) ( ( x>=5 ? 0 : \
|
||||
x==0 ? R(0x90,0xc0) : \
|
||||
x==4 ? R(0x80,0x90) : \
|
||||
R(0x80,0xc0) ) \
|
||||
| ( R(0x80,0xc0) >> 6 ) \
|
||||
| ( R(0x80,0xc0) >> 12 ) \
|
||||
| x )
|
||||
|
||||
const uint32_t bittab[] = {
|
||||
C(0x2),C(0x3),C(0x4),C(0x5),C(0x6),C(0x7),
|
||||
C(0x8),C(0x9),C(0xa),C(0xb),C(0xc),C(0xd),C(0xe),C(0xf),
|
||||
D(0x0),D(0x1),D(0x2),D(0x3),D(0x4),D(0x5),D(0x6),D(0x7),
|
||||
D(0x8),D(0x9),D(0xa),D(0xb),D(0xc),D(0xd),D(0xe),D(0xf),
|
||||
E(0x0),E(0x1),E(0x2),E(0x3),E(0x4),E(0x5),E(0x6),E(0x7),
|
||||
E(0x8),E(0x9),E(0xa),E(0xb),E(0xc),E(0xd),E(0xe),E(0xf),
|
||||
F(0x0),F(0x1),F(0x2),F(0x3),F(0x4)
|
||||
};
|
26
third_party/musl/multibyte.h
vendored
Normal file
26
third_party/musl/multibyte.h
vendored
Normal file
|
@ -0,0 +1,26 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_MUSL_MULTIBYTE_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_MUSL_MULTIBYTE_H_
|
||||
|
||||
#define bittab __fsmu8
|
||||
|
||||
extern const uint32_t bittab[];
|
||||
|
||||
/* Upper 6 state bits are a negative integer offset to bound-check next byte */
|
||||
/* equivalent to: ( (b-0x80) | (b+offset) ) & ~0x3f */
|
||||
#define OOB(c,b) (((((b)>>3)-0x10)|(((b)>>3)+((int32_t)(c)>>26))) & ~7)
|
||||
|
||||
/* Interval [a,b). Either a must be 80 or b must be c0, lower 3 bits clear. */
|
||||
#define R(a,b) ((uint32_t)((a==0x80 ? 0x40u-b : 0u-a) << 23))
|
||||
#define FAILSTATE R(0x80,0x80)
|
||||
|
||||
#define SA 0xc2u
|
||||
#define SB 0xf4u
|
||||
|
||||
/* Arbitrary encoding for representing code units instead of characters. */
|
||||
#define CODEUNIT(c) (0xdfff & (signed char)(c))
|
||||
#define IS_CODEUNIT(c) ((unsigned)(c)-0xdf80 < 0x80)
|
||||
|
||||
/* Get inline definition of MB_CUR_MAX. */
|
||||
#include "libc/str/locale.internal.h"
|
||||
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_MUSL_MULTIBYTE_H_ */
|
94
third_party/musl/newlocale.c
vendored
Normal file
94
third_party/musl/newlocale.c
vendored
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
#define malloc _mapanon
|
||||
#define calloc undef
|
||||
#define realloc undef
|
||||
#define free undef
|
||||
|
||||
static int default_locale_init_done;
|
||||
static struct __locale_struct default_locale, default_ctype_locale;
|
||||
|
||||
int __loc_is_allocated(locale_t loc)
|
||||
{
|
||||
return loc && loc != C_LOCALE && loc != UTF8_LOCALE
|
||||
&& loc != &default_locale && loc != &default_ctype_locale;
|
||||
}
|
||||
|
||||
static locale_t do_newlocale(int mask, const char *name, locale_t loc)
|
||||
{
|
||||
struct __locale_struct tmp;
|
||||
|
||||
for (int i=0; i<LC_ALL; i++) {
|
||||
tmp.cat[i] = (!(mask & (1<<i)) && loc) ? loc->cat[i] :
|
||||
__get_locale(i, (mask & (1<<i)) ? name : "");
|
||||
if (tmp.cat[i] == LOC_MAP_FAILED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* For locales with allocated storage, modify in-place. */
|
||||
if (__loc_is_allocated(loc)) {
|
||||
*loc = tmp;
|
||||
return loc;
|
||||
}
|
||||
|
||||
/* Otherwise, first see if we can use one of the builtin locales.
|
||||
* This makes the common usage case for newlocale, getting a C locale
|
||||
* with predictable behavior, very fast, and more importantly, fail-safe. */
|
||||
if (!memcmp(&tmp, C_LOCALE, sizeof tmp)) return C_LOCALE;
|
||||
if (!memcmp(&tmp, UTF8_LOCALE, sizeof tmp)) return UTF8_LOCALE;
|
||||
|
||||
/* And provide builtins for the initial default locale, and a
|
||||
* variant of the C locale honoring the default locale's encoding. */
|
||||
if (!default_locale_init_done) {
|
||||
for (int i=0; i<LC_ALL; i++)
|
||||
default_locale.cat[i] = __get_locale(i, "");
|
||||
default_ctype_locale.cat[LC_CTYPE] = default_locale.cat[LC_CTYPE];
|
||||
default_locale_init_done = 1;
|
||||
}
|
||||
if (!memcmp(&tmp, &default_locale, sizeof tmp)) return &default_locale;
|
||||
if (!memcmp(&tmp, &default_ctype_locale, sizeof tmp))
|
||||
return &default_ctype_locale;
|
||||
|
||||
/* If no builtin locale matched, attempt to allocate and copy. */
|
||||
if ((loc = malloc(sizeof *loc))) *loc = tmp;
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
locale_t newlocale(int mask, const char *name, locale_t loc)
|
||||
{
|
||||
pthread_mutex_lock(&__locale_lock);
|
||||
loc = do_newlocale(mask, name, loc);
|
||||
pthread_mutex_unlock(&__locale_lock);
|
||||
return loc;
|
||||
}
|
102
third_party/musl/setlocale.c
vendored
Normal file
102
third_party/musl/setlocale.c
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
static char buf[LC_ALL*(LOCALE_NAME_MAX+1)];
|
||||
|
||||
char *setlocale(int cat, const char *name)
|
||||
{
|
||||
const struct __locale_map *lm;
|
||||
|
||||
if ((unsigned)cat > LC_ALL) return 0;
|
||||
|
||||
pthread_mutex_lock(&__locale_lock);
|
||||
|
||||
/* For LC_ALL, setlocale is required to return a string which
|
||||
* encodes the current setting for all categories. The format of
|
||||
* this string is unspecified, and only the following code, which
|
||||
* performs both the serialization and deserialization, depends
|
||||
* on the format, so it can easily be changed if needed. */
|
||||
if (cat == LC_ALL) {
|
||||
int i;
|
||||
if (name) {
|
||||
struct __locale_struct tmp_locale;
|
||||
char part[LOCALE_NAME_MAX+1] = "C.UTF-8";
|
||||
const char *p = name;
|
||||
for (i=0; i<LC_ALL; i++) {
|
||||
const char *z = strchrnul(p, ';');
|
||||
if (z-p <= LOCALE_NAME_MAX) {
|
||||
memcpy(part, p, z-p);
|
||||
part[z-p] = 0;
|
||||
if (*z) p = z+1;
|
||||
}
|
||||
lm = __get_locale(i, part);
|
||||
if (lm == LOC_MAP_FAILED) {
|
||||
pthread_mutex_unlock(&__locale_lock);
|
||||
return 0;
|
||||
}
|
||||
tmp_locale.cat[i] = lm;
|
||||
}
|
||||
__global_locale = tmp_locale;
|
||||
}
|
||||
char *s = buf;
|
||||
const char *part;
|
||||
int same = 0;
|
||||
for (i=0; i<LC_ALL; i++) {
|
||||
const struct __locale_map *lm =
|
||||
__global_locale.cat[i];
|
||||
if (lm == __global_locale.cat[0]) same++;
|
||||
part = lm ? lm->name : "C";
|
||||
size_t l = strlen(part);
|
||||
memcpy(s, part, l);
|
||||
s[l] = ';';
|
||||
s += l+1;
|
||||
}
|
||||
*--s = 0;
|
||||
pthread_mutex_unlock(&__locale_lock);
|
||||
return same==LC_ALL ? (char *)part : buf;
|
||||
}
|
||||
|
||||
if (name) {
|
||||
lm = __get_locale(cat, name);
|
||||
if (lm == LOC_MAP_FAILED) {
|
||||
pthread_mutex_unlock(&__locale_lock);
|
||||
return 0;
|
||||
}
|
||||
__global_locale.cat[cat] = lm;
|
||||
} else {
|
||||
lm = __global_locale.cat[cat];
|
||||
}
|
||||
char *ret = lm ? (char *)lm->name : "C";
|
||||
|
||||
pthread_mutex_unlock(&__locale_lock);
|
||||
|
||||
return ret;
|
||||
}
|
21
third_party/musl/strfmon.c
vendored
21
third_party/musl/strfmon.c
vendored
|
@ -27,7 +27,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/locale.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/ctype.h"
|
||||
#include "libc/thread/tls.h"
|
||||
|
@ -37,7 +37,7 @@ static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_l
|
|||
{
|
||||
size_t l;
|
||||
double x;
|
||||
int left;
|
||||
int fill, nogrp, negpar, nosym, left, intl;
|
||||
int lp, rp, w, fw;
|
||||
char *s0=s;
|
||||
for (; n && *fmt; ) {
|
||||
|
@ -50,17 +50,29 @@ static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_l
|
|||
fmt++;
|
||||
if (*fmt == '%') goto literal;
|
||||
|
||||
fill = ' ';
|
||||
nogrp = 0;
|
||||
negpar = 0;
|
||||
nosym = 0;
|
||||
left = 0;
|
||||
for (; ; fmt++) {
|
||||
switch (*fmt) {
|
||||
case '=':
|
||||
fill = *++fmt;
|
||||
(void)fill;
|
||||
continue;
|
||||
case '^':
|
||||
nogrp = 1;
|
||||
(void)nogrp;
|
||||
continue;
|
||||
case '(':
|
||||
negpar = 1;
|
||||
(void)negpar;
|
||||
case '+':
|
||||
continue;
|
||||
case '!':
|
||||
nosym = 1;
|
||||
(void)nosym;
|
||||
continue;
|
||||
case '-':
|
||||
left = 1;
|
||||
|
@ -78,6 +90,9 @@ static ssize_t vstrfmon_l(char *s, size_t n, locale_t loc, const char *fmt, va_l
|
|||
if (*fmt=='.') for (rp=0, fmt++; isdigit(*fmt); fmt++)
|
||||
rp = 10*rp + (*fmt-'0');
|
||||
|
||||
intl = *fmt++ == 'i';
|
||||
(void)intl;
|
||||
|
||||
w = lp + 1 + rp;
|
||||
if (!left && fw>w) w = fw;
|
||||
|
||||
|
@ -112,7 +127,7 @@ ssize_t strfmon(char *restrict s, size_t n, const char *restrict fmt, ...)
|
|||
ssize_t ret;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vstrfmon_l(s, n, (locale_t)__get_tls()->tib_locale, fmt, ap);
|
||||
ret = vstrfmon_l(s, n, CURRENT_LOCALE, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
return ret;
|
||||
|
|
313
third_party/musl/strftime.c
vendored
Normal file
313
third_party/musl/strftime.c
vendored
Normal file
|
@ -0,0 +1,313 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/ctype.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/langinfo.h"
|
||||
#include "libc/str/locale.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
#include "libc/str/nltypes.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/time.h"
|
||||
#include "third_party/musl/time_impl.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
static int is_leap(int y)
|
||||
{
|
||||
/* Avoid overflow */
|
||||
if (y>INT_MAX-1900) y -= 2000;
|
||||
y += 1900;
|
||||
return !(y%4) && ((y%100) || !(y%400));
|
||||
}
|
||||
|
||||
static int week_num(const struct tm *tm)
|
||||
{
|
||||
int val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
|
||||
/* If 1 Jan is just 1-3 days past Monday,
|
||||
* the previous week is also in this year. */
|
||||
if ((tm->tm_wday + 371U - tm->tm_yday - 2) % 7 <= 2)
|
||||
val++;
|
||||
if (!val) {
|
||||
val = 52;
|
||||
/* If 31 December of prev year a Thursday,
|
||||
* or Friday of a leap year, then the
|
||||
* prev year has 53 weeks. */
|
||||
int dec31 = (tm->tm_wday + 7U - tm->tm_yday - 1) % 7;
|
||||
if (dec31 == 4 || (dec31 == 5 && is_leap(tm->tm_year%400-1)))
|
||||
val++;
|
||||
} else if (val == 53) {
|
||||
/* If 1 January is not a Thursday, and not
|
||||
* a Wednesday of a leap year, then this
|
||||
* year has only 52 weeks. */
|
||||
int jan1 = (tm->tm_wday + 371U - tm->tm_yday) % 7;
|
||||
if (jan1 != 4 && (jan1 != 3 || !is_leap(tm->tm_year)))
|
||||
val = 1;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
const char *__strftime_fmt_1(char (*s)[100], size_t *l, int f, const struct tm *tm, locale_t loc, int pad)
|
||||
{
|
||||
nl_item item;
|
||||
long long val;
|
||||
const char *fmt = "-";
|
||||
int width = 2, def_pad = '0';
|
||||
|
||||
switch (f) {
|
||||
case 'a':
|
||||
if (tm->tm_wday > 6U) goto string;
|
||||
item = ABDAY_1 + tm->tm_wday;
|
||||
goto nl_strcat;
|
||||
case 'A':
|
||||
if (tm->tm_wday > 6U) goto string;
|
||||
item = DAY_1 + tm->tm_wday;
|
||||
goto nl_strcat;
|
||||
case 'h':
|
||||
case 'b':
|
||||
if (tm->tm_mon > 11U) goto string;
|
||||
item = ABMON_1 + tm->tm_mon;
|
||||
goto nl_strcat;
|
||||
case 'B':
|
||||
if (tm->tm_mon > 11U) goto string;
|
||||
item = MON_1 + tm->tm_mon;
|
||||
goto nl_strcat;
|
||||
case 'c':
|
||||
item = D_T_FMT;
|
||||
goto nl_strftime;
|
||||
case 'C':
|
||||
val = (1900LL+tm->tm_year) / 100;
|
||||
goto number;
|
||||
case 'e':
|
||||
def_pad = '_';
|
||||
case 'd':
|
||||
val = tm->tm_mday;
|
||||
goto number;
|
||||
case 'D':
|
||||
fmt = "%m/%d/%y";
|
||||
goto recu_strftime;
|
||||
case 'F':
|
||||
fmt = "%Y-%m-%d";
|
||||
goto recu_strftime;
|
||||
case 'g':
|
||||
case 'G':
|
||||
val = tm->tm_year + 1900LL;
|
||||
if (tm->tm_yday < 3 && week_num(tm) != 1) val--;
|
||||
else if (tm->tm_yday > 360 && week_num(tm) == 1) val++;
|
||||
if (f=='g') val %= 100;
|
||||
else width = 4;
|
||||
goto number;
|
||||
case 'H':
|
||||
val = tm->tm_hour;
|
||||
goto number;
|
||||
case 'I':
|
||||
val = tm->tm_hour;
|
||||
if (!val) val = 12;
|
||||
else if (val > 12) val -= 12;
|
||||
goto number;
|
||||
case 'j':
|
||||
val = tm->tm_yday+1;
|
||||
width = 3;
|
||||
goto number;
|
||||
case 'm':
|
||||
val = tm->tm_mon+1;
|
||||
goto number;
|
||||
case 'M':
|
||||
val = tm->tm_min;
|
||||
goto number;
|
||||
case 'n':
|
||||
*l = 1;
|
||||
return "\n";
|
||||
case 'p':
|
||||
item = tm->tm_hour >= 12 ? PM_STR : AM_STR;
|
||||
goto nl_strcat;
|
||||
case 'r':
|
||||
item = T_FMT_AMPM;
|
||||
goto nl_strftime;
|
||||
case 'R':
|
||||
fmt = "%H:%M";
|
||||
goto recu_strftime;
|
||||
case 's':
|
||||
val = __tm_to_secs(tm) - tm->tm_gmtoff;
|
||||
width = 1;
|
||||
goto number;
|
||||
case 'S':
|
||||
val = tm->tm_sec;
|
||||
goto number;
|
||||
case 't':
|
||||
*l = 1;
|
||||
return "\t";
|
||||
case 'T':
|
||||
fmt = "%H:%M:%S";
|
||||
goto recu_strftime;
|
||||
case 'u':
|
||||
val = tm->tm_wday ? tm->tm_wday : 7;
|
||||
width = 1;
|
||||
goto number;
|
||||
case 'U':
|
||||
val = (tm->tm_yday + 7U - tm->tm_wday) / 7;
|
||||
goto number;
|
||||
case 'W':
|
||||
val = (tm->tm_yday + 7U - (tm->tm_wday+6U)%7) / 7;
|
||||
goto number;
|
||||
case 'V':
|
||||
val = week_num(tm);
|
||||
goto number;
|
||||
case 'w':
|
||||
val = tm->tm_wday;
|
||||
width = 1;
|
||||
goto number;
|
||||
case 'x':
|
||||
item = D_FMT;
|
||||
goto nl_strftime;
|
||||
case 'X':
|
||||
item = T_FMT;
|
||||
goto nl_strftime;
|
||||
case 'y':
|
||||
val = (tm->tm_year + 1900LL) % 100;
|
||||
if (val < 0) val = -val;
|
||||
goto number;
|
||||
case 'Y':
|
||||
val = tm->tm_year + 1900LL;
|
||||
if (val >= 10000) {
|
||||
*l = snprintf(*s, sizeof *s, "%lld", val);
|
||||
return *s;
|
||||
}
|
||||
width = 4;
|
||||
goto number;
|
||||
case 'z':
|
||||
if (tm->tm_isdst < 0) {
|
||||
*l = 0;
|
||||
return "";
|
||||
}
|
||||
*l = snprintf(*s, sizeof *s, "%+.4ld",
|
||||
tm->tm_gmtoff/3600*100 + tm->tm_gmtoff%3600/60);
|
||||
return *s;
|
||||
case 'Z':
|
||||
if (tm->tm_isdst < 0 || !tm->tm_zone) {
|
||||
*l = 0;
|
||||
return "";
|
||||
}
|
||||
fmt = tm->tm_zone;
|
||||
goto string;
|
||||
case '%':
|
||||
*l = 1;
|
||||
return "%";
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
number:
|
||||
switch (pad ? pad : def_pad) {
|
||||
case '-': *l = snprintf(*s, sizeof *s, "%lld", val); break;
|
||||
case '_': *l = snprintf(*s, sizeof *s, "%*lld", width, val); break;
|
||||
case '0':
|
||||
default: *l = snprintf(*s, sizeof *s, "%0*lld", width, val); break;
|
||||
}
|
||||
return *s;
|
||||
nl_strcat:
|
||||
fmt = nl_langinfo_l(item, loc);
|
||||
string:
|
||||
*l = strlen(fmt);
|
||||
return fmt;
|
||||
nl_strftime:
|
||||
fmt = nl_langinfo_l(item, loc);
|
||||
recu_strftime:
|
||||
*l = strftime_l(*s, sizeof *s, fmt, tm, loc);
|
||||
if (!*l) return 0;
|
||||
return *s;
|
||||
}
|
||||
|
||||
size_t strftime_l(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm, locale_t loc)
|
||||
{
|
||||
size_t l, k;
|
||||
char buf[100];
|
||||
char *p;
|
||||
const char *t;
|
||||
int pad, plus;
|
||||
unsigned long width;
|
||||
for (l=0; l<n; f++) {
|
||||
if (!*f) {
|
||||
s[l] = 0;
|
||||
return l;
|
||||
}
|
||||
if (*f != '%') {
|
||||
s[l++] = *f;
|
||||
continue;
|
||||
}
|
||||
f++;
|
||||
pad = 0;
|
||||
if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
|
||||
if ((plus = (*f == '+'))) f++;
|
||||
if (isdigit(*f)) {
|
||||
width = strtoul(f, &p, 10);
|
||||
} else {
|
||||
width = 0;
|
||||
p = (void *)f;
|
||||
}
|
||||
if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
|
||||
if (!width && p!=f) width = 1;
|
||||
} else {
|
||||
width = 0;
|
||||
}
|
||||
f = p;
|
||||
if (*f == 'E' || *f == 'O') f++;
|
||||
t = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
|
||||
if (!t) break;
|
||||
if (width) {
|
||||
/* Trim off any sign and leading zeros, then
|
||||
* count remaining digits to determine behavior
|
||||
* for the + flag. */
|
||||
if (*t=='+' || *t=='-') t++, k--;
|
||||
for (; *t=='0' && t[1]-'0'<10U; t++, k--);
|
||||
if (width < k) width = k;
|
||||
size_t d;
|
||||
for (d=0; t[d]-'0'<10U; d++);
|
||||
if (tm->tm_year < -1900) {
|
||||
s[l++] = '-';
|
||||
width--;
|
||||
} else if (plus && d+(width-k) >= (*p=='C'?3:5)) {
|
||||
s[l++] = '+';
|
||||
width--;
|
||||
}
|
||||
for (; width > k && l < n; width--)
|
||||
s[l++] = '0';
|
||||
}
|
||||
if (k > n-l) k = n-l;
|
||||
memcpy(s+l, t, k);
|
||||
l += k;
|
||||
}
|
||||
if (n) {
|
||||
if (l==n) l=n-1;
|
||||
s[l] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t strftime(char *restrict s, size_t n, const char *restrict f, const struct tm *restrict tm)
|
||||
{
|
||||
return strftime_l(s, n, f, tm, CURRENT_LOCALE);
|
||||
}
|
453
third_party/musl/strptime.c
vendored
453
third_party/musl/strptime.c
vendored
|
@ -29,248 +29,269 @@
|
|||
#include "libc/macros.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/ctype.h"
|
||||
#include "libc/str/langinfo.h"
|
||||
#include "libc/time.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
char *
|
||||
strptime(const char *s, const char *f, struct tm *tm)
|
||||
char *strptime(const char *restrict s, const char *restrict f, struct tm *restrict tm)
|
||||
{
|
||||
int i, w, neg, adj, min, range, itemsize, *dest, dummy;
|
||||
const char *ex, *ss;
|
||||
int i, w, neg, adj, min, range, *dest, dummy;
|
||||
const char *ex;
|
||||
size_t len;
|
||||
int want_century = 0, century = 0, relyear = 0;
|
||||
while (*f) {
|
||||
if (*f != '%') {
|
||||
if (isspace(*f)) {
|
||||
for (; *s && isspace(*s); s++);
|
||||
} else if (*s != *f) {
|
||||
return 0;
|
||||
} else {
|
||||
s++;
|
||||
}
|
||||
if (isspace(*f)) for (; *s && isspace(*s); s++);
|
||||
else if (*s != *f) return 0;
|
||||
else s++;
|
||||
f++;
|
||||
continue;
|
||||
}
|
||||
f++;
|
||||
if (*f == '+')
|
||||
f++;
|
||||
if (*f == '+') f++;
|
||||
if (isdigit(*f)) {
|
||||
char *new_f;
|
||||
w = strtoul(f, &new_f, 10);
|
||||
w=strtoul(f, &new_f, 10);
|
||||
f = new_f;
|
||||
} else {
|
||||
w = -1;
|
||||
w=-1;
|
||||
}
|
||||
adj = 0;
|
||||
adj=0;
|
||||
switch (*f++) {
|
||||
case 'a':
|
||||
dest = &tm->tm_wday;
|
||||
ss = (const char *)kWeekdayNameShort;
|
||||
range = ARRAYLEN(kWeekdayNameShort);
|
||||
itemsize = sizeof(kWeekdayNameShort[0]);
|
||||
goto symbolic_range;
|
||||
case 'A':
|
||||
dest = &tm->tm_wday;
|
||||
ss = (const char *)kWeekdayName;
|
||||
range = ARRAYLEN(kWeekdayName);
|
||||
itemsize = sizeof(kWeekdayName[0]);
|
||||
goto symbolic_range;
|
||||
case 'b':
|
||||
case 'h':
|
||||
dest = &tm->tm_mon;
|
||||
ss = (const char *)kMonthNameShort;
|
||||
range = ARRAYLEN(kMonthNameShort);
|
||||
itemsize = sizeof(kMonthNameShort[0]);
|
||||
goto symbolic_range;
|
||||
case 'B':
|
||||
dest = &tm->tm_mon;
|
||||
ss = (const char *)kMonthName;
|
||||
range = ARRAYLEN(kMonthName);
|
||||
itemsize = sizeof(kMonthName[0]);
|
||||
goto symbolic_range;
|
||||
case 'c':
|
||||
s = strptime(s, "%a %b %e %T %Y", tm);
|
||||
if (!s)
|
||||
return 0;
|
||||
case 'a': case 'A':
|
||||
dest = &tm->tm_wday;
|
||||
min = ABDAY_1;
|
||||
range = 7;
|
||||
goto symbolic_range;
|
||||
case 'b': case 'B': case 'h':
|
||||
dest = &tm->tm_mon;
|
||||
min = ABMON_1;
|
||||
range = 12;
|
||||
goto symbolic_range;
|
||||
case 'c':
|
||||
s = strptime(s, nl_langinfo(D_T_FMT), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'C':
|
||||
dest = ¢ury;
|
||||
if (w<0) w=2;
|
||||
want_century |= 2;
|
||||
goto numeric_digits;
|
||||
case 'd': case 'e':
|
||||
dest = &tm->tm_mday;
|
||||
min = 1;
|
||||
range = 31;
|
||||
goto numeric_range;
|
||||
case 'D':
|
||||
s = strptime(s, "%m/%d/%y", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'F':
|
||||
/* Use temp buffer to implement the odd requirement
|
||||
* that entire field be width-limited but the year
|
||||
* subfield not itself be limited. */
|
||||
i = 0;
|
||||
char tmp[20];
|
||||
if (*s == '-' || *s == '+') tmp[i++] = *s++;
|
||||
while (*s=='0' && isdigit(s[1])) s++;
|
||||
for (; *s && i<(size_t)w && i+1<sizeof tmp; i++) {
|
||||
tmp[i] = *s++;
|
||||
}
|
||||
tmp[i] = 0;
|
||||
char *p = strptime(tmp, "%12Y-%m-%d", tm);
|
||||
if (!p) return 0;
|
||||
s -= tmp+i-p;
|
||||
break;
|
||||
case 'H':
|
||||
dest = &tm->tm_hour;
|
||||
min = 0;
|
||||
range = 24;
|
||||
goto numeric_range;
|
||||
case 'I':
|
||||
dest = &tm->tm_hour;
|
||||
min = 1;
|
||||
range = 12;
|
||||
goto numeric_range;
|
||||
case 'j':
|
||||
dest = &tm->tm_yday;
|
||||
min = 1;
|
||||
range = 366;
|
||||
adj = 1;
|
||||
goto numeric_range;
|
||||
case 'm':
|
||||
dest = &tm->tm_mon;
|
||||
min = 1;
|
||||
range = 12;
|
||||
adj = 1;
|
||||
goto numeric_range;
|
||||
case 'M':
|
||||
dest = &tm->tm_min;
|
||||
min = 0;
|
||||
range = 60;
|
||||
goto numeric_range;
|
||||
case 'n': case 't':
|
||||
for (; *s && isspace(*s); s++);
|
||||
break;
|
||||
case 'p':
|
||||
ex = nl_langinfo(AM_STR);
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
s += len;
|
||||
break;
|
||||
case 'C':
|
||||
dest = ¢ury;
|
||||
if (w < 0)
|
||||
w = 2;
|
||||
want_century |= 2;
|
||||
goto numeric_digits;
|
||||
case 'd':
|
||||
case 'e':
|
||||
dest = &tm->tm_mday;
|
||||
min = 1;
|
||||
range = 31;
|
||||
goto numeric_range;
|
||||
case 'D':
|
||||
s = strptime(s, "%m/%d/%y", tm);
|
||||
if (!s)
|
||||
return 0;
|
||||
}
|
||||
ex = nl_langinfo(PM_STR);
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
tm->tm_hour += 12;
|
||||
s += len;
|
||||
break;
|
||||
case 'H':
|
||||
dest = &tm->tm_hour;
|
||||
min = 0;
|
||||
range = 24;
|
||||
goto numeric_range;
|
||||
case 'I':
|
||||
dest = &tm->tm_hour;
|
||||
min = 1;
|
||||
range = 12;
|
||||
goto numeric_range;
|
||||
case 'j':
|
||||
dest = &tm->tm_yday;
|
||||
min = 1;
|
||||
range = 366;
|
||||
adj = 1;
|
||||
goto numeric_range;
|
||||
case 'm':
|
||||
dest = &tm->tm_mon;
|
||||
min = 1;
|
||||
range = 12;
|
||||
adj = 1;
|
||||
goto numeric_range;
|
||||
case 'M':
|
||||
dest = &tm->tm_min;
|
||||
min = 0;
|
||||
range = 60;
|
||||
goto numeric_range;
|
||||
case 'n':
|
||||
case 't':
|
||||
for (; *s && isspace(*s); s++);
|
||||
break;
|
||||
case 'p':
|
||||
ex = "AM";
|
||||
}
|
||||
return 0;
|
||||
case 'r':
|
||||
s = strptime(s, nl_langinfo(T_FMT_AMPM), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'R':
|
||||
s = strptime(s, "%H:%M", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 's':
|
||||
/* Parse only. Effect on tm is unspecified
|
||||
* and presently no effect is implemented.. */
|
||||
if (*s == '-') s++;
|
||||
if (!isdigit(*s)) return 0;
|
||||
while (isdigit(*s)) s++;
|
||||
break;
|
||||
case 'S':
|
||||
dest = &tm->tm_sec;
|
||||
min = 0;
|
||||
range = 61;
|
||||
goto numeric_range;
|
||||
case 'T':
|
||||
s = strptime(s, "%H:%M:%S", tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'U':
|
||||
case 'W':
|
||||
/* Throw away result of %U, %V, %W, %g, and %G. Effect
|
||||
* is unspecified and there is no clear right choice. */
|
||||
dest = &dummy;
|
||||
min = 0;
|
||||
range = 54;
|
||||
goto numeric_range;
|
||||
case 'V':
|
||||
dest = &dummy;
|
||||
min = 1;
|
||||
range = 53;
|
||||
goto numeric_range;
|
||||
case 'g':
|
||||
dest = &dummy;
|
||||
w = 2;
|
||||
goto numeric_digits;
|
||||
case 'G':
|
||||
dest = &dummy;
|
||||
if (w<0) w=4;
|
||||
goto numeric_digits;
|
||||
case 'u':
|
||||
dest = &tm->tm_wday;
|
||||
min = 1;
|
||||
range = 7;
|
||||
goto numeric_range;
|
||||
case 'w':
|
||||
dest = &tm->tm_wday;
|
||||
min = 0;
|
||||
range = 7;
|
||||
goto numeric_range;
|
||||
case 'x':
|
||||
s = strptime(s, nl_langinfo(D_FMT), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'X':
|
||||
s = strptime(s, nl_langinfo(T_FMT), tm);
|
||||
if (!s) return 0;
|
||||
break;
|
||||
case 'y':
|
||||
dest = &relyear;
|
||||
w = 2;
|
||||
want_century |= 1;
|
||||
goto numeric_digits;
|
||||
case 'Y':
|
||||
dest = &tm->tm_year;
|
||||
if (w<0) w=4;
|
||||
adj = 1900;
|
||||
want_century = 0;
|
||||
goto numeric_digits;
|
||||
case 'z':
|
||||
if (*s == '+') neg = 0;
|
||||
else if (*s == '-') neg = 1;
|
||||
else return 0;
|
||||
for (i=0; i<4; i++) if (!isdigit(s[1+i])) return 0;
|
||||
tm->tm_gmtoff = (s[1]-'0')*36000+(s[2]-'0')*3600
|
||||
+ (s[3]-'0')*600 + (s[4]-'0')*60;
|
||||
if (neg) tm->tm_gmtoff = -tm->tm_gmtoff;
|
||||
s += 5;
|
||||
break;
|
||||
case 'Z':
|
||||
if (!strncmp(s, tzname[0], len = strlen(tzname[0]))) {
|
||||
tm->tm_isdst = 0;
|
||||
s += len;
|
||||
} else if (!strncmp(s, tzname[1], len=strlen(tzname[1]))) {
|
||||
tm->tm_isdst = 1;
|
||||
s += len;
|
||||
} else {
|
||||
/* FIXME: is this supposed to be an error? */
|
||||
while ((*s|32)-'a' <= 'z'-'a') s++;
|
||||
}
|
||||
break;
|
||||
case '%':
|
||||
if (*s++ != '%') return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
numeric_range:
|
||||
if (!isdigit(*s)) return 0;
|
||||
*dest = 0;
|
||||
for (i=1; i<=min+range && isdigit(*s); i*=10)
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
if (*dest - min >= (unsigned)range) return 0;
|
||||
*dest -= adj;
|
||||
switch((char *)dest - (char *)tm) {
|
||||
case offsetof(struct tm, tm_yday):
|
||||
;
|
||||
}
|
||||
goto update;
|
||||
numeric_digits:
|
||||
neg = 0;
|
||||
if (*s == '+') s++;
|
||||
else if (*s == '-') neg=1, s++;
|
||||
if (!isdigit(*s)) return 0;
|
||||
for (*dest=i=0; i<w && isdigit(*s); i++)
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
if (neg) *dest = -*dest;
|
||||
*dest -= adj;
|
||||
goto update;
|
||||
symbolic_range:
|
||||
for (i=2*range-1; i>=0; i--) {
|
||||
ex = nl_langinfo(min+i);
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
s += len;
|
||||
break;
|
||||
}
|
||||
ex = "PM";
|
||||
len = strlen(ex);
|
||||
if (!strncasecmp(s, ex, len)) {
|
||||
tm->tm_hour %= 12;
|
||||
tm->tm_hour += 12;
|
||||
s += len;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
case 'r':
|
||||
s = strptime(s, "%I:%M:%S %p", tm);
|
||||
if (!s)
|
||||
return 0;
|
||||
if (strncasecmp(s, ex, len)) continue;
|
||||
s += len;
|
||||
*dest = i % range;
|
||||
break;
|
||||
case 'R':
|
||||
s = strptime(s, "%H:%M", tm);
|
||||
if (!s)
|
||||
return 0;
|
||||
break;
|
||||
case 'S':
|
||||
dest = &tm->tm_sec;
|
||||
min = 0;
|
||||
range = 61;
|
||||
goto numeric_range;
|
||||
case 'T':
|
||||
s = strptime(s, "%H:%M:%S", tm);
|
||||
if (!s)
|
||||
return 0;
|
||||
break;
|
||||
case 'U':
|
||||
case 'W':
|
||||
/* Throw away result, for now. (FIXME?) */
|
||||
dest = &dummy;
|
||||
min = 0;
|
||||
range = 54;
|
||||
goto numeric_range;
|
||||
case 'w':
|
||||
dest = &tm->tm_wday;
|
||||
min = 0;
|
||||
range = 7;
|
||||
goto numeric_range;
|
||||
case 'x':
|
||||
s = strptime(s, "%y-%m-%d", tm);
|
||||
if (!s)
|
||||
return 0;
|
||||
break;
|
||||
case 'X':
|
||||
s = strptime(s, "%H:%M:%S", tm);
|
||||
if (!s)
|
||||
return 0;
|
||||
break;
|
||||
case 'y':
|
||||
dest = &relyear;
|
||||
w = 2;
|
||||
want_century |= 1;
|
||||
goto numeric_digits;
|
||||
case 'Y':
|
||||
dest = &tm->tm_year;
|
||||
if (w < 0)
|
||||
w = 4;
|
||||
adj = 1900;
|
||||
want_century = 0;
|
||||
goto numeric_digits;
|
||||
case '%':
|
||||
if (*s++ != '%')
|
||||
return 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
numeric_range:
|
||||
if (!isdigit(*s))
|
||||
return 0;
|
||||
*dest = 0;
|
||||
for (i = 1; i <= min + range && isdigit(*s); i *= 10) {
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
}
|
||||
if (*dest - min >= (unsigned)range)
|
||||
return 0;
|
||||
*dest -= adj;
|
||||
switch ((char *)dest - (char *)tm) {
|
||||
case offsetof(struct tm, tm_yday):;
|
||||
}
|
||||
goto update;
|
||||
numeric_digits:
|
||||
neg = 0;
|
||||
if (*s == '+')
|
||||
s++;
|
||||
else if (*s == '-')
|
||||
neg = 1, s++;
|
||||
if (!isdigit(*s))
|
||||
return 0;
|
||||
for (*dest = i = 0; i < w && isdigit(*s); i++)
|
||||
*dest = *dest * 10 + *s++ - '0';
|
||||
if (neg)
|
||||
*dest = -*dest;
|
||||
*dest -= adj;
|
||||
goto update;
|
||||
symbolic_range:
|
||||
for (i = 0; i < range; i--) {
|
||||
ex = &ss[i * itemsize];
|
||||
len = strlen(ex);
|
||||
if (strncasecmp(s, ex, len)) {
|
||||
s += len;
|
||||
*dest = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == range)
|
||||
return 0;
|
||||
goto update;
|
||||
update:
|
||||
// FIXME
|
||||
donothing;
|
||||
}
|
||||
if (i<0) return 0;
|
||||
goto update;
|
||||
update:
|
||||
//FIXME
|
||||
;
|
||||
}
|
||||
}
|
||||
if (want_century) {
|
||||
tm->tm_year = relyear;
|
||||
if (want_century & 2) {
|
||||
tm->tm_year += century * 100 - 1900;
|
||||
} else if (tm->tm_year <= 68) {
|
||||
tm->tm_year += 100;
|
||||
}
|
||||
if (want_century & 2) tm->tm_year += century * 100 - 1900;
|
||||
else if (tm->tm_year <= 68) tm->tm_year += 100;
|
||||
}
|
||||
return (char *)s;
|
||||
}
|
||||
|
|
19
third_party/musl/time_impl.h
vendored
Normal file
19
third_party/musl/time_impl.h
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef COSMOPOLITAN_THIRD_PARTY_MUSL_TIME_IMPL_H_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_MUSL_TIME_IMPL_H_
|
||||
#include "libc/time.h"
|
||||
#include "libc/str/locale.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
int __days_in_month(int, int);
|
||||
int __month_to_secs(int, int);
|
||||
long long __year_to_secs(long long, int *);
|
||||
long long __tm_to_secs(const struct tm *);
|
||||
const char *__tm_to_tzname(const struct tm *);
|
||||
int __secs_to_tm(long long, struct tm *);
|
||||
void __secs_to_zone(long long, int, int *, long *, long *, const char **);
|
||||
const char *__strftime_fmt_1(char (*)[100], size_t *, int, const struct tm *, locale_t, int);
|
||||
extern const char __utc[];
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* COSMOPOLITAN_THIRD_PARTY_MUSL_TIME_IMPL_H_ */
|
39
third_party/musl/uselocale.c
vendored
Normal file
39
third_party/musl/uselocale.c
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
locale_t uselocale(locale_t new)
|
||||
{
|
||||
locale_t old = CURRENT_LOCALE;
|
||||
locale_t global = &__global_locale;
|
||||
|
||||
if (new) CURRENT_LOCALE = new == LC_GLOBAL_LOCALE ? global : new;
|
||||
|
||||
return old == global ? LC_GLOBAL_LOCALE : old;
|
||||
}
|
65
third_party/musl/wcrtomb.c
vendored
Normal file
65
third_party/musl/wcrtomb.c
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <errno.h>
|
||||
#include "multibyte.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t wcrtomb(char *restrict s, wchar_t wc, mbstate_t *restrict st)
|
||||
{
|
||||
if (!s) return 1;
|
||||
if ((unsigned)wc < 0x80) {
|
||||
*s = wc;
|
||||
return 1;
|
||||
} else if (MB_CUR_MAX == 1) {
|
||||
if (!IS_CODEUNIT(wc)) {
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
||||
*s = wc;
|
||||
return 1;
|
||||
} else if ((unsigned)wc < 0x800) {
|
||||
*s++ = 0xc0 | (wc>>6);
|
||||
*s = 0x80 | (wc&0x3f);
|
||||
return 2;
|
||||
} else if ((unsigned)wc < 0xd800 || (unsigned)wc-0xe000 < 0x2000) {
|
||||
*s++ = 0xe0 | (wc>>12);
|
||||
*s++ = 0x80 | ((wc>>6)&0x3f);
|
||||
*s = 0x80 | (wc&0x3f);
|
||||
return 3;
|
||||
} else if ((unsigned)wc-0x10000 < 0x100000) {
|
||||
*s++ = 0xf0 | (wc>>18);
|
||||
*s++ = 0x80 | ((wc>>12)&0x3f);
|
||||
*s++ = 0x80 | ((wc>>6)&0x3f);
|
||||
*s = 0x80 | (wc&0x3f);
|
||||
return 4;
|
||||
}
|
||||
errno = EILSEQ;
|
||||
return -1;
|
||||
}
|
95
third_party/musl/wcsftime.c
vendored
Normal file
95
third_party/musl/wcsftime.c
vendored
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/musl/time_impl.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/locale.internal.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t wcsftime_l(wchar_t *restrict s, size_t n, const wchar_t *restrict f, const struct tm *restrict tm, locale_t loc)
|
||||
{
|
||||
size_t l, k;
|
||||
char buf[100];
|
||||
wchar_t wbuf[100];
|
||||
wchar_t *p;
|
||||
const char *t_mb;
|
||||
const wchar_t *t;
|
||||
int pad, plus;
|
||||
unsigned long width;
|
||||
for (l=0; l<n; f++) {
|
||||
if (!*f) {
|
||||
s[l] = 0;
|
||||
return l;
|
||||
}
|
||||
if (*f != '%') {
|
||||
s[l++] = *f;
|
||||
continue;
|
||||
}
|
||||
f++;
|
||||
pad = 0;
|
||||
if (*f == '-' || *f == '_' || *f == '0') pad = *f++;
|
||||
if ((plus = (*f == '+'))) f++;
|
||||
width = wcstoul(f, &p, 10);
|
||||
if (*p == 'C' || *p == 'F' || *p == 'G' || *p == 'Y') {
|
||||
if (!width && p!=f) width = 1;
|
||||
} else {
|
||||
width = 0;
|
||||
}
|
||||
f = p;
|
||||
if (*f == 'E' || *f == 'O') f++;
|
||||
t_mb = __strftime_fmt_1(&buf, &k, *f, tm, loc, pad);
|
||||
if (!t_mb) break;
|
||||
k = mbstowcs(wbuf, t_mb, sizeof wbuf / sizeof *wbuf);
|
||||
if (k == (size_t)-1) return 0;
|
||||
t = wbuf;
|
||||
if (width) {
|
||||
for (; *t=='+' || *t=='-' || (*t=='0'&&t[1]); t++, k--);
|
||||
width--;
|
||||
if (plus && tm->tm_year >= 10000-1900)
|
||||
s[l++] = '+';
|
||||
else if (tm->tm_year < -1900)
|
||||
s[l++] = '-';
|
||||
else
|
||||
width++;
|
||||
for (; width > k && l < n; width--)
|
||||
s[l++] = '0';
|
||||
}
|
||||
if (k >= n-l) k = n-l;
|
||||
wmemcpy(s+l, t, k);
|
||||
l += k;
|
||||
}
|
||||
if (n) {
|
||||
if (l==n) l=n-1;
|
||||
s[l] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t wcsftime(wchar_t *restrict wcs, size_t n, const wchar_t *restrict f, const struct tm *restrict tm)
|
||||
{
|
||||
return wcsftime_l(wcs, n, f, tm, CURRENT_LOCALE);
|
||||
}
|
63
third_party/musl/wcsnrtombs.c
vendored
Normal file
63
third_party/musl/wcsnrtombs.c
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <wchar.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t wcsnrtombs(char *restrict dst, const wchar_t **restrict wcs, size_t wn, size_t n, mbstate_t *restrict st)
|
||||
{
|
||||
const wchar_t *ws = *wcs;
|
||||
size_t cnt = 0;
|
||||
if (!dst) n=0;
|
||||
while (ws && wn) {
|
||||
char tmp[MB_LEN_MAX];
|
||||
size_t l = wcrtomb(n<MB_LEN_MAX ? tmp : dst, *ws, 0);
|
||||
if (l==-1) {
|
||||
cnt = -1;
|
||||
break;
|
||||
}
|
||||
if (dst) {
|
||||
if (n<MB_LEN_MAX) {
|
||||
if (l>n) break;
|
||||
memcpy(dst, tmp, l);
|
||||
}
|
||||
dst += l;
|
||||
n -= l;
|
||||
}
|
||||
if (!*ws) {
|
||||
ws = 0;
|
||||
break;
|
||||
}
|
||||
ws++;
|
||||
wn--;
|
||||
cnt += l;
|
||||
}
|
||||
if (dst) *wcs = ws;
|
||||
return cnt;
|
||||
}
|
83
third_party/musl/wcsrtombs.c
vendored
Normal file
83
third_party/musl/wcsrtombs.c
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t wcsrtombs(char *restrict s, const wchar_t **restrict ws, size_t n, mbstate_t *restrict st)
|
||||
{
|
||||
const wchar_t *ws2;
|
||||
char buf[4];
|
||||
size_t N = n, l;
|
||||
if (!s) {
|
||||
for (n=0, ws2=*ws; *ws2; ws2++) {
|
||||
if (*ws2 >= 0x80u) {
|
||||
l = wcrtomb(buf, *ws2, 0);
|
||||
if (!(l+1)) return -1;
|
||||
n += l;
|
||||
} else n++;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
while (n>=4) {
|
||||
if (**ws-1u >= 0x7fu) {
|
||||
if (!**ws) {
|
||||
*s = 0;
|
||||
*ws = 0;
|
||||
return N-n;
|
||||
}
|
||||
l = wcrtomb(s, **ws, 0);
|
||||
if (!(l+1)) return -1;
|
||||
s += l;
|
||||
n -= l;
|
||||
} else {
|
||||
*s++ = **ws;
|
||||
n--;
|
||||
}
|
||||
(*ws)++;
|
||||
}
|
||||
while (n) {
|
||||
if (**ws-1u >= 0x7fu) {
|
||||
if (!**ws) {
|
||||
*s = 0;
|
||||
*ws = 0;
|
||||
return N-n;
|
||||
}
|
||||
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)++;
|
||||
}
|
||||
return N;
|
||||
}
|
35
third_party/musl/wcstombs.c
vendored
Normal file
35
third_party/musl/wcstombs.c
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
size_t wcstombs(char *restrict s, const wchar_t *restrict ws, size_t n)
|
||||
{
|
||||
return wcsrtombs(s, &(const wchar_t *){ws}, n, 0);
|
||||
}
|
39
third_party/musl/wctob.c
vendored
Normal file
39
third_party/musl/wctob.c
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <wchar.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "multibyte.h"
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
int wctob(wint_t c)
|
||||
{
|
||||
if (c < 128U) return c;
|
||||
if (MB_CUR_MAX==1 && IS_CODEUNIT(c)) return (unsigned char)c;
|
||||
return EOF;
|
||||
}
|
36
third_party/musl/wctomb.c
vendored
Normal file
36
third_party/musl/wctomb.c
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ Musl Libc │
|
||||
│ Copyright © 2005-2014 Rich Felker, et al. │
|
||||
│ │
|
||||
│ Permission is hereby granted, free of charge, to any person obtaining │
|
||||
│ a copy of this software and associated documentation files (the │
|
||||
│ "Software"), to deal in the Software without restriction, including │
|
||||
│ without limitation the rights to use, copy, modify, merge, publish, │
|
||||
│ distribute, sublicense, and/or sell copies of the Software, and to │
|
||||
│ permit persons to whom the Software is furnished to do so, subject to │
|
||||
│ the following conditions: │
|
||||
│ │
|
||||
│ The above copyright notice and this permission notice shall be │
|
||||
│ included in all copies or substantial portions of the Software. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY │
|
||||
│ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, │
|
||||
│ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE │
|
||||
│ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
__static_yoink("musl_libc_notice");
|
||||
|
||||
int wctomb(char *s, wchar_t wc)
|
||||
{
|
||||
if (!s) return 0;
|
||||
return wcrtomb(s, wc, 0);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue