mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-07-26 04:20:30 +00:00
Make improvements
This commit is contained in:
parent
3e4fd4b0ad
commit
e44a0cf6f8
256 changed files with 23100 additions and 2294 deletions
|
@ -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
33
libc/str/bcmp.c
Normal 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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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
54
libc/str/memcmp.c
Normal 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;
|
||||
}
|
|
@ -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
38
libc/str/strcasecmp.c
Normal 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
35
libc/str/strcasecmp16.c
Normal 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
35
libc/str/strcmp.c
Normal 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
34
libc/str/strcmp16.c
Normal 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
39
libc/str/strncasecmp.c
Normal 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
36
libc/str/strncasecmp16.c
Normal 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
35
libc/str/strncmp.c
Normal 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
35
libc/str/strncmp16.c
Normal 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];
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
36
libc/str/wcscasecmp.c
Normal 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
35
libc/str/wcscmp.c
Normal 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
36
libc/str/wcsncasecmp.c
Normal 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
35
libc/str/wcsncmp.c
Normal 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];
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue