mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 08:18:30 +00:00
Pay off more technical debt
This makes breaking changes to add underscores to many non-standard function names provided by the c library. MODE=tiny is now tinier and we now use smaller locks that are better for tiny apps in this mode. Some headers have been renamed to be in the same folder as the build package, so it'll be easier to know which build dependency is needed. Certain old misguided interfaces have been removed. Intel intrinsics headers are now listed in libc/isystem (but not in the amalgamation) to help further improve open source compatibility. Header complexity has also been reduced. Lastly, more shell scripts are now available.
This commit is contained in:
parent
b69f3d2488
commit
6f7d0cb1c3
960 changed files with 4072 additions and 4873 deletions
0
libc/str/_tpenc.h
Executable file
0
libc/str/_tpenc.h
Executable file
|
@ -1,40 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/bsf.h"
|
||||
|
||||
/**
|
||||
* Returns position of first bit set.
|
||||
*
|
||||
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
|
||||
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
|
||||
* 0x00000000 wut 32 0 wut 32
|
||||
* 0x00000001 0 0 1 0 31
|
||||
* 0x80000001 0 0 1 31 0
|
||||
* 0x80000000 31 31 32 31 0
|
||||
* 0x00000010 4 4 5 4 27
|
||||
* 0x08000010 4 4 5 27 4
|
||||
* 0x08000000 27 27 28 27 4
|
||||
* 0xffffffff 0 0 1 31 0
|
||||
*
|
||||
* @param x is a 32-bit integer
|
||||
* @return number in range 0..31 or undefined if 𝑥 is 0
|
||||
*/
|
||||
int(bsf)(int x) {
|
||||
return bsf(x);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/bsf.h"
|
||||
|
||||
/**
|
||||
* Returns position of first bit set.
|
||||
*
|
||||
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
|
||||
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
|
||||
* 0x00000000 wut 32 0 wut 32
|
||||
* 0x00000001 0 0 1 0 31
|
||||
* 0x80000001 0 0 1 31 0
|
||||
* 0x80000000 31 31 32 31 0
|
||||
* 0x00000010 4 4 5 4 27
|
||||
* 0x08000010 4 4 5 27 4
|
||||
* 0x08000000 27 27 28 27 4
|
||||
* 0xffffffff 0 0 1 31 0
|
||||
*
|
||||
* @param 𝑥 is a 64-bit integer
|
||||
* @return number in range 0..63 or undefined if 𝑥 is 0
|
||||
*/
|
||||
int(bsfl)(long x) {
|
||||
return bsfl(x);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/bsf.h"
|
||||
|
||||
/**
|
||||
* Returns position of first bit set.
|
||||
*
|
||||
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
|
||||
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
|
||||
* 0x00000000 wut 32 0 wut 32
|
||||
* 0x00000001 0 0 1 0 31
|
||||
* 0x80000001 0 0 1 31 0
|
||||
* 0x80000000 31 31 32 31 0
|
||||
* 0x00000010 4 4 5 4 27
|
||||
* 0x08000010 4 4 5 27 4
|
||||
* 0x08000000 27 27 28 27 4
|
||||
* 0xffffffff 0 0 1 31 0
|
||||
*
|
||||
* @param 𝑥 is a 64-bit integer
|
||||
* @return number in range 0..63 or undefined if 𝑥 is 0
|
||||
*/
|
||||
int(bsfll)(long long x) {
|
||||
return bsfll(x);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
|
||||
/**
|
||||
* Returns binary logarithm of 𝑥.
|
||||
*
|
||||
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
|
||||
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
|
||||
* 0x00000000 wut 32 0 wut 32
|
||||
* 0x00000001 0 0 1 0 31
|
||||
* 0x80000001 0 0 1 31 0
|
||||
* 0x80000000 31 31 32 31 0
|
||||
* 0x00000010 4 4 5 4 27
|
||||
* 0x08000010 4 4 5 27 4
|
||||
* 0x08000000 27 27 28 27 4
|
||||
* 0xffffffff 0 0 1 31 0
|
||||
*
|
||||
* @param x is a 32-bit integer
|
||||
* @return number in range 0..31 or undefined if 𝑥 is 0
|
||||
*/
|
||||
int(bsr)(int x) {
|
||||
return bsr(x);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
|
||||
/**
|
||||
* Returns binary logarithm of 𝑥.
|
||||
*
|
||||
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
|
||||
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
|
||||
* 0x00000000 wut 32 0 wut 32
|
||||
* 0x00000001 0 0 1 0 31
|
||||
* 0x80000001 0 0 1 31 0
|
||||
* 0x80000000 31 31 32 31 0
|
||||
* 0x00000010 4 4 5 4 27
|
||||
* 0x08000010 4 4 5 27 4
|
||||
* 0x08000000 27 27 28 27 4
|
||||
* 0xffffffff 0 0 1 31 0
|
||||
*
|
||||
* @param x is a 64-bit integer
|
||||
* @return number in range 0..63 or undefined if 𝑥 is 0
|
||||
*/
|
||||
int(bsrl)(long x) {
|
||||
return bsrl(x);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
|
||||
/**
|
||||
* Returns binary logarithm of 𝑥.
|
||||
*
|
||||
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
|
||||
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
|
||||
* 0x00000000 wut 32 0 wut 32
|
||||
* 0x00000001 0 0 1 0 31
|
||||
* 0x80000001 0 0 1 31 0
|
||||
* 0x80000000 31 31 32 31 0
|
||||
* 0x00000010 4 4 5 4 27
|
||||
* 0x08000010 4 4 5 27 4
|
||||
* 0x08000000 27 27 28 27 4
|
||||
* 0xffffffff 0 0 1 31 0
|
||||
*
|
||||
* @param x is a 64-bit integer
|
||||
* @return number in range 0..63 or undefined if 𝑥 is 0
|
||||
*/
|
||||
int(bsrll)(long long x) {
|
||||
return bsrll(x);
|
||||
}
|
|
@ -17,9 +17,9 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
|
@ -37,7 +37,7 @@ static inline noasan uint64_t WildRead64(const signed char *p) {
|
|||
*
|
||||
* x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
|
||||
* 0b100000100110000010001110110110111
|
||||
* bitreverse32(0x104c11db7)
|
||||
* _bitreverse32(0x104c11db7)
|
||||
*
|
||||
* This implementation takes 32 picoseconds per byte or 30 gibibyte/s.
|
||||
*
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/asan.internal.h"
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/nexgen32e/nexgen32e.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
|
||||
|
@ -65,7 +65,7 @@ void djbsort(int32_t *a, size_t n) {
|
|||
if (X86_HAVE(AVX2)) {
|
||||
djbsort_avx2(a, n);
|
||||
} else {
|
||||
intsort(a, n, 1ul << bsrl(n - 1));
|
||||
intsort(a, n, 1ul << _bsrl(n - 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* @param s is a NUL-terminated string
|
||||
* @param suffix is also NUL-terminated
|
||||
*/
|
||||
bool endswith(const char *s, const char *suffix) {
|
||||
bool _endswith(const char *s, const char *suffix) {
|
||||
size_t n, m;
|
||||
n = strlen(s);
|
||||
m = strlen(suffix);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* @param s is a NUL-terminated string
|
||||
* @param suffix is also NUL-terminated
|
||||
*/
|
||||
bool endswith16(const char16_t *s, const char16_t *suffix) {
|
||||
bool _endswith16(const char16_t *s, const char16_t *suffix) {
|
||||
size_t n, m;
|
||||
n = strlen16(s);
|
||||
m = strlen16(suffix);
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_ERRFUN_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_ERRFUN_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
char *strerrno(int) nosideeffect libcesque;
|
||||
char *strerdoc(int) nosideeffect libcesque;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_ERRFUN_H_ */
|
|
@ -17,12 +17,12 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/nexgen32e/cachesize.h"
|
||||
#include "libc/nexgen32e/cpuid4.internal.h"
|
||||
|
||||
static unsigned getcachesize_cpuid4(int type, int level) {
|
||||
static unsigned _getcachesize_cpuid4(int type, int level) {
|
||||
unsigned i, k;
|
||||
static int once;
|
||||
static unsigned char kCacheKey[8];
|
||||
|
@ -50,8 +50,8 @@ static unsigned getcachesize_cpuid4(int type, int level) {
|
|||
* @param level starts at 1
|
||||
* @return size in bytes, or 0 if unknown
|
||||
*/
|
||||
unsigned getcachesize(int type, int level) {
|
||||
unsigned _getcachesize(int type, int level) {
|
||||
assert(1 <= type && type <= 3);
|
||||
assert(level >= 1);
|
||||
return getcachesize_cpuid4(type, level);
|
||||
return _getcachesize_cpuid4(type, level);
|
||||
}
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
||||
static void longsorter(long *A, size_t n) {
|
||||
static void _longsorter(long *A, size_t n) {
|
||||
long t, p;
|
||||
size_t i, j;
|
||||
if (n < 2) return;
|
||||
|
@ -31,8 +31,8 @@ static void longsorter(long *A, size_t n) {
|
|||
A[i] = A[j];
|
||||
A[j] = t;
|
||||
}
|
||||
longsorter(A, i);
|
||||
longsorter(A + i, n - i);
|
||||
_longsorter(A, i);
|
||||
_longsorter(A + i, n - i);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -42,9 +42,9 @@ static void longsorter(long *A, size_t n) {
|
|||
* -Lord Capulet
|
||||
*
|
||||
*/
|
||||
void longsort(long *A, size_t n) {
|
||||
longsorter(A, n);
|
||||
void _longsort(long *A, size_t n) {
|
||||
_longsorter(A, n);
|
||||
if (n > 1000) {
|
||||
STRACE("longsort(%p, %'zu)", A, n);
|
||||
STRACE("_longsort(%p, %'zu)", A, n);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
└─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/nexgen32e/bsf.h"
|
||||
#include "libc/intrin/bsf.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* @param s is a NUL-terminated string
|
||||
* @param prefix is also NUL-terminated
|
||||
*/
|
||||
bool startswith(const char *s, const char *prefix) {
|
||||
bool _startswith(const char *s, const char *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* @param s is a NUL-terminated string
|
||||
* @param prefix is also NUL-terminated
|
||||
*/
|
||||
bool startswith16(const char16_t *s, const char16_t *prefix) {
|
||||
bool _startswith16(const char16_t *s, const char16_t *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
bool startswithi(const char *s, const char *prefix) {
|
||||
bool _startswithi(const char *s, const char *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
|
|
|
@ -29,7 +29,7 @@ int tolower(int);
|
|||
int ispunct(int);
|
||||
int toupper(int);
|
||||
int hextoint(int);
|
||||
int cescapec(int);
|
||||
int _cescapec(int);
|
||||
|
||||
int iswalnum(wint_t);
|
||||
int iswalpha(wint_t);
|
||||
|
@ -141,13 +141,13 @@ char *strtok_r(char *, const char *, char **) paramsnonnull((2, 3));
|
|||
wchar_t *wcstok(wchar_t *, const wchar_t *, wchar_t **) paramsnonnull((2, 3));
|
||||
char *wstrtrunc(uint16_t *) memcpyesque;
|
||||
char *wstrntrunc(uint16_t *, size_t) memcpyesque;
|
||||
bool startswith(const char *, const char *) strlenesque;
|
||||
bool startswithi(const char *, const char *) strlenesque;
|
||||
bool startswith16(const char16_t *, const char16_t *) strlenesque;
|
||||
bool wcsstartswith(const wchar_t *, const wchar_t *) strlenesque;
|
||||
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;
|
||||
bool _startswith(const char *, const char *) strlenesque;
|
||||
bool _startswithi(const char *, const char *) strlenesque;
|
||||
bool _startswith16(const char16_t *, const char16_t *) strlenesque;
|
||||
bool _wcsstartswith(const wchar_t *, const wchar_t *) strlenesque;
|
||||
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 strverscmp(const char *, const char *);
|
||||
wchar_t *wmemset(wchar_t *, wchar_t, size_t) memcpyesque;
|
||||
|
@ -213,6 +213,8 @@ char *strsignal(int) returnsnonnull libcesque;
|
|||
char *strerror(int) returnsnonnull dontthrow nocallback;
|
||||
int strerror_r(int, char *, size_t) dontthrow nocallback;
|
||||
int strerror_wr(int, uint32_t, char *, size_t) dontthrow nocallback;
|
||||
char *_strerrno(int) nosideeffect libcesque;
|
||||
char *_strerdoc(int) nosideeffect libcesque;
|
||||
int __xpg_strerror_r(int, char *, size_t) dontthrow nocallback;
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "libc/intrin/pmovmskb.h"
|
||||
#include "libc/intrin/psubb.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/bsf.h"
|
||||
#include "libc/intrin/bsf.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/thompike.h"
|
||||
#include "libc/str/unicode.h"
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_THOMPIKE_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_THOMPIKE_H_
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
|
||||
#define ThomPikeCont(x) (0200 == (0300 & (x)))
|
||||
#define ThomPikeByte(x) ((x) & (((1 << ThomPikeMsb(x)) - 1) | 3))
|
||||
#define ThomPikeLen(x) (7 - ThomPikeMsb(x))
|
||||
#define ThomPikeMsb(x) ((255 & (x)) < 252 ? bsr(255 & ~(x)) : 1)
|
||||
#define ThomPikeMsb(x) ((255 & (x)) < 252 ? _bsr(255 & ~(x)) : 1)
|
||||
#define ThomPikeMerge(x, y) ((x) << 6 | 077 & (y))
|
||||
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_THOMPIKE_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_TPDECODECB_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_TPDECODECB_H_
|
||||
#include "libc/nexgen32e/bsr.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
/* TODO(jart): DELETE? */
|
||||
|
@ -19,7 +19,7 @@ forceinline int tpdecodecb(wint_t *out, int first,
|
|||
if ((wc = get(arg, i++)) == -1) return -1;
|
||||
}
|
||||
if (__builtin_expect(!(0 <= wc && wc <= 0x7F), 0)) {
|
||||
msb = wc < 252 ? bsr(~wc & 0xff) : 1;
|
||||
msb = wc < 252 ? _bsr(~wc & 0xff) : 1;
|
||||
need = 7 - msb;
|
||||
wc &= ((1u << msb) - 1) | 0b00000011;
|
||||
for (j = 1; j < need; ++j) {
|
||||
|
|
|
@ -1,22 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_TPENC_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_TPENC_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
uint64_t tpenc(int32_t) pureconst;
|
||||
|
||||
#if defined(__MNO_RED_ZONE__) && defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
#define tpenc(CODE) \
|
||||
({ \
|
||||
long Edi, Buf; \
|
||||
asm("call\ttpenc" \
|
||||
: "=a"(Buf), "=D"(Edi) \
|
||||
: "1"((int)(CODE)) \
|
||||
: "rcx", "rdx", "cc"); \
|
||||
Buf; \
|
||||
})
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_TPENC_H_ */
|
|
@ -16,8 +16,8 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/str/internal.h"
|
||||
#include "libc/str/tpenc.h"
|
||||
#include "libc/str/tpencode.internal.h"
|
||||
|
||||
/* TODO: DELETE */
|
||||
|
@ -47,7 +47,7 @@ unsigned(tpencode)(char *p, size_t size, wint_t wc, bool32 awesome) {
|
|||
return 2;
|
||||
}
|
||||
i = 0;
|
||||
w = tpenc(wc);
|
||||
w = _tpenc(wc);
|
||||
do {
|
||||
if (!size--) break;
|
||||
p[i++] = w & 0xff;
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include "libc/intrin/pandn.h"
|
||||
#include "libc/intrin/pcmpgtw.h"
|
||||
#include "libc/intrin/pmovmskb.h"
|
||||
#include "libc/intrin/tpenc.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};
|
||||
|
@ -74,7 +74,7 @@ axdx_t tprecode16to8(char *dst, size_t dstsize, const char16_t *src) {
|
|||
if (!(y = src[r.dx++])) break;
|
||||
x = MergeUtf16(x, y);
|
||||
}
|
||||
w = tpenc(x);
|
||||
w = _tpenc(x);
|
||||
while (w && r.ax + 1 < dstsize) {
|
||||
dst[r.ax++] = w & 0xFF;
|
||||
w >>= 8;
|
||||
|
|
|
@ -1,263 +0,0 @@
|
|||
/*-*- 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 │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/intrin/repmovsb.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/kompressor.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/undeflate.h"
|
||||
|
||||
#define kDeflateCompressionTypeNone 0b00
|
||||
#define kDeflateCompressionTypeFixedHuffman 0b01
|
||||
#define kDeflateCompressionTypeDynamicHuffman 0b10
|
||||
|
||||
#define kDeflateCodeLengthCopyPrevious3To6Times 16
|
||||
#define kDeflateCodeLengthRepeatZero3To10Times 17
|
||||
#define kDeflateCodeLengthRepeatZero11To138Times 18
|
||||
|
||||
#define CONSUME(BITS) \
|
||||
hold.word >>= BITS; \
|
||||
hold.bits -= BITS
|
||||
|
||||
#define MOAR(BITS) \
|
||||
while (hold.bits < BITS) { \
|
||||
al = *ip++; \
|
||||
hold.word |= (size_t)al << hold.bits; \
|
||||
hold.bits += 8; \
|
||||
}
|
||||
|
||||
struct DeflateHold {
|
||||
uint64_t word;
|
||||
size_t bits;
|
||||
};
|
||||
|
||||
static const struct DeflateConsts {
|
||||
uint16_t lenbase[32];
|
||||
uint16_t distbase[32];
|
||||
uint8_t lenbits[32];
|
||||
uint8_t distbits[32];
|
||||
uint8_t orders[19];
|
||||
struct RlDecode lensrl[6];
|
||||
} kDeflate = {
|
||||
{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27,
|
||||
31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258},
|
||||
{1, 2, 3, 4, 5, 7, 9, 13, 17, 25,
|
||||
33, 49, 65, 97, 129, 193, 257, 385, 513, 769,
|
||||
1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577},
|
||||
{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2,
|
||||
2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5},
|
||||
{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6,
|
||||
6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13},
|
||||
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15},
|
||||
{{144, 8}, {112, 9}, {24, 7}, {8, 8}, {32, 5}, {0, 0}},
|
||||
};
|
||||
|
||||
static uint32_t undeflatetree(struct DeflateState *ds, uint32_t *tree,
|
||||
const uint8_t *lens, size_t symcount) {
|
||||
size_t i, len;
|
||||
uint32_t code, slot;
|
||||
uint16_t codes[16], first[16], counts[16];
|
||||
bzero(counts, sizeof(counts));
|
||||
for (i = 0; i < symcount; i++) {
|
||||
counts[lens[i]]++;
|
||||
}
|
||||
codes[0] = 0;
|
||||
first[0] = 0;
|
||||
counts[0] = 0;
|
||||
for (i = 1; i < ARRAYLEN(codes); i++) {
|
||||
codes[i] = (codes[i - 1] + counts[i - 1]) << 1;
|
||||
first[i] = first[i - 1] + counts[i - 1];
|
||||
}
|
||||
assert(first[15] + counts[15] <= symcount);
|
||||
for (i = 0; i < symcount; i++) {
|
||||
if ((len = lens[i])) {
|
||||
code = codes[len]++;
|
||||
slot = first[len]++;
|
||||
tree[slot] = code << (32 - len) | i << 4 | len;
|
||||
}
|
||||
}
|
||||
return first[15];
|
||||
}
|
||||
|
||||
static struct DeflateHold undeflatesymbol(struct DeflateHold hold,
|
||||
const uint32_t *tree,
|
||||
size_t treecount,
|
||||
uint32_t *out_symbol) {
|
||||
size_t left, right, m;
|
||||
uint32_t search, key;
|
||||
left = 0;
|
||||
right = treecount;
|
||||
search = BITREVERSE16(hold.word);
|
||||
search <<= 16;
|
||||
search |= 0xffff;
|
||||
while (left < right) { /* TODO(jart): Make this O(1) like Zlib. */
|
||||
m = (left + right) >> 1;
|
||||
if (search < tree[m]) {
|
||||
right = m;
|
||||
} else {
|
||||
left = m + 1;
|
||||
}
|
||||
}
|
||||
key = tree[left - 1];
|
||||
assert(!((search ^ key) >> (32 - (key & 0xf))));
|
||||
*out_symbol = (key >> 4) & 0xfff;
|
||||
CONSUME(key & 0xf);
|
||||
return hold;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decompresses raw DEFLATE data.
|
||||
*
|
||||
* This is 10x smaller and 10x slower than chromium zlib.
|
||||
*
|
||||
* @param output should be followed by a single guard page, and have
|
||||
* 36kb of guard pages preceding it too because buffer overflows
|
||||
* are part of the design of this algorithm
|
||||
* @note h/t Phil Katz, David Huffman, Claude Shannon
|
||||
*/
|
||||
ssize_t undeflate(void *output, size_t outputsize, void *input,
|
||||
size_t inputsize, struct DeflateState *ds) {
|
||||
struct DeflateHold hold;
|
||||
bool isfinalblock;
|
||||
size_t i, nlit, ndist;
|
||||
uint8_t *ip, *ipe, *op, *si, b, al, last, compressiontype;
|
||||
uint32_t j, l, len, sym, tlit, tdist, tlen, nlen;
|
||||
|
||||
op = output;
|
||||
ip = input;
|
||||
ipe = ip + inputsize;
|
||||
hold.word = 0;
|
||||
hold.bits = 0;
|
||||
isfinalblock = 0;
|
||||
|
||||
while (!isfinalblock) {
|
||||
MOAR(3);
|
||||
isfinalblock = hold.word & 0b1;
|
||||
CONSUME(1);
|
||||
compressiontype = hold.word & 0b11;
|
||||
CONSUME(2);
|
||||
|
||||
switch (compressiontype) {
|
||||
case kDeflateCompressionTypeNone:
|
||||
CONSUME(hold.bits & 7);
|
||||
MOAR(32);
|
||||
len = hold.word & 0xffff;
|
||||
nlen = (hold.word >> 16) & 0xffff;
|
||||
assert(len == ~nlen);
|
||||
CONSUME(32);
|
||||
while (len--) {
|
||||
if (hold.bits) {
|
||||
*op++ = hold.word;
|
||||
CONSUME(8);
|
||||
} else {
|
||||
*op++ = *ip++;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case kDeflateCompressionTypeFixedHuffman:
|
||||
nlit = 288;
|
||||
ndist = 32;
|
||||
rldecode(ds->lens, kDeflate.lensrl);
|
||||
break;
|
||||
|
||||
case kDeflateCompressionTypeDynamicHuffman:
|
||||
MOAR(5 + 5 + 4);
|
||||
nlit = (hold.word & 0b11111) + 257;
|
||||
CONSUME(5);
|
||||
ndist = (hold.word & 0b11111) + 1;
|
||||
CONSUME(5);
|
||||
nlen = (hold.word & 0b1111) + 4;
|
||||
CONSUME(4);
|
||||
for (i = 0; i < nlen; i++) {
|
||||
MOAR(3);
|
||||
ds->lenlens[kDeflate.orders[i]] = hold.word & 0b111;
|
||||
CONSUME(3);
|
||||
}
|
||||
for (; i < ARRAYLEN(ds->lenlens); i++) {
|
||||
ds->lenlens[kDeflate.orders[i]] = 0;
|
||||
}
|
||||
tlen =
|
||||
undeflatetree(ds, ds->lencodes, ds->lenlens, ARRAYLEN(ds->lenlens));
|
||||
i = 0;
|
||||
last = 0;
|
||||
while (i < nlit + ndist) {
|
||||
MOAR(16);
|
||||
hold = undeflatesymbol(hold, ds->lencodes, tlen, &sym);
|
||||
b = 2;
|
||||
j = 1;
|
||||
switch (sym) {
|
||||
case kDeflateCodeLengthRepeatZero11To138Times:
|
||||
b += 4;
|
||||
j += 8;
|
||||
/* fallthrough */
|
||||
case kDeflateCodeLengthRepeatZero3To10Times:
|
||||
b += 1;
|
||||
last = 0;
|
||||
/* fallthrough */
|
||||
case kDeflateCodeLengthCopyPrevious3To6Times:
|
||||
MOAR(b);
|
||||
j += (hold.word & ((1u << b) - 1u)) + 2u;
|
||||
CONSUME(b);
|
||||
break;
|
||||
default:
|
||||
last = sym;
|
||||
break;
|
||||
}
|
||||
while (j--) {
|
||||
ds->lens[i++] = last;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
tlit = undeflatetree(ds, ds->litcodes, ds->lens, nlit);
|
||||
tdist = undeflatetree(ds, ds->distcodes, &ds->lens[nlit], ndist);
|
||||
|
||||
do {
|
||||
MOAR(16);
|
||||
hold = undeflatesymbol(hold, ds->litcodes, tlit, &sym);
|
||||
if (sym < 256) {
|
||||
*op++ = sym;
|
||||
} else if (sym > 256) {
|
||||
sym -= 257;
|
||||
b = kDeflate.lenbits[sym];
|
||||
MOAR(b);
|
||||
l = kDeflate.lenbase[sym] + (hold.word & ((1u << b) - 1));
|
||||
CONSUME(b);
|
||||
MOAR(16);
|
||||
hold = undeflatesymbol(hold, ds->distcodes, tdist, &sym);
|
||||
b = kDeflate.distbits[sym];
|
||||
MOAR(b);
|
||||
/* max readback: 24577 + 2**13-1 = 32768 */
|
||||
si = op - ((uint32_t)kDeflate.distbase[sym] +
|
||||
(uint32_t)(hold.word & ((1u << b) - 1)));
|
||||
CONSUME(b);
|
||||
repmovsb(&op, &si, l);
|
||||
}
|
||||
} while (sym != 256);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_UNDEFLATE_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_UNDEFLATE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
struct DeflateState {
|
||||
uint8_t lenlens[19];
|
||||
uint32_t lencodes[19];
|
||||
uint32_t distcodes[32];
|
||||
uint32_t litcodes[288];
|
||||
uint8_t lens[288 + 32];
|
||||
};
|
||||
|
||||
ssize_t undeflate(void *output, size_t outputsize, void *input,
|
||||
size_t inputsize, struct DeflateState *ds);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_UNDEFLATE_H_ */
|
|
@ -24,7 +24,7 @@
|
|||
* @param s is a NUL-terminated string
|
||||
* @param suffix is also NUL-terminated
|
||||
*/
|
||||
bool wcsendswith(const wchar_t *s, const wchar_t *suffix) {
|
||||
bool _wcsendswith(const wchar_t *s, const wchar_t *suffix) {
|
||||
size_t n, m;
|
||||
n = wcslen(s);
|
||||
m = wcslen(suffix);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* @param s is a NUL-terminated string
|
||||
* @param prefix is also NUL-terminated
|
||||
*/
|
||||
bool wcsstartswith(const wchar_t *s, const wchar_t *prefix) {
|
||||
bool _wcsstartswith(const wchar_t *s, const wchar_t *prefix) {
|
||||
for (;;) {
|
||||
if (!*prefix) return true;
|
||||
if (!*s) return false;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue