Import C++ Standard Template Library

You can now use the hardest fastest and most dangerous language there is
with Cosmopolitan. So far about 75% of LLVM libcxx has been added. A few
breaking changes needed to be made to help this go smoothly.

- Rename nothrow to dontthrow
- Rename nodiscard to dontdiscard
- Add some libm functions, e.g. lgamma, nan, etc.
- Change intmax_t from int128 to int64 like everything else
- Introduce %jjd formatting directive for int128_t
- Introduce strtoi128(), strtou128(), etc.
- Rename bsrmax() to bsr128()

Some of the templates that should be working currently are std::vector,
std::string, std::map, std::set, std::deque, etc.
This commit is contained in:
Justine Tunney 2022-03-22 05:51:41 -07:00
parent 5022f9e920
commit 868af3f950
286 changed files with 123987 additions and 507 deletions

View file

@ -15,7 +15,7 @@
"alignas(x)",
"alignof(x)",
"artificial=",
"nodiscard=",
"dontdiscard=",
"mayalias=",
"forceinline=",
"forcealign(x)=",
@ -48,7 +48,7 @@
"nosideeffect=",
"unreachable=",
"thatispacked=",
"nothrow=",
"dontthrow=",
"nocallback=",
"relegated=",
"hidden=",

View file

@ -111,12 +111,12 @@ include libc/rand/rand.mk # │
include libc/unicode/unicode.mk # │
include third_party/dlmalloc/dlmalloc.mk #─┘
include libc/mem/mem.mk #─┐
include libc/ohmyplus/ohmyplus.mk # ├──DYNAMIC RUNTIME
include libc/zipos/zipos.mk # │ You can now use stdio
include third_party/gdtoa/gdtoa.mk # │ You can finally call malloc()
include libc/time/time.mk # │
include libc/zipos/zipos.mk # ├──DYNAMIC RUNTIME
include third_party/gdtoa/gdtoa.mk # │ You can now use stdio
include libc/time/time.mk # │ You can finally call malloc()
include libc/alg/alg.mk # │
include libc/stdio/stdio.mk # │
include third_party/libcxx/libcxx.mk # │
include libc/thread/thread.mk # │
include net/net.mk # │
include libc/log/log.mk # │
@ -145,6 +145,7 @@ include third_party/maxmind/maxmind.mk
include third_party/lua/lua.mk
include third_party/make/make.mk
include third_party/argon2/argon2.mk
include third_party/smallz4/smallz4.mk
include third_party/sqlite3/sqlite3.mk
include third_party/mbedtls/test/test.mk
include third_party/quickjs/quickjs.mk
@ -255,7 +256,6 @@ COSMOPOLITAN_OBJECTS = \
LIBC_NT_WS2_32 \
LIBC_NT_IPHLPAPI \
LIBC_NT_MSWSOCK \
LIBC_OHMYPLUS \
LIBC_X \
THIRD_PARTY_GETOPT \
LIBC_LOG \
@ -308,7 +308,6 @@ COSMOPOLITAN_HEADERS = \
LIBC_MEM \
LIBC_NEXGEN32E \
LIBC_NT \
LIBC_OHMYPLUS \
LIBC_RAND \
LIBC_RUNTIME \
LIBC_SOCK \

Binary file not shown.

View file

@ -149,7 +149,6 @@ DEFAULT_CFLAGS = \
-std=gnu2x
DEFAULT_CXXFLAGS = \
-std=gnu++11 \
-fno-rtti \
-fno-exceptions \
-fuse-cxa-atexit \

View file

@ -48,7 +48,7 @@
set -- --regex-c='/^\(\(hidden\|extern\|const\) \)*[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)/\4/b' "$@"
# ctags doesn't understand function prototypes, e.g.
# bool isheap(void *p) nothrow nocallback;
# bool isheap(void *p) dontthrow nocallback;
set -- --regex-c='/^[_[:alpha:]][_[:alnum:]]*[ *][ *]*\([_[:alpha:]][_[:alnum:]]*[ *][ *]*\)*\([_[:alpha:]][_$[:alnum:]]*\)(.*/\2/b' "$@"
# ctags doesn't understand function pointers, e.g.

View file

@ -31,7 +31,7 @@ o/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds)
o/%.inc: %.h ; @$(COMPILE) -APREPROCESS $(PREPROCESS) $(OUTPUT_OPTION) -D__ASSEMBLER__ -P $<
o/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
o/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -xc -g0 -o $@ $<
o/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $<
o/%.okk: % ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $<
o/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/%.zip.o: o/% ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
@ -60,7 +60,8 @@ o/$(MODE)/%.o: %.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx
o/$(MODE)/%.o: o/$(MODE)/%.cc ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) $(OUTPUT_OPTION) $<
o/$(MODE)/%.lds: %.lds ; @$(COMPILE) -APREPROCESS $(PREPROCESS.lds) $(OUTPUT_OPTION) $<
o/$(MODE)/%.h.ok: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.c) -xc -g0 -o $@ $<
o/$(MODE)/%.h.okk: %.h ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $<
o/$(MODE)/%.hh.ok: %.hh ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $<
o/$(MODE)/%.okk: % ; @$(COMPILE) -ACHECK.h $(COMPILE.cxx) -xc++ -g0 -o $@ $<
o/$(MODE)/%.cxx.o: %.c ; @$(COMPILE) -AOBJECTIFY.cxx $(OBJECTIFY.cxx) -xc++ $(OUTPUT_OPTION) $<
o/$(MODE)/%.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
o/$(MODE)/%.greg.o: %.greg.c ; @$(COMPILE) -AOBJECTIFY.greg $(OBJECTIFY.greg.c) $(OUTPUT_OPTION) $<
@ -77,7 +78,9 @@ o/$(MODE)/%.runs: o/$(MODE)/% ; @$(COMPILE) -ACHECK -tT$@ $< $(TESTARGS)
o/$(MODE)/%.pkg: ; @$(COMPILE) -APACKAGE -T$@ $(PKG) $(OUTPUT_OPTION) $(addprefix -d,$(filter %.pkg,$^)) $(filter %.o,$^)
o/$(MODE)/%.zip.o: % ; @$(COMPILE) -AZIPOBJ $(ZIPOBJ) $(ZIPOBJ_FLAGS) $(OUTPUT_OPTION) $<
o/$(MODE)/%-gcc.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
o/$(MODE)/%-gcc.asm: %.cc ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $<
o/$(MODE)/%-clang.asm: %.c ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.c) -S -g0 $(OUTPUT_OPTION) $<
o/$(MODE)/%-clang.asm: %.cc ; @$(COMPILE) -AOBJECTIFY.c $(OBJECTIFY.cxx) -S -g0 $(OUTPUT_OPTION) $<
o/$(MODE)/%-clang.asm: CC = $(CLANG)
o/%.a:

38
examples/cplusplus-stl.cc Normal file
View file

@ -0,0 +1,38 @@
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
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/stdio/stdio.h"
#include "third_party/libcxx/map"
#include "third_party/libcxx/string"
int main(int argc, char *argv[]) {
printf("std::map + std::string example\n");
std::map<std::string, int> m{
{"CPU", 10},
{"GPU", 15},
{"RAM", 20},
};
printf("m[\"CPU\"] is %d\n", m["CPU"]);
printf("m[\"RAM\"] is %d\n", m["RAM"]);
printf("m[\"GPU\"] is %d\n", m["GPU"]);
printf("setting cpu to 25\n");
m["CPU"] = 25; // update an existing value
printf("m[\"CPU\"] is %d\n", m["CPU"]);
printf("m[\"RAM\"] is %d\n", m["RAM"]);
printf("m[\"GPU\"] is %d\n", m["GPU"]);
}

View file

@ -51,7 +51,6 @@ EXAMPLES_DIRECTDEPS = \
LIBC_NT_USER32 \
LIBC_NT_WS2_32 \
LIBC_NT_ADVAPI32 \
LIBC_OHMYPLUS \
LIBC_RAND \
LIBC_RUNTIME \
LIBC_SOCK \
@ -73,6 +72,7 @@ EXAMPLES_DIRECTDEPS = \
THIRD_PARTY_DLMALLOC \
THIRD_PARTY_GDTOA \
THIRD_PARTY_GETOPT \
THIRD_PARTY_LIBCXX \
THIRD_PARTY_LINENOISE \
THIRD_PARTY_LUA \
THIRD_PARTY_MBEDTLS \

View file

@ -26,7 +26,6 @@
#include "libc/macros.internal.h"
#include "libc/math.h"
#include "libc/mem/mem.h"
#include "libc/ohmyplus/vector.h"
#include "libc/runtime/runtime.h"
#include "libc/sock/sock.h"
#include "libc/stdio/stdio.h"
@ -43,6 +42,7 @@
#include "libc/zip.h"
#include "libc/zipos/zipos.internal.h"
#include "third_party/getopt/getopt.h"
#include "third_party/libcxx/vector"
#include "tool/viz/lib/knobs.h"
STATIC_YOINK("zip_uri_support");

View file

@ -8,10 +8,10 @@ COSMOPOLITAN_C_START_
void *bsearch(const void *, const void *, size_t, size_t,
int cmp(const void *, const void *))
paramsnonnull() nothrow nosideeffect;
paramsnonnull() dontthrow nosideeffect;
void *bsearch_r(const void *, const void *, size_t, size_t,
int cmp(const void *, const void *, void *), void *)
paramsnonnull((1, 2, 5)) nothrow nosideeffect;
paramsnonnull((1, 2, 5)) dontthrow nosideeffect;
void djbsort(int32_t *, size_t);
void qsort(void *, size_t, size_t, int (*)(const void *, const void *))
paramsnonnull();
@ -19,9 +19,9 @@ void qsort_r(void *, size_t, size_t,
int cmp(const void *, const void *, void *), void *arg)
paramsnonnull((1, 4));
int tarjan(int, const int (*)[2], int, int[], int[], int *)
paramsnonnull((2, 4)) nocallback nothrow;
paramsnonnull((2, 4)) nocallback dontthrow;
#define __algalloc returnspointerwithnoaliases nothrow nocallback nodiscard
#define __algalloc returnspointerwithnoaliases dontthrow nocallback dontdiscard
char *replacestr(const char *, const char *, const char *)
paramsnonnull() __algalloc;

View file

@ -11,15 +11,15 @@ struct critbit0 {
size_t count;
};
bool critbit0_contains(struct critbit0 *, const char *) nothrow nosideeffect
bool critbit0_contains(struct critbit0 *, const char *) dontthrow nosideeffect
paramsnonnull();
bool critbit0_insert(struct critbit0 *, const char *) paramsnonnull();
bool critbit0_delete(struct critbit0 *, const char *) nothrow paramsnonnull();
void critbit0_clear(struct critbit0 *) nothrow paramsnonnull();
bool critbit0_delete(struct critbit0 *, const char *) dontthrow paramsnonnull();
void critbit0_clear(struct critbit0 *) dontthrow paramsnonnull();
char *critbit0_get(struct critbit0 *, const char *);
intptr_t critbit0_allprefixed(struct critbit0 *, const char *,
intptr_t (*)(const char *, void *), void *)
paramsnonnull((1, 2, 3)) nothrow;
paramsnonnull((1, 2, 3)) dontthrow;
bool critbit0_emplace(struct critbit0 *, char *, size_t) paramsnonnull();
COSMOPOLITAN_C_END_

View file

@ -12,7 +12,9 @@ void __assert_fail(const char *, const char *, int) hidden wontreturn relegated;
((void)((EXPR) || (__assert_fail(#EXPR, __FILE__, __LINE__), 0)))
#endif
#ifndef __cplusplus
#define static_assert _Static_assert
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -66,8 +66,8 @@ COSMOPOLITAN_C_START_
typedef int sig_atomic_t;
DIR *fdopendir(int) nodiscard;
DIR *opendir(const char *) nodiscard;
DIR *fdopendir(int) dontdiscard;
DIR *opendir(const char *) dontdiscard;
bool fileexists(const char *);
bool isdirectory(const char *);
bool isexecutable(const char *);
@ -76,12 +76,12 @@ bool issymlink(const char *);
bool32 isatty(int) nosideeffect;
bool32 ischardev(int) nosideeffect;
char *commandv(const char *, char[hasatleast PATH_MAX]);
char *get_current_dir_name(void) nodiscard;
char *get_current_dir_name(void) dontdiscard;
char *getcwd(char *, size_t);
char *realpath(const char *, char *);
char *replaceuser(const char *) nodiscard;
char *replaceuser(const char *) dontdiscard;
char *ttyname(int);
int access(const char *, int) nothrow;
int access(const char *, int) dontthrow;
int arch_prctl();
int chdir(const char *);
int chmod(const char *, uint32_t);
@ -105,7 +105,7 @@ int execvpe(const char *, char *const[], char *const[]);
int faccessat(int, const char *, int, uint32_t);
int fadvise(int, uint64_t, uint64_t, int);
int fchdir(int);
int fchmod(int, uint32_t) nothrow;
int fchmod(int, uint32_t) dontthrow;
int fchmodat(int, const char *, uint32_t, int);
int fchown(int, uint32_t, uint32_t);
int fchownat(int, const char *, uint32_t, uint32_t, int);
@ -129,7 +129,7 @@ int getrlimit(int, struct rlimit *);
int getrusage(int, struct rusage *);
int kill(int, int);
int killpg(int, int);
int link(const char *, const char *) nothrow;
int link(const char *, const char *) dontthrow;
int linkat(int, const char *, int, const char *, int);
int lstat(const char *, struct stat *);
int lutimes(const char *, const struct timeval[2]);

View file

@ -35,6 +35,6 @@
* @see open(), touch()
* @asyncsignalsafe
*/
nodiscard int creat(const char *file, uint32_t mode) {
dontdiscard int creat(const char *file, uint32_t mode) {
return openat(AT_FDCWD, file, O_CREAT | O_WRONLY | O_TRUNC, mode);
}

View file

@ -296,7 +296,7 @@ int sys_truncate_nt(const char *, u64) hidden;
int sys_unlinkat_nt(int, const char *, int) hidden;
int sys_utimensat_nt(int, const char *, const struct timespec *, int) hidden;
int sys_utimes_nt(const char *, const struct timeval[2]) hidden;
ssize_t sys_open_nt(int, const char *, u32, i32) nodiscard hidden;
ssize_t sys_open_nt(int, const char *, u32, i32) dontdiscard hidden;
ssize_t sys_read_nt(struct Fd *, const struct iovec *, size_t, ssize_t) hidden;
ssize_t sys_readlinkat_nt(int, const char *, char *, size_t) hidden;
ssize_t sys_write_nt(int, const struct iovec *, size_t, ssize_t) hidden;

View file

@ -17,14 +17,14 @@ int tcsetpgrp(int, int32_t);
int32_t tcgetpgrp(int);
int openpty(int *, int *, char *, const struct termios *,
const struct winsize *) paramsnonnull((1, 2)) nodiscard;
const struct winsize *) paramsnonnull((1, 2)) dontdiscard;
int forkpty(int *, char *, const struct termios *, const struct winsize *)
paramsnonnull((1, 2)) nodiscard;
paramsnonnull((1, 2)) dontdiscard;
errno_t ptsname_r(int, char *, size_t);
int grantpt(int);
int unlockpt(int);
int posix_openpt(int) nodiscard;
int posix_openpt(int) dontdiscard;
int tcdrain(int);
int tcgetsid(int);

View file

@ -39,14 +39,14 @@
#define uid_t uint32_t
#define rlim_t uint64_t /* int64_t on bsd */
#define int_fast8_t __INT_FAST8_TYPE__
#define uint_fast8_t __UINT_FAST8_TYPE__
#define int_fast16_t __INT_FAST16_TYPE__
#define uint_fast16_t __UINT_FAST16_TYPE__
#define int_fast32_t __INT_FAST32_TYPE__
#define uint_fast32_t __UINT_FAST32_TYPE__
#define int_fast64_t __INT_FAST64_TYPE__
#define uint_fast64_t __UINT_FAST64_TYPE__
typedef __INT_FAST8_TYPE__ int_fast8_t;
typedef __UINT_FAST8_TYPE__ uint_fast8_t;
typedef __INT_FAST16_TYPE__ int_fast16_t;
typedef __UINT_FAST16_TYPE__ uint_fast16_t;
typedef __INT_FAST32_TYPE__ int_fast32_t;
typedef __UINT_FAST32_TYPE__ uint_fast32_t;
typedef __INT_FAST64_TYPE__ int_fast64_t;
typedef __UINT_FAST64_TYPE__ uint_fast64_t;
#define atomic_bool _Atomic(_Bool)
#define atomic_bool32 atomic_int_fast32_t

View file

@ -17,6 +17,7 @@ COSMOPOLITAN_C_START_
int abs(int) libcesque pureconst;
long labs(long) libcesque pureconst;
long long llabs(long long) libcesque pureconst;
intmax_t imaxabs(intmax_t) libcesque pureconst;
int atoi(const char *) paramsnonnull() libcesque;
long atol(const char *) paramsnonnull() libcesque;
long long atoll(const char *) paramsnonnull() libcesque;
@ -24,7 +25,6 @@ unsigned long strtoul(const char *, char **, int) paramsnonnull((1));
long long strtoll(const char *, char **, int) paramsnonnull((1));
unsigned long long strtoull(const char *, char **, int) paramsnonnull((1));
long long strtonum(const char *, long long, long long, const char **);
intmax_t div10(intmax_t, unsigned *) hidden;
intmax_t strtoimax(const char *, char **, int) paramsnonnull((1));
uintmax_t strtoumax(const char *, char **, int) paramsnonnull((1));
intmax_t wcstoimax(const wchar_t *, wchar_t **, int);
@ -33,18 +33,22 @@ long wcstol(const wchar_t *, wchar_t **, int);
unsigned long wcstoul(const wchar_t *, wchar_t **, int);
long strtol(const char *, char **, int) paramsnonnull((1)) libcesque;
long sizetol(const char *, long) paramsnonnull() libcesque;
long long wcstoll(const wchar_t *, wchar_t **, int);
unsigned long long wcstoull(const wchar_t *, wchar_t **, int);
int wcscoll(const wchar_t *, const wchar_t *);
size_t wcsxfrm(wchar_t *, const wchar_t *, size_t);
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § conversion » time
*/
int64_t DosDateTimeToUnix(unsigned, unsigned) nothrow;
struct timeval WindowsTimeToTimeVal(int64_t) nothrow;
struct timespec WindowsTimeToTimeSpec(int64_t) nothrow;
int64_t TimeSpecToWindowsTime(struct timespec) nothrow;
int64_t TimeValToWindowsTime(struct timeval) nothrow;
struct timeval WindowsDurationToTimeVal(int64_t) nothrow;
struct timespec WindowsDurationToTimeSpec(int64_t) nothrow;
int64_t DosDateTimeToUnix(unsigned, unsigned) dontthrow;
struct timeval WindowsTimeToTimeVal(int64_t) dontthrow;
struct timespec WindowsTimeToTimeSpec(int64_t) dontthrow;
int64_t TimeSpecToWindowsTime(struct timespec) dontthrow;
int64_t TimeValToWindowsTime(struct timeval) dontthrow;
struct timeval WindowsDurationToTimeVal(int64_t) dontthrow;
struct timespec WindowsDurationToTimeSpec(int64_t) dontthrow;
static inline struct NtFileTime MakeFileTime(int64_t x) {
return (struct NtFileTime){(uint32_t)x, (uint32_t)(x >> 32)};
@ -110,10 +114,13 @@ imaxdiv_t imaxdiv(intmax_t, intmax_t) pureconst;
#define lldiv(num, den) ((lldiv_t){(num) / (den), (num) % (den)})
#endif
#ifndef __STRICT_ANSI__
intmax_t __imaxabs(intmax_t) libcesque pureconst;
#define imaxabs(x) __imaxabs(x)
#endif /* !ANSI */
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__)
int128_t i128abs(int128_t) libcesque pureconst;
int128_t strtoi128(const char *, char **, int) paramsnonnull((1));
uint128_t strtou128(const char *, char **, int) paramsnonnull((1));
int128_t wcstoi128(const wchar_t *, wchar_t **, int);
uint128_t wcstou128(const wchar_t *, wchar_t **, int);
#endif /* gcc 4.6+ */
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -90,7 +90,8 @@ static int __fmt_atoi(const char **str) {
* - `%ld` long (64-bit)
* - `%lu` unsigned long (64-bit)
* - `%lx` unsigned long (64-bit hexadecimal)
* - `%jd` intmax_t (128-bit)
* - `%jd` intmax_t (64-bit)
* - `%jjd` int128_t (128-bit)
*
* Width Modifiers
*
@ -291,6 +292,10 @@ hidden int __fmt(void *fn, void *arg, const char *format, va_list va) {
case 'j': /* intmax_t */
format++;
signbit = sizeof(intmax_t) * 8 - 1;
if (*format == 'j') {
format++;
signbit = sizeof(int128_t) * 8 - 1;
}
break;
case 'l':
if (format[1] == 'f' || format[1] == 'F') {

View file

@ -15,18 +15,18 @@
COSMOPOLITAN_C_START_
int snprintf(char *, size_t, const char *, ...) printfesque(3)
paramsnonnull((3)) nothrow nocallback;
paramsnonnull((3)) dontthrow nocallback;
int vsnprintf(char *, size_t, const char *, va_list)
paramsnonnull((3)) nothrow nocallback;
paramsnonnull((3)) dontthrow nocallback;
int sprintf(char *, const char *, ...) printfesque(2)
paramsnonnull((2)) nothrow nocallback frownedupon(snprintf);
paramsnonnull((2)) dontthrow nocallback frownedupon(snprintf);
int vsprintf(char *, const char *, va_list)
paramsnonnull((2)) nothrow nocallback frownedupon(vsnprintf);
paramsnonnull((2)) dontthrow nocallback frownedupon(vsnprintf);
int sscanf(const char *, const char *, ...) scanfesque(2);
int vsscanf(const char *, const char *, va_list);
int vcscanf(int (*)(void *), int (*)(int, void *), void *, const char *,
va_list);
int strerror_r(int, char *, size_t) nothrow nocallback;
int strerror_r(int, char *, size_t) dontthrow nocallback;
const char *strerror_short(int) nosideeffect;
const char *strerror_long(int) nosideeffect;
int __fmt(void *, void *, const char *, va_list) hidden;

View file

@ -16,12 +16,9 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/bits/bits.h"
#include "libc/mem/mem.h"
#include "libc/fmt/conv.h"
#include "libc/macros.internal.h"
void __vector_reserve(size_t n, size_t m, intptr_t **data, size_t *toto) {
if ((n = roundup2pow(n)) > *toto) {
*toto = n;
*data = realloc(*data, n * m);
}
int128_t i128abs(int128_t x) {
return ABS(x);
}

View file

@ -19,6 +19,6 @@
#include "libc/fmt/conv.h"
#include "libc/macros.internal.h"
intmax_t(imaxabs)(intmax_t x) {
intmax_t imaxabs(intmax_t x) {
return ABS(x);
}

View file

@ -26,7 +26,7 @@
#define BUFFER_SIZE 144
uintmax_t __udivmodti4(uintmax_t, uintmax_t, uintmax_t *);
uint128_t __udivmodti4(uint128_t, uint128_t, uint128_t *);
static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg,
char *buf, unsigned len, bool negative,
@ -91,9 +91,9 @@ static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg,
}
int __fmt_ntoa2(int out(const char *, void *, size_t), void *arg,
uintmax_t value, bool neg, unsigned log2base, unsigned prec,
uint128_t value, bool neg, unsigned log2base, unsigned prec,
unsigned width, unsigned flags, const char *alphabet) {
uintmax_t remainder;
uint128_t remainder;
unsigned len, count, digit;
char buf[BUFFER_SIZE];
len = 0;
@ -132,7 +132,7 @@ int __fmt_ntoa(int out(const char *, void *, size_t), void *arg, va_list va,
unsigned long prec, unsigned long width, unsigned char flags,
const char *lang) {
bool neg;
uintmax_t value, sign;
uint128_t value, sign;
/* ignore '0' flag when prec is given */
if (flags & FLAGS_PRECISION) {

60
libc/fmt/strtoi128.c Normal file
View file

@ -0,0 +1,60 @@
/*-*- 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/str/str.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 (__builtin_mul_overflow(x, base, &x) ||
__builtin_add_overflow(x, c * d, &x)) {
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;
}

View file

@ -23,7 +23,7 @@
#include "libc/str/str.h"
/**
* Decodes 128-bit signed integer from ASCII string.
* Decodes intmax_t 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

24
libc/fmt/strtoll_l.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2022 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/unicode/locale.h"
long long strtoll_l(const char *nptr, char **endptr, int base, locale_t l) {
return strtoll(nptr, endptr, base);
}

53
libc/fmt/strtou128.c Normal file
View file

@ -0,0 +1,53 @@
/*-*- 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"
/**
* 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;
}

25
libc/fmt/strtoull_l.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2022 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/unicode/locale.h"
unsigned long long strtoull_l(const char *nptr, char **endptr, int base,
locale_t l) {
return strtoull(nptr, endptr, base);
}

View file

@ -21,7 +21,7 @@
#include "libc/str/str.h"
/**
* Decodes 128-bit unsigned integer from ASCII string.
* Decodes uintmax_t 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

26
libc/fmt/swprintf.c Normal file
View file

@ -0,0 +1,26 @@
/*-*- 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 2022 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/fmt/fmt.h"
#include "libc/runtime/runtime.h"
int swprintf(wchar_t* ws, size_t n, const wchar_t* format, ...) {
assert(!"not implemented");
abort();
}

View file

@ -70,7 +70,7 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg,
}
break;
case '%': {
uintmax_t number;
uint128_t number;
void *buf;
size_t bufsize;
unsigned width = 0;
@ -117,8 +117,12 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg,
case '\'':
thousands = true;
break;
case 'j': /* 128-bit */
bits = sizeof(intmax_t) * 8;
case 'j': /* j=64-bit jj=128-bit */
if (bits < 64) {
bits = 64;
} else {
bits = 128;
}
break;
case 'l': /* long */
case 'L': /* loooong */
@ -185,7 +189,7 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg,
}
} while ((c = callback(arg)) != -1);
if (!discard) {
uintmax_t bane = (uintmax_t)1 << (bits - 1);
uint128_t bane = (uint128_t)1 << (bits - 1);
if (!(number & ~((bane - 1) | (issigned ? 0 : bane))) ||
(issigned && number == bane /* two's complement bane */)) {
++items;
@ -198,8 +202,8 @@ int vcscanf(int callback(void *), int unget(int, void *), void *arg,
}
void *out = va_arg(va, void *);
switch (bits) {
case sizeof(uintmax_t) * CHAR_BIT:
*(uintmax_t *)out = number;
case sizeof(uint128_t) * CHAR_BIT:
*(uint128_t *)out = number;
break;
case 48:
case 64:

60
libc/fmt/wcstoi128.c Normal file
View file

@ -0,0 +1,60 @@
/*-*- 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/str/str.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 (__builtin_mul_overflow(x, base, &x) ||
__builtin_add_overflow(x, c * d, &x)) {
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;
}

View file

@ -23,7 +23,7 @@
#include "libc/str/str.h"
/**
* Decodes 128-bit signed integer from wide string.
* Decodes intmax_t 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

View file

@ -23,7 +23,7 @@
#include "libc/str/str.h"
/**
* Decodes signed integer from wide string.
* Decodes signed long 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

59
libc/fmt/wcstoll.c Normal file
View file

@ -0,0 +1,59 @@
/*-*- 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/str/str.h"
/**
* Decodes signed long long 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 the decoded signed saturated number
*/
long long wcstoll(const wchar_t *s, wchar_t **endptr, int base) {
char t = 0;
int d, c = *s;
long long 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 (__builtin_mul_overflow(x, base, &x) ||
__builtin_add_overflow(x, c * d, &x)) {
x = d > 0 ? LONG_LONG_MAX : LONG_LONG_MIN;
errno = ERANGE;
t |= 2;
}
} while ((c = kBase36[*++s & 255]) && --c < base);
}
}
if (t && endptr) *endptr = s;
return x;
}

25
libc/fmt/wcstoll_l.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2022 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/unicode/locale.h"
long long wcstoll_l(const wchar_t *nptr, wchar_t **endptr, int base,
locale_t l) {
return wcstoll(nptr, endptr, base);
}

53
libc/fmt/wcstou128.c Normal file
View file

@ -0,0 +1,53 @@
/*-*- 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"
/**
* 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;
}

53
libc/fmt/wcstoull.c Normal file
View file

@ -0,0 +1,53 @@
/*-*- 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/str/str.h"
/**
* Decodes unsigned long long 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 `-`
*/
unsigned long long wcstoull(const wchar_t *s, wchar_t **endptr, int base) {
char t = 0;
int d, c = *s;
unsigned long long 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;
}

25
libc/fmt/wcstoull_l.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2022 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/unicode/locale.h"
unsigned long long wcstoull_l(const wchar_t *nptr, wchar_t **endptr, int base,
locale_t l) {
return wcstoull(nptr, endptr, base);
}

View file

@ -21,7 +21,7 @@
#include "libc/str/str.h"
/**
* Decodes 128-bit unsigned integer from wide string.
* Decodes uintmax_t 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

View file

@ -102,6 +102,8 @@ typedef __CHAR16_TYPE__ char16_t;
typedef __CHAR32_TYPE__ char32_t;
#endif
#define _LIBCPP_STDINT_H
typedef int errno_t;
typedef __SIZE_TYPE__ size_t;
typedef __PTRDIFF_TYPE__ ssize_t;
@ -118,30 +120,18 @@ typedef __INT32_TYPE__ int32_t;
typedef __UINT32_TYPE__ uint32_t;
typedef __INT64_TYPE__ int64_t;
typedef __UINT64_TYPE__ uint64_t;
typedef __INTMAX_TYPE__ intmax_t;
typedef __UINTMAX_TYPE__ uintmax_t;
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__)
typedef signed __int128 int128_t;
typedef unsigned __int128 uint128_t;
#endif
typedef struct {
intptr_t ax, dx;
} axdx_t;
#ifdef __SIZEOF_INTMAX__
#undef __SIZEOF_INTMAX__
#endif
#if !defined(__STRICT_ANSI__) && __SIZEOF_POINTER__ == 8 && \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 406 || defined(__llvm__))
#define __SIZEOF_INTMAX__ 16
#else
#define __SIZEOF_INTMAX__ __SIZEOF_POINTER__
#endif
#if __SIZEOF_INTMAX__ == 16
typedef signed __int128 int128_t;
typedef unsigned __int128 uint128_t;
typedef int128_t intmax_t;
typedef uint128_t uintmax_t;
#elif __SIZEOF_INTMAX__ == 8
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
#endif
#ifndef __chibicc__
#define va_list __builtin_va_list
#define va_arg(ap, type) __builtin_va_arg(ap, type)
@ -152,11 +142,11 @@ typedef uint64_t uintmax_t;
#include "libc/integral/lp64arg.inc"
#endif
#define libcesque nothrow nocallback
#define libcesque dontthrow nocallback
#define memcpyesque libcesque
#define strlenesque libcesque nosideeffect paramsnonnull()
#define vallocesque \
libcesque nodiscard returnsaligned((PAGESIZE)) returnspointerwithnoaliases
libcesque dontdiscard returnsaligned((PAGESIZE)) returnspointerwithnoaliases
#define reallocesque libcesque returnsaligned((16))
#define mallocesque reallocesque returnspointerwithnoaliases
#define interruptfn nocallersavedregisters forcealignargpointer
@ -299,13 +289,13 @@ typedef uint64_t uintmax_t;
#endif
#endif
#ifndef nodiscard
#ifndef dontdiscard
#if !defined(__STRICT_ANSI__) && \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 304 || \
__has_attribute(__warn_unused_result__))
#define nodiscard __attribute__((__warn_unused_result__))
#define dontdiscard __attribute__((__warn_unused_result__))
#else
#define nodiscard
#define dontdiscard
#endif
#endif
@ -408,15 +398,15 @@ typedef uint64_t uintmax_t;
#endif
#endif
#ifndef nothrow
#ifndef dontthrow
#if defined(__cplusplus) && !defined(__STRICT_ANSI__) && \
(__has_attribute(nothrow) || \
(__has_attribute(dontthrow) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 303)
#define nothrow __attribute__((__nothrow__))
#define dontthrow __attribute__((__nothrow__))
#elif defined(_MSC_VER)
#define nothrow __declspec(nothrow)
#define dontthrow __declspec(nothrow)
#else
#define nothrow
#define dontthrow
#endif
#endif
@ -677,6 +667,7 @@ typedef uint64_t uintmax_t;
#pragma GCC diagnostic ignored "-Wdangling-else" /* come on tidy */
#pragma GCC diagnostic ignored "-Wformat-security" /* come on tidy */
#pragma GCC diagnostic ignored "-Wunused-value" /* breaks macros */
#pragma GCC diagnostic ignored "-Wdeprecated-declarations" /* libcxx */
#ifndef __cplusplus
#pragma GCC diagnostic ignored "-Wimplicit-int"
#endif /* C++ */

View file

@ -12,6 +12,8 @@
#define __INTPTR_MAX__ 0x7fffffffffffffffl
#define __UINTPTR_MAX__ 0xfffffffffffffffful
#define __WINT_MAX__ 0xffffffffu
#define __UINTMAX_MAX__ 0xffffffffffffffffUL
#define __INTMAX_MAX__ 0x7fffffffffffffffL
#define __SIZEOF_SHORT__ 2
#define __SIZEOF_INT__ 4
@ -30,21 +32,23 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#define __INT8_TYPE__ signed char
#define __UINT8_TYPE__ unsigned char
#define __INT16_TYPE__ short int
#define __UINT16_TYPE__ short unsigned int
#define __INT32_TYPE__ int
#define __UINT32_TYPE__ unsigned int
#define __INT64_TYPE__ long int
#define __UINT64_TYPE__ long unsigned int
#define __INTPTR_TYPE__ long int
#define __UINTPTR_TYPE__ long unsigned int
#define __PTRDIFF_TYPE__ long int
#define __SIZE_TYPE__ long unsigned int
#define __WCHAR_TYPE__ int
#define __CHAR16_TYPE__ short unsigned int
#define __CHAR32_TYPE__ unsigned int
#define __INT16_TYPE__ short int
#define __INT32_TYPE__ int
#define __INT64_TYPE__ long int
#define __INT8_TYPE__ signed char
#define __INTMAX_TYPE__ long int
#define __INTPTR_TYPE__ long int
#define __PTRDIFF_TYPE__ long int
#define __SIZE_TYPE__ long unsigned int
#define __UINT16_TYPE__ short unsigned int
#define __UINT32_TYPE__ unsigned int
#define __UINT64_TYPE__ long unsigned int
#define __UINT8_TYPE__ unsigned char
#define __UINTMAX_TYPE__ long unsigned int
#define __UINTPTR_TYPE__ long unsigned int
#define __WCHAR_TYPE__ int
#define __WINT_TYPE__ unsigned int
#define __INT_LEAST8_TYPE__ __INT8_TYPE__

View file

@ -323,7 +323,7 @@ static void __asan_exit(void) {
_Exit(99);
}
nodiscard static __asan_die_f *__asan_die(void) {
dontdiscard static __asan_die_f *__asan_die(void) {
if (weaken(__die)) {
return weaken(__die);
} else {
@ -601,7 +601,8 @@ const char *__asan_describe_access_poison(signed char kind) {
}
}
nodiscard static __asan_die_f *__asan_report_invalid_pointer(const void *addr) {
dontdiscard static __asan_die_f *__asan_report_invalid_pointer(
const void *addr) {
kprintf("%n\e[J\e[1;31masan error\e[0m: this corruption at %p shadow %p%n",
addr, SHADOW(addr));
return __asan_die();
@ -719,9 +720,9 @@ static void __asan_report_memory_origin(const unsigned char *addr, int size,
}
}
nodiscard static __asan_die_f *__asan_report(const void *addr, int size,
const char *message,
signed char kind) {
dontdiscard static __asan_die_f *__asan_report(const void *addr, int size,
const char *message,
signed char kind) {
int i;
wint_t c;
signed char t;
@ -826,8 +827,8 @@ void __asan_verify(const void *p, size_t n) {
__asan_unreachable();
}
nodiscard __asan_die_f *__asan_report_memory_fault(void *addr, int size,
const char *message) {
dontdiscard __asan_die_f *__asan_report_memory_fault(void *addr, int size,
const char *message) {
return __asan_report(addr, size, message,
__asan_fault(SHADOW(addr), -128).kind);
}

View file

@ -202,7 +202,7 @@ static void __ubsan_exit(void) {
_Exit(99);
}
nodiscard static __ubsan_die_f *__ubsan_die(void) {
dontdiscard static __ubsan_die_f *__ubsan_die(void) {
if (weaken(__die)) {
return weaken(__die);
} else {
@ -216,8 +216,8 @@ static void __ubsan_warning(const struct UbsanSourceLocation *loc,
loc->line, SUBTLE, description, RESET);
}
nodiscard __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) {
dontdiscard __ubsan_die_f *__ubsan_abort(const struct UbsanSourceLocation *loc,
const char *description) {
kprintf("%n%s:%d: %subsan error%s: %s%n", loc->file, loc->line, RED2, RESET,
description);
return __ubsan_die();

View file

@ -48,6 +48,8 @@ typedef __UINT_LEAST64_TYPE__ uint_least64_t;
#define __PRI128 "ll"
#elif __SIZEOF_INTMAX__ == 16
#define __PRI128 "j"
#else
#define __PRI128 "jj"
#endif
#if __SIZEOF_POINTER__ == __SIZEOF_INT__

View file

@ -1,4 +1,10 @@
#ifndef LIBC_ISYSTEM_ENDIAN_H_
#define LIBC_ISYSTEM_ENDIAN_H_
#define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
#define __BIG_ENDIAN __ORDER_BIG_ENDIAN__
#define __PDP_ENDIAN __ORDER_PDP_ENDIAN__
#define __BYTE_ORDER __BYTE_ORDER__
#include "libc/bits/newbie.h"
#endif
#endif /* LIBC_ISYSTEM_ENDIAN_H_ */

38
libc/isystem/features.h Normal file
View file

@ -0,0 +1,38 @@
#ifndef COSMOPOLITAN_LIBC_ISYSTEM_FEATURES_H_
#define COSMOPOLITAN_LIBC_ISYSTEM_FEATURES_H_
#if defined(_ALL_SOURCE) && !defined(_GNU_SOURCE)
#define _GNU_SOURCE 1
#endif
#if defined(_DEFAULT_SOURCE) && !defined(_BSD_SOURCE)
#define _BSD_SOURCE 1
#endif
#if !defined(_POSIX_SOURCE) && !defined(_POSIX_C_SOURCE) && \
!defined(_XOPEN_SOURCE) && !defined(_GNU_SOURCE) && \
!defined(_BSD_SOURCE) && !defined(__STRICT_ANSI__)
#define _BSD_SOURCE 1
#define _XOPEN_SOURCE 700
#endif
#if __STDC_VERSION__ >= 199901L
#define __restrict restrict
#elif !defined(__GNUC__)
#define __restrict
#endif
#if __STDC_VERSION__ >= 199901L || defined(__cplusplus)
#define __inline inline
#elif !defined(__GNUC__)
#define __inline
#endif
#if __STDC_VERSION__ >= 201112L
#elif defined(__GNUC__)
#define _Noreturn __attribute__((__noreturn__))
#else
#define _Noreturn
#endif
#endif /* COSMOPOLITAN_LIBC_ISYSTEM_FEATURES_H_ */

View file

@ -1,4 +1,5 @@
#ifndef LIBC_ISYSTEM_STDINT_H_
#define LIBC_ISYSTEM_STDINT_H_
#include "libc/limits.h"
#include "libc/literal.h"
#endif

View file

@ -1,6 +1,8 @@
#ifndef LIBC_ISYSTEM_STDIO_H_
#define LIBC_ISYSTEM_STDIO_H_
#include "libc/calls/calls.h"
#include "libc/fmt/fmt.h"
#include "libc/log/log.h"
#include "libc/stdio/stdio.h"
#include "libc/stdio/temp.h"
#endif

View file

@ -1,9 +1,11 @@
#ifndef LIBC_ISYSTEM_STDLIB_H_
#define LIBC_ISYSTEM_STDLIB_H_
#include "libc/alg/alg.h"
#include "libc/fmt/conv.h"
#include "libc/mem/mem.h"
#include "libc/rand/rand.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/temp.h"
#include "libc/sysv/consts/exit.h"
#include "third_party/gdtoa/gdtoa.h"
#endif

View file

@ -1,5 +1,6 @@
#ifndef LIBC_ISYSTEM_TIME_H_
#define LIBC_ISYSTEM_TIME_H_
#include "libc/sysv/consts/sched.h"
#include "libc/time/struct/tm.h"
#include "libc/time/time.h"
#endif

View file

@ -1,4 +1,5 @@
#ifndef LIBC_ISYSTEM_WCHAR_H_
#define LIBC_ISYSTEM_WCHAR_H_
#include "libc/str/str.h"
#include "libc/time/time.h"
#endif

View file

@ -22,7 +22,6 @@ o/$(MODE)/libc: o/$(MODE)/libc/alg \
o/$(MODE)/libc/mem \
o/$(MODE)/libc/nexgen32e \
o/$(MODE)/libc/nt \
o/$(MODE)/libc/ohmyplus \
o/$(MODE)/libc/rand \
o/$(MODE)/libc/runtime \
o/$(MODE)/libc/sock \

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_LIMITS_H_
#define COSMOPOLITAN_LIBC_LIMITS_H_
#define __STDC_LIMIT_MACROS
#define UCHAR_MIN 0
#define UCHAR_MAX 255
@ -32,6 +33,8 @@
#define UINT16_MAX __UINT16_MAX__
#define UINT32_MAX __UINT32_MAX__
#define UINT64_MAX __UINT64_MAX__
#define INTMAX_MAX __INTMAX_MAX__
#define UINTMAX_MAX __UINTMAX_MAX__
#define SCHAR_MIN (-SCHAR_MAX - 1)
#define SHRT_MIN (-SHRT_MAX - 1)
@ -70,27 +73,18 @@
#define UINT32_MIN 0u
#define UINT64_MIN 0ull
#define UINTPTR_MIN 0ull
#define UINTMAX_MIN ((uintmax_t)0)
#define MB_CUR_MAX 4
#define MB_LEN_MAX 4
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#if __GNUC__ * 100 + __GNUC_MINOR__ >= 406 || defined(__llvm__)
#define INTMAX_MAX \
(((intmax_t)0x7fffffffffffffff) << 64 | (intmax_t)0xffffffffffffffff)
#define UINTMAX_MAX \
(((uintmax_t)0xffffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff)
#define INT128_MIN INTMAX_MIN
#define INT128_MAX INTMAX_MAX
#define UINTMAX_MIN ((uintmax_t)0)
#define UINT128_MIN ((uintmax_t)0)
#define UINT128_MAX UINTMAX_MAX
#else
#define INTMAX_MAX __INT64_MAX__
#define UINTMAX_MAX __UINT64_MAX__
#define UINTMAX_MIN UINT64_MIN
#define INT128_MIN (-INT128_MAX - 1)
#define UINT128_MIN ((uint128_t)0)
#define INT128_MAX \
((int128_t)0x7fffffffffffffff << 64 | (int128_t)0xffffffffffffffff)
#define UINT128_MAX \
((uint128_t)0xffffffffffffffff << 64 | (uint128_t)0xffffffffffffffff)
#endif /* GCC 4.6+ */
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_LIMITS_H_ */

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_LITERAL_H_
#define COSMOPOLITAN_LIBC_LITERAL_H_
#define __STDC_CONSTANT_MACROS
#ifdef __INT8_C
#define INT8_C(c) __INT8_C(c)

View file

@ -182,6 +182,8 @@ float fminf(float, float);
float fmodf(float, float);
float hypotf(float, float);
float ldexpf(float, int);
float lgammaf(float);
float lgammaf_r(float, int *);
float log10f(float);
float log1pf(float);
float log2f(float);
@ -205,10 +207,11 @@ float sinhf(float);
float sqrtf(float);
float tanf(float);
float tanhf(float);
float truncf(float);
float tgammaf(float);
float truncf(float);
int finitef(float);
int finitel(long double);
long double acoshl(long double);
long double acosl(long double);
long double asinhl(long double);
@ -237,6 +240,8 @@ long double fminl(long double, long double);
long double fmodl(long double, long double);
long double hypotl(long double, long double);
long double ldexpl(long double, int);
long double lgammal(long double);
long double lgammal_r(long double, int *);
long double log10l(long double);
long double log1pl(long double);
long double log2l(long double);
@ -260,8 +265,8 @@ long double sinl(long double);
long double sqrtl(long double);
long double tanhl(long double);
long double tanl(long double);
long double tgammal(long double);
long double truncl(long double);
int finitel(long double);
long lrint(double);
long lrintf(float);
@ -283,12 +288,15 @@ long long llroundl(long double);
double frexp(double, int *);
double modf(double, double *);
double nan(const char *);
double remquo(double, double, int *);
float frexpf(float, int *);
float modff(float, float *);
float nanf(const char *);
float remquof(float, float, int *);
long double frexpl(long double, int *);
long double modfl(long double, long double *);
long double nanl(const char *);
long double remquol(long double, long double, int *);
void sincos(double, double *, double *);
void sincosf(float, float *, float *);

View file

@ -28,7 +28,7 @@
*
* @return pointer that must be free()'d, or NULL w/ errno
*/
nodiscard char *get_current_dir_name(void) {
dontdiscard char *get_current_dir_name(void) {
const char *p;
if ((p = getenv("PWD")) && _isabspath(p)) {
return strdup(p);

View file

@ -15,16 +15,16 @@ void free(void *) libcesque;
void *malloc(size_t) attributeallocsize((1)) mallocesque;
void *calloc(size_t, size_t) attributeallocsize((1, 2)) mallocesque;
void *memalign(size_t, size_t) attributeallocalign((1))
attributeallocsize((2)) returnspointerwithnoaliases libcesque nodiscard;
attributeallocsize((2)) returnspointerwithnoaliases libcesque dontdiscard;
void *realloc(void *, size_t) reallocesque;
void *realloc_in_place(void *, size_t) reallocesque;
void *reallocarray(void *, size_t, size_t) nodiscard;
void *reallocarray(void *, size_t, size_t) dontdiscard;
void *valloc(size_t) attributeallocsize((1)) vallocesque;
void *pvalloc(size_t) vallocesque;
char *strdup(const char *) paramsnonnull() mallocesque;
char *strndup(const char *, size_t) paramsnonnull() mallocesque;
void *aligned_alloc(size_t, size_t) attributeallocsize((1))
attributeallocsize((2)) returnspointerwithnoaliases libcesque nodiscard;
attributeallocsize((2)) returnspointerwithnoaliases libcesque dontdiscard;
int posix_memalign(void **, size_t, size_t);
bool __grow(void *, size_t *, size_t, size_t) paramsnonnull((1, 2)) libcesque;
@ -34,7 +34,7 @@ size_t malloc_usable_size(const void *);
void **independent_calloc(size_t, size_t, void **);
void **independent_comalloc(size_t, size_t *, void **);
wchar_t *wcsdup(const wchar_t *) strlenesque nodiscard;
wchar_t *wcsdup(const wchar_t *) strlenesque dontdiscard;
struct mallinfo {
size_t arena; /* non-mmapped space allocated from system */

View file

@ -21,7 +21,7 @@
#include "libc/mem/mem.h"
#include "libc/str/str.h"
nodiscard void *unhexstr(const char *hexdigs) {
dontdiscard void *unhexstr(const char *hexdigs) {
assert(strlen(hexdigs) % 2 == 0);
return unhexbuf(malloc(strlen(hexdigs) / 2), strlen(hexdigs) / 2, hexdigs);
}

View file

@ -20,7 +20,7 @@ COSMOPOLITAN_C_START_
int bsf(int) pureconst;
int bsfl(long) pureconst;
int bsfll(long long) pureconst;
int bsfmax(uintmax_t) pureconst;
int bsf128(uintmax_t) pureconst;
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define bsf(u) \

View file

@ -20,7 +20,7 @@ COSMOPOLITAN_C_START_
int bsr(int) pureconst;
int bsrl(long) pureconst;
int bsrll(long long) pureconst;
int bsrmax(uintmax_t) pureconst;
int bsr128(uint128_t) pureconst;
#if defined(__GNUC__) && defined(__x86_64__) && !defined(__STRICT_ANSI__)
#define bsr(u) \

View file

@ -33,7 +33,7 @@
// @param rsi:rdi is 128-bit unsigned 𝑥 value
// @return eax number in range [0,128) or undef if 𝑥 is 0
// @see also treasure trove of nearly identical functions
bsrmax: .leafprologue
bsr128: .leafprologue
.profilable
bsr %rsi,%rax
jnz 2f
@ -41,4 +41,4 @@ bsrmax: .leafprologue
1: .leafepilogue
2: add $64,%eax
jmp 1b
.endfn bsrmax,globl
.endfn bsr128,globl

View file

@ -71,12 +71,12 @@ bool32 OfferVirtualMemory(void *inout_VirtualAddress, size_t Size,
int Priority);
int64_t GetProcessHeap(void);
void *HeapAlloc(int64_t hHeap, uint32_t dwFlags, size_t dwBytes) nodiscard;
void *HeapAlloc(int64_t hHeap, uint32_t dwFlags, size_t dwBytes) dontdiscard;
bool32 HeapFree(int64_t hHeap, uint32_t dwFlags, void *opt_lpMem);
void *HeapReAlloc(int64_t hHeap, uint32_t dwFlags, void *lpMem,
size_t dwBytes) nodiscard;
size_t dwBytes) dontdiscard;
void *GlobalAlloc(uint32_t uFlags, uint64_t dwBytes) nodiscard;
void *GlobalAlloc(uint32_t uFlags, uint64_t dwBytes) dontdiscard;
void *GlobalFree(void *hMem);
#if ShouldUseMsabiAttribute()

View file

@ -22,7 +22,7 @@
COSMOPOLITAN_C_START_
char16_t *GetCommandLine(void) nosideeffect;
char16_t *GetEnvironmentStrings(void) nodiscard;
char16_t *GetEnvironmentStrings(void) dontdiscard;
bool32 FreeEnvironmentStrings(char16_t *) paramsnonnull();
bool32 ReadFile(int64_t hFile, void *lpBuffer, uint32_t nNumberOfBytesToRead,
uint32_t *lpNumberOfBytesRead,
@ -35,7 +35,7 @@ bool32 TerminateProcess(int64_t hProcess, uint32_t uExitCode);
int64_t GetCurrentProcess(void) pureconst;
void ExitProcess(uint32_t uExitCode) wontreturn;
uint32_t GetLastError(void) nosideeffect;
bool32 CloseHandle(int64_t hObject) nothrow nocallback;
bool32 CloseHandle(int64_t hObject) dontthrow nocallback;
intptr_t GetStdHandle(int64_t nStdHandle) nosideeffect;
bool32 SetStdHandle(int64_t nStdHandle, int64_t hHandle);
bool32 SetDefaultDllDirectories(unsigned dirflags);

View file

@ -328,7 +328,7 @@ struct NtInterfaceInfo {
*/
int32_t WSAStartup(uint16_t wVersionRequested, struct NtWsaData *lpWSAData)
paramsnonnull() nodiscard;
paramsnonnull() dontdiscard;
int WSACleanup(void);
int WSAGetLastError(void);
@ -348,7 +348,7 @@ int __sys_select_nt(int, struct NtFdSet *, struct NtFdSet *, struct NtFdSet *,
uint64_t WSASocket(int af, int type, int protocol,
const struct NtWsaProtocolInfo *opt_lpProtocolInfo,
const uint32_t opt_group, uint32_t dwFlags) nodiscard;
const uint32_t opt_group, uint32_t dwFlags) dontdiscard;
int WSAConnect(uint64_t s, const struct sockaddr *name, const int namelen,
const struct NtIovec *opt_lpCallerData,
@ -378,7 +378,7 @@ int64_t WSAAccept(uint64_t s, struct sockaddr *out_addr,
int32_t *opt_inout_addrlen,
const NtConditionProc opt_lpfnCondition,
const uint32_t *opt_dwCallbackData)
paramsnonnull((2)) nodiscard;
paramsnonnull((2)) dontdiscard;
int WSASend(uint64_t s, const struct NtIovec *lpBuffers, uint32_t dwBufferCount,
uint32_t *opt_out_lpNumberOfBytesSent, uint32_t dwFlags,
@ -440,7 +440,7 @@ int WSANSPIoctl(int64_t hLookup, uint32_t dwControlCode,
const struct NtWsaCompletion *opt_lpCompletion)
paramsnonnull((3, 5, 7));
int64_t WSACreateEvent(void) nodiscard;
int64_t WSACreateEvent(void) dontdiscard;
bool32 WSACloseEvent(const int64_t hEvent);
bool32 WSAResetEvent(const int64_t hEvent);
bool32 WSASetEvent(const int64_t hEvent);

View file

@ -1,56 +0,0 @@
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
PKGS += LIBC_OHMYPLUS
LIBC_OHMYPLUS_ARTIFACTS += LIBC_OHMYPLUS_A
LIBC_OHMYPLUS = $(LIBC_OHMYPLUS_A_DEPS) $(LIBC_OHMYPLUS_A)
LIBC_OHMYPLUS_A = o/$(MODE)/libc/ohmyplus/ohmyplus.a
LIBC_OHMYPLUS_A_FILES := $(wildcard libc/ohmyplus/*)
LIBC_OHMYPLUS_A_HDRS = $(filter %.h,$(LIBC_OHMYPLUS_A_FILES))
LIBC_OHMYPLUS_A_SRCS_S = $(filter %.S,$(LIBC_OHMYPLUS_A_FILES))
LIBC_OHMYPLUS_A_SRCS_C = $(filter %.c,$(LIBC_OHMYPLUS_A_FILES))
LIBC_OHMYPLUS_A_SRCS_CXX = $(filter %.cc,$(LIBC_OHMYPLUS_A_FILES))
LIBC_OHMYPLUS_A_SRCS = \
$(LIBC_OHMYPLUS_A_SRCS_S) \
$(LIBC_OHMYPLUS_A_SRCS_C) \
$(LIBC_OHMYPLUS_A_SRCS_CXX)
LIBC_OHMYPLUS_A_OBJS = \
$(LIBC_OHMYPLUS_A_SRCS_S:%.S=o/$(MODE)/%.o) \
$(LIBC_OHMYPLUS_A_SRCS_C:%.c=o/$(MODE)/%.o) \
$(LIBC_OHMYPLUS_A_SRCS_CXX:%.cc=o/$(MODE)/%.o)
LIBC_OHMYPLUS_A_CHECKS = \
$(LIBC_OHMYPLUS_A).pkg \
$(LIBC_OHMYPLUS_A_HDRS:%=o/$(MODE)/%.okk)
LIBC_OHMYPLUS_A_DIRECTDEPS = \
LIBC_BITS \
LIBC_INTRIN \
LIBC_MEM \
LIBC_STUBS \
LIBC_NEXGEN32E
LIBC_OHMYPLUS_A_DEPS := \
$(call uniq,$(foreach x,$(LIBC_OHMYPLUS_A_DIRECTDEPS),$($(x))))
$(LIBC_OHMYPLUS_A): \
libc/ohmyplus/ \
$(LIBC_OHMYPLUS_A).pkg \
$(LIBC_OHMYPLUS_A_OBJS)
$(LIBC_OHMYPLUS_A).pkg: \
$(LIBC_OHMYPLUS_A_OBJS) \
$(foreach x,$(LIBC_OHMYPLUS_A_DIRECTDEPS),$($(x)_A).pkg)
LIBC_OHMYPLUS_LIBS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)))
LIBC_OHMYPLUS_SRCS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_SRCS))
LIBC_OHMYPLUS_HDRS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_HDRS))
LIBC_OHMYPLUS_CHECKS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_CHECKS))
LIBC_OHMYPLUS_OBJS = $(foreach x,$(LIBC_OHMYPLUS_ARTIFACTS),$($(x)_OBJS))
$(LIBC_OHMYPLUS_OBJS): $(BUILD_FILES) libc/ohmyplus/ohmyplus.mk
.PHONY: o/$(MODE)/libc/ohmyplus
o/$(MODE)/libc/ohmyplus: $(LIBC_OHMYPLUS_CHECKS)

View file

@ -1,56 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_OHMYPLUS_VECTOR_H_
#define COSMOPOLITAN_LIBC_OHMYPLUS_VECTOR_H_
#ifdef __cplusplus
extern "C" {
void __vector_reserve(size_t, size_t, intptr_t **, size_t *);
} /* extern c */
namespace std {
template <class T>
class vector {
public:
vector() : data_(NULL), size_(0), toto_(0) {
}
vector(size_t n) : data_(NULL), size_(n), toto_(0) {
VectorReserve(n);
}
size_t size() const {
return size_;
}
size_t capacity() const {
return toto_;
}
T &front() {
return data_[0];
}
T &back() {
return data_[size_ - 1];
}
void clear() {
size_ = 0;
}
void reserve(size_t n) {
VectorReserve(n);
}
void resize(size_t n) {
reserve((size_ = n));
}
bool empty() const {
return !size_;
}
T &operator[](size_t i) {
return data_[i];
}
private:
T *data_;
size_t size_;
size_t toto_;
void VectorReserve(size_t n) {
__vector_reserve(n, sizeof(T), (intptr_t **)&data_, &toto_);
}
};
}; /* namespace std */
#endif /* __cplusplus */
#endif /* COSMOPOLITAN_LIBC_OHMYPLUS_VECTOR_H_ */

View file

@ -10,7 +10,7 @@ void *_gc(void *) hidden;
void *_defer(void *, void *) hidden;
void __defer(struct StackFrame *, void *, void *) hidden;
void __deferer(struct StackFrame *, void *, void *) hidden;
void _gclongjmp(jmp_buf, int) nothrow wontreturn;
void _gclongjmp(jmp_buf, int) dontthrow wontreturn;
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define _gc(THING) _defer((void *)_weakfree, (void *)(THING))

View file

@ -74,15 +74,15 @@ errno_t __dos2errno(uint32_t);
void _firewall(const void *, uint32_t) hidden;
int32_t __sys_accept(int32_t, void *, uint32_t *, int) nodiscard hidden;
int32_t __sys_accept4(int32_t, void *, uint32_t *, int) nodiscard hidden;
int32_t __sys_accept(int32_t, void *, uint32_t *, int) dontdiscard hidden;
int32_t __sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden;
int32_t __sys_connect(int32_t, const void *, uint32_t) hidden;
int32_t __sys_socket(int32_t, int32_t, int32_t) hidden;
int32_t __sys_getsockname(int32_t, void *, uint32_t *) hidden;
int32_t __sys_getpeername(int32_t, void *, uint32_t *) hidden;
int32_t __sys_socketpair(int32_t, int32_t, int32_t, int32_t[2]) hidden;
int32_t sys_accept4(int32_t, void *, uint32_t *, int) nodiscard hidden;
int32_t sys_accept4(int32_t, void *, uint32_t *, int) dontdiscard hidden;
int32_t sys_accept(int32_t, void *, uint32_t *) hidden;
int32_t sys_bind(int32_t, const void *, uint32_t) hidden;
int32_t sys_connect(int32_t, const void *, uint32_t) hidden;

View file

@ -21,6 +21,6 @@
/**
* Delegates to mkotempsm() w/ owner-only non-execute access.
*/
nodiscard int mkostemps(char *template, int suffixlen, unsigned flags) {
dontdiscard int mkostemps(char *template, int suffixlen, unsigned flags) {
return mkostempsm(template, suffixlen, flags, 0600);
}

View file

@ -74,8 +74,8 @@ static uint64_t g_mkostemps_reseed;
* or -1 w/ errno
* @see kTmpPath
*/
nodiscard int mkostempsm(char *template, int suffixlen, unsigned flags,
int mode) {
dontdiscard int mkostempsm(char *template, int suffixlen, unsigned flags,
int mode) {
if (g_mkostemps_reseed++ % RESEED == 0) g_mkostemps_rand = rand64();
return mkostempsmi(template, suffixlen, flags, &g_mkostemps_rand, mode, open);
}

View file

@ -22,9 +22,9 @@
* Formats and writes string to stdout.
*
* Cosmopolitan supports most of the standard formatting behaviors
* described by `man 3 printf`, in addition to the following:
* described by `man 3 printf`, in addition to the following
*
* - `%jd`, `%jx`, etc. are {,u}intmax_t which in Cosmopolitan is 128-bit.
* - `%jjd`, `%jjx`, etc. are {,u}int128_t (cosmopolitan only)
*
* - `%'d` or `%,d` may be used to insert thousands separators. The prior is
* consistent with C; the latter is consistent with Python.

View file

@ -57,9 +57,9 @@ int putchar(int);
int puts(const char *);
ssize_t getline(char **, size_t *, FILE *) paramsnonnull();
ssize_t getdelim(char **, size_t *, int, FILE *) paramsnonnull();
FILE *fopen(const char *, const char *) paramsnonnull() nodiscard;
FILE *fdopen(int, const char *) paramsnonnull() nodiscard;
FILE *fmemopen(void *, size_t, const char *) paramsnonnull((3)) nodiscard;
FILE *fopen(const char *, const char *) paramsnonnull() dontdiscard;
FILE *fdopen(int, const char *) paramsnonnull() dontdiscard;
FILE *fmemopen(void *, size_t, const char *) paramsnonnull((3)) dontdiscard;
FILE *freopen(const char *, const char *, FILE *) paramsnonnull((2, 3));
size_t fread(void *, size_t, size_t, FILE *) paramsnonnull((4));
size_t fwrite(const void *, size_t, size_t, FILE *) paramsnonnull((4));
@ -90,16 +90,31 @@ int systemexec(const char *);
*/
int printf(const char *, ...) printfesque(1)
paramsnonnull((1)) nothrow nocallback;
int vprintf(const char *, va_list) paramsnonnull() nothrow nocallback;
paramsnonnull((1)) dontthrow nocallback;
int vprintf(const char *, va_list) paramsnonnull() dontthrow nocallback;
int fprintf(FILE *, const char *, ...) printfesque(2)
paramsnonnull((1, 2)) nothrow nocallback;
int vfprintf(FILE *, const char *, va_list) paramsnonnull() nothrow nocallback;
paramsnonnull((1, 2)) dontthrow nocallback;
int vfprintf(FILE *, const char *, va_list)
paramsnonnull() dontthrow nocallback;
int scanf(const char *, ...) scanfesque(1);
int vscanf(const char *, va_list);
int fscanf(FILE *, const char *, ...) scanfesque(2);
int vfscanf(FILE *, const char *, va_list);
int fwprintf(FILE *, const wchar_t *, ...);
int fwscanf(FILE *, const wchar_t *, ...);
int swprintf(wchar_t *, size_t, const wchar_t *, ...);
int swscanf(const wchar_t *, const wchar_t *, ...);
int vfwprintf(FILE *, const wchar_t *, va_list);
int vfwscanf(FILE *, const wchar_t *, va_list);
int vswprintf(wchar_t *, size_t, const wchar_t *, va_list);
int vswscanf(const wchar_t *, const wchar_t *, va_list);
int vwprintf(const wchar_t *, va_list);
int vwscanf(const wchar_t *, va_list);
int wprintf(const wchar_t *, ...);
int wscanf(const wchar_t *, ...);
int fwide(FILE *, int);
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § standard i/o » optimizations
*/

View file

@ -4,16 +4,17 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
nodiscard FILE *tmpfile(void);
nodiscard int mkstemp(char *);
nodiscard int mkostemp(char *, unsigned);
nodiscard int mkstemps(char *, int);
nodiscard int mkostemps(char *, int, unsigned);
nodiscard int mkostempsm(char *, int, unsigned, int);
dontdiscard FILE *tmpfile(void);
dontdiscard int mkstemp(char *);
dontdiscard int mkostemp(char *, unsigned);
dontdiscard int mkstemps(char *, int);
dontdiscard int mkostemps(char *, int, unsigned);
dontdiscard int mkostempsm(char *, int, unsigned, int);
compatfn char *mktemp(char *);
char *tmpnam(char *);
int mkostempsmi(char *, int, unsigned, uint64_t *, int,
int (*)(const char *, int, ...)) hidden nodiscard;
int (*)(const char *, int, ...)) hidden dontdiscard;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -192,7 +192,7 @@ wchar_t *wmempcpy(wchar_t *, const wchar_t *, size_t) memcpyesque;
wchar_t *wmemmove(wchar_t *, const wchar_t *, size_t) memcpyesque;
void *tinymemccpy(void *, const void *, int, size_t) memcpyesque;
void *memmem(const void *, size_t, const void *, size_t) libcesque nosideeffect;
char *strerror(int) returnsnonnull nothrow nocallback;
char *strerror(int) returnsnonnull dontthrow nocallback;
long a64l(const char *);
char *l64a(long);
@ -254,6 +254,10 @@ typedef unsigned wctype_t;
wctype_t wctype(const char *) strlenesque;
int iswctype(wint_t, wctype_t) pureconst;
typedef const int *wctrans_t;
wctrans_t wctrans(const char *);
wint_t towctrans(wint_t, wctrans_t);
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § strings » system
*/

25
libc/str/towctrans.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2022 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/str/str.h"
wint_t towctrans(wint_t c, wctrans_t t) {
if (t == (wctrans_t)1) return towupper(c);
if (t == (wctrans_t)2) return towlower(c);
return c;
}

25
libc/str/wctrans.c Normal file
View file

@ -0,0 +1,25 @@
/*-*- 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 2022 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/str/str.h"
wctrans_t wctrans(const char *s) {
if (!strcmp(s, "toupper")) return (wctrans_t)1;
if (!strcmp(s, "tolower")) return (wctrans_t)2;
return 0;
}

View file

@ -7,6 +7,7 @@
#include "libc/testlib/testlib.h"
#include "libc/time/time.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
#define EZBENCH(INIT, EXPR) EZBENCH2(#EXPR, INIT, EXPR)
@ -189,5 +190,7 @@ void __testlib_ezbenchreport_n(const char *, char, size_t, uint64_t);
#define EZBENCH_N(NAME, N, EXPR) (void)0
#define EZBENCH_K(NAME, K, EXPR) (void)0
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_TESTLIB_EZBENCH_H_ */

View file

@ -25,7 +25,7 @@
static size_t sbufi_;
static char sbufs_[2][256];
nodiscard testonly char *testlib_formatint(intptr_t x) {
dontdiscard testonly char *testlib_formatint(intptr_t x) {
char *str = sbufi_ < ARRAYLEN(sbufs_) ? sbufs_[sbufi_++] : malloc(256);
char *p = str;
p += sprintf(p, "%ld\t(or %#lx", x, x);

View file

@ -19,6 +19,6 @@
#include "libc/testlib/testlib.h"
#include "libc/x/x.h"
nodiscard testonly char *testlib_formatrange(intptr_t beg, intptr_t end) {
dontdiscard testonly char *testlib_formatrange(intptr_t beg, intptr_t end) {
return xasprintf("[%#ld,%#ld]", beg, end);
}

View file

@ -24,7 +24,7 @@
/**
* Turns string into code.
*/
nodiscard testonly char *testlib_formatstr(size_t cw, const void *s, int n) {
dontdiscard testonly char *testlib_formatstr(size_t cw, const void *s, int n) {
if (s) {
switch (cw) {
case 1:

View file

@ -4,6 +4,7 @@
#include "libc/calls/struct/timespec.h"
#include "libc/calls/struct/timeval.h"
#include "libc/time/struct/timezone.h"
#include "libc/time/struct/tm.h"
#include "libc/time/struct/utimbuf.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
@ -63,8 +64,9 @@ extern long double (*nowl)(void);
long double ConvertTicksToNanos(uint64_t);
void RefreshTime(void);
double difftime(int64_t, int64_t) nothrow pureconst;
double difftime(int64_t, int64_t) dontthrow pureconst;
char *iso8601(char[hasatleast 20], struct tm *);
size_t wcsftime(wchar_t *, size_t, const wchar_t *, const struct tm *);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

71
libc/tinymath/cosdf.c Normal file
View file

@ -0,0 +1,71 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
Musl Libc
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/math.h"
asm(".ident\t\"\\n\\n\
fdlibm (fdlibm license)\\n\
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\"");
asm(".ident\t\"\\n\\n\
Musl libc (MIT License)\\n\
Copyright 2005-2014 Rich Felker, et. al.\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */
/* origin: FreeBSD /usr/src/lib/msun/src/k_cosf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Debugged and optimized by Bruce D. Evans.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]). */
static const double
C0 = -0x1ffffffd0c5e81.0p-54, /* -0.499999997251031003120 */
C1 = 0x155553e1053a42.0p-57, /* 0.0416666233237390631894 */
C2 = -0x16c087e80f1e27.0p-62, /* -0.00138867637746099294692 */
C3 = 0x199342e0ee5069.0p-68; /* 0.0000243904487962774090654 */
float __cosdf(double x)
{
double_t r, w, z;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x*x;
w = z*z;
r = C2+z*C3;
return ((1.0+z*C0) + w*C1) + (w*z)*r;
}

View file

@ -322,6 +322,5 @@ double lgamma_r(double x, int *signgamp)
*/
double lgamma(double x)
{
extern int __signgam;
return lgamma_r(x, &__signgam);
}

View file

@ -3,6 +3,11 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
extern int __signgam;
float __cosdf(double);
float __sindf(double);
float __tandf(double, int);
double __sin(double, double, int);
double __tan(double, double, int);
double __cos(double, double);

24
libc/tinymath/lgamma.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2022 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/math.h"
#include "libc/tinymath/kernel.internal.h"
double lgamma(double x) {
return lgamma_r(x, &__signgam);
}

321
libc/tinymath/lgamma_r.c Normal file
View file

@ -0,0 +1,321 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
Musl Libc
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/math.h"
#include "libc/tinymath/kernel.internal.h"
asm(".ident\t\"\\n\\n\
fdlibm (fdlibm license)\\n\
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\"");
asm(".ident\t\"\\n\\n\
Musl libc (MIT License)\\n\
Copyright 2005-2014 Rich Felker, et. al.\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */
/* origin: FreeBSD /usr/src/lib/msun/src/e_lgamma_r.c */
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*
*/
/* lgamma_r(x, signgamp)
* Reentrant version of the logarithm of the Gamma function
* with user provide pointer for the sign of Gamma(x).
*
* Method:
* 1. Argument Reduction for 0 < x <= 8
* Since gamma(1+s)=s*gamma(s), for x in [0,8], we may
* reduce x to a number in [1.5,2.5] by
* lgamma(1+s) = log(s) + lgamma(s)
* for example,
* lgamma(7.3) = log(6.3) + lgamma(6.3)
* = log(6.3*5.3) + lgamma(5.3)
* = log(6.3*5.3*4.3*3.3*2.3) + lgamma(2.3)
* 2. Polynomial approximation of lgamma around its
* minimun ymin=1.461632144968362245 to maintain monotonicity.
* On [ymin-0.23, ymin+0.27] (i.e., [1.23164,1.73163]), use
* Let z = x-ymin;
* lgamma(x) = -1.214862905358496078218 + z^2*poly(z)
* where
* poly(z) is a 14 degree polynomial.
* 2. Rational approximation in the primary interval [2,3]
* We use the following approximation:
* s = x-2.0;
* lgamma(x) = 0.5*s + s*P(s)/Q(s)
* with accuracy
* |P/Q - (lgamma(x)-0.5s)| < 2**-61.71
* Our algorithms are based on the following observation
*
* zeta(2)-1 2 zeta(3)-1 3
* lgamma(2+s) = s*(1-Euler) + --------- * s - --------- * s + ...
* 2 3
*
* where Euler = 0.5771... is the Euler constant, which is very
* close to 0.5.
*
* 3. For x>=8, we have
* lgamma(x)~(x-0.5)log(x)-x+0.5*log(2pi)+1/(12x)-1/(360x**3)+....
* (better formula:
* lgamma(x)~(x-0.5)*(log(x)-1)-.5*(log(2pi)-1) + ...)
* Let z = 1/x, then we approximation
* f(z) = lgamma(x) - (x-0.5)(log(x)-1)
* by
* 3 5 11
* w = w0 + w1*z + w2*z + w3*z + ... + w6*z
* where
* |w - f(z)| < 2**-58.74
*
* 4. For negative x, since (G is gamma function)
* -x*G(-x)*G(x) = pi/sin(pi*x),
* we have
* G(x) = pi/(sin(pi*x)*(-x)*G(-x))
* since G(-x) is positive, sign(G(x)) = sign(sin(pi*x)) for x<0
* Hence, for x<0, signgam = sign(sin(pi*x)) and
* lgamma(x) = log(|Gamma(x)|)
* = log(pi/(|x*sin(pi*x)|)) - lgamma(-x);
* Note: one should avoid compute pi*(-x) directly in the
* computation of sin(pi*(-x)).
*
* 5. Special Cases
* lgamma(2+s) ~ s*(1-Euler) for tiny s
* lgamma(1) = lgamma(2) = 0
* lgamma(x) ~ -log(|x|) for tiny x
* lgamma(0) = lgamma(neg.integer) = inf and raise divide-by-zero
* lgamma(inf) = inf
* lgamma(-inf) = inf (bug for bug compatible with C99!?)
*
*/
static const double
pi = 3.14159265358979311600e+00, /* 0x400921FB, 0x54442D18 */
a0 = 7.72156649015328655494e-02, /* 0x3FB3C467, 0xE37DB0C8 */
a1 = 3.22467033424113591611e-01, /* 0x3FD4A34C, 0xC4A60FAD */
a2 = 6.73523010531292681824e-02, /* 0x3FB13E00, 0x1A5562A7 */
a3 = 2.05808084325167332806e-02, /* 0x3F951322, 0xAC92547B */
a4 = 7.38555086081402883957e-03, /* 0x3F7E404F, 0xB68FEFE8 */
a5 = 2.89051383673415629091e-03, /* 0x3F67ADD8, 0xCCB7926B */
a6 = 1.19270763183362067845e-03, /* 0x3F538A94, 0x116F3F5D */
a7 = 5.10069792153511336608e-04, /* 0x3F40B6C6, 0x89B99C00 */
a8 = 2.20862790713908385557e-04, /* 0x3F2CF2EC, 0xED10E54D */
a9 = 1.08011567247583939954e-04, /* 0x3F1C5088, 0x987DFB07 */
a10 = 2.52144565451257326939e-05, /* 0x3EFA7074, 0x428CFA52 */
a11 = 4.48640949618915160150e-05, /* 0x3F07858E, 0x90A45837 */
tc = 1.46163214496836224576e+00, /* 0x3FF762D8, 0x6356BE3F */
tf = -1.21486290535849611461e-01, /* 0xBFBF19B9, 0xBCC38A42 */
/* tt = -(tail of tf) */
tt = -3.63867699703950536541e-18, /* 0xBC50C7CA, 0xA48A971F */
t0 = 4.83836122723810047042e-01, /* 0x3FDEF72B, 0xC8EE38A2 */
t1 = -1.47587722994593911752e-01, /* 0xBFC2E427, 0x8DC6C509 */
t2 = 6.46249402391333854778e-02, /* 0x3FB08B42, 0x94D5419B */
t3 = -3.27885410759859649565e-02, /* 0xBFA0C9A8, 0xDF35B713 */
t4 = 1.79706750811820387126e-02, /* 0x3F9266E7, 0x970AF9EC */
t5 = -1.03142241298341437450e-02, /* 0xBF851F9F, 0xBA91EC6A */
t6 = 6.10053870246291332635e-03, /* 0x3F78FCE0, 0xE370E344 */
t7 = -3.68452016781138256760e-03, /* 0xBF6E2EFF, 0xB3E914D7 */
t8 = 2.25964780900612472250e-03, /* 0x3F6282D3, 0x2E15C915 */
t9 = -1.40346469989232843813e-03, /* 0xBF56FE8E, 0xBF2D1AF1 */
t10 = 8.81081882437654011382e-04, /* 0x3F4CDF0C, 0xEF61A8E9 */
t11 = -5.38595305356740546715e-04, /* 0xBF41A610, 0x9C73E0EC */
t12 = 3.15632070903625950361e-04, /* 0x3F34AF6D, 0x6C0EBBF7 */
t13 = -3.12754168375120860518e-04, /* 0xBF347F24, 0xECC38C38 */
t14 = 3.35529192635519073543e-04, /* 0x3F35FD3E, 0xE8C2D3F4 */
u0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
u1 = 6.32827064025093366517e-01, /* 0x3FE4401E, 0x8B005DFF */
u2 = 1.45492250137234768737e+00, /* 0x3FF7475C, 0xD119BD6F */
u3 = 9.77717527963372745603e-01, /* 0x3FEF4976, 0x44EA8450 */
u4 = 2.28963728064692451092e-01, /* 0x3FCD4EAE, 0xF6010924 */
u5 = 1.33810918536787660377e-02, /* 0x3F8B678B, 0xBF2BAB09 */
v1 = 2.45597793713041134822e+00, /* 0x4003A5D7, 0xC2BD619C */
v2 = 2.12848976379893395361e+00, /* 0x40010725, 0xA42B18F5 */
v3 = 7.69285150456672783825e-01, /* 0x3FE89DFB, 0xE45050AF */
v4 = 1.04222645593369134254e-01, /* 0x3FBAAE55, 0xD6537C88 */
v5 = 3.21709242282423911810e-03, /* 0x3F6A5ABB, 0x57D0CF61 */
s0 = -7.72156649015328655494e-02, /* 0xBFB3C467, 0xE37DB0C8 */
s1 = 2.14982415960608852501e-01, /* 0x3FCB848B, 0x36E20878 */
s2 = 3.25778796408930981787e-01, /* 0x3FD4D98F, 0x4F139F59 */
s3 = 1.46350472652464452805e-01, /* 0x3FC2BB9C, 0xBEE5F2F7 */
s4 = 2.66422703033638609560e-02, /* 0x3F9B481C, 0x7E939961 */
s5 = 1.84028451407337715652e-03, /* 0x3F5E26B6, 0x7368F239 */
s6 = 3.19475326584100867617e-05, /* 0x3F00BFEC, 0xDD17E945 */
r1 = 1.39200533467621045958e+00, /* 0x3FF645A7, 0x62C4AB74 */
r2 = 7.21935547567138069525e-01, /* 0x3FE71A18, 0x93D3DCDC */
r3 = 1.71933865632803078993e-01, /* 0x3FC601ED, 0xCCFBDF27 */
r4 = 1.86459191715652901344e-02, /* 0x3F9317EA, 0x742ED475 */
r5 = 7.77942496381893596434e-04, /* 0x3F497DDA, 0xCA41A95B */
r6 = 7.32668430744625636189e-06, /* 0x3EDEBAF7, 0xA5B38140 */
w0 = 4.18938533204672725052e-01, /* 0x3FDACFE3, 0x90C97D69 */
w1 = 8.33333333333329678849e-02, /* 0x3FB55555, 0x5555553B */
w2 = -2.77777777728775536470e-03, /* 0xBF66C16C, 0x16B02E5C */
w3 = 7.93650558643019558500e-04, /* 0x3F4A019F, 0x98CF38B6 */
w4 = -5.95187557450339963135e-04, /* 0xBF4380CB, 0x8C0FE741 */
w5 = 8.36339918996282139126e-04, /* 0x3F4B67BA, 0x4CDAD5D1 */
w6 = -1.63092934096575273989e-03; /* 0xBF5AB89D, 0x0B9E43E4 */
/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
static double sin_pi(double x)
{
int n;
/* spurious inexact if odd int */
x = 2.0*(x*0.5 - floor(x*0.5)); /* x mod 2.0 */
n = (int)(x*4.0);
n = (n+1)/2;
x -= n*0.5f;
x *= pi;
switch (n) {
default: /* case 4: */
case 0: return __sin(x, 0.0, 0);
case 1: return __cos(x, 0.0);
case 2: return __sin(-x, 0.0, 0);
case 3: return -__cos(x, 0.0);
}
}
/**
* Returns natural logarithm of absolute value of Gamma function.
*/
double lgamma_r(double x, int *signgamp)
{
union {double f; uint64_t i;} u = {x};
double_t t,y,z,nadj,p,p1,p2,p3,q,r,w;
uint32_t ix;
int sign,i;
/* purge off +-inf, NaN, +-0, tiny and negative arguments */
*signgamp = 1;
sign = u.i>>63;
ix = u.i>>32 & 0x7fffffff;
if (ix >= 0x7ff00000)
return x*x;
if (ix < (0x3ff-70)<<20) { /* |x|<2**-70, return -log(|x|) */
if(sign) {
x = -x;
*signgamp = -1;
}
return -log(x);
}
if (sign) {
x = -x;
t = sin_pi(x);
if (t == 0.0) /* -integer */
return 1.0/(x-x);
if (t > 0.0)
*signgamp = -1;
else
t = -t;
nadj = log(pi/(t*x));
}
/* purge off 1 and 2 */
if ((ix == 0x3ff00000 || ix == 0x40000000) && (uint32_t)u.i == 0)
r = 0;
/* for x < 2.0 */
else if (ix < 0x40000000) {
if (ix <= 0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */
r = -log(x);
if (ix >= 0x3FE76944) {
y = 1.0 - x;
i = 0;
} else if (ix >= 0x3FCDA661) {
y = x - (tc-1.0);
i = 1;
} else {
y = x;
i = 2;
}
} else {
r = 0.0;
if (ix >= 0x3FFBB4C3) { /* [1.7316,2] */
y = 2.0 - x;
i = 0;
} else if(ix >= 0x3FF3B4C4) { /* [1.23,1.73] */
y = x - tc;
i = 1;
} else {
y = x - 1.0;
i = 2;
}
}
switch (i) {
case 0:
z = y*y;
p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
p = y*p1+p2;
r += (p-0.5*y);
break;
case 1:
z = y*y;
w = z*y;
p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
p = z*p1-(tt-w*(p2+y*p3));
r += tf + p;
break;
case 2:
p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
p2 = 1.0+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
r += -0.5*y + p1/p2;
}
} else if (ix < 0x40200000) { /* x < 8.0 */
i = (int)x;
y = x - (double)i;
p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
q = 1.0+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
r = 0.5*y+p/q;
z = 1.0; /* lgamma(1+s) = log(s) + lgamma(s) */
switch (i) {
case 7: z *= y + 6.0; /* FALLTHRU */
case 6: z *= y + 5.0; /* FALLTHRU */
case 5: z *= y + 4.0; /* FALLTHRU */
case 4: z *= y + 3.0; /* FALLTHRU */
case 3: z *= y + 2.0; /* FALLTHRU */
r += log(z);
break;
}
} else if (ix < 0x43900000) { /* 8.0 <= x < 2**58 */
t = log(x);
z = 1.0/x;
y = z*z;
w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
r = (x-0.5)*(t-1.0)+w;
} else /* 2**58 <= x <= inf */
r = x*(log(x)-1.0);
if (sign)
r = nadj - r;
return r;
}

24
libc/tinymath/lgammaf.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2022 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/math.h"
#include "libc/tinymath/kernel.internal.h"
float lgammaf(float x) {
return lgammaf_r(x, &__signgam);
}

256
libc/tinymath/lgammaf_r.c Normal file
View file

@ -0,0 +1,256 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
Musl Libc
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/math.h"
#include "libc/tinymath/kernel.internal.h"
asm(".ident\t\"\\n\\n\
fdlibm (fdlibm license)\\n\
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\"");
asm(".ident\t\"\\n\\n\
Musl libc (MIT License)\\n\
Copyright 2005-2014 Rich Felker, et. al.\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */
/* origin: FreeBSD /usr/src/lib/msun/src/e_lgammaf_r.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
static const float
pi = 3.1415927410e+00, /* 0x40490fdb */
a0 = 7.7215664089e-02, /* 0x3d9e233f */
a1 = 3.2246702909e-01, /* 0x3ea51a66 */
a2 = 6.7352302372e-02, /* 0x3d89f001 */
a3 = 2.0580807701e-02, /* 0x3ca89915 */
a4 = 7.3855509982e-03, /* 0x3bf2027e */
a5 = 2.8905137442e-03, /* 0x3b3d6ec6 */
a6 = 1.1927076848e-03, /* 0x3a9c54a1 */
a7 = 5.1006977446e-04, /* 0x3a05b634 */
a8 = 2.2086278477e-04, /* 0x39679767 */
a9 = 1.0801156895e-04, /* 0x38e28445 */
a10 = 2.5214456400e-05, /* 0x37d383a2 */
a11 = 4.4864096708e-05, /* 0x383c2c75 */
tc = 1.4616321325e+00, /* 0x3fbb16c3 */
tf = -1.2148628384e-01, /* 0xbdf8cdcd */
/* tt = -(tail of tf) */
tt = 6.6971006518e-09, /* 0x31e61c52 */
t0 = 4.8383611441e-01, /* 0x3ef7b95e */
t1 = -1.4758771658e-01, /* 0xbe17213c */
t2 = 6.4624942839e-02, /* 0x3d845a15 */
t3 = -3.2788541168e-02, /* 0xbd064d47 */
t4 = 1.7970675603e-02, /* 0x3c93373d */
t5 = -1.0314224288e-02, /* 0xbc28fcfe */
t6 = 6.1005386524e-03, /* 0x3bc7e707 */
t7 = -3.6845202558e-03, /* 0xbb7177fe */
t8 = 2.2596477065e-03, /* 0x3b141699 */
t9 = -1.4034647029e-03, /* 0xbab7f476 */
t10 = 8.8108185446e-04, /* 0x3a66f867 */
t11 = -5.3859531181e-04, /* 0xba0d3085 */
t12 = 3.1563205994e-04, /* 0x39a57b6b */
t13 = -3.1275415677e-04, /* 0xb9a3f927 */
t14 = 3.3552918467e-04, /* 0x39afe9f7 */
u0 = -7.7215664089e-02, /* 0xbd9e233f */
u1 = 6.3282704353e-01, /* 0x3f2200f4 */
u2 = 1.4549225569e+00, /* 0x3fba3ae7 */
u3 = 9.7771751881e-01, /* 0x3f7a4bb2 */
u4 = 2.2896373272e-01, /* 0x3e6a7578 */
u5 = 1.3381091878e-02, /* 0x3c5b3c5e */
v1 = 2.4559779167e+00, /* 0x401d2ebe */
v2 = 2.1284897327e+00, /* 0x4008392d */
v3 = 7.6928514242e-01, /* 0x3f44efdf */
v4 = 1.0422264785e-01, /* 0x3dd572af */
v5 = 3.2170924824e-03, /* 0x3b52d5db */
s0 = -7.7215664089e-02, /* 0xbd9e233f */
s1 = 2.1498242021e-01, /* 0x3e5c245a */
s2 = 3.2577878237e-01, /* 0x3ea6cc7a */
s3 = 1.4635047317e-01, /* 0x3e15dce6 */
s4 = 2.6642270386e-02, /* 0x3cda40e4 */
s5 = 1.8402845599e-03, /* 0x3af135b4 */
s6 = 3.1947532989e-05, /* 0x3805ff67 */
r1 = 1.3920053244e+00, /* 0x3fb22d3b */
r2 = 7.2193557024e-01, /* 0x3f38d0c5 */
r3 = 1.7193385959e-01, /* 0x3e300f6e */
r4 = 1.8645919859e-02, /* 0x3c98bf54 */
r5 = 7.7794247773e-04, /* 0x3a4beed6 */
r6 = 7.3266842264e-06, /* 0x36f5d7bd */
w0 = 4.1893854737e-01, /* 0x3ed67f1d */
w1 = 8.3333335817e-02, /* 0x3daaaaab */
w2 = -2.7777778450e-03, /* 0xbb360b61 */
w3 = 7.9365057172e-04, /* 0x3a500cfd */
w4 = -5.9518753551e-04, /* 0xba1c065c */
w5 = 8.3633989561e-04, /* 0x3a5b3dd2 */
w6 = -1.6309292987e-03; /* 0xbad5c4e8 */
/* sin(pi*x) assuming x > 2^-100, if sin(pi*x)==0 the sign is arbitrary */
static float sin_pi(float x)
{
double_t y;
int n;
/* spurious inexact if odd int */
x = 2*(x*0.5f - floorf(x*0.5f)); /* x mod 2.0 */
n = (int)(x*4);
n = (n+1)/2;
y = x - n*0.5f;
y *= 3.14159265358979323846;
switch (n) {
default: /* case 4: */
case 0: return __sindf(y);
case 1: return __cosdf(y);
case 2: return __sindf(-y);
case 3: return -__cosdf(y);
}
}
/**
* Returns natural logarithm of absolute value of Gamma function.
*/
float lgammaf_r(float x, int *signgamp)
{
union {float f; uint32_t i;} u = {x};
float t,y,z,nadj,p,p1,p2,p3,q,r,w;
uint32_t ix;
int i,sign;
/* purge off +-inf, NaN, +-0, tiny and negative arguments */
*signgamp = 1;
sign = u.i>>31;
ix = u.i & 0x7fffffff;
if (ix >= 0x7f800000)
return x*x;
if (ix < 0x35000000) { /* |x| < 2**-21, return -log(|x|) */
if (sign) {
*signgamp = -1;
x = -x;
}
return -logf(x);
}
if (sign) {
x = -x;
t = sin_pi(x);
if (t == 0.0f) /* -integer */
return 1.0f/(x-x);
if (t > 0.0f)
*signgamp = -1;
else
t = -t;
nadj = logf(pi/(t*x));
}
/* purge off 1 and 2 */
if (ix == 0x3f800000 || ix == 0x40000000)
r = 0;
/* for x < 2.0 */
else if (ix < 0x40000000) {
if (ix <= 0x3f666666) { /* lgamma(x) = lgamma(x+1)-log(x) */
r = -logf(x);
if (ix >= 0x3f3b4a20) {
y = 1.0f - x;
i = 0;
} else if (ix >= 0x3e6d3308) {
y = x - (tc-1.0f);
i = 1;
} else {
y = x;
i = 2;
}
} else {
r = 0.0f;
if (ix >= 0x3fdda618) { /* [1.7316,2] */
y = 2.0f - x;
i = 0;
} else if (ix >= 0x3F9da620) { /* [1.23,1.73] */
y = x - tc;
i = 1;
} else {
y = x - 1.0f;
i = 2;
}
}
switch(i) {
case 0:
z = y*y;
p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10))));
p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11)))));
p = y*p1+p2;
r += p - 0.5f*y;
break;
case 1:
z = y*y;
w = z*y;
p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */
p2 = t1+w*(t4+w*(t7+w*(t10+w*t13)));
p3 = t2+w*(t5+w*(t8+w*(t11+w*t14)));
p = z*p1-(tt-w*(p2+y*p3));
r += (tf + p);
break;
case 2:
p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5)))));
p2 = 1.0f+y*(v1+y*(v2+y*(v3+y*(v4+y*v5))));
r += -0.5f*y + p1/p2;
}
} else if (ix < 0x41000000) { /* x < 8.0 */
i = (int)x;
y = x - (float)i;
p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6))))));
q = 1.0f+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6)))));
r = 0.5f*y+p/q;
z = 1.0f; /* lgamma(1+s) = log(s) + lgamma(s) */
switch (i) {
case 7: z *= y + 6.0f; /* FALLTHRU */
case 6: z *= y + 5.0f; /* FALLTHRU */
case 5: z *= y + 4.0f; /* FALLTHRU */
case 4: z *= y + 3.0f; /* FALLTHRU */
case 3: z *= y + 2.0f; /* FALLTHRU */
r += logf(z);
break;
}
} else if (ix < 0x5c800000) { /* 8.0 <= x < 2**58 */
t = logf(x);
z = 1.0f/x;
y = z*z;
w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6)))));
r = (x-0.5f)*(t-1.0f)+w;
} else /* 2**58 <= x <= inf */
r = x*(logf(x)-1.0f);
if (sign)
r = nadj - r;
return r;
}

View file

@ -1,7 +1,7 @@
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi
/*-*- 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
Copyright 2022 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
@ -16,8 +16,8 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/macros.internal.h"
#include "libc/math.h"
__imaxabs:
jmp imaxabs
.endfn __imaxabs,globl
double nan(const char *s) {
return NAN;
}

23
libc/tinymath/nanf.c Normal file
View file

@ -0,0 +1,23 @@
/*-*- 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 2022 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/math.h"
float nanf(const char *s) {
return NAN;
}

23
libc/tinymath/nanl.c Normal file
View file

@ -0,0 +1,23 @@
/*-*- 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 2022 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/math.h"
long double nanl(const char *s) {
return NAN;
}

72
libc/tinymath/sindf.c Normal file
View file

@ -0,0 +1,72 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
Musl Libc
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/math.h"
asm(".ident\t\"\\n\\n\
fdlibm (fdlibm license)\\n\
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\"");
asm(".ident\t\"\\n\\n\
Musl libc (MIT License)\\n\
Copyright 2005-2014 Rich Felker, et. al.\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */
/* origin: FreeBSD /usr/src/lib/msun/src/k_sinf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Optimized by Bruce D. Evans.
*/
/*
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunPro, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]). */
static const double
S1 = -0x15555554cbac77.0p-55, /* -0.166666666416265235595 */
S2 = 0x111110896efbb2.0p-59, /* 0.0083333293858894631756 */
S3 = -0x1a00f9e2cae774.0p-65, /* -0.000198393348360966317347 */
S4 = 0x16cd878c3b46a7.0p-71; /* 0.0000027183114939898219064 */
float __sindf(double x)
{
double_t r, s, w, z;
/* Try to optimize for parallel evaluation as in __tandf.c. */
z = x*x;
w = z*z;
r = S3 + z*S4;
s = z*x;
return (x + s*(S1 + z*S2)) + s*w*r;
}

90
libc/tinymath/tandf.c Normal file
View file

@ -0,0 +1,90 @@
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
vi: set et ft=c ts=8 tw=8 fenc=utf-8 :vi
Musl Libc
Copyright © 2005-2020 Rich Felker, et al.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/math.h"
asm(".ident\t\"\\n\\n\
fdlibm (fdlibm license)\\n\
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\"");
asm(".ident\t\"\\n\\n\
Musl libc (MIT License)\\n\
Copyright 2005-2014 Rich Felker, et. al.\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */
/* origin: FreeBSD /usr/src/lib/msun/src/k_tanf.c */
/*
* Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
* Optimized by Bruce D. Evans.
*/
/*
* ====================================================
* Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/
/* |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]). */
static const double T[] = {
0x15554d3418c99f.0p-54, /* 0.333331395030791399758 */
0x1112fd38999f72.0p-55, /* 0.133392002712976742718 */
0x1b54c91d865afe.0p-57, /* 0.0533812378445670393523 */
0x191df3908c33ce.0p-58, /* 0.0245283181166547278873 */
0x185dadfcecf44e.0p-61, /* 0.00297435743359967304927 */
0x1362b9bf971bcd.0p-59, /* 0.00946564784943673166728 */
};
float __tandf(double x, int odd)
{
double_t z,r,w,s,t,u;
z = x*x;
/*
* Split up the polynomial into small independent terms to give
* opportunities for parallel evaluation. The chosen splitting is
* micro-optimized for Athlons (XP, X64). It costs 2 multiplications
* relative to Horner's method on sequential machines.
*
* We add the small terms from lowest degree up for efficiency on
* non-sequential machines (the lowest degree terms tend to be ready
* earlier). Apart from this, we don't care about order of
* operations, and don't need to to care since we have precision to
* spare. However, the chosen splitting is good for accuracy too,
* and would give results as accurate as Horner's method if the
* small terms were added from highest degree down.
*/
r = T[4] + z*T[5];
t = T[2] + z*T[3];
w = z*z;
s = z*x;
u = T[0] + z*T[1];
r = (x + s*u) + (s*w)*(t + w*r);
return odd ? -1.0/r : r;
}

24
libc/unicode/isdigit_l.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2022 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/str/str.h"
#include "libc/unicode/locale.h"
int isdigit_l(int c, locale_t l) {
return iswdigit(c);
}

24
libc/unicode/isxdigit_l.c Normal file
View file

@ -0,0 +1,24 @@
/*-*- 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 2022 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/str/str.h"
#include "libc/unicode/locale.h"
int isxdigit_l(int c, locale_t l) {
return iswxdigit(c);
}

View file

@ -1,5 +1,6 @@
#ifndef COSMOPOLITAN_LIBC_UNICODE_LOCALE_H_
#define COSMOPOLITAN_LIBC_UNICODE_LOCALE_H_
#include "libc/fmt/conv.h"
#define LC_CTYPE 0
#define LC_NUMERIC 1
@ -19,7 +20,24 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
struct __locale_struct;
typedef struct __locale_struct *locale_t;
char *setlocale(int, const char *);
locale_t uselocale(locale_t);
locale_t newlocale(int, const char *, locale_t);
long long strtoll_l(const char *, char **, int, locale_t);
unsigned long long strtoull_l(const char *, char **, int, locale_t);
long long wcstoll_l(const wchar_t *, wchar_t **, int, locale_t);
unsigned long long wcstoull_l(const wchar_t *, wchar_t **, int, locale_t);
float strtof_l(const char *, char **, locale_t);
float wcstof_l(const wchar_t *, wchar_t **, locale_t);
double wcstod_l(const wchar_t *, wchar_t **, locale_t);
long double wcstold_l(const wchar_t *, wchar_t **, locale_t);
double strtod_l(const char *, char **, locale_t);
long double strtold_l(const char *, char **, locale_t);
int isxdigit_l(int, locale_t);
int isdigit_l(int, locale_t);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -14,7 +14,7 @@ COSMOPOLITAN_C_START_
Standard Library veneers for folks not building embedded RTOS */
#define _XPNN paramsnonnull()
#define _XRET nothrow nocallback nodiscard returnsnonnull
#define _XRET dontthrow nocallback dontdiscard returnsnonnull
#define _XMAL returnspointerwithnoaliases _XRET
#define _XMALPG returnsaligned((PAGESIZE)) _XMAL
@ -38,7 +38,7 @@ char *xvasprintf(const char *, va_list) _XPNN _XMAL;
char *xgetline(struct FILE *) _XPNN mallocesque;
void *xmalloc(size_t) attributeallocsize((1)) _XMAL;
void *xrealloc(void *, size_t)
attributeallocsize((2)) nothrow nocallback nodiscard;
attributeallocsize((2)) dontthrow nocallback dontdiscard;
void *xcalloc(size_t, size_t) attributeallocsize((1, 2)) _XMAL;
void *xvalloc(size_t) attributeallocsize((1)) _XMALPG;
void *xmemalign(size_t, size_t) attributeallocalign((1))
@ -52,13 +52,13 @@ char *xstrmul(const char *, size_t) paramsnonnull((1)) _XMAL;
char *xinet_ntop(int, const void *) _XPNN _XMAL;
void *xunbinga(size_t, const char16_t *) attributeallocalign((1)) _XMAL _XRET;
void *xunbing(const char16_t *) _XMAL _XRET;
char16_t *utf8toutf16(const char *, size_t, size_t *) nodiscard;
char *utf16toutf8(const char16_t *, size_t, size_t *) nodiscard;
wchar_t *utf8toutf32(const char *, size_t, size_t *) nodiscard;
wchar_t *utf16to32(const char16_t *, size_t, size_t *) nodiscard;
char *xhomedir(void) nodiscard;
char *xstripext(const char *) nodiscard;
char *xstripexts(const char *) nodiscard;
char16_t *utf8toutf16(const char *, size_t, size_t *) dontdiscard;
char *utf16toutf8(const char16_t *, size_t, size_t *) dontdiscard;
wchar_t *utf8toutf32(const char *, size_t, size_t *) dontdiscard;
wchar_t *utf16to32(const char16_t *, size_t, size_t *) dontdiscard;
char *xhomedir(void) dontdiscard;
char *xstripext(const char *) dontdiscard;
char *xstripexts(const char *) dontdiscard;
void *xload(bool *, void **, const void *, size_t, size_t);
void *xloadzd(bool *, void **, const void *, size_t, size_t, size_t, size_t,
uint32_t);
@ -88,7 +88,7 @@ char *xiso8601ts(struct timespec *) mallocesque;
void *xslurp(const char *, size_t *)
paramsnonnull((1)) returnspointerwithnoaliases
returnsaligned((PAGESIZE)) nodiscard;
returnsaligned((PAGESIZE)) dontdiscard;
int xbarf(const char *, const void *, size_t);
/*───────────────────────────────────────────────────────────────────────────│─╗

View file

@ -29,7 +29,7 @@ struct Bog {
const char *p[];
};
static testonly nodiscard struct Bog *NewBog(unsigned n) {
static testonly dontdiscard struct Bog *NewBog(unsigned n) {
struct Bog *res = malloc(sizeof(struct Bog) + sizeof(const char *) * n);
res->i = 0;
res->n = n;

View file

@ -306,24 +306,24 @@ TEST(strtoimax, testEndPtr) {
ASSERT_EQ(1, e - p);
}
TEST(strtoimax, testLimits) {
TEST(strtoi128, testLimits) {
EXPECT_EQ(
((uintmax_t)0xffffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff,
strtoimax("-1", NULL, 0));
((uint128_t)0xffffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff,
strtoi128("-1", NULL, 0));
EXPECT_EQ(
((uintmax_t)0x7fffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff,
strtoimax("0x7fffffffffffffffffffffffffffffff", NULL, 0));
((uint128_t)0x7fffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff,
strtoi128("0x7fffffffffffffffffffffffffffffff", NULL, 0));
}
TEST(strtoimax, testOutsideLimit) {
TEST(strtoi128, testOutsideLimit) {
errno = 0;
EXPECT_EQ(
((uintmax_t)0x7fffffffffffffff) << 64 | (uintmax_t)0xffffffffffffffff,
strtoimax("0x80000000000000000000000000000000", NULL, 0));
((uint128_t)0x7fffffffffffffff) << 64 | (uint128_t)0xffffffffffffffff,
strtoi128("0x80000000000000000000000000000000", NULL, 0));
EXPECT_EQ(ERANGE, errno);
errno = 0;
EXPECT_EQ(((uintmax_t)0x8000000000000000) << 64 | 0x0000000000000000,
strtoimax("-0x80000000000000000000000000000001", NULL, 0));
EXPECT_EQ(((uint128_t)0x8000000000000000) << 64 | 0x0000000000000000,
strtoi128("-0x80000000000000000000000000000001", NULL, 0));
EXPECT_EQ(ERANGE, errno);
}
@ -335,6 +335,7 @@ TEST(strtoul, neghex) {
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));
@ -353,16 +354,16 @@ TEST(strtoumax, testBinary) {
EXPECT_EQ(42, strtoumax("0b101010", NULL, 2));
}
TEST(strtoumax, testMaximum) {
EXPECT_EQ(UINTMAX_MAX,
strtoumax("340282366920938463463374607431768211455", NULL, 0));
EXPECT_EQ(UINTMAX_MAX,
strtoumax("0xffffffffffffffffffffffffffffffff", NULL, 0));
TEST(strtou128, test128imum) {
EXPECT_EQ(UINT128_MAX,
strtou128("340282366920938463463374607431768211455", NULL, 0));
EXPECT_EQ(UINT128_MAX,
strtou128("0xffffffffffffffffffffffffffffffff", NULL, 0));
}
TEST(strtoumax, testTwosBane) {
EXPECT_EQ(((uintmax_t)0x8000000000000000) << 64 | 0x0000000000000000,
strtoumax("0x80000000000000000000000000000000", NULL, 0));
TEST(strtou128, testTwosBane) {
EXPECT_EQ(((uint128_t)0x8000000000000000) << 64 | 0x0000000000000000,
strtou128("0x80000000000000000000000000000000", NULL, 0));
}
TEST(wcstol, test) {
@ -566,4 +567,12 @@ 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)));
}

Some files were not shown because too many files have changed in this diff Show more