Add glob and some finer tuning of documentation

This commit is contained in:
Justine Tunney 2020-06-21 00:10:11 -07:00
parent 799e24a87b
commit d51409ccd9
77 changed files with 1321 additions and 736 deletions

View file

@ -13,17 +13,14 @@ 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;
void djbsort(size_t n, int32_t[n]);
void qsort(void *items, size_t itemcount, size_t itemsize,
int cmp(const void *, const void *)) paramsnonnull();
void qsort_r(void *items, size_t itemcount, size_t itemsize,
void qsort(void *, size_t, size_t, int (*)(const void *, const void *))
paramsnonnull();
void qsort_r(void *, size_t, size_t,
int cmp(const void *, const void *, void *), void *arg)
paramsnonnull((1, 4));
int tarjan(uint32_t vertex_count, const uint32_t (*edges)[2],
uint32_t edge_count, uint32_t out_sorted[],
uint32_t out_opt_components[], uint32_t *out_opt_componentcount)
paramsnonnull((2, 4)) nocallback nothrow;
void heapsortcar(int32_t (*A)[2], unsigned n)
paramsnonnull() nocallback nothrow;
int tarjan(uint32_t, const uint32_t (*)[2], uint32_t, uint32_t[], uint32_t[],
uint32_t *) paramsnonnull((2, 4)) nocallback nothrow;
void heapsortcar(int32_t (*)[2], unsigned) paramsnonnull() nocallback nothrow;
void *memmem(const void *, size_t, const void *, size_t)
paramsnonnull() nothrow nocallback nosideeffect;
@ -56,16 +53,16 @@ struct critbit0 {
size_t count;
};
bool critbit0_contains(struct critbit0 *t, const char *u) nothrow nosideeffect
bool critbit0_contains(struct critbit0 *, const char *) nothrow nosideeffect
paramsnonnull();
bool critbit0_insert(struct critbit0 *t, const char *u) paramsnonnull();
bool critbit0_delete(struct critbit0 *t, const char *u) nothrow paramsnonnull();
void critbit0_clear(struct critbit0 *t) nothrow paramsnonnull();
char *critbit0_get(struct critbit0 *t, const char *u);
intptr_t critbit0_allprefixed(struct critbit0 *t, const char *prefix,
intptr_t (*callback)(const char *elem, void *arg),
void *arg) paramsnonnull((1, 2, 3)) nothrow;
bool critbit0_emplace(struct critbit0 *t, char *u, size_t ulen) 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();
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;
bool critbit0_emplace(struct critbit0 *, char *, size_t) paramsnonnull();
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § algorithms » comparators

View file

@ -76,6 +76,7 @@ static textwindows noinline DIR *opendir$nt(const char *name) {
*
* @returns newly allocated DIR object, or NULL w/ errno
* @errors ENOENT, ENOTDIR, EACCES, EMFILE, ENFILE, ENOMEM
* @see glob()
*/
DIR *opendir(const char *name) {
if (!IsWindows() && !IsXnu()) {

View file

@ -12,7 +12,7 @@ int ioctl(int, uint64_t, void *);
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § system calls » input output control » undiamonding
*/
#ifdef __GNUC__
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#include "libc/macros.h"
#include "libc/sysv/consts/termios.h"
@ -46,7 +46,7 @@ forceinline int ioctl$dispatch(int fd, uint64_t request, void *memory) {
return ioctl$default(fd, request, memory);
}
#endif /* GNUC */
#endif /* GNUC && !ANSI */
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_IOCTL_H_ */

View file

@ -28,8 +28,9 @@ int unlockpt(int);
int posix_openpt(int) nodiscard;
/*───────────────────────────────────────────────────────────────────────────│─╗
cosmopolitan § teletypewriter » optimizations
cosmopolitan § teletypewriter » undiamonding
*/
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
#define tcsetattr(FD, OPT, TIO) tcsetattr$dispatch(FD, OPT, TIO)
forceinline int tcsetattr$dispatch(int fd, int opt, const struct termios *tio) {
@ -44,6 +45,7 @@ forceinline int tcgetattr$dispatch(int fd, const struct termios *tio) {
return ioctl(fd, TCGETS, (void *)tio);
}
#endif /* GNUC && !ANSI */
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_CALLS_TERMIOS_H_ */

View file

@ -3,7 +3,7 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
/**
* @fileoverview Types for scoundrels.
* @fileoverview Types we'd prefer hadn't been invented.
*/
#define blkcnt_t int64_t

View file

@ -49,7 +49,7 @@ aes_block_t unrijndael(uint32_t, aes_block_t, const struct Rijndael *);
aligned(64) extern const uint8_t kAesSbox[256];
aligned(64) extern const uint8_t kAesSboxInverse[256];
aes_block_t InvMixColumns(aes_block_t x) hidden;
aes_block_t InvMixColumns(aes_block_t) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -18,12 +18,10 @@ COSMOPOLITAN_C_START_
struct MappedFile;
Elf64_Ehdr *mapelfread(const char *filename, struct MappedFile *mf);
char *getelfstringtable(const Elf64_Ehdr *elf, size_t mapsize);
Elf64_Sym *getelfsymboltable(const Elf64_Ehdr *elf, size_t mapsize,
Elf64_Xword *out_count);
Elf64_Shdr *getelfsectionbyaddress(const Elf64_Ehdr *elf, size_t mapsize,
void *addr);
Elf64_Ehdr *mapelfread(const char *, struct MappedFile *);
char *getelfstringtable(const Elf64_Ehdr *, size_t);
Elf64_Sym *getelfsymboltable(const Elf64_Ehdr *, size_t, Elf64_Xword *);
Elf64_Shdr *getelfsectionbyaddress(const Elf64_Ehdr *, size_t, void *);
forceinline void checkelfaddress(const Elf64_Ehdr *elf, size_t mapsize,
intptr_t addr, size_t addrsize) {
@ -66,8 +64,9 @@ static inline Elf64_Shdr *getelfsectionheaderaddress(const Elf64_Ehdr *elf,
static inline void *getelfsectionaddress(const Elf64_Ehdr *elf, size_t mapsize,
const Elf64_Shdr *shdr) {
intptr_t addr = (intptr_t)elf + (intptr_t)shdr->sh_offset;
intptr_t size = (intptr_t)shdr->sh_size;
intptr_t addr, size;
addr = (intptr_t)elf + (intptr_t)shdr->sh_offset;
size = (intptr_t)shdr->sh_size;
checkelfaddress(elf, mapsize, addr, size);
return (void *)addr;
}
@ -83,13 +82,16 @@ static inline void getelfvirtualaddressrange(const Elf64_Ehdr *elf,
size_t elfsize,
intptr_t *out_start,
intptr_t *out_end) {
intptr_t start = INTPTR_MAX;
intptr_t end = 0;
for (unsigned i = 0; i < elf->e_phnum; ++i) {
Elf64_Phdr *phdr = getelfsegmentheaderaddress(elf, elfsize, i);
unsigned i;
Elf64_Phdr *phdr;
intptr_t start, end, pstart, pend;
start = INTPTR_MAX;
end = 0;
for (i = 0; i < elf->e_phnum; ++i) {
phdr = getelfsegmentheaderaddress(elf, elfsize, i);
if (phdr->p_type != PT_LOAD) continue;
intptr_t pstart = phdr->p_vaddr;
intptr_t pend = phdr->p_vaddr + phdr->p_memsz;
pstart = phdr->p_vaddr;
pend = phdr->p_vaddr + phdr->p_memsz;
if (pstart < start) start = pstart;
if (pend > end) end = pend;
}

View file

@ -23,9 +23,10 @@
Elf64_Shdr *getelfsectionbyaddress(const Elf64_Ehdr *elf, size_t mapsize,
void *addr) {
Elf64_Half i;
Elf64_Shdr *shdr;
if (elf) {
for (i = elf->e_shnum; i > 0; --i) {
Elf64_Shdr *shdr = getelfsectionheaderaddress(elf, mapsize, i - 1);
shdr = getelfsectionheaderaddress(elf, mapsize, i - 1);
if ((intptr_t)addr >= shdr->sh_addr &&
(intptr_t)addr < shdr->sh_addr + shdr->sh_size) {
return shdr;

View file

@ -7,20 +7,15 @@ COSMOPOLITAN_C_START_
cosmopolitan § escaping
*/
unsigned cescapec(int c);
int escapec(char *buf, unsigned size, const char *unescaped, unsigned length)
unsigned cescapec(int);
int escapec(char *, unsigned, const char *, unsigned)
paramsnonnull((3)) nothrow nocallback;
int escapesh(char *buf, unsigned size, const char *unescaped, unsigned length)
paramsnonnull((3));
bool escapedos(char16_t *buffer, unsigned buflen, const char16_t *unquoted,
unsigned len);
int aescapec(char **escaped, const char *unescaped, unsigned length)
paramsnonnull();
int aescapesh(char **escaped, const char *unescaped, unsigned length)
paramsnonnull();
int aescape(char **escaped, size_t size, const char *unescaped, unsigned length,
int impl(char *escaped, unsigned size, const char *unescaped,
unsigned length)) hidden;
int escapesh(char *, unsigned, const char *, unsigned) paramsnonnull((3));
bool escapedos(char16_t *, unsigned, const char16_t *, unsigned);
int aescapec(char **, const char *, unsigned) paramsnonnull();
int aescapesh(char **, const char *, unsigned) paramsnonnull();
int aescape(char **, size_t, const char *, unsigned,
int (*)(char *, unsigned, const char *, unsigned)) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -20,11 +20,6 @@
#include "libc/escape/escape.h"
#include "libc/str/str.h"
asm(".ident\t\"\\n\\n\
NSSM (Public Domain)\\n\
Credit: Iain Patterson\n\
http://iain.cx/\"");
static textwindows bool shouldescapedos(const char16_t c) {
if (c == u'"') return true;
if (c == u'&') return true;
@ -48,6 +43,7 @@ static textwindows bool shouldquotedos(const char16_t c) {
/**
* Escapes command so DOS can run it.
* @see Iain Patterson's NSSM for original code in public domain
*/
textwindows bool escapedos(char16_t *buffer, unsigned buflen,
const char16_t *unquoted, unsigned len) {

View file

@ -170,138 +170,138 @@ kErrnoNames:
/ @assume linker invoked as LC_ALL=C ld ...
/ @see libc/sysv/systemfive.S
/ @see libc/sysv/consts/syscon.h
yoink E2BIG
yoink EACCES
yoink EADDRINUSE
yoink EADDRNOTAVAIL
yoink EADV
yoink EAFNOSUPPORT
yoink EAGAIN
yoink EALREADY
yoink EBADE
yoink EBADF
yoink EBADFD
yoink EBADMSG
yoink EBADR
yoink EBADRQC
yoink EBADSLT
yoink EBFONT
yoink EBUSY
yoink ECANCELED
yoink ECHILD
yoink ECHRNG
yoink ECOMM
yoink ECONNABORTED
yoink ECONNREFUSED
yoink ECONNRESET
yoink EDEADLK
yoink EDESTADDRREQ
yoink EDOM
yoink EDOTDOT
yoink EDQUOT
yoink EEXIST
yoink EFAULT
yoink EFBIG
yoink EHOSTDOWN
yoink EHOSTUNREACH
yoink EHWPOISON
yoink EIDRM
yoink EILSEQ
yoink EINPROGRESS
yoink EINTR
yoink EINVAL
yoink EIO
yoink EISCONN
yoink EISDIR
yoink EISNAM
yoink EKEYEXPIRED
yoink EKEYREJECTED
yoink EKEYREVOKED
yoink EL2HLT
yoink EL2NSYNC
yoink EL3HLT
yoink EL3RST
yoink ELIBACC
yoink ELIBBAD
yoink ELIBEXEC
yoink ELIBMAX
yoink ELIBSCN
yoink ELNRNG
yoink ELOOP
yoink EMEDIUMTYPE
yoink EMFILE
yoink EMLINK
yoink EMSGSIZE
yoink EMULTIHOP
yoink ENAMETOOLONG
yoink ENAVAIL
yoink ENETDOWN
yoink ENETRESET
yoink ENETUNREACH
yoink ENFILE
yoink ENOANO
yoink ENOBUFS
yoink ENOCSI
yoink ENODATA
yoink ENODEV
yoink ENOENT
yoink ENOEXEC
yoink ENOKEY
yoink ENOLCK
yoink ENOLINK
yoink ENOMEDIUM
yoink ENOMEM
yoink ENOMSG
yoink ENONET
yoink ENOPKG
yoink ENOPROTOOPT
yoink ENOSPC
yoink ENOSR
yoink ENOSTR
yoink ENOSYS
yoink ENOTBLK
yoink ENOTCONN
yoink ENOTDIR
yoink ENOTEMPTY
yoink ENOTNAM
yoink ENOTRECOVERABLE
yoink ENOTSOCK
yoink ENOTSUP
yoink ENOTTY
yoink ENOTUNIQ
yoink ENXIO
yoink EOPNOTSUPP
yoink EOVERFLOW
yoink EOWNERDEAD
yoink EPERM
yoink EPFNOSUPPORT
yoink EPIPE
yoink EPROTO
yoink EPROTONOSUPPORT
yoink EPROTOTYPE
yoink ERANGE
yoink EREMCHG
yoink EREMOTE
yoink EREMOTEIO
yoink ERESTART
yoink ERFKILL
yoink EROFS
yoink ESHUTDOWN
yoink ESOCKTNOSUPPORT
yoink ESPIPE
yoink ESRCH
yoink ESRMNT
yoink ESTALE
yoink ESTRPIPE
yoink ETIME
yoink ETIMEDOUT
yoink ETOOMANYREFS
yoink ETXTBSY
yoink EUCLEAN
yoink EUNATCH
yoink EUSERS
yoink EXDEV
yoink EXFULL
.yoink E2BIG
.yoink EACCES
.yoink EADDRINUSE
.yoink EADDRNOTAVAIL
.yoink EADV
.yoink EAFNOSUPPORT
.yoink EAGAIN
.yoink EALREADY
.yoink EBADE
.yoink EBADF
.yoink EBADFD
.yoink EBADMSG
.yoink EBADR
.yoink EBADRQC
.yoink EBADSLT
.yoink EBFONT
.yoink EBUSY
.yoink ECANCELED
.yoink ECHILD
.yoink ECHRNG
.yoink ECOMM
.yoink ECONNABORTED
.yoink ECONNREFUSED
.yoink ECONNRESET
.yoink EDEADLK
.yoink EDESTADDRREQ
.yoink EDOM
.yoink EDOTDOT
.yoink EDQUOT
.yoink EEXIST
.yoink EFAULT
.yoink EFBIG
.yoink EHOSTDOWN
.yoink EHOSTUNREACH
.yoink EHWPOISON
.yoink EIDRM
.yoink EILSEQ
.yoink EINPROGRESS
.yoink EINTR
.yoink EINVAL
.yoink EIO
.yoink EISCONN
.yoink EISDIR
.yoink EISNAM
.yoink EKEYEXPIRED
.yoink EKEYREJECTED
.yoink EKEYREVOKED
.yoink EL2HLT
.yoink EL2NSYNC
.yoink EL3HLT
.yoink EL3RST
.yoink ELIBACC
.yoink ELIBBAD
.yoink ELIBEXEC
.yoink ELIBMAX
.yoink ELIBSCN
.yoink ELNRNG
.yoink ELOOP
.yoink EMEDIUMTYPE
.yoink EMFILE
.yoink EMLINK
.yoink EMSGSIZE
.yoink EMULTIHOP
.yoink ENAMETOOLONG
.yoink ENAVAIL
.yoink ENETDOWN
.yoink ENETRESET
.yoink ENETUNREACH
.yoink ENFILE
.yoink ENOANO
.yoink ENOBUFS
.yoink ENOCSI
.yoink ENODATA
.yoink ENODEV
.yoink ENOENT
.yoink ENOEXEC
.yoink ENOKEY
.yoink ENOLCK
.yoink ENOLINK
.yoink ENOMEDIUM
.yoink ENOMEM
.yoink ENOMSG
.yoink ENONET
.yoink ENOPKG
.yoink ENOPROTOOPT
.yoink ENOSPC
.yoink ENOSR
.yoink ENOSTR
.yoink ENOSYS
.yoink ENOTBLK
.yoink ENOTCONN
.yoink ENOTDIR
.yoink ENOTEMPTY
.yoink ENOTNAM
.yoink ENOTRECOVERABLE
.yoink ENOTSOCK
.yoink ENOTSUP
.yoink ENOTTY
.yoink ENOTUNIQ
.yoink ENXIO
.yoink EOPNOTSUPP
.yoink EOVERFLOW
.yoink EOWNERDEAD
.yoink EPERM
.yoink EPFNOSUPPORT
.yoink EPIPE
.yoink EPROTO
.yoink EPROTONOSUPPORT
.yoink EPROTOTYPE
.yoink ERANGE
.yoink EREMCHG
.yoink EREMOTE
.yoink EREMOTEIO
.yoink ERESTART
.yoink ERFKILL
.yoink EROFS
.yoink ESHUTDOWN
.yoink ESOCKTNOSUPPORT
.yoink ESPIPE
.yoink ESRCH
.yoink ESRMNT
.yoink ESTALE
.yoink ESTRPIPE
.yoink ETIME
.yoink ETIMEDOUT
.yoink ETOOMANYREFS
.yoink ETXTBSY
.yoink EUCLEAN
.yoink EUNATCH
.yoink EUSERS
.yoink EXDEV
.yoink EXFULL
.type kErrnoStart,@object
.type kErrnoEnd,@object

View file

@ -37,6 +37,12 @@
static const int kPow10[] = {1, 10, 100, 1000, 10000,
100000, 1000000, 10000000, 100000000, 1000000000};
/**
* Formats floating point number.
*
* @see xdtoa() for higher precision at the cost of bloat
* @see palandprintf() which is intended caller
*/
int ftoa(int out(int, void *), void *arg, long double value, unsigned long prec,
unsigned long width, unsigned long flags) {
long whole, frac;

View file

@ -56,7 +56,52 @@ static unsigned ppatoi(const char **str) {
/**
* Implements {,v}{,s{,n},{,{,x}as},f,d}printf state machine.
* @see libc/stdio/printf.c for documentation
*
* Type Specifiers
*
* - `%s` char * (thompson-pike unicode)
* - `%ls` wchar_t * (32-bit unicode thompson-pike unicode)
* - `%hs` char16_t * (16-bit unicode thompson-pike unicode)
* - `%b` int (radix 2 binary)
* - `%o` int (radix 8 octal)
* - `%d` int (radix 10 decimal)
* - `%x` int (radix 16 hexadecimal)
* - `%X` int (radix 16 hexadecimal uppercase)
* - `%u` unsigned
* - `%f` double
* - `%Lf` long double
* - `%p` pointer (48-bit hexadecimal)
*
* Length Modifiers
*
* - `%hhd` char (8-bit)
* - `%hd` short (16-bit)
* - `%ld` long (64-bit)
* - `%lu` unsigned long (64-bit)
* - `%lx` unsigned long (64-bit hexadecimal)
* - `%jd` intmax_t (128-bit)
*
* Width Modifiers
*
* - `%08d` fixed columns w/ zero leftpadding
* - `%8d` fixed columns w/ space leftpadding
* - `%*s` variable column string (thompson-pike)
* - `%.*s` variable column data (ignore nul terminator)
*
* Formatting Modifiers
*
* - `%,d` thousands separators
* - `%'s` escaped c string literal
* - `%'c` escaped c character literal
* - `%`s` escaped double quoted c string literal
* - `%`c` escaped double quoted c character literal
* - `%+d` plus leftpad if positive (aligns w/ negatives)
* - `% d` space leftpad if positive (aligns w/ negatives)
* - `%#s` datum (radix 256 null-terminated ibm cp437)
* - `%#x` int (radix 16 hexadecimal w/ 0x prefix if not zero)
*
* @note implementation detail of printf(), snprintf(), etc.
* @see printf() for wordier documentation
*/
hidden int palandprintf(void *fn, void *arg, const char *format, va_list va) {
int (*out)(int, void *);

View file

@ -50,8 +50,18 @@
#endif
#if defined(__GNUC__) && __GNUC__ < 6
/*
* Compilers don't understand the features we've added to the format
* string DSL, such as c string escaping, therefore we can't use it.
* Ideally compilers should grant us more flexibility to define DSLs
*
* The recommended approach to turning this back on is `CFLAGS=-std=c11`
* which puts the compiler in __STRICT_ANSI__ mode, which Cosmopolitan
* respects by disabling all the esoteric tuning in headers like this.
*/
#pragma GCC diagnostic ignored "-Wformat-security"
#endif /* __GNUC__ + 0 < 6 */
#else
#define PFLINK(FMT) FMT
#define SFLINK(FMT) FMT

View file

@ -25,7 +25,7 @@
* @return number of bytes written, excluding the NUL terminator; or,
* if the output buffer wasn't passed, or was too short, then the
* number of characters that *would* have been written is returned
* @see libc/fmt/fmt.h for documentation
* @see palandprintf() and printf() for detailed documentation
*/
int(snprintf)(char* buf, size_t count, const char* fmt, ...) {
int rc;

View file

@ -20,6 +20,12 @@
#include "libc/fmt/fmt.h"
#include "libc/limits.h"
/**
* Formats string to buffer that's hopefully large enough.
*
* @see palandprintf() and printf() for detailed documentation
* @see snprintf() for same w/ buf size param
*/
int(sprintf)(char *buf, const char *fmt, ...) {
int rc;
va_list va;

View file

@ -74,6 +74,8 @@ forceinline int emitquote(int out(int, void *), void *arg, unsigned flags,
* This function is used by palandprintf() to implement the %s and %c
* directives. The content outputted to the array is always UTF-8, but
* the input may be UTF-16 or UTF-32.
*
* @see palandprintf()
*/
int stoa(int out(int, void *), void *arg, void *data, unsigned long flags,
unsigned long precision, unsigned long width, unsigned char signbit,

View file

@ -34,6 +34,9 @@
* 8-bit through 128-bit integers (with validation), floating point
* numbers, etc. It can also be used to convert UTF-8 to UTF-16/32.
*
* - `%d` parses integer
* - `%ms` parses string allocating buffer assigning pointer
*
* @param callback supplies UTF-8 characters using -1 sentinel
* @param fmt is a computer program embedded inside a c string, written
* in a domain-specific programming language that, by design, lacks

View file

@ -40,7 +40,7 @@ static int vsnprintfputchar(unsigned char c, struct SprintfStr *str) {
}
/**
* Formats string to buffer.
* Formats string to buffer w/ preexisting vararg state.
*
* @param buf stores output and a NUL-terminator is always written,
* provided buf!=NULL && size!=0
@ -50,7 +50,7 @@ static int vsnprintfputchar(unsigned char c, struct SprintfStr *str) {
* number of characters that *would* have been written is returned
* @throw EOVERFLOW when a formatted field exceeds its limit, which can
* be checked by setting errno to 0 before calling
* @see libc/fmt/fmt.h for further documentation
* @see palandprintf() and printf() for detailed documentation
*/
int(vsnprintf)(char *buf, size_t size, const char *fmt, va_list va) {
struct SprintfStr str = {buf, 0, size};

View file

@ -20,6 +20,12 @@
#include "libc/fmt/fmt.h"
#include "libc/limits.h"
/**
* Formats string to buffer hopefully large enough w/ vararg state.
*
* @see palandprintf() and printf() for detailed documentation
* @see vsnprintf() for modern alternative w/ buf size param
*/
int(vsprintf)(char *buf, const char *fmt, va_list va) {
return (vsnprintf)(buf, INT_MAX, fmt, va);
}

View file

@ -21,7 +21,7 @@
#include "libc/fmt/vsscanf.h"
/**
* String decoder.
* Decodes string.
*
* @see libc/fmt/vcscanf.h (for docs and implementation)
* @note to offer the best performance, we assume small codebases

View file

@ -1015,8 +1015,9 @@ typedef uint64_t uintmax_t;
/**
* Pulls source of object being compiled into zip.
* @note automates compliance with gpl terms
* @see -DIM_FEELING_NAUGHTY
* @note automates most compliance with gpl terms
* @see libc/zipos/zipcentraldir.S
* @see ape/ape.lds
*/
#ifdef __BASE_FILE__
STATIC_YOINK_SOURCE(__BASE_FILE__);

View file

@ -50,8 +50,7 @@ void exit(int) noreturn;
void quick_exit(int) noreturn;
void _exit(int) libcesque noreturn;
void _Exit(int) libcesque noreturn;
void abort(void) noreturn noinstrument forcealignargpointer;
void abort_(void) asm("abort") noreturn noinstrument privileged;
void abort(void) noreturn noinstrument;
void panic(void) noreturn noinstrument privileged;
void triplf(void) noreturn noinstrument privileged;
int __cxa_atexit(void *, void *, void *) libcesque;

View file

@ -44,7 +44,7 @@ size_t fread(void *buf, size_t stride, size_t count, FILE *f) {
if (i % stride != 0) abort(); /* todo(jart) */
return i / stride;
}
p[i] = (unsigned char)c;
p[i] = c & 0xff;
}
return count;
}

View file

@ -12,13 +12,13 @@ extern unsigned char g_stderrbuf[BUFSIZ];
int fflushregister(FILE *) hidden;
void fflushunregister(FILE *) hidden;
int freadbuf(FILE *f) hidden;
int fwritebuf(FILE *f) hidden;
int fsreadbuf(FILE *f) hidden;
int fswritebuf(FILE *f) hidden;
long fseteof(FILE *f) hidden;
long fseterrno(FILE *f) hidden;
long fseterr(FILE *f, int err) hidden;
int freadbuf(FILE *) hidden;
int fwritebuf(FILE *) hidden;
int fsreadbuf(FILE *) hidden;
int fswritebuf(FILE *) hidden;
long fseteof(FILE *) hidden;
long fseterrno(FILE *) hidden;
long fseterr(FILE *, int) hidden;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -59,6 +59,7 @@
* it implies the quoting modifier, wraps the value with {,u,L}['"]
* quotes, displays NULL as "NULL" rather than "(null)", etc.
*
* @see palandprintf() for intuitive reference documentation
* @see {,v}{,s{,n},{,{,x}as},f,d}printf
*/
int(printf)(const char* fmt, ...) {

View file

@ -4,29 +4,29 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
int getc_unlocked(FILE *f) paramsnonnull();
int getc_unlocked(FILE *) paramsnonnull();
int getchar_unlocked(void);
int putc_unlocked(int c, FILE *f) paramsnonnull();
int putchar_unlocked(int c);
void clearerr_unlocked(FILE *f);
int feof_unlocked(FILE *f);
int ferror_unlocked(FILE *f);
int fileno_unlocked(FILE *f);
int fflush_unlocked(FILE *f);
int fgetc_unlocked(FILE *f);
int fputc_unlocked(int c, FILE *f);
size_t fread_unlocked(void *ptr, size_t size, size_t n, FILE *f);
size_t fwrite_unlocked(const void *ptr, size_t size, size_t n, FILE *f);
char *fgets_unlocked(char *s, int n, FILE *f);
int fputs_unlocked(const char *s, FILE *f);
wint_t getwc_unlocked(FILE *f);
int putc_unlocked(int, FILE *) paramsnonnull();
int putchar_unlocked(int);
void clearerr_unlocked(FILE *);
int feof_unlocked(FILE *);
int ferror_unlocked(FILE *);
int fileno_unlocked(FILE *);
int fflush_unlocked(FILE *);
int fgetc_unlocked(FILE *);
int fputc_unlocked(int, FILE *);
size_t fread_unlocked(void *, size_t, size_t, FILE *);
size_t fwrite_unlocked(const void *, size_t, size_t, FILE *);
char *fgets_unlocked(char *, int, FILE *);
int fputs_unlocked(const char *, FILE *);
wint_t getwc_unlocked(FILE *);
wint_t getwchar_unlocked(void);
wint_t fgetwc_unlocked(FILE *f);
wint_t fputwc_unlocked(wchar_t wc, FILE *f);
wint_t putwc_unlocked(wchar_t wc, FILE *f);
wint_t putwchar_unlocked(wchar_t wc);
wchar_t *fgetws_unlocked(wchar_t *ws, int n, FILE *f);
int fputws_unlocked(const wchar_t *ws, FILE *f);
wint_t fgetwc_unlocked(FILE *);
wint_t fputwc_unlocked(wchar_t, FILE *);
wint_t putwc_unlocked(wchar_t, FILE *);
wint_t putwchar_unlocked(wchar_t);
wchar_t *fgetws_unlocked(wchar_t *, int, FILE *);
int fputws_unlocked(const wchar_t *, FILE *);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -21,8 +21,10 @@
.source __FILE__
clearerr_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call clearerr
.leafepilogue
pop %rbp
ret
.endfn clearerr_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
feof_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call feof
.leafepilogue
pop %rbp
ret
.endfn feof_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
ferror_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call ferror
.leafepilogue
pop %rbp
ret
.endfn ferror_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fflush_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fflush
.leafepilogue
pop %rbp
ret
.endfn fflush_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fgetc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fgetc
.leafepilogue
pop %rbp
ret
.endfn fgetc_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fgets_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fgets
.leafepilogue
pop %rbp
ret
.endfn fgets_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fgetwc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fgetwc
.leafepilogue
pop %rbp
ret
.endfn fgetwc_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fgetws_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fgetws
.leafepilogue
pop %rbp
ret
.endfn fgetws_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fileno_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fileno
.leafepilogue
pop %rbp
ret
.endfn fileno_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fputc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fputc
.leafepilogue
pop %rbp
ret
.endfn fputc_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fputs_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fputs
.leafepilogue
pop %rbp
ret
.endfn fputs_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fputwc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fputwc
.leafepilogue
pop %rbp
ret
.endfn fputwc_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fputws_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fputws
.leafepilogue
pop %rbp
ret
.endfn fputws_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fread_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fread
.leafepilogue
pop %rbp
ret
.endfn fread_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
fwrite_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fwrite
.leafepilogue
pop %rbp
ret
.endfn fwrite_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
getc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call getc
.leafepilogue
pop %rbp
ret
.endfn getc_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
getchar_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call getchar
.leafepilogue
pop %rbp
ret
.endfn getchar_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
getwc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fgetwc_unlocked
.leafepilogue
pop %rbp
ret
.endfn getwc_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
getwchar_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call getwchar
.leafepilogue
pop %rbp
ret
.endfn getwchar_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
putc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call putc
.leafepilogue
pop %rbp
ret
.endfn putc_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
putchar_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call putchar
.leafepilogue
pop %rbp
ret
.endfn putchar_unlocked,globl

View file

@ -21,8 +21,10 @@
.source __FILE__
putwc_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call fputwc_unlocked
.leafepilogue
pop %rbp
ret
.endfn putwc_unlocked,globl

View file

@ -22,8 +22,10 @@
.source __FILE__
putwchar_unlocked:
.leafprologue
.profilable # so we can fix code supporting this abomination
push %rbp
mov %rsp,%rbp
.profilable # note: no consensus for threads exists in abis
call putwchar
.leafepilogue
pop %rbp
ret
.endfn putwchar_unlocked,globl

View file

@ -1760,18 +1760,6 @@ syscon misc READ_POSITION 52 0 0 0 0
syscon misc READ_REVERSE 15 0 0 0 0
syscon misc READ_TOC 67 0 0 0 0
syscon glob GLOB_NOCHECK 0x10 0x10 0x10 0x10 0 # unix consensus
syscon glob GLOB_ABORTED 2 -2 -2 -2 0 # bsd consensus
syscon glob GLOB_APPEND 0x20 1 1 1 0 # bsd consensus
syscon glob GLOB_DOOFFS 8 2 2 2 0 # bsd consensus
syscon glob GLOB_ERR 1 4 4 4 0 # bsd consensus
syscon glob GLOB_MARK 2 8 8 8 0 # bsd consensus
syscon glob GLOB_NOMATCH 3 -3 -3 -3 0 # bsd consensus
syscon glob GLOB_NOSORT 4 0x20 0x20 0x20 0 # bsd consensus
syscon glob GLOB_NOSPACE 1 -1 -1 -1 0 # bsd consensus
syscon glob GLOB_NOSYS 4 -4 -4 -4 0 # bsd consensus
syscon glob GLOB_NOESCAPE 0x40 0x2000 0x2000 0x1000 0
# getpriority() / setpriority() magnums (a.k.a. nice)
#
# group name GNU/Systemd XNU's Not UNIX FreeBSD OpenBSD XENIX Commentary

View file

@ -1,34 +0,0 @@
#ifndef COSMOPOLITAN_LIBC_SYSV_CONSTS_GLOB_H_
#define COSMOPOLITAN_LIBC_SYSV_CONSTS_GLOB_H_
#include "libc/runtime/symbolic.h"
#define GLOB_ABORTED SYMBOLIC(GLOB_ABORTED)
#define GLOB_APPEND SYMBOLIC(GLOB_APPEND)
#define GLOB_DOOFFS SYMBOLIC(GLOB_DOOFFS)
#define GLOB_ERR SYMBOLIC(GLOB_ERR)
#define GLOB_MARK SYMBOLIC(GLOB_MARK)
#define GLOB_NOCHECK SYMBOLIC(GLOB_NOCHECK)
#define GLOB_NOESCAPE SYMBOLIC(GLOB_NOESCAPE)
#define GLOB_NOMATCH SYMBOLIC(GLOB_NOMATCH)
#define GLOB_NOSORT SYMBOLIC(GLOB_NOSORT)
#define GLOB_NOSPACE SYMBOLIC(GLOB_NOSPACE)
#define GLOB_NOSYS SYMBOLIC(GLOB_NOSYS)
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
hidden extern const long GLOB_ABORTED;
hidden extern const long GLOB_APPEND;
hidden extern const long GLOB_DOOFFS;
hidden extern const long GLOB_ERR;
hidden extern const long GLOB_MARK;
hidden extern const long GLOB_NOCHECK;
hidden extern const long GLOB_NOESCAPE;
hidden extern const long GLOB_NOMATCH;
hidden extern const long GLOB_NOSORT;
hidden extern const long GLOB_NOSPACE;
hidden extern const long GLOB_NOSYS;
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_LIBC_SYSV_CONSTS_GLOB_H_ */

View file

@ -60,6 +60,7 @@ void *xvalloc(size_t) attributeallocsize((1)) _XMALPG;
void *xmemalign(size_t, size_t) attributeallocalign((1))
attributeallocsize((2)) _XMAL;
char *xstrdup(const char *) _XPNN _XMAL;
char *xstrndup(const char *, size_t) _XPNN _XMAL;
char *xstrcat(const char *, ...) paramsnonnull((1)) nullterminated() _XMAL;
char *xstrmul(const char *, size_t) paramsnonnull((1)) _XMAL;
char *xinet_ntop(int, const void *) _XPNN _XMAL;

36
libc/x/xstrndup.c Normal file
View file

@ -0,0 +1,36 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi
Copyright 2020 Justine Alexandra Roberts Tunney
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/log/log.h"
#include "libc/mem/mem.h"
#include "libc/x/x.h"
/**
* Allocates new copy of string, with byte limit.
*
* @param s is a NUL-terminated byte string
* @param n if less than strlen(s) will truncate the string
* @return new string or NULL w/ errno
* @error ENOMEM
*/
char *xstrndup(const char *s, size_t n) {
void *res = strndup(s, n);
if (!res) die();
return res;
}