Make improvements

This commit is contained in:
Justine Tunney 2020-12-01 03:43:40 -08:00
parent 3e4fd4b0ad
commit e44a0cf6f8
256 changed files with 23100 additions and 2294 deletions

View file

@ -1,20 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_RUNTIME_APPENDCHAR_H_
#define COSMOPOLITAN_LIBC_RUNTIME_APPENDCHAR_H_
#ifndef __STRICT_ANSI__
#include "libc/str/str.h"
#include "libc/str/tpenc.h"
#include "libc/str/tpencode.internal.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
static inline void AppendChar(char **p, char *pe, wint_t wc) {
uint64_t w;
w = tpenc(wc);
do {
if (*p >= pe) break;
*(*p)++ = w & 0xff;
} while (w >>= 8);
}
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* !ANSI */
#endif /* COSMOPOLITAN_LIBC_RUNTIME_APPENDCHAR_H_ */

33
libc/str/bcmp.c Normal file
View file

@ -0,0 +1,33 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares memory.
*
* This API was thought to be nearly extinct until recent versions
* of Clang (c. 2019) started generating synthetic calls to it.
*
* @return unsigned char subtraction at stop index
* @asyncsignalsafe
*/
int bcmp(const void *a, const void *b, size_t n) {
return memcmp(a, b, n);
}

View file

@ -1,4 +1,4 @@
/*-*- mode:c; indent-tabs-mode:nil; tab-width:2; coding:utf-8 -*-│
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
@ -19,15 +19,9 @@
*/
#include "libc/str/str.h"
int getkvlin(const char *name, const char *const unsorted[]) {
unsigned i, n;
if (unsorted) {
n = strlen(name);
for (i = 0; unsorted[i]; ++i) {
if (strncmp(unsorted[i], name, n) == 0 && unsorted[i][n] == '=') {
return i;
}
}
}
return -1;
/**
* Copies memory the legacy way.
*/
void *bcopy(void *dst, const void *src, size_t n) {
return memmove(dst, src, n);
}

View file

@ -22,11 +22,17 @@
wint_t DecodeNtsUtf16(const char16_t **s) {
wint_t x, y;
if (!IsUcs2((x = *(*s)++))) {
if ((y = *(*s)++)) {
x = MergeUtf16(x, y);
for (;;) {
if (!(x = *(*s)++)) break;
if (IsUtf16Cont(x)) continue;
if (IsUcs2(x)) {
return x;
} else {
x = 0;
if ((y = *(*s)++)) {
return MergeUtf16(x, y);
} else {
return 0;
}
}
}
return x;

View file

@ -21,6 +21,8 @@
#include "libc/str/str.h"
#include "libc/str/utf16.h"
/* TODO: DELETE */
/**
* Decodes UTF-16 character.
*

54
libc/str/memcmp.c Normal file
View file

@ -0,0 +1,54 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/intrin/pcmpeqb.h"
#include "libc/intrin/pmovmskb.h"
#include "libc/nexgen32e/bsf.h"
#include "libc/str/str.h"
/**
* Compares memory.
*
* @return unsigned char subtraction at stop index
* @asyncsignalsafe
*/
int memcmp(const void *a, const void *b, size_t n) {
int c;
size_t i;
unsigned m;
uint8_t *p1, *p2;
uint8_t v1[16], v2[16];
if (n) {
for (p1 = a, p2 = b, i = 0; i + 16 <= n; i += 16) {
memcpy(v1, p1 + i, 16);
memcpy(v2, p2 + i, 16);
pcmpeqb(v1, v1, v2);
if ((m = pmovmskb(v1) - 0xffff)) {
i += bsf(m);
return p1[i] - p2[i];
}
}
for (; i < n; ++i) {
if ((c = p1[i] - p2[i])) {
return c;
}
}
}
return 0;
}

View file

@ -9,7 +9,6 @@ COSMOPOLITAN_C_START_
extern const uint8_t gperf_downcase[256];
extern const uint8_t kToLower[256];
extern const uint8_t kToUpper[256];
extern const uint16_t kToLower16[256];
extern const uint8_t kBase36[256];
extern const char16_t kCp437[256];
@ -170,7 +169,6 @@ bool endswith(const char *, const char *) strlenesque;
bool endswith16(const char16_t *, const char16_t *) strlenesque;
bool wcsendswith(const wchar_t *, const wchar_t *) strlenesque;
const char *IndexDoubleNulString(const char *, unsigned) strlenesque;
int getkvlin(const char *, const char *const[]);
wchar_t *wmemset(wchar_t *, wchar_t, size_t) memcpyesque;
char16_t *memset16(char16_t *, char16_t, size_t) memcpyesque;
compatfn wchar_t *wmemcpy(wchar_t *, const wchar_t *, size_t) memcpyesque;
@ -199,8 +197,8 @@ bool escapedos(char16_t *, unsigned, const char16_t *, unsigned);
typedef unsigned mbstate_t;
size_t tprecode8to16(char16_t *, size_t, const char *);
size_t tprecode16to8(char *, size_t, const char16_t *);
axdx_t tprecode8to16(char16_t *, size_t, const char *);
axdx_t tprecode16to8(char *, size_t, const char16_t *);
int strcmp8to16(const char *, const char16_t *) strlenesque;
int strncmp8to16(const char *, const char16_t *, size_t) strlenesque;
int strcasecmp8to16(const char *, const char16_t *) strlenesque;
@ -240,9 +238,6 @@ char *strsignal(int) returnsnonnull libcesque;
*/
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
extern int (*const __memcmp)(const void *, const void *, size_t);
#define memcmp(a, b, n) __memcmp(a, b, n)
char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
#define strncpy(DEST, SRC, N) _strncpy(DEST, SRC, N) /* pacify bad warning */
@ -265,12 +260,12 @@ char *_strncpy(char *, const char *, size_t) asm("strncpy") memcpyesque;
#define __memcpy_isgoodsize(SIZE) \
(isconstant(SIZE) && ((SIZE) <= __BIGGEST_ALIGNMENT__ * 2 && \
__builtin_popcount((unsigned)(SIZE)) == 1))
__builtin_popcountl((unsigned)(SIZE)) == 1))
#define __memset_isgoodsize(SIZE) \
(isconstant(SIZE) && (((SIZE) <= __BIGGEST_ALIGNMENT__ && \
__builtin_popcount((unsigned)(SIZE)) == 1) || \
((SIZE) % __BIGGEST_ALIGNMENT__ == 0 && \
#define __memset_isgoodsize(SIZE) \
(isconstant(SIZE) && (((SIZE) <= __BIGGEST_ALIGNMENT__ && \
__builtin_popcountl((unsigned)(SIZE)) == 1) || \
((SIZE) % __BIGGEST_ALIGNMENT__ == 0 && \
(SIZE) / __BIGGEST_ALIGNMENT__ <= 3)))
#define memcpy(DEST, SRC, SIZE) \

38
libc/str/strcasecmp.c Normal file
View file

@ -0,0 +1,38 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated strings case-insensitively.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int strcasecmp(const char *a, const char *b) {
int x, y;
size_t i = 0;
if (a == b) return 0;
while ((x = kToLower[a[i] & 0xff]) == (y = kToLower[b[i] & 0xff]) && b[i]) {
++i;
}
return x - y;
}

35
libc/str/strcasecmp16.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated UCS-2 strings case-insensitively.
*
* @param a is first non-null NUL-terminated char16 string pointer
* @param b is second non-null NUL-terminated char16 string pointer
* @return is <0, 0, or >0 based on uint16_t comparison
* @asyncsignalsafe
*/
int strcasecmp16(const char16_t *l, const char16_t *r) {
int x, y;
size_t i = 0;
while ((x = tolower(l[i])) == (y = tolower(r[i])) && r[i]) ++i;
return x - y;
}

35
libc/str/strcmp.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated strings.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int strcmp(const char *a, const char *b) {
size_t i = 0;
if (a == b) return 0;
while (a[i] == b[i] && b[i]) ++i;
return (a[i] & 0xff) - (b[i] & 0xff);
}

34
libc/str/strcmp16.c Normal file
View file

@ -0,0 +1,34 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated UCS-2 strings.
*
* @param a is first non-null NUL-terminated char16 string pointer
* @param b is second non-null NUL-terminated char16 string pointer
* @return is <0, 0, or >0 based on uint16_t comparison
* @asyncsignalsafe
*/
int strcmp16(const char16_t *l, const char16_t *r) {
size_t i = 0;
while (l[i] == r[i] && r[i]) ++i;
return l[i] - r[i];
}

39
libc/str/strncasecmp.c Normal file
View file

@ -0,0 +1,39 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated strings case-insensitively w/ limit.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int strncasecmp(const char *a, const char *b, size_t n) {
int x, y;
size_t i = 0;
if (!n-- || a == b) return 0;
while ((x = kToLower[a[i] & 0xff]) == (y = kToLower[b[i] & 0xff]) && b[i] &&
i < n) {
++i;
}
return x - y;
}

36
libc/str/strncasecmp16.c Normal file
View file

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated UCS-2 strings case-insensitively w/ limit.
*
* @param a is first non-null NUL-terminated char16 string pointer
* @param b is second non-null NUL-terminated char16 string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int strncasecmp16(const char16_t *a, const char16_t *b, size_t n) {
int x, y;
size_t i = 0;
if (!n-- || a == b) return 0;
while ((x = tolower(a[i])) == (y = tolower(b[i])) && b[i] && i < n) ++i;
return x - y;
}

35
libc/str/strncmp.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated strings w/ limit.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int strncmp(const char *a, const char *b, size_t n) {
size_t i = 0;
if (!n-- || a == b) return 0;
while (a[i] == b[i] && b[i] && i < n) ++i;
return (a[i] & 0xff) - (b[i] & 0xff);
}

35
libc/str/strncmp16.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated UCS-2 strings w/ limit.
*
* @param a is first non-null NUL-terminated char16 string pointer
* @param b is second non-null NUL-terminated char16 string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int strncmp16(const char16_t *a, const char16_t *b, size_t n) {
size_t i = 0;
if (!n-- || a == b) return 0;
while (i < n && a[i] == b[i] && b[i]) ++i;
return a[i] - b[i];
}

View file

@ -18,38 +18,62 @@
02110-1301 USA
*/
#include "libc/conv/conv.h"
#include "libc/intrin/packsswb.h"
#include "libc/intrin/pandn.h"
#include "libc/intrin/pcmpgtw.h"
#include "libc/intrin/pmovmskb.h"
#include "libc/str/str.h"
#include "libc/str/tpenc.h"
#include "libc/str/utf16.h"
static const int16_t kDel16[8] = {127, 127, 127, 127, 127, 127, 127, 127};
/**
* Transcodes UTF-16 to UTF-8.
*
* @param dst is output buffer
* @param dstsize is bytes in dst
* @param src is NUL-terminated UTF-16 input string
* @return number of bytes written excluding NUL
* @return ax bytes written excluding nul
* @return dx index of character after nul word in src
*/
size_t tprecode16to8(char *dst, size_t dstsize, const char16_t *src) {
size_t i;
axdx_t tprecode16to8(char *dst, size_t dstsize, const char16_t *src) {
axdx_t r;
uint64_t w;
wint_t x, y;
i = 0;
if (dstsize) {
for (;;) {
if (!(x = *src++)) break;
if (IsUtf16Cont(x)) continue;
if (!IsUcs2(x)) {
if (!(y = *src++)) break;
x = MergeUtf16(x, y);
}
w = tpenc(x);
while (w && i + 1 < dstsize) {
dst[i++] = w & 0xFF;
w >>= 8;
int16_t v1[8], v2[8], v3[8], vz[8];
r.ax = 0;
r.dx = 0;
for (;;) {
if (!IsTiny() && !((uintptr_t)(src + r.dx) & 15)) {
/* 10x speedup for ascii */
memset(vz, 0, 16);
while (r.ax + 8 < dstsize) {
memcpy(v1, src + r.dx, 16);
pcmpgtw(v2, v1, vz);
pcmpgtw(v3, v1, kDel16);
pandn((void *)v2, (void *)v3, (void *)v2);
if (pmovmskb((void *)v2) != 0xFFFF) break;
packsswb((void *)v1, v1, v1);
memcpy(dst + r.ax, v1, 8);
r.ax += 8;
r.dx += 8;
}
}
dst[i] = 0;
if (!(x = src[r.dx++])) break;
if (IsUtf16Cont(x)) continue;
if (!IsUcs2(x)) {
if (!(y = src[r.dx++])) break;
x = MergeUtf16(x, y);
}
w = tpenc(x);
while (w && r.ax + 1 < dstsize) {
dst[r.ax++] = w & 0xFF;
w >>= 8;
}
}
return i;
if (r.ax < dstsize) {
dst[r.ax] = 0;
}
return r;
}

View file

@ -17,6 +17,10 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/intrin/pcmpgtb.h"
#include "libc/intrin/pmovmskb.h"
#include "libc/intrin/punpckhbw.h"
#include "libc/intrin/punpcklbw.h"
#include "libc/str/str.h"
#include "libc/str/thompike.h"
#include "libc/str/utf16.h"
@ -27,34 +31,56 @@
* @param dst is output buffer
* @param dstsize is shorts in dst
* @param src is NUL-terminated UTF-8 input string
* @return number of shorts written excluding NUL
* @return ax shorts written excluding nul
* @return dx index of character after nul word in src
*/
size_t tprecode8to16(char16_t *dst, size_t dstsize, const char *src) {
size_t i;
axdx_t tprecode8to16(char16_t *dst, size_t dstsize, const char *src) {
axdx_t r;
unsigned n;
uint64_t w;
wint_t x, y;
i = 0;
if (dstsize) {
for (;;) {
if (!(x = *src++ & 0xff)) break;
if (ThomPikeCont(x)) continue;
if (!isascii(x)) {
n = ThomPikeLen(x);
x = ThomPikeByte(x);
while (--n) {
if (!(y = *src++ & 0xff)) goto stop;
x = ThomPikeMerge(x, y);
}
}
w = EncodeUtf16(x);
while (w && i + 1 < dstsize) {
dst[i++] = w & 0xFFFF;
w >>= 16;
uint8_t v1[16], v2[16], vz[16];
r.ax = 0;
r.dx = 0;
for (;;) {
if (!IsTiny() && !((uintptr_t)(src + r.dx) & 15)) {
/* 34x speedup for ascii */
memset(vz, 0, 16);
while (r.ax + 16 < dstsize) {
memcpy(v1, src + r.dx, 16);
pcmpgtb((int8_t *)v2, (int8_t *)v1, (int8_t *)vz);
if (pmovmskb(v2) != 0xFFFF) break;
punpcklbw(v2, v1, vz);
punpckhbw(v1, v1, vz);
memcpy(dst + r.ax + 0, v2, 16);
memcpy(dst + r.ax + 8, v1, 16);
r.ax += 16;
r.dx += 16;
}
}
stop:
dst[i] = 0;
x = src[r.dx++] & 0xff;
if (ThomPikeCont(x)) continue;
if (!isascii(x)) {
n = ThomPikeLen(x);
x = ThomPikeByte(x);
while (--n) {
if ((y = src[r.dx++] & 0xff)) {
x = ThomPikeMerge(x, y);
} else {
x = 0;
break;
}
}
}
if (!x) break;
w = EncodeUtf16(x);
while (w && r.ax + 1 < dstsize) {
dst[r.ax++] = w & 0xFFFF;
w >>= 16;
}
}
return i;
if (r.ax < dstsize) {
dst[r.ax] = 0;
}
return r;
}

View file

@ -20,8 +20,6 @@ COSMOPOLITAN_C_START_
((((wc)-0x10000) & 1023) + 0xDC00) << 16) \
: 0xFFFD)
wint_t DecodeNtsUtf16(const char16_t **);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_STR_UTF16_H_ */

36
libc/str/wcscasecmp.c Normal file
View file

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated wide strings case-insensitively.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int wcscasecmp(const wchar_t *a, const wchar_t *b) {
size_t i = 0;
unsigned x, y;
if (a == b) return 0;
while ((x = tolower(a[i])) == (y = tolower(b[i])) && b[i]) ++i;
return x - y;
}

35
libc/str/wcscmp.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated wide strings.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int wcscmp(const wchar_t *a, const wchar_t *b) {
size_t i = 0;
if (a == b) return 0;
while (a[i] == b[i] && b[i]) ++i;
return (unsigned)a[i] - (unsigned)b[i];
}

36
libc/str/wcsncasecmp.c Normal file
View file

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated wide strings case-insensitively w/ limit.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int wcsncasecmp(const wchar_t *a, const wchar_t *b, size_t n) {
size_t i = 0;
unsigned x, y;
if (!n-- || a == b) return 0;
while ((x = tolower(a[i])) == (y = tolower(b[i])) && b[i] && i < n) ++i;
return x - y;
}

35
libc/str/wcsncmp.c Normal file
View file

@ -0,0 +1,35 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/str/str.h"
/**
* Compares NUL-terminated wide strings w/ limit.
*
* @param a is first non-null NUL-terminated string pointer
* @param b is second non-null NUL-terminated string pointer
* @return is <0, 0, or >0 based on uint8_t comparison
* @asyncsignalsafe
*/
int wcsncmp(const wchar_t *a, const wchar_t *b, size_t n) {
size_t i = 0;
if (!n-- || a == b) return 0;
while (i < n && a[i] == b[i] && b[i]) ++i;
return (unsigned)a[i] - (unsigned)b[i];
}

View file

@ -19,6 +19,6 @@
*/
#include "libc/str/str.h"
compatfn wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count) {
wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, size_t count) {
return memcpy(dest, src, count * sizeof(wchar_t));
}

View file

@ -19,6 +19,6 @@
*/
#include "libc/str/str.h"
compatfn wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count) {
wchar_t *wmemmove(wchar_t *dest, const wchar_t *src, size_t count) {
return memmove(dest, src, count * sizeof(wchar_t));
}