diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index ea4774c94..431b8a5b5 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -35,7 +35,6 @@ "returnstwice=", "textwindows=", "privileged=", - "compatfn=", "dontinstrument=", "nodebuginfo=", "interruptfn=", diff --git a/bin/aarch64-unknown-cosmo-nm b/bin/aarch64-unknown-cosmo-nm new file mode 100755 index 000000000..bd25f1b79 --- /dev/null +++ b/bin/aarch64-unknown-cosmo-nm @@ -0,0 +1,13 @@ +#!/bin/sh + +MODE=${MODE:-${m:-aarch64}} +COSMO=${COSMO:-/opt/cosmo} +COSMOS=${COSMOS:-/opt/cosmos/aarch64} +TOOL="$COSMO/o/third_party/gcc/bin/aarch64-linux-musl-nm" + +if [ ! -x "$TOOL" ]; then + echo "$0: you need to run: aarch64-unknown-cosmo-cc --update" >&2 + exit 1 +fi + +exec "$TOOL" "$@" diff --git a/bin/cosmocc b/bin/cosmocc index 5fe2dcc0d..32b7568e9 100755 --- a/bin/cosmocc +++ b/bin/cosmocc @@ -276,7 +276,7 @@ for x; do # information." set -- "$@" -momit-leaf-frame-pointer -foptimize-sibling-calls continue - elif [ x"$x" = x"-Werror" ] || \ + elif [ x"$x" != x"${x#-Werror}" ] || \ [ x"$x" = x"-pedantic-errors" ]; then # this toolchain is intended for building other people's code # elevating warnings into errors, should only be done by devs diff --git a/bin/x86_64-unknown-cosmo-nm b/bin/x86_64-unknown-cosmo-nm new file mode 100755 index 000000000..679370e60 --- /dev/null +++ b/bin/x86_64-unknown-cosmo-nm @@ -0,0 +1,13 @@ +#!/bin/sh + +MODE=${MODE:-$m} +COSMO=${COSMO:-/opt/cosmo} +COSMOS=${COSMOS:-/opt/cosmos} +TOOL="$COSMO/o/third_party/gcc/bin/x86_64-linux-musl-nm" + +if [ ! -x "$TOOL" ]; then + echo "$0: you need to run: x86_64-unknown-cosmo-cc --update" >&2 + exit 1 +fi + +exec "$TOOL" "$@" diff --git a/libc/fmt/conv.h b/libc/fmt/conv.h index 90e9ce4e1..75b0c2a5b 100644 --- a/libc/fmt/conv.h +++ b/libc/fmt/conv.h @@ -131,7 +131,7 @@ imaxdiv_t imaxdiv(intmax_t, intmax_t) pureconst; #endif #if (__GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__)) && \ - !defined(__STRICT_ANSI__) + !defined(__STRICT_ANSI__) && defined(_COSMO_SOURCE) int128_t i128abs(int128_t) libcesque pureconst; int128_t strtoi128(const char *, char **, int) paramsnonnull((1)); diff --git a/libc/fmt/itoa.h b/libc/fmt/itoa.h index c5bf541f8..725eee704 100644 --- a/libc/fmt/itoa.h +++ b/libc/fmt/itoa.h @@ -42,11 +42,6 @@ size_t uint64toarray_radix16(uint64_t, char[hasatleast 17]); size_t uint64toarray_fixed16(uint64_t, char[hasatleast 17], uint8_t); size_t uint64toarray_radix8(uint64_t, char[hasatleast 24]); -#ifndef __STRICT_ANSI__ -size_t int128toarray_radix10(int128_t, char *); -size_t uint128toarray_radix10(uint128_t, char *); -#endif - COSMOPOLITAN_C_END_ #endif /* _COSMO_SOURCE */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/fmt/itoa128radix10.greg.c b/libc/fmt/itoa128radix10.greg.c deleted file mode 100644 index bc884f542..000000000 --- a/libc/fmt/itoa128radix10.greg.c +++ /dev/null @@ -1,53 +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/fmt/conv.h" -#include "libc/fmt/itoa.h" -#include "libc/limits.h" -#include "libc/mem/reverse.internal.h" - -uint128_t __udivmodti4(uint128_t, uint128_t, uint128_t *); - -/** - * Converts unsigned 128-bit integer to string. - * @param a needs at least 40 bytes - * @return bytes written w/o nul - */ -dontinline size_t uint128toarray_radix10(uint128_t i, char *a) { - size_t j; - uint128_t rem; - j = 0; - do { - i = __udivmodti4(i, 10, &rem); - a[j++] = rem + '0'; - } while (i > 0); - a[j] = '\0'; - reverse(a, j); - return j; -} - -/** - * Converts signed 128-bit integer to string. - * @param a needs at least 41 bytes - * @return bytes written w/o nul - */ -size_t int128toarray_radix10(int128_t i, char *a) { - if (i >= 0) return uint128toarray_radix10(i, a); - *a++ = '-'; - return 1 + uint128toarray_radix10(-(uint128_t)i, a); -} diff --git a/libc/fmt/leb128.h b/libc/fmt/leb128.h index e062fa34b..e7a0175e7 100644 --- a/libc/fmt/leb128.h +++ b/libc/fmt/leb128.h @@ -4,15 +4,11 @@ #ifdef _COSMO_SOURCE COSMOPOLITAN_C_START_ -#define sleb64 __sleb64 -#define zleb64 __zleb64 -#define uleb64 __uleb64 -#define unzleb64 __unzleb64 -#define unuleb64 __unuleb64 -#define sleb128 __sleb128 -#define zleb128 __zleb128 -#define uleb128 __uleb128 -#define unsleb128 __unsleb128 +#define sleb64 __sleb64 +#define zleb64 __zleb64 +#define uleb64 __uleb64 +#define unzleb64 __unzleb64 +#define unuleb64 __unuleb64 char *sleb64(char *, int64_t); char *zleb64(char[hasatleast 10], int64_t); @@ -20,13 +16,6 @@ char *uleb64(char[hasatleast 10], uint64_t); int unzleb64(const char *, size_t, int64_t *); int unuleb64(char *, size_t, uint64_t *); -#ifndef __STRICT_ANSI__ -char *sleb128(char *, int128_t); -char *zleb128(char *, int128_t); -char *uleb128(char *, uint128_t); -int unsleb128(const void *, size_t, int128_t *); -#endif /* __STRICT_ANSI__ */ - COSMOPOLITAN_C_END_ #endif /* _COSMO_SOURCE */ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/libc/fmt/sleb128.c b/libc/fmt/sleb128.c deleted file mode 100644 index c2d65908b..000000000 --- a/libc/fmt/sleb128.c +++ /dev/null @@ -1,36 +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/fmt/leb128.h" - -/** - * Encodes signed leb128 integer. - */ -char *sleb128(char *p, int128_t x) { - int c; - for (;;) { - c = x & 127; - x >>= 7; - if ((x == 0 && !(c & 64)) || (x == -1 && (c & 64))) { - *p++ = c; - return p; - } else { - *p++ = c | 128; - } - } -} diff --git a/libc/fmt/strtoi128.c b/libc/fmt/strtoi128.c deleted file mode 100644 index b8caa1502..000000000 --- a/libc/fmt/strtoi128.c +++ /dev/null @@ -1,61 +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/errno.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/strtol.internal.h" -#include "libc/limits.h" -#include "libc/stdckdint.h" -#include "libc/str/str.h" -#include "libc/str/tab.internal.h" - -/** - * Decodes 128-bit signed integer from ASCII string. - * - * @param s is a non-null nul-terminated string - * @param endptr if non-null will always receive a pointer to the char - * following the last one this function processed, which is usually - * the NUL byte, or in the case of invalid strings, would point to - * the first invalid character - * @param base can be anywhere between [2,36] or 0 to auto-detect based - * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or - * decimal (base 10) by default - * @return decoded saturated integer - * @see strtou128() - */ -int128_t strtoi128(const char *s, char **endptr, int base) { - char t = 0; - int d, c = *s; - int128_t x = 0; - CONSUME_SPACES(s, c); - GET_SIGN(s, c, d); - GET_RADIX(s, c, base); - if ((c = kBase36[c & 255]) && --c < base) { - if (!((t |= 1) & 2)) { - do { - if (ckd_mul(&x, x, base) || ckd_add(&x, x, c * d)) { - x = d > 0 ? INT128_MAX : INT128_MIN; - errno = ERANGE; - t |= 2; - } - } while ((c = kBase36[*++s & 255]) && --c < base); - } - } - if (t && endptr) *endptr = s; - return x; -} diff --git a/libc/fmt/strtou128.c b/libc/fmt/strtou128.c deleted file mode 100644 index 1dd25cf88..000000000 --- a/libc/fmt/strtou128.c +++ /dev/null @@ -1,54 +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/fmt/conv.h" -#include "libc/fmt/strtol.internal.h" -#include "libc/str/str.h" -#include "libc/str/tab.internal.h" - -/** - * Decodes 128-bit unsigned integer from ASCII string. - * - * @param s is a non-null nul-terminated string - * @param endptr if non-null will always receive a pointer to the char - * following the last one this function processed, which is usually - * the NUL byte, or in the case of invalid strings, would point to - * the first invalid character - * @param base can be anywhere between [2,36] or 0 to auto-detect based - * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or - * decimal (base 10) by default - * @return decoded integer mod 2¹²⁸ negated if leading `-` - * @see strtoi128() - */ -uint128_t strtou128(const char *s, char **endptr, int base) { - char t = 0; - int d, c = *s; - uint128_t x = 0; - CONSUME_SPACES(s, c); - GET_SIGN(s, c, d); - GET_RADIX(s, c, base); - if ((c = kBase36[c & 255]) && --c < base) { - t |= 1; - do { - x *= base; - x += c; - } while ((c = kBase36[*++s & 255]) && --c < base); - } - if (t && endptr) *endptr = s; - return d > 0 ? x : -x; -} diff --git a/libc/fmt/uleb128.c b/libc/fmt/uleb128.c deleted file mode 100644 index 3fb3418b0..000000000 --- a/libc/fmt/uleb128.c +++ /dev/null @@ -1,35 +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/fmt/leb128.h" - -/** - * Encodes unsigned leb128 integer. - */ -char *uleb128(char *p, uint128_t x) { - int c; - for (;;) { - c = x & 127; - if (!(x >>= 7)) { - *p++ = c; - return p; - } else { - *p++ = c | 128; - } - } -} diff --git a/libc/fmt/unsleb128.c b/libc/fmt/unsleb128.c deleted file mode 100644 index 90cfe1fa6..000000000 --- a/libc/fmt/unsleb128.c +++ /dev/null @@ -1,44 +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/fmt/leb128.h" - -/** - * Decodes a GNU-style varint from a buffer. - * - * The GNU Assembler is able to encode numbers this way, since it's used - * by the DWARF debug format. - */ -int unsleb128(const void *buf, size_t size, int128_t *out) { - int b; - int128_t r, w; - unsigned char c; - const unsigned char *p, *pe; - pe = (p = buf) + size; - r = b = 0; - do { - if (size && p == pe) return -1; - c = *p++; - w = c & 0x7f; - r |= w << b; - b += 7; - } while (c & 0x80); - if (c & 0x40) r |= -1ull << b; - if (out) *out = r; - return p - (const unsigned char *)buf; -} diff --git a/libc/fmt/wcstoi128.c b/libc/fmt/wcstoi128.c deleted file mode 100644 index 0aa453c8f..000000000 --- a/libc/fmt/wcstoi128.c +++ /dev/null @@ -1,61 +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/errno.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/strtol.internal.h" -#include "libc/limits.h" -#include "libc/stdckdint.h" -#include "libc/str/str.h" -#include "libc/str/tab.internal.h" - -/** - * Decodes 128-bit signed integer from wide string. - * - * @param s is a non-null nul-terminated string - * @param endptr if non-null will always receive a pointer to the char - * following the last one this function processed, which is usually - * the NUL byte, or in the case of invalid strings, would point to - * the first invalid character - * @param base can be anywhere between [2,36] or 0 to auto-detect based - * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or - * decimal (base 10) by default - * @return decoded saturated integer - * @see strtou128() - */ -int128_t wcstoi128(const wchar_t *s, wchar_t **endptr, int base) { - char t = 0; - int128_t x = 0; - int d, c = *s; - CONSUME_SPACES(s, c); - GET_SIGN(s, c, d); - GET_RADIX(s, c, base); - if ((c = kBase36[c & 255]) && --c < base) { - if (!((t |= 1) & 2)) { - do { - if (ckd_mul(&x, x, base) || ckd_add(&x, x, c * d)) { - x = d > 0 ? INT128_MAX : INT128_MIN; - errno = ERANGE; - t |= 2; - } - } while ((c = kBase36[*++s & 255]) && --c < base); - } - } - if (t && endptr) *endptr = s; - return x; -} diff --git a/libc/fmt/wcstou128.c b/libc/fmt/wcstou128.c deleted file mode 100644 index 2d2fa01d1..000000000 --- a/libc/fmt/wcstou128.c +++ /dev/null @@ -1,54 +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/fmt/conv.h" -#include "libc/fmt/strtol.internal.h" -#include "libc/str/str.h" -#include "libc/str/tab.internal.h" - -/** - * Decodes 128-bit unsigned integer from wide string. - * - * @param s is a non-null nul-terminated string - * @param endptr if non-null will always receive a pointer to the char - * following the last one this function processed, which is usually - * the NUL byte, or in the case of invalid strings, would point to - * the first invalid character - * @param base can be anywhere between [2,36] or 0 to auto-detect based - * on the the prefixes 0 (octal), 0x (hexadecimal), 0b (binary), or - * decimal (base 10) by default - * @return decoded integer mod 2¹²⁸ negated if leading `-` - * @see strtoi128() - */ -uint128_t wcstou128(const wchar_t *s, wchar_t **endptr, int base) { - char t = 0; - int d, c = *s; - uint128_t x = 0; - CONSUME_SPACES(s, c); - GET_SIGN(s, c, d); - GET_RADIX(s, c, base); - if ((c = kBase36[c & 255]) && --c < base) { - t |= 1; - do { - x *= base; - x += c; - } while ((c = kBase36[*++s & 255]) && --c < base); - } - if (t && endptr) *endptr = s; - return d > 0 ? x : -x; -} diff --git a/libc/fmt/zleb128.c b/libc/fmt/zleb128.c deleted file mode 100644 index fa3b232c3..000000000 --- a/libc/fmt/zleb128.c +++ /dev/null @@ -1,39 +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/fmt/leb128.h" - -/** - * Encodes signed integer to array. - */ -char *zleb128(char *p, int128_t x) { - int c; - uint128_t u; - u = x; - u <<= 1; - u ^= x >> 127; - for (;;) { - c = u & 127; - if (!(u >>= 7)) { - *p++ = c; - return p; - } else { - *p++ = c | 128; - } - } -} diff --git a/libc/integral/c.inc b/libc/integral/c.inc index 7113129e4..b8e6bdbfd 100644 --- a/libc/integral/c.inc +++ b/libc/integral/c.inc @@ -130,12 +130,14 @@ typedef __UINT64_TYPE__ uint64_t; typedef __INTMAX_TYPE__ intmax_t; typedef __UINTMAX_TYPE__ uintmax_t; +#ifdef _COSMO_SOURCE #if ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406 || \ defined(__llvm__)) && \ !defined(__STRICT_ANSI__) typedef signed __int128 int128_t; typedef unsigned __int128 uint128_t; #endif +#endif /* _COSMO_SOURCE */ typedef struct { intptr_t ax, dx; } axdx_t; @@ -196,23 +198,6 @@ typedef struct { _Section(".privileged") dontinline dontinstrument dontubsan dontasan #endif -#ifndef dontinstrument -#if !defined(__STRICT_ANSI__) && \ - (__has_attribute(__no_instrument_function__) || \ - (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 204) -#if ((__GNUC__ + 0) >= 7 && !defined(__chibicc__)) || \ - __has_attribute(__patchable_function_entry__) -#define dontinstrument \ - __attribute__((__no_instrument_function__, \ - __patchable_function_entry__(0, 0))) -#else -#define dontinstrument __attribute__((__no_instrument_function__)) -#endif -#else -#define dontinstrument -#endif -#endif - #ifndef wontreturn #if !defined(__STRICT_ANSI__) && \ (__has_attribute(__noreturn__) || \ @@ -283,16 +268,6 @@ typedef struct { #endif /* __cplusplus */ #endif /* forceinline */ -#ifndef mayalias -#if !defined(__STRICT_ANSI__) && \ - (__has_attribute(__may_alias__) || \ - (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303) -#define mayalias __attribute__((__may_alias__)) -#else -#define mayalias -#endif -#endif - #ifndef dontdiscard #if !defined(__STRICT_ANSI__) && \ ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 304 || \ @@ -414,53 +389,6 @@ typedef struct { #endif #endif -#ifndef dontoptimize -#ifndef __STRICT_ANSI__ -#if defined(__llvm__) || __has_attribute(__optnone__) -#define dontoptimize __attribute__((__optnone__)) -#elif (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ - __has_attribute(__optimize__) -#define dontoptimize __attribute__((__optimize__(0))) -#endif -#else -#define dontoptimize -#endif -#endif - -#ifndef optimizesize -#ifndef __STRICT_ANSI__ -#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ - __has_attribute(__optimize__) -#define optimizesize __attribute__((__optimize__("s"))) -#elif defined(__llvm__) || __has_attribute(__optnone__) -#define optimizesize __attribute__((__optnone__)) -#endif -#else -#define optimizesize -#endif -#endif - -#ifndef optimizespeed -/* warning: corrupts frame pointer; only use on leaf functions */ -#if !defined(__STRICT_ANSI__) && \ - ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ - __has_attribute(__optimize__)) -#define optimizespeed __attribute__((__optimize__(3))) -#else -#define optimizespeed -#endif -#endif - -#ifndef unrollloops -#if !defined(__STRICT_ANSI__) && \ - ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ - __has_attribute(__optimize__)) -#define unrollloops __attribute__((__optimize__("unroll-loops"))) -#else -#define unrollloops -#endif -#endif - #ifndef returnstwice #if !defined(__STRICT_ANSI__) && \ (__has_attribute(__returns_twice__) || \ @@ -480,16 +408,6 @@ typedef struct { #endif #endif -#ifndef _Microarchitecture -#if !defined(__STRICT_ANSI__) && \ - (__has_attribute(__target__) || \ - (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 404) -#define _Microarchitecture(march) __attribute__((__target__(march))) -#else -#define _Microarchitecture(march) -#endif -#endif - #if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 408 || \ __has_attribute(__force_align_arg_pointer__) #define forcealignargpointer __attribute__((__force_align_arg_pointer__)) @@ -557,6 +475,99 @@ typedef struct { #define autotype(x) typeof(x) #endif +#if defined(__STRICT_ANSI__) || \ + (!defined(__GNUC__) && !defined(__builtin_offsetof)) +#define offsetof(type, member) ((unsigned long)&((type *)0)->member) +#else +#define offsetof(type, member) __builtin_offsetof(type, member) +#endif + +#ifdef _COSMO_SOURCE + +#ifndef dontinstrument +#if !defined(__STRICT_ANSI__) && \ + (__has_attribute(__no_instrument_function__) || \ + (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 204) +#if ((__GNUC__ + 0) >= 7 && !defined(__chibicc__)) || \ + __has_attribute(__patchable_function_entry__) +#define dontinstrument \ + __attribute__((__no_instrument_function__, \ + __patchable_function_entry__(0, 0))) +#else +#define dontinstrument __attribute__((__no_instrument_function__)) +#endif +#else +#define dontinstrument +#endif +#endif + +#ifndef mayalias +#if !defined(__STRICT_ANSI__) && \ + (__has_attribute(__may_alias__) || \ + (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303) +#define mayalias __attribute__((__may_alias__)) +#else +#define mayalias +#endif +#endif + +#ifndef dontoptimize +#ifndef __STRICT_ANSI__ +#if defined(__llvm__) || __has_attribute(__optnone__) +#define dontoptimize __attribute__((__optnone__)) +#elif (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ + __has_attribute(__optimize__) +#define dontoptimize __attribute__((__optimize__(0))) +#endif +#else +#define dontoptimize +#endif +#endif + +#ifndef optimizesize +#ifndef __STRICT_ANSI__ +#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ + __has_attribute(__optimize__) +#define optimizesize __attribute__((__optimize__("s"))) +#elif defined(__llvm__) || __has_attribute(__optnone__) +#define optimizesize __attribute__((__optnone__)) +#endif +#else +#define optimizesize +#endif +#endif + +#ifndef optimizespeed +/* warning: corrupts frame pointer; only use on leaf functions */ +#if !defined(__STRICT_ANSI__) && \ + ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ + __has_attribute(__optimize__)) +#define optimizespeed __attribute__((__optimize__(3))) +#else +#define optimizespeed +#endif +#endif + +#ifndef unrollloops +#if !defined(__STRICT_ANSI__) && \ + ((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \ + __has_attribute(__optimize__)) +#define unrollloops __attribute__((__optimize__("unroll-loops"))) +#else +#define unrollloops +#endif +#endif + +#ifndef _Microarchitecture +#if !defined(__STRICT_ANSI__) && \ + (__has_attribute(__target__) || \ + (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 404) +#define _Microarchitecture(march) __attribute__((__target__(march))) +#else +#define _Microarchitecture(march) +#endif +#endif + #ifdef __x86_64__ #if __GNUC__ >= 7 || __has_attribute(__no_caller_saved_registers__) #define nocallersavedregisters __attribute__((__no_caller_saved_registers__)) @@ -604,6 +615,12 @@ void abort(void) wontreturn; do { \ } while (0) +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +#define _Vector_size(k) __attribute__((__vector_size__(k))) +#else +#define _Vector_size(k) [k] +#endif + #ifndef __STRICT_ANSI__ #define textstartup _Section(".text.startup") #define textexit _Section(".text.exit") @@ -620,27 +637,6 @@ void abort(void) wontreturn; #define antiquity #endif -#ifndef compatfn -#define compatfn -#endif - -#ifndef frownedupon -#define frownedupon(alternative) -#endif - -#if defined(__GNUC__) && !defined(__STRICT_ANSI__) -#define _Vector_size(k) __attribute__((__vector_size__(k))) -#else -#define _Vector_size(k) [k] -#endif - -#if defined(__STRICT_ANSI__) || \ - (!defined(__GNUC__) && !defined(__builtin_offsetof)) -#define offsetof(type, member) ((unsigned long)&((type *)0)->member) -#else -#define offsetof(type, member) __builtin_offsetof(type, member) -#endif - #ifdef __llvm__ #define __builtin_ia32_movntdq(x, y) (*(x) = (y)) #endif @@ -761,6 +757,8 @@ void abort(void) wontreturn; #define DebugBreak() (void)0 #endif +#endif /* _COSMO_SOURCE */ + #ifndef __STRICT_ANSI__ #define __veil(CONSTRAINT, EXPRESSION) \ ({ \ diff --git a/libc/isystem/cosmo.h b/libc/isystem/cosmo.h index 4cf250d90..462e3aced 100644 --- a/libc/isystem/cosmo.h +++ b/libc/isystem/cosmo.h @@ -1,5 +1,6 @@ #ifndef _COSMO_H #define _COSMO_H +#include "libc/stdbool.h" #ifdef _COSMO_SOURCE #define COSMO_ALREADY_DEFINED diff --git a/libc/isystem/sys/procfs.h b/libc/isystem/sys/procfs.h new file mode 100644 index 000000000..11b6ad0d4 --- /dev/null +++ b/libc/isystem/sys/procfs.h @@ -0,0 +1,60 @@ +#ifndef _SYS_PROCFS_H +#define _SYS_PROCFS_H +#include +#ifdef __cplusplus +extern "C" { +#endif + +struct elf_siginfo { + int si_signo; + int si_code; + int si_errno; +}; + +struct elf_prstatus { + struct elf_siginfo pr_info; + short int pr_cursig; + unsigned long int pr_sigpend; + unsigned long int pr_sighold; + pid_t pr_pid; + pid_t pr_ppid; + pid_t pr_pgrp; + pid_t pr_sid; + struct { + long tv_sec, tv_usec; + } pr_utime, pr_stime, pr_cutime, pr_cstime; + elf_gregset_t pr_reg; + int pr_fpvalid; +}; + +#define ELF_PRARGSZ 80 + +struct elf_prpsinfo { + char pr_state; + char pr_sname; + char pr_zomb; + char pr_nice; + unsigned long int pr_flag; +#if UINTPTR_MAX == 0xffffffff + unsigned short int pr_uid; + unsigned short int pr_gid; +#else + unsigned int pr_uid; + unsigned int pr_gid; +#endif + int pr_pid, pr_ppid, pr_pgrp, pr_sid; + char pr_fname[16]; + char pr_psargs[ELF_PRARGSZ]; +}; + +typedef void *psaddr_t; +typedef elf_gregset_t prgregset_t; +typedef elf_fpregset_t prfpregset_t; +typedef pid_t lwpid_t; +typedef struct elf_prstatus prstatus_t; +typedef struct elf_prpsinfo prpsinfo_t; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libc/isystem/sys/user.h b/libc/isystem/sys/user.h new file mode 100644 index 000000000..99b5f8212 --- /dev/null +++ b/libc/isystem/sys/user.h @@ -0,0 +1,77 @@ +#ifndef _SYS_USER_H +#define _SYS_USER_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __x86_64__ + +#undef __WORDSIZE +#define __WORDSIZE 64 + +typedef struct user_fpregs_struct { + uint16_t cwd, swd, ftw, fop; + uint64_t rip, rdp; + uint32_t mxcsr, mxcr_mask; + uint32_t st_space[32], xmm_space[64], padding[24]; +} elf_fpregset_t; + +struct user_regs_struct { + unsigned long r15, r14, r13, r12, rbp, rbx, r11, r10, r9, r8; + unsigned long rax, rcx, rdx, rsi, rdi, orig_rax, rip; + unsigned long cs, eflags, rsp, ss, fs_base, gs_base, ds, es, fs, gs; +}; +#define ELF_NGREG 27 +typedef unsigned long long elf_greg_t, elf_gregset_t[ELF_NGREG]; + +struct user { + struct user_regs_struct regs; + int u_fpvalid; + struct user_fpregs_struct i387; + unsigned long u_tsize; + unsigned long u_dsize; + unsigned long u_ssize; + unsigned long start_code; + unsigned long start_stack; + long signal; + int reserved; + struct user_regs_struct *u_ar0; + struct user_fpregs_struct *u_fpstate; + unsigned long magic; + char u_comm[32]; + unsigned long u_debugreg[8]; +}; + +#define PAGE_MASK (~(4096 - 1)) +#define NBPG 4096 +#define UPAGES 1 +#define HOST_TEXT_START_ADDR (u.start_code) +#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) + +#elif defined(__aarch64__) + +struct user_regs_struct { + unsigned long long regs[31]; + unsigned long long sp; + unsigned long long pc; + unsigned long long pstate; +}; + +struct user_fpsimd_struct { + unsigned __int128 vregs[32]; + unsigned int fpsr; + unsigned int fpcr; +}; + +#define ELF_NREG 34 +typedef unsigned long elf_greg_t, elf_gregset_t[ELF_NREG]; +typedef struct user_fpsimd_struct elf_fpregset_t; + +#else +#error "unsupported architecture" +#endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libc/limits.h b/libc/limits.h index 458dc7348..92b8d6750 100644 --- a/libc/limits.h +++ b/libc/limits.h @@ -79,6 +79,7 @@ #define MB_CUR_MAX 4 #define MB_LEN_MAX 4 +#ifdef _COSMO_SOURCE #if __GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__) #define INT128_MIN (-INT128_MAX - 1) #define UINT128_MIN ((uint128_t)0) @@ -87,6 +88,7 @@ #define UINT128_MAX \ ((uint128_t)0xffffffffffffffff << 64 | (uint128_t)0xffffffffffffffff) #endif /* GCC 4.6+ */ +#endif /* _COSMO_SOURCE */ #define SIG_ATOMIC_MIN INT32_MIN #define SIG_ATOMIC_MAX INT32_MAX diff --git a/libc/literal.h b/libc/literal.h index 9f7184db8..87cc05893 100644 --- a/libc/literal.h +++ b/libc/literal.h @@ -30,12 +30,4 @@ #define UINTMAX_C(c) c##ULL #endif -#if __SIZEOF_INTMAX__ == 16 -#define INT128_C(c) ((intmax_t)(c)) -#define UINT128_C(c) ((uintmax_t)(c)) -#elif __SIZEOF_INTMAX__ == 8 -#define INT128_C(c) __INT64_C(c) -#define UINT128_C(c) __UINT64_C(c) -#endif - #endif /* COSMOPOLITAN_LIBC_LITERAL_H_ */ diff --git a/libc/math.h b/libc/math.h index 45d7ba16d..fbd4d9347 100644 --- a/libc/math.h +++ b/libc/math.h @@ -6,7 +6,6 @@ #define M_E 2.7182818284590452354 /* 𝑒 */ #define M_LOG2_10 0xd.49a784bcd1b8afep-2 /* log₂10 ≈ 3.3219280948873623478 */ -#define M_LOG10_2 0x9.a209a84fbcff799p-5 /* log₁₀2 ≈ 0.301029995663981195 */ #define M_LOG2E 0xb.8aa3b295c17f0bcp-3 /* log₂𝑒 ≈ 1.4426950408889634074 */ #define M_LOG10E 0.43429448190325182765 /* log₁₀𝑒 */ #define M_LN2 0xb.17217f7d1cf79acp-4 /* logₑ2 ≈ */ diff --git a/libc/stdio/vcscanf.c b/libc/stdio/vcscanf.c index 3094f7dac..a6e865b6b 100644 --- a/libc/stdio/vcscanf.c +++ b/libc/stdio/vcscanf.c @@ -18,7 +18,6 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/fmt/conv.h" #include "libc/fmt/fmt.h" -#include "libc/intrin/kprintf.h" #include "libc/intrin/weaken.h" #include "libc/mem/mem.h" #include "libc/runtime/runtime.h" @@ -101,7 +100,7 @@ int __vcscanf(int callback(void *), // bool discard = false; for (;;) { switch (p[i++]) { - case '%': /* %% → % */ + case '%': // %% → % goto NonDirectiveCharacter; case '0': case '1': @@ -134,56 +133,48 @@ int __vcscanf(int callback(void *), // case '\'': thousands = true; break; - case 'j': /* j=64-bit jj=128-bit */ + case 'j': // j=64-bit jj=128-bit if (bits < 64) { bits = 64; } else { bits = 128; } break; - case 'l': /* long */ - case 'L': /* loooong */ + case 'l': // long + case 'L': // loooong charbytes = sizeof(wchar_t); - /* fallthrough */ - case 't': /* ptrdiff_t */ - case 'Z': /* size_t */ - case 'z': /* size_t */ + // fallthrough + case 't': // ptrdiff_t + case 'Z': // size_t + case 'z': // size_t bits = 64; break; - case 'h': /* short and char */ + case 'h': // short and char charbytes = sizeof(char16_t); bits >>= 1; break; - case 'b': /* binary */ + case 'b': // binary base = 2; prefix = 'b'; while (isspace(c)) { c = READ; } goto ConsumeBasePrefix; - case 'p': /* pointer (NexGen32e) */ + case 'p': // pointer bits = 48; - while (isspace(c)) { - c = READ; - } - /* fallthrough */ + // fallthrough case 'x': - case 'X': /* hexadecimal */ + case 'X': // hexadecimal base = 16; prefix = 'x'; while (isspace(c)) { c = READ; } goto ConsumeBasePrefix; - case 'o': /* octal */ + case 'o': // octal base = 8; - while (isspace(c)) { - c = READ; - } - goto DecodeNumber; - case 'n': - goto ReportConsumed; - case 'd': // decimal + goto SetupNumber; + case 'i': // flexidecimal issigned = true; while (isspace(c)) { c = READ; @@ -191,12 +182,38 @@ int __vcscanf(int callback(void *), // if (c == '+' || (isneg = c == '-')) { c = READ; } + if (c == '0') { + c = READ; + if (c == -1) { + number = 0; + goto GotNumber; + } + if (c == 'x' || c == 'X') { + c = READ; + base = 16; + } else if (c == 'b' || c == 'B') { + base = 2; + } else { + base = 8; + } + } else { + base = 10; + } + goto DecodeNumber; + case 'n': + goto ReportConsumed; + case 'd': // decimal + issigned = true; // fallthrough case 'u': base = 10; + SetupNumber: while (isspace(c)) { c = READ; } + if (c == '+' || (isneg = c == '-')) { + c = READ; + } goto DecodeNumber; default: items = einval(); @@ -217,7 +234,7 @@ int __vcscanf(int callback(void *), // } } DecodeNumber: - if (c != -1) { + if (c != -1 && kBase36[(unsigned char)c] <= base) { number = 0; width = !width ? bits : width; do { @@ -227,15 +244,16 @@ int __vcscanf(int callback(void *), // number *= base; number += diglet - 1; } else if (thousands && diglet == ',') { - /* ignore */ + // ignore } else { break; } } while ((c = READ) != -1 && width > 0); + GotNumber: if (!discard) { uint128_t bane = (uint128_t)1 << (bits - 1); if (!(number & ~((bane - 1) | (issigned ? 0 : bane))) || - (issigned && number == bane /* two's complement bane */)) { + (issigned && number == bane)) { ++items; } else { items = erange(); diff --git a/libc/stdio/vsnprintf.c b/libc/stdio/vsnprintf.c index aa85a6b98..dfed1ed20 100644 --- a/libc/stdio/vsnprintf.c +++ b/libc/stdio/vsnprintf.c @@ -16,6 +16,7 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/dce.h" #include "libc/fmt/fmt.h" #include "libc/limits.h" @@ -46,8 +47,7 @@ static int vsnprintfputchar(const char *s, struct SprintfStr *t, size_t n) { /** * Formats string to buffer w/ preexisting vararg state. * - * @param buf stores output and a NUL-terminator is always written, - * provided buf!=NULL && size!=0 + * @param buf stores output * @param size is byte capacity buf * @return number of bytes written, excluding the NUL terminator; or, * if the output buffer wasn't passed, or was too short, then the @@ -58,7 +58,8 @@ static int vsnprintfputchar(const char *s, struct SprintfStr *t, size_t n) { */ int vsnprintf(char *buf, size_t size, const char *fmt, va_list va) { struct SprintfStr str = {buf, 0, size}; - __fmt(vsnprintfputchar, &str, fmt, va); + int rc = __fmt(vsnprintfputchar, &str, fmt, va); + if (rc < 0) return rc; if (str.n) str.p[MIN(str.i, str.n - 1)] = '\0'; return str.i; } diff --git a/libc/sysv/consts/ok.h b/libc/sysv/consts/ok.h index bfc398cfc..c043e7299 100644 --- a/libc/sysv/consts/ok.h +++ b/libc/sysv/consts/ok.h @@ -9,8 +9,8 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern const unsigned X_OK; -extern const unsigned W_OK; +extern const int X_OK; +extern const int W_OK; extern const unsigned R_OK; /* warning: is sign bit on windows */ COSMOPOLITAN_C_END_ diff --git a/test/libc/fmt/atoi_test.c b/test/libc/fmt/atoi_test.c index a7d2c0780..7d8c30b89 100644 --- a/test/libc/fmt/atoi_test.c +++ b/test/libc/fmt/atoi_test.c @@ -306,37 +306,12 @@ TEST(strtoimax, testEndPtr) { ASSERT_EQ(1, e - p); } -TEST(strtoi128, testLimits) { - EXPECT_EQ( - ((uint128_t)0xffffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff, - strtoi128("-1", NULL, 0)); - EXPECT_EQ( - ((uint128_t)0x7fffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff, - strtoi128("0x7fffffffffffffffffffffffffffffff", NULL, 0)); -} - -TEST(strtoi128, testOutsideLimit) { - errno = 0; - EXPECT_EQ( - ((uint128_t)0x7fffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff, - strtoi128("0x80000000000000000000000000000000", NULL, 0)); - EXPECT_EQ(ERANGE, errno); - errno = 0; - EXPECT_EQ(((uint128_t)0x8000000000000000) << 64 | 0x0000000000000000, - strtoi128("-0x80000000000000000000000000000001", NULL, 0)); - EXPECT_EQ(ERANGE, errno); -} - TEST(strtoul, neghex) { errno = 0; ASSERT_EQ(-16, (long)strtoul("0xfffffffffffffff0", NULL, 0)); EXPECT_EQ(0, errno); } -TEST(strtoumax, testZero) { - EXPECT_EQ(UINTMAX_MIN, strtoumax("0", NULL, 0)); - EXPECT_EQ(UINT128_MIN, strtou128("0", NULL, 0)); -} TEST(strtoumax, testDecimal) { EXPECT_EQ(123, strtoumax("123", NULL, 0)); EXPECT_EQ(-123, strtoumax("-123", NULL, 0)); @@ -354,18 +329,6 @@ TEST(strtoumax, testBinary) { EXPECT_EQ(42, strtoumax("0b101010", NULL, 2)); } -TEST(strtou128, test128imum) { - EXPECT_EQ(UINT128_MAX, - strtou128("340282366920938463463374607431768211455", NULL, 0)); - EXPECT_EQ(UINT128_MAX, - strtou128("0xffffffffffffffffffffffffffffffff", NULL, 0)); -} - -TEST(strtou128, testTwosBane) { - EXPECT_EQ(((uint128_t)0x8000000000000000) << 64 | 0x0000000000000000, - strtou128("0x80000000000000000000000000000000", NULL, 0)); -} - TEST(wcstol, test) { EXPECT_EQ(0, wcstol(L"", 0, 10)); EXPECT_EQ(0, wcstol(L"0", 0, 10)); @@ -591,12 +554,4 @@ BENCH(atoi, bench) { __expropriate(wcstoimax(__veil("r", L"100000000"), 0, 10))); EZBENCH2("wcstoumax 10⁸", donothing, __expropriate(wcstoimax(__veil("r", L"100000000"), 0, 10))); - EZBENCH2("strtoi128 10⁸", donothing, - __expropriate(strtoi128(__veil("r", "100000000"), 0, 10))); - EZBENCH2("strtou128 10⁸", donothing, - __expropriate(strtoi128(__veil("r", "100000000"), 0, 10))); - EZBENCH2("wcstoi128 10⁸", donothing, - __expropriate(wcstoi128(__veil("r", L"100000000"), 0, 10))); - EZBENCH2("wcstou128 10⁸", donothing, - __expropriate(wcstoi128(__veil("r", L"100000000"), 0, 10))); } diff --git a/test/libc/fmt/formatint64_test.c b/test/libc/fmt/formatint64_test.c index 533789f54..d709dfd6f 100644 --- a/test/libc/fmt/formatint64_test.c +++ b/test/libc/fmt/formatint64_test.c @@ -48,26 +48,6 @@ TEST(FormatUint64, test) { EXPECT_STREQ("9223372036854775808", buf); } -TEST(int128toarray_radix10, test) { - char buf[41]; - EXPECT_EQ(1, int128toarray_radix10(0, buf)); - EXPECT_STREQ("0", buf); - EXPECT_EQ(39, int128toarray_radix10(INT128_MAX, buf)); - EXPECT_STREQ("170141183460469231731687303715884105727", buf); - EXPECT_EQ(40, int128toarray_radix10(INT128_MIN, buf)); - EXPECT_STREQ("-170141183460469231731687303715884105728", buf); -} - -TEST(uint128toarray_radix10, test) { - char buf[40]; - EXPECT_EQ(1, uint128toarray_radix10(0, buf)); - EXPECT_STREQ("0", buf); - EXPECT_EQ(39, uint128toarray_radix10(UINT128_MAX, buf)); - EXPECT_STREQ("340282366920938463463374607431768211455", buf); - EXPECT_EQ(39, uint128toarray_radix10(INT128_MIN, buf)); - EXPECT_STREQ("170141183460469231731687303715884105728", buf); -} - BENCH(itoa64radix10, bench) { char b[21]; EZBENCH2("itoa64radix10", donothing, FormatUint64(b, UINT64_MAX)); diff --git a/test/libc/fmt/sleb128_test.c b/test/libc/fmt/sleb128_test.c deleted file mode 100644 index 457df431c..000000000 --- a/test/libc/fmt/sleb128_test.c +++ /dev/null @@ -1,111 +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 2021 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/fmt/fmt.h" -#include "libc/fmt/leb128.h" -#include "libc/limits.h" -#include "libc/testlib/ezbench.h" -#include "libc/testlib/testlib.h" - -char p[19]; - -TEST(sleb128, testZero) { - EXPECT_EQ(1, sleb128(p, 0) - p); - EXPECT_EQ(0, p[0]); -} - -TEST(sleb128, testOne) { - EXPECT_EQ(1, sleb128(p, 1) - p); - EXPECT_EQ(1, p[0]); -} - -TEST(sleb128, test255) { - EXPECT_EQ(2, sleb128(p, 255) - p); - EXPECT_EQ(255, p[0] & 255); - EXPECT_EQ(1, p[1]); -} - -TEST(sleb128, testNeg1) { - EXPECT_EQ(1, sleb128(p, -1) - p); - EXPECT_EQ(127, p[0]); -} - -TEST(sleb128, testNeg255) { - EXPECT_EQ(2, sleb128(p, -255) - p); - EXPECT_EQ(129, p[0] & 255); - EXPECT_EQ(126, p[1]); -} - -TEST(sleb128, testMax) { - EXPECT_EQ(19, sleb128(p, INT128_MAX) - p); - EXPECT_EQ(255, p[0x00] & 255); - EXPECT_EQ(255, p[0x01] & 255); - EXPECT_EQ(255, p[0x02] & 255); - EXPECT_EQ(255, p[0x03] & 255); - EXPECT_EQ(255, p[0x04] & 255); - EXPECT_EQ(255, p[0x05] & 255); - EXPECT_EQ(255, p[0x06] & 255); - EXPECT_EQ(255, p[0x07] & 255); - EXPECT_EQ(255, p[0x08] & 255); - EXPECT_EQ(255, p[0x09] & 255); - EXPECT_EQ(255, p[0x0a] & 255); - EXPECT_EQ(255, p[0x0b] & 255); - EXPECT_EQ(255, p[0x0c] & 255); - EXPECT_EQ(255, p[0x0d] & 255); - EXPECT_EQ(255, p[0x0e] & 255); - EXPECT_EQ(255, p[0x0f] & 255); - EXPECT_EQ(255, p[0x10] & 255); - EXPECT_EQ(255, p[0x11] & 255); - EXPECT_EQ(001, p[0x12] & 255); -} - -TEST(sleb128, testMin) { - EXPECT_EQ(19, sleb128(p, INT128_MIN) - p); - EXPECT_EQ(128, p[0x00] & 255); - EXPECT_EQ(128, p[0x01] & 255); - EXPECT_EQ(128, p[0x02] & 255); - EXPECT_EQ(128, p[0x03] & 255); - EXPECT_EQ(128, p[0x04] & 255); - EXPECT_EQ(128, p[0x05] & 255); - EXPECT_EQ(128, p[0x06] & 255); - EXPECT_EQ(128, p[0x07] & 255); - EXPECT_EQ(128, p[0x08] & 255); - EXPECT_EQ(128, p[0x09] & 255); - EXPECT_EQ(128, p[0x0a] & 255); - EXPECT_EQ(128, p[0x0b] & 255); - EXPECT_EQ(128, p[0x0c] & 255); - EXPECT_EQ(128, p[0x0d] & 255); - EXPECT_EQ(128, p[0x0e] & 255); - EXPECT_EQ(128, p[0x0f] & 255); - EXPECT_EQ(128, p[0x10] & 255); - EXPECT_EQ(128, p[0x11] & 255); - EXPECT_EQ(126, p[0x12] & 255); -} - -BENCH(sleb128, bench) { - EZBENCH2("uleb64 INT64_MAX", donothing, uleb64(p, INT64_MAX)); - EZBENCH2("zleb64 INT64_MAX", donothing, zleb64(p, INT64_MAX)); - EZBENCH2("sleb64 INT64_MAX", donothing, sleb64(p, INT64_MAX)); - EZBENCH2("uleb128 INT64_MAX", donothing, uleb128(p, INT64_MAX)); - EZBENCH2("zleb128 INT64_MAX", donothing, zleb128(p, INT64_MAX)); - EZBENCH2("sleb128 INT64_MAX", donothing, sleb128(p, INT64_MAX)); - EZBENCH2("zleb64 INT64_MIN", donothing, zleb64(p, INT64_MIN)); - EZBENCH2("sleb64 INT64_MIN", donothing, sleb64(p, INT64_MIN)); - EZBENCH2("zleb128 INT64_MIN", donothing, zleb128(p, INT64_MIN)); - EZBENCH2("sleb128 INT64_MIN", donothing, sleb128(p, INT64_MIN)); -} diff --git a/test/libc/fmt/uleb128_test.c b/test/libc/fmt/uleb128_test.c deleted file mode 100644 index fa3531c57..000000000 --- a/test/libc/fmt/uleb128_test.c +++ /dev/null @@ -1,70 +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 2021 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/fmt/leb128.h" -#include "libc/limits.h" -#include "libc/stdio/stdio.h" -#include "libc/testlib/testlib.h" - -char p[19]; - -TEST(uleb128, testZero) { - EXPECT_EQ(1, uleb128(p, 0) - p); - EXPECT_EQ(0, p[0]); -} - -TEST(uleb128, testOne) { - EXPECT_EQ(1, uleb128(p, 1) - p); - EXPECT_EQ(1, p[0]); -} - -TEST(uleb128, test255) { - EXPECT_EQ(2, uleb128(p, 255) - p); - EXPECT_EQ(255, p[0] & 255); - EXPECT_EQ(1, p[1]); -} - -TEST(uleb128, testFFFF) { - EXPECT_EQ(3, uleb128(p, 0xFFFF) - p); - EXPECT_EQ(255, p[0] & 255); - EXPECT_EQ(255, p[1] & 255); - EXPECT_EQ(3, p[2] & 255); -} - -TEST(uleb128, testMax) { - EXPECT_EQ(19, uleb128(p, UINT128_MAX) - p); - EXPECT_EQ(255, p[0x00] & 255); - EXPECT_EQ(255, p[0x01] & 255); - EXPECT_EQ(255, p[0x02] & 255); - EXPECT_EQ(255, p[0x03] & 255); - EXPECT_EQ(255, p[0x04] & 255); - EXPECT_EQ(255, p[0x05] & 255); - EXPECT_EQ(255, p[0x06] & 255); - EXPECT_EQ(255, p[0x07] & 255); - EXPECT_EQ(255, p[0x08] & 255); - EXPECT_EQ(255, p[0x09] & 255); - EXPECT_EQ(255, p[0x0a] & 255); - EXPECT_EQ(255, p[0x0b] & 255); - EXPECT_EQ(255, p[0x0c] & 255); - EXPECT_EQ(255, p[0x0d] & 255); - EXPECT_EQ(255, p[0x0e] & 255); - EXPECT_EQ(255, p[0x0f] & 255); - EXPECT_EQ(255, p[0x10] & 255); - EXPECT_EQ(255, p[0x11] & 255); - EXPECT_EQ(003, p[0x12] & 255); -} diff --git a/test/libc/stdio/fprintf_test.c b/test/libc/stdio/fprintf_test.c index d3e590c97..03748973f 100644 --- a/test/libc/stdio/fprintf_test.c +++ b/test/libc/stdio/fprintf_test.c @@ -17,8 +17,10 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dce.h" +#include "libc/mem/gc.internal.h" #include "libc/stdio/stdio.h" #include "libc/testlib/testlib.h" +#include "libc/x/xasprintf.h" TEST(fprintf, testWriteError) { // Only Linux, NetBSD and FreeBSD are known to have /dev/full @@ -32,3 +34,8 @@ TEST(fprintf, testWriteError) { ASSERT_EQ(fclose(fp), 0); } + +TEST(fun, test) { + ASSERT_STREQ("-0x1.4p+0", gc(xasprintf("%a", -1.25))); + ASSERT_STREQ("0x1p-17", gc(xasprintf("%a", 7.62939453125e-6))); +} diff --git a/test/libc/stdio/sscanf_test.c b/test/libc/stdio/sscanf_test.c index 00415f254..4d14edadf 100644 --- a/test/libc/stdio/sscanf_test.c +++ b/test/libc/stdio/sscanf_test.c @@ -284,3 +284,55 @@ TEST(sscanf, eofConditions) { EXPECT_EQ(-1, sscanf("123", "%*d%n", &x)); EXPECT_EQ(666, x); } + +TEST(sscanf, decimal) { + int x = 666; + int y = 666; + EXPECT_EQ(1, sscanf("019", "%d%d", &x, &y)); + EXPECT_EQ(19, x); + EXPECT_EQ(666, y); +} + +TEST(sscanf, octal) { + int x = 666; + int y = 666; + EXPECT_EQ(2, sscanf("019", "%o%d", &x, &y)); + EXPECT_EQ(1, x); + EXPECT_EQ(9, y); +} + +TEST(sscanf, flexdecimal_octal) { + int x = 666; + int y = 666; + EXPECT_EQ(2, sscanf("019", "%i%d", &x, &y)); + EXPECT_EQ(1, x); + EXPECT_EQ(9, y); +} + +TEST(sscanf, flexdecimal_decimal) { + int x = 666; + int y = 666; + EXPECT_EQ(1, sscanf("109a", "%i%d", &x, &y)); + EXPECT_EQ(109, x); + EXPECT_EQ(666, y); +} + +TEST(sscanf, flexdecimal_hex) { + int x = 666; + int y = 666; + EXPECT_EQ(1, sscanf("0x19a", "%i%d", &x, &y)); + EXPECT_EQ(0x19a, x); + EXPECT_EQ(666, y); +} + +TEST(sscanf, luplus) { + long x = 666; + EXPECT_EQ(1, sscanf("+123", "%lu", &x)); + EXPECT_EQ(123, x); +} + +TEST(sscanf, lupluser) { + long x = 666; + EXPECT_EQ(1, sscanf("+123", "%li", &x)); + EXPECT_EQ(123, x); +} diff --git a/third_party/chibicc/test/int128_test.c b/third_party/chibicc/test/int128_test.c index c84532252..bf096b84d 100644 --- a/third_party/chibicc/test/int128_test.c +++ b/third_party/chibicc/test/int128_test.c @@ -38,8 +38,8 @@ __int128 sub128x6(int f, __int128 a, __int128 b, __int128 c, __int128 d, return f - a - b - c - d - e; } -void lotsOfArgs(const char *file, int line, const char *func, int128_t beg, - int128_t end, int128_t got, const char *gotcode, bool isfatal) { +void lotsOfArgs(const char *file, int line, const char *func, __int128 beg, + __int128 end, __int128 got, const char *gotcode, bool isfatal) { } void testLang128(void) { diff --git a/tool/emacs/c.lang b/tool/emacs/c.lang index a628f07fa..ca360c179 100644 --- a/tool/emacs/c.lang +++ b/tool/emacs/c.lang @@ -120,7 +120,6 @@ Keywords={ "privileged", "hasatleast", "nodebuginfo", -"frownedupon", "noreturn", "initarray", "mayalias", @@ -133,7 +132,6 @@ Keywords={ "attributeallocalign", "dontdiscard", "nointerpose", -"compatfn", "returnsnonnull", "strftimeesque", "firstclass", diff --git a/tool/emacs/cosmo-c-constants.el b/tool/emacs/cosmo-c-constants.el index 69db3bfa8..581647195 100644 --- a/tool/emacs/cosmo-c-constants.el +++ b/tool/emacs/cosmo-c-constants.el @@ -111,7 +111,6 @@ "INFINITY" "M_E" "M_LOG2_10" - "M_LOG10_2" "M_LOG2E" "M_LOG10E" "M_LN2" diff --git a/tool/emacs/cosmo-c-keywords.el b/tool/emacs/cosmo-c-keywords.el index 4aa48d155..2b5d7cd38 100644 --- a/tool/emacs/cosmo-c-keywords.el +++ b/tool/emacs/cosmo-c-keywords.el @@ -70,7 +70,6 @@ "privileged" "hasatleast" "nodebuginfo" - "frownedupon" "wontreturn" "dontasan" "nomsan" @@ -87,7 +86,6 @@ "attributeallocalign" "dontdiscard" "nointerpose" - "compatfn" "returnsnonnull" "strftimeesque" "firstclass" diff --git a/tool/emacs/key.py b/tool/emacs/key.py index 470b265d5..422077c7b 100644 --- a/tool/emacs/key.py +++ b/tool/emacs/key.py @@ -328,14 +328,12 @@ cosmo_kws = frozenset([ "attributeallocsize", "autotype", "byanymeansnecessary", - "compatfn", "decltype", "externinline", "firstclass", "flattenout", "forcealignargpointer", "forceinline", - "frownedupon", "hasatleast", "initarray", "interruptfn", @@ -389,14 +387,12 @@ cosmo_kws = frozenset([ "attributeallocsize", "autotype", "byanymeansnecessary", - "compatfn", "decltype", "externinline", "firstclass", "flattenout", "forcealignargpointer", "forceinline", - "frownedupon", "hasatleast", "initarray", "interruptfn",