Auto-generate some documentation

This commit is contained in:
Justine Tunney 2020-12-26 02:09:07 -08:00
parent 117d0111ab
commit 13437dd19b
97 changed files with 2033 additions and 661 deletions

View file

@ -21,12 +21,8 @@
#include "libc/macros.h"
#include "libc/mem/mem.h"
#include "libc/str/str.h"
/* clang-format off */
static void KnuthMorrisPrattInit(m, T, W)
ssize_t m, T[m + 1];
const char W[m];
{
static void KnuthMorrisPrattInit(ssize_t m, ssize_t *T, const char *W) {
ssize_t i = 2;
ssize_t j = 0;
T[0] = -1;
@ -43,10 +39,8 @@ static void KnuthMorrisPrattInit(m, T, W)
T[m] = 0;
}
static size_t KnuthMorrisPratt(m, T, W, n, S)
const long n, m, T[m + 1];
const char W[m], S[n];
{
static size_t KnuthMorrisPratt(long m, const long *T, const char *W, long n,
const char *S) {
long i = 0, j = 0;
while (i + j < n) {
if (W[i] == S[i + j]) {
@ -60,8 +54,6 @@ static size_t KnuthMorrisPratt(m, T, W, n, S)
return j;
}
/* clang-format on */
/**
* Searches for fixed-length substring in memory region.
*

View file

@ -20,6 +20,9 @@
#include "libc/fmt/conv.h"
#include "libc/macros.h"
/**
* Returns absolute value of x.
*/
int(abs)(int x) {
return ABS(x);
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/bits/bits.h"
/**
* Reverses bits in 16-bit word.
*/
uint16_t(bitreverse16)(uint16_t x) {
return kReverseBits[x & 0x00FF] << 8 | kReverseBits[(x & 0xFF00) >> 8];
}

View file

@ -20,6 +20,9 @@
#include "libc/bits/bits.h"
#include "libc/bits/bswap.h"
/**
* Reverses bits in 32-bit word.
*/
uint32_t(bitreverse32)(uint32_t x) {
x = bswap_32(x);
x = ((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1);

View file

@ -20,6 +20,9 @@
#include "libc/bits/bits.h"
#include "libc/bits/bswap.h"
/**
* Reverses bits in 64-bit word.
*/
uint64_t bitreverse64(uint64_t x) {
x = bswap_64(x);
x = ((x & 0xaaaaaaaaaaaaaaaa) >> 1) | ((x & 0x5555555555555555) << 1);

View file

@ -19,6 +19,9 @@
*/
#include "libc/bits/bits.h"
/**
* Reverses bits in 8-bit word.
*/
uint8_t(bitreverse8)(uint8_t x) {
return kReverseBits[x];
}

View file

@ -17,5 +17,12 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/safemacros.internal.h"
const char *emptytonull(const char *s) { return s && !*s ? 0 : s; }
/**
* Returns string where empty string is made null.
* @see nulltoempty()
*/
const char *(emptytonull)(const char *s) {
return s && !*s ? 0 : s;
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/runtime/runtime.h"
/**
* Returns a or b or aborts if both are null.
*/
const char *(firstnonnull)(const char *a, const char *b) {
if (a) return a;
if (b) return b;

View file

@ -19,6 +19,11 @@
*/
#include "libc/bits/bits.h"
/**
* Returns gray code for x.
* @see https://en.wikipedia.org/wiki/Gray_code
* @see ungray()
*/
uint32_t gray(uint32_t x) {
return x ^ (x >> 1);
}

View file

@ -21,6 +21,7 @@
/**
* Counts number of different bits.
* @see https://en.wikipedia.org/wiki/Hamming_code
*/
unsigned long hamming(unsigned long x, unsigned long y) {
return popcnt(x ^ y);

View file

@ -36,7 +36,8 @@ static axdx_t RotateQuadrant(long n, long y, long x, long ry, long rx) {
/**
* Generates Hilbert space-filling curve.
*
* @see morton()
* @see https://en.wikipedia.org/wiki/Hilbert_curve
* @see unhilbert()
*/
long hilbert(long n, long y, long x) {
axdx_t m;
@ -56,7 +57,8 @@ long hilbert(long n, long y, long x) {
/**
* Decodes Hilbert space-filling curve.
*
* @see unmorton()
* @see https://en.wikipedia.org/wiki/Hilbert_curve
* @see hilbert()
*/
axdx_t unhilbert(long n, long i) {
axdx_t m;

View file

@ -18,4 +18,9 @@
02110-1301 USA
*/
bool isempty(const char *s) { return !s || !*s; }
/**
* Returns true if s is empty string or null.
*/
bool isempty(const char *s) {
return !s || !*s;
}

View file

@ -21,6 +21,8 @@
/**
* Interleaves bits.
* @see https://en.wikipedia.org/wiki/Z-order_curve
* @see unmorton()
*/
unsigned long(morton)(unsigned long y, unsigned long x) {
x = (x | x << 020) & 0x0000FFFF0000FFFF;

View file

@ -17,5 +17,12 @@
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA
*/
#include "libc/bits/safemacros.internal.h"
const char *nulltoempty(const char *s) { return s ? s : ""; }
/**
* Returns 𝑠 converting null to empty string.
* @see emptytonull()
*/
const char *(nulltoempty)(const char *s) {
return s ? s : "";
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/bits/popcnt.h"
/**
* Returns number of bits set in integer.
*/
uint64_t(popcnt)(uint64_t x) {
x = x - ((x >> 1) & 0x5555555555555555);
x = ((x >> 2) & 0x3333333333333333) + (x & 0x3333333333333333);

View file

@ -3,13 +3,13 @@
#include "libc/macros.h"
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#if !defined(__GNUC__) || defined(__STRICT_ANSI__)
#define pushpop(x) (x)
#else
/**
* PushPop
* An elegant weapon for a more civilized age.
*/
#if !defined(__GNUC__) || defined(__STRICT_ANSI__)
#define pushpop(x) (x)
#else
#define pushpop(x) \
({ \
typeof(x) Popped; \

View file

@ -19,4 +19,9 @@
*/
#include "libc/macros.h"
long(rounddown)(long w, long k) { return ROUNDDOWN(w, k); }
/**
* Rounds down 𝑤 to next two power 𝑘.
*/
long(rounddown)(long w, long k) {
return ROUNDDOWN(w, k);
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/macros.h"
/**
* Rounds up 𝑤 to next two power 𝑘.
*/
long(roundup)(long w, long k) {
return ROUNDUP(w, k);
}

View file

@ -22,7 +22,7 @@
/**
* Returns 𝑥 rounded up to next two power and log'd.
* @see roundup2pow
* @see roundup2pow()
*/
unsigned long roundup2log(unsigned long x) {
return x > 1 ? (bsrl(x - 1) + 1) : x ? 1 : 0;

View file

@ -24,7 +24,7 @@
* Returns 𝑥 rounded up to next two power.
*
* @define (𝑥>02^logx, x=00, 𝑇)
* @see rounddown2pow)()
* @see rounddown2pow()
*/
unsigned long roundup2pow(unsigned long x) {
return x > 1 ? 1ul << (bsrl(x - 1) + 1) : x ? 1 : 0;

View file

@ -19,6 +19,11 @@
*/
#include "libc/bits/bits.h"
/**
* Decodes gray code.
* @see https://en.wikipedia.org/wiki/Gray_code
* @see gray()
*/
uint32_t ungray(uint32_t x) {
x ^= x >> 16;
x ^= x >> 8;

View file

@ -35,6 +35,7 @@ static unsigned long GetOddBits(unsigned long x) {
* @param 𝑖 is interleaved index
* @return deinterleaved coordinate {ax := 𝑦, dx := 𝑥}
* @see en.wikipedia.org/wiki/Z-order_curve
* @see morton()
*/
axdx_t(unmorton)(unsigned long i) {
return (axdx_t){GetOddBits(i >> 1), GetOddBits(i)};

View file

@ -25,15 +25,15 @@
/**
* Changes file permissions via open()'d file descriptor, e.g.:
*
* CHECK_NE(-1, chmod("foo/bar.txt", 0644));
* CHECK_NE(-1, chmod("o/default/program.com", 0755));
* CHECK_NE(-1, chmod("privatefolder/", 0700));
* CHECK_NE(-1, chmod("foo/bar.txt", 0644));
* CHECK_NE(-1, chmod("o/default/program.com", 0755));
* CHECK_NE(-1, chmod("privatefolder/", 0700));
*
* The esoteric bits generally available on System V are:
*
* CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit
* CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit
* CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit
* CHECK_NE(-1, chmod("/opt/", 01000)); // sticky bit
* CHECK_NE(-1, chmod("/usr/bin/sudo", 04755)); // setuid bit
* CHECK_NE(-1, chmod("/usr/bin/wall", 02755)); // setgid bit
*
* This works on Windows NT if you ignore the error ;-)
*

View file

@ -24,7 +24,7 @@
/**
* Does things with file descriptor, via re-imagined hourglass api, e.g.
*
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
* CHECK_NE(-1, fcntl(fd, F_SETFD, FD_CLOEXEC));
*
* @param cmd can be F_{GET,SET}{FD,FL}, etc.
* @param arg can be FD_CLOEXEC, etc. depending

View file

@ -118,13 +118,13 @@ static textwindows noinline struct dirent *readdir$nt(DIR *dir) {
/**
* Opens directory, e.g.
*
* DIR *d;
* struct dirent *e;
* CHECK((d = opendir(path)));
* while ((e = readdir(d))) {
* printf("%s/%s\n", path, e->d_name);
* }
* LOGIFNEG1(closedir(d));
* DIR *d;
* struct dirent *e;
* CHECK((d = opendir(path)));
* while ((e = readdir(d))) {
* printf("%s/%s\n", path, e->d_name);
* }
* LOGIFNEG1(closedir(d));
*
* @returns newly allocated DIR object, or NULL w/ errno
* @errors ENOENT, ENOTDIR, EACCES, EMFILE, ENFILE, ENOMEM

View file

@ -27,18 +27,18 @@
/**
* Launches program, e.g.
*
* char buf[2];
* int ws, pid, fds[3] = {-1, -1, STDERR_FILENO};
* CHECK_NE(-1, (pid = spawnve(0, fds, commandv("ssh"),
* (char *const[]){"ssh", hostname, "cat", NULL},
* environ)));
* CHECK_EQ(+2, write(fds[0], "hi", 2));
* CHECK_NE(-1, close(fds[0]));
* CHECK_EQ(+2, read(fds[1], buf, 2)));
* CHECK_NE(-1, close(fds[1]));
* CHECK_EQ(+0, memcmp(buf, "hi", 2)));
* CHECK_NE(-1, waitpid(pid, &ws, 0));
* CHECK_EQ(+0, WEXITSTATUS(ws));
* char buf[2];
* int ws, pid, fds[3] = {-1, -1, STDERR_FILENO};
* CHECK_NE(-1, (pid = spawnve(0, fds, commandv("ssh"),
* (char *const[]){"ssh", hostname, "cat", 0},
* environ)));
* CHECK_EQ(+2, write(fds[0], "hi", 2));
* CHECK_NE(-1, close(fds[0]));
* CHECK_EQ(+2, read(fds[1], buf, 2)));
* CHECK_NE(-1, close(fds[1]));
* CHECK_EQ(+0, memcmp(buf, "hi", 2)));
* CHECK_NE(-1, waitpid(pid, &ws, 0));
* CHECK_EQ(+0, WEXITSTATUS(ws));
*
* @param stdiofds may optionally be passed to customize standard i/o
* @param stdiofds[𝑖] may be -1 to receive a pipe() fd
@ -49,6 +49,7 @@
* @param envp[0,n-2] specifies "foo=bar" environment variables
* @param envp[n-1] is NULL
* @return pid of child, or -1 w/ errno
* @deprecated just use vfork() and execve()
*/
int spawnve(unsigned flags, int stdiofds[3], const char *program,
char *const argv[], char *const envp[]) {

View file

@ -27,7 +27,7 @@
* @asyncsignalsafe
*/
bool32 isatty(int fd) {
char buf[sizeof(uint16_t) * 4] forcealign(2);
_Alignas(short) char buf[sizeof(uint16_t) * 4];
if (!IsWindows()) {
return ioctl$sysv(fd, TIOCGWINSZ, &buf) != -1;
} else {

View file

@ -21,38 +21,37 @@
#include "libc/calls/kntprioritycombos.internal.h"
#include "libc/limits.h"
#include "libc/macros.h"
#include "libc/nexgen32e/ffs.h"
#include "libc/nt/enum/processcreationflags.h"
#include "libc/nt/enum/threadpriority.h"
#define FFS(x) __builtin_ffs(x)
const struct NtPriorityCombo kNtPriorityCombos[] = {
{-20, FFS(kNtHighPriorityClass), kNtThreadPriorityHighest, 15},
{-18, FFS(kNtHighPriorityClass), kNtThreadPriorityTimeCritical, 15},
{-17, FFS(kNtNormalPriorityClass), kNtThreadPriorityTimeCritical, 15},
{-15, FFS(kNtIdlePriorityClass), kNtThreadPriorityTimeCritical, 15},
{-13, FFS(kNtHighPriorityClass), kNtThreadPriorityAboveNormal, 14},
{-11, FFS(kNtHighPriorityClass), kNtThreadPriorityNormal, 13},
{-9, FFS(kNtHighPriorityClass), kNtThreadPriorityBelowNormal, 12},
{-7, FFS(kNtNormalPriorityClass), kNtThreadPriorityHighest, 11},
{-5, FFS(kNtHighPriorityClass), kNtThreadPriorityLowest, 11},
{-3, FFS(kNtNormalPriorityClass), kNtThreadPriorityAboveNormal, 10},
{-1, FFS(kNtNormalPriorityClass), kNtThreadPriorityHighest, 9},
{0, FFS(kNtNormalPriorityClass), kNtThreadPriorityNormal, 9},
{1, FFS(kNtNormalPriorityClass), kNtThreadPriorityAboveNormal, 8},
{2, FFS(kNtNormalPriorityClass), kNtThreadPriorityBelowNormal, 8},
{3, FFS(kNtNormalPriorityClass), kNtThreadPriorityNormal, 7},
{4, FFS(kNtNormalPriorityClass), kNtThreadPriorityLowest, 7},
{5, FFS(kNtIdlePriorityClass), kNtThreadPriorityHighest, 6},
{6, FFS(kNtNormalPriorityClass), kNtThreadPriorityBelowNormal, 6},
{7, FFS(kNtIdlePriorityClass), kNtThreadPriorityAboveNormal, 5},
{9, FFS(kNtNormalPriorityClass), kNtThreadPriorityLowest, 5},
{11, FFS(kNtIdlePriorityClass), kNtThreadPriorityNormal, 4},
{13, FFS(kNtIdlePriorityClass), kNtThreadPriorityBelowNormal, 3},
{15, FFS(kNtIdlePriorityClass), kNtThreadPriorityLowest, 2},
{17, FFS(kNtHighPriorityClass), kNtThreadPriorityIdle, 1},
{18, FFS(kNtNormalPriorityClass), kNtThreadPriorityIdle, 1},
{19, FFS(kNtIdlePriorityClass), kNtThreadPriorityIdle, 1},
{-20, ffs(kNtHighPriorityClass), kNtThreadPriorityHighest, 15},
{-18, ffs(kNtHighPriorityClass), kNtThreadPriorityTimeCritical, 15},
{-17, ffs(kNtNormalPriorityClass), kNtThreadPriorityTimeCritical, 15},
{-15, ffs(kNtIdlePriorityClass), kNtThreadPriorityTimeCritical, 15},
{-13, ffs(kNtHighPriorityClass), kNtThreadPriorityAboveNormal, 14},
{-11, ffs(kNtHighPriorityClass), kNtThreadPriorityNormal, 13},
{-9, ffs(kNtHighPriorityClass), kNtThreadPriorityBelowNormal, 12},
{-7, ffs(kNtNormalPriorityClass), kNtThreadPriorityHighest, 11},
{-5, ffs(kNtHighPriorityClass), kNtThreadPriorityLowest, 11},
{-3, ffs(kNtNormalPriorityClass), kNtThreadPriorityAboveNormal, 10},
{-1, ffs(kNtNormalPriorityClass), kNtThreadPriorityHighest, 9},
{0, ffs(kNtNormalPriorityClass), kNtThreadPriorityNormal, 9},
{1, ffs(kNtNormalPriorityClass), kNtThreadPriorityAboveNormal, 8},
{2, ffs(kNtNormalPriorityClass), kNtThreadPriorityBelowNormal, 8},
{3, ffs(kNtNormalPriorityClass), kNtThreadPriorityNormal, 7},
{4, ffs(kNtNormalPriorityClass), kNtThreadPriorityLowest, 7},
{5, ffs(kNtIdlePriorityClass), kNtThreadPriorityHighest, 6},
{6, ffs(kNtNormalPriorityClass), kNtThreadPriorityBelowNormal, 6},
{7, ffs(kNtIdlePriorityClass), kNtThreadPriorityAboveNormal, 5},
{9, ffs(kNtNormalPriorityClass), kNtThreadPriorityLowest, 5},
{11, ffs(kNtIdlePriorityClass), kNtThreadPriorityNormal, 4},
{13, ffs(kNtIdlePriorityClass), kNtThreadPriorityBelowNormal, 3},
{15, ffs(kNtIdlePriorityClass), kNtThreadPriorityLowest, 2},
{17, ffs(kNtHighPriorityClass), kNtThreadPriorityIdle, 1},
{18, ffs(kNtNormalPriorityClass), kNtThreadPriorityIdle, 1},
{19, ffs(kNtIdlePriorityClass), kNtThreadPriorityIdle, 1},
};
const unsigned kNtPriorityCombosLen = ARRAYLEN(kNtPriorityCombos);

View file

@ -29,11 +29,11 @@
* how long each sequence is, so that each read consumes a single thing
* from the underlying file descriptor, e.g.
*
* "a" ALFA
* "\316\261" ALPHA
* "\033[A" CURSOR UP
* "\033[38;5;202m" ORANGERED
* "\eOP" PF1
* "a" ALFA
* "\316\261" ALPHA
* "\033[A" CURSOR UP
* "\033[38;5;202m" ORANGERED
* "\eOP" PF1
*
* This routine generalizes to ascii, utf-8, chorded modifier keys,
* function keys, color codes, c0/c1 control codes, cursor movement,
@ -48,9 +48,9 @@
* tokenized as a single read. Lastly note, this function has limited
* support for UNICODE representations of C0/C1 control codes, e.g.
*
* "\000" NUL
* "\300\200" NUL
* "\302\233A" CURSOR UP
* "\000" NUL
* "\300\200" NUL
* "\302\233A" CURSOR UP
*
* @param buf is guaranteed to receive a NUL terminator if size>0
* @return number of bytes read (helps differentiate "\0" vs. "")

View file

@ -28,27 +28,28 @@
*
* Raise SIGALRM every 1.5s:
*
* CHECK_NE(-1, sigaction(SIGALRM,
* &(struct sigaction){.sa_sigaction = missingno},
* NULL));
* CHECK_NE(-1, setitimer(ITIMER_REAL,
* &(const struct itimerval){{1, 500000}, {1, 500000}},
* NULL));
* CHECK_NE(-1, sigaction(SIGALRM,
* &(struct sigaction){.sa_sigaction = missingno},
* NULL));
* CHECK_NE(-1, setitimer(ITIMER_REAL,
* &(const struct itimerval){{1, 500000},
* {1, 500000}},
* NULL));
*
* Set single-shot 50ms timer callback to interrupt laggy connect():
*
* CHECK_NE(-1, sigaction(SIGALRM,
* &(struct sigaction){.sa_sigaction = missingno,
* .sa_flags = SA_RESETHAND},
* NULL));
* CHECK_NE(-1, setitimer(ITIMER_REAL,
* &(const struct itimerval){{0, 0}, {0, 50000}},
* NULL));
* if (connect(...) == -1 && errno == EINTR) { ... }
* CHECK_NE(-1, sigaction(SIGALRM,
* &(struct sigaction){.sa_sigaction = missingno,
* .sa_flags = SA_RESETHAND},
* NULL));
* CHECK_NE(-1, setitimer(ITIMER_REAL,
* &(const struct itimerval){{0, 0}, {0, 50000}},
* NULL));
* if (connect(...) == -1 && errno == EINTR) { ... }
*
* Disarm timer:
*
* CHECK_NE(-1, setitimer(ITIMER_REAL, &(const struct itimerval){0}, NULL));
* CHECK_NE(-1, setitimer(ITIMER_REAL, &(const struct itimerval){0}, NULL));
*
* Be sure to check for EINTR on your i/o calls, for best low latency.
*

View file

@ -112,10 +112,10 @@ static void sigaction$native2cosmo(union metasigaction *sa) {
/**
* Installs handler for kernel interrupt, e.g.:
*
* void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx);
* struct sigaction sa = {.sa_sigaction = GotCtrlC,
* .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO};
* CHECK_NE(-1, sigaction(SIGINT, &sa, NULL));
* void GotCtrlC(int sig, siginfo_t *si, ucontext_t *ctx);
* struct sigaction sa = {.sa_sigaction = GotCtrlC,
* .sa_flags = SA_RESETHAND|SA_RESTART|SA_SIGINFO};
* CHECK_NE(-1, sigaction(SIGINT, &sa, NULL));
*
* @see xsigaction() for a much better api
* @asyncsignalsafe

View file

@ -26,9 +26,9 @@
/**
* Changes program signal blocking state, e.g.:
*
* sigset_t oldmask;
* sigprocmask(SIG_BLOCK, &kSigsetFull, &oldmask);
* sigprocmask(SIG_SETMASK, &oldmask, NULL);
* sigset_t oldmask;
* sigprocmask(SIG_BLOCK, &kSigsetFull, &oldmask);
* sigprocmask(SIG_SETMASK, &oldmask, NULL);
*
* @param how can be SIG_BLOCK (U), SIG_UNBLOCK (/), SIG_SETMASK (=)
* @param set is the new mask content (optional)

View file

@ -5,6 +5,7 @@
cosmopolitan § autotune » dead code elimination
*/
#ifndef SUPPORT_VECTOR
/**
* Supported Platforms Tuning Knob (Runtime & Compile-Time)
*
@ -17,7 +18,6 @@
* offer marginal improvements in terms of code size and performance, at
* the cost of portability.
*/
#ifndef SUPPORT_VECTOR
#define SUPPORT_VECTOR 0b11111111
#endif
#define LINUX 1

View file

@ -10,7 +10,7 @@ typedef struct Elf64_Rela {
* ELF64_R_TYPE(r_info) R_X86_64_{64,PC32,GOTPCRELX,...}
* ELF64_R_INFO(sym, type) r_info
*/
/*u64*/ Elf64_Xword r_info; /** @see ELF64_R_{SYM,SIZE,INFO} */
/*u64*/ Elf64_Xword r_info; /* ELF64_R_{SYM,SIZE,INFO} */
/*i64*/ Elf64_Sxword r_addend;
} Elf64_Rela;

View file

@ -26,23 +26,23 @@
*
* Cosmopolitan displays RADIX-256 numbers using these digits:
*
* 0123456789abcdef
* 0 
* 1§
* 2 !"#$%&'()*+,-./
* 30123456789:;<=>?
* 4@ABCDEFGHIJKLMNO
* 5PQRSTUVWXYZ[\]^_
* 6`abcdefghijklmno
* 7pqrstuvwxyz{|}~
* 8ÇüéâäàåçêëèïîìÄÅ
* 9ÉæÆôöòûùÿÖÜ¢£¥ƒ
* aáíóúñѪº¿¬½¼¡«»
* b
* c
* d
* eαßΓπΣσμτΦΘΩδφε
* f±÷°·²λ
* 0123456789abcdef
* 0 
* 1§
* 2 !"#$%&'()*+,-./
* 30123456789:;<=>?
* 4@ABCDEFGHIJKLMNO
* 5PQRSTUVWXYZ[\]^_
* 6`abcdefghijklmno
* 7pqrstuvwxyz{|}~
* 8ÇüéâäàåçêëèïîìÄÅ
* 9ÉæÆôöòûùÿÖÜ¢£¥ƒ
* aáíóúñѪº¿¬½¼¡«»
* b
* c
* d
* eαßΓπΣσμτΦΘΩδφε
* f±÷°·²λ
*
* IBM designed these glyphs for the PC to map onto the display bytes at
* (char *)0xb8000. Because IBM authorized buyers of its PCs to inspect

View file

@ -18,10 +18,6 @@
#define __far
#endif
/**
* Gets type of expression.
* @see autotype() which is a better alternative for certain use cases
*/
#if !defined(__GNUC__) && __cplusplus + 0 >= 201103L
#define typeof(x) decltype(x)
#elif (defined(__STRICT_ANSI__) || !defined(__GNUC__)) && \
@ -143,35 +139,10 @@ typedef __UINT32_TYPE__ uint32_t;
typedef __INT64_TYPE__ int64_t;
typedef __UINT64_TYPE__ uint64_t;
/**
* AX:DX register pair.
*
* Every ABI we support permits functions to return two machine words.
* Normally it's best to define a one-off struct. Sometimes we don't
* want the boilerplate.
*
* @see System V Application Binary Interface NexGen32e Architecture
* Processor Supplement, Version 1.0, December 5th, 2018
* @see agner.org/optimize/calling_conventions.pdf (chapter 6)
* @see LISP primitives CONS[CAR,CDR] w/ IBM 704 naming
* @see int128_t
*/
typedef struct {
intptr_t ax, dx;
} axdx_t;
/*
* GCC, Clang, and System V ABI all incorrectly define intmax_t.
*
* [intmax_t] designates a signed integer type capable of
* representing any value of any signed integer type.
* ──Quoth ISO/IEC 9899:201x 7.20.1.5
*
* This surprising contradiction is most likely due to Linux distro
* practices of using dynamic shared objects which needs to change.
*
* http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2303.pdf
*/
#ifdef __SIZEOF_INTMAX__
#undef __SIZEOF_INTMAX__
#endif
@ -210,11 +181,6 @@ typedef uint64_t uintmax_t;
#define mallocesque reallocesque returnspointerwithnoaliases
#define interruptfn nocallersavedregisters forcealignargpointer
/**
* Declares combinator, i.e. never reads/writes global memory.
* Thus enabling LICM, CSE, DCE, etc. optimizations.
* @see nosideeffect
*/
#ifndef pureconst
#ifndef __STRICT_ANSI__
#define pureconst __attribute__((__const__))
@ -223,9 +189,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Aligns automatic or static variable.
*/
#ifndef forcealign
#ifndef __STRICT_ANSI__
#define forcealign(bytes) __attribute__((__aligned__(bytes)))
@ -234,21 +197,12 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Disables alignment.
* @param opt_bytes defaults to __BIGGEST_ALIGNMENT__
* @see nosideeffect
*/
#ifndef __STRICT_ANSI__
#define thatispacked __attribute__((__packed__))
#else
#define thatispacked
#endif
/**
* Declares prototype as using well-known format string DSL.
* Thereby allowing compiler to identify certain bugs.
*/
#ifndef __STRICT_ANSI__
#define printfesque(n) __attribute__((__format__(__gnu_printf__, n, n + 1)))
#define scanfesque(n) __attribute__((__format__(__gnu_scanf__, n, n + 1)))
@ -297,11 +251,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Declares prototype as never mutating global memory.
* Thus enabling CSE, DCE, LICM [clang-only?], etc. optimizations.
* @see pureconst
*/
#ifndef nosideeffect
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__pure__) || \
@ -332,18 +281,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Makes function behave as much like macro as possible, meaning:
*
* 1. always inlined, i.e. even with -fno-inline
* 2. unlinkable, i.e. elf data is not generated
* 3. steppable, i.e. dwarf data is generated
* 4. unprofilable
* 5. unhookable
*
* @note consider static or writing a macro
* @see externinline
*/
#ifndef forceinline
#ifdef __cplusplus
#define forceinline inline
@ -372,19 +309,6 @@ typedef uint64_t uintmax_t;
#endif /* __cplusplus */
#endif /* forceinline */
/**
* Permits untyped or punned memory manipulation w/o asm.
*
* “The fundamental problem is that it is not possible to write real
* programs using the X3J11 definition of C. The committee has created
* an unreal language that no one can or will actually use. While the
* problems of `const' may owe to careless drafting of the
* specification, `noalias' is an altogether mistaken notion, and must
* not survive. ──Dennis Ritchie in 1988-03-20.
*
* @see asm(), memcpy(), memset(), read32be(), etc.
* @see unsigned char
*/
#ifndef mayalias
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__may_alias__) || \
@ -395,11 +319,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Declares prototype as returning freeable resource.
* Compilation will fail if caller ignores return value.
* @see gc(), free(), close(), etc.
*/
#ifndef nodiscard
#if !defined(__STRICT_ANSI__) && \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 304 || \
@ -410,10 +329,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Declares variadic function as needing NULL sentinel argument.
* @see execl() for example
*/
#ifndef nullterminated
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__sentinel__) || __GNUC__ >= 4)
@ -448,10 +363,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Relocates function to .text.unlikely section of binary.
* @note can be used to minimize page-faults and improve locality
*/
#ifndef relegated
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__cold__) || \
@ -470,11 +381,6 @@ typedef uint64_t uintmax_t;
#define warnifused(s)
#endif
/**
* Relocates function to .text.hot section of binary.
* @note can be used to minimize page-faults w/ improved locality
* @note most appropriately automated by profile-guided opts
*/
#ifndef firstclass
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__hot__) || \
@ -485,12 +391,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Declares all or specific parameters as never receiving NULL.
*
* This can be checked at both compile-time (only for constexprs) and
* runtime too (only in MODE=dbg mode) by synthetic Ubsan code.
*/
#ifndef paramsnonnull
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__nonnull__) || \
@ -501,22 +401,12 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Declares array argument w/ minimum size contract, e.g.
*
* int foo(int bar[hasatleast 2]) { ... }
*/
#if __STDC_VERSION__ + 0 >= 199901L
#define hasatleast static
#else
#define hasatleast
#endif
/**
* Qualifies char pointer so it's treated like every other type.
*
* int foo(int bar[hasatleast 2]) { ... }
*/
#if __STDC_VERSION__ + 0 < 199901L && !defined(restrict)
#if !defined(__STRICT_ANSI__) && !defined(__cplusplus) && \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 301 || defined(_MSC_VER))
@ -527,10 +417,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Declares prototype that can't mutate caller's static variables.
* @note consider more .c files or declare in function
*/
#ifndef nocallback
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__leaf__) || \
@ -554,11 +440,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Asks compiler to not optimize function definition.
*
* @todo this is dangerous delete?
*/
#ifndef nooptimize
#ifndef __STRICT_ANSI__
#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
@ -572,13 +453,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Asks compiler to generate as little code as possible for function.
*
* This does the same thing as relegated, but without relocation.
*
* @todo this is dangerous delete?
*/
#ifndef optimizesize
#ifndef __STRICT_ANSI__
#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
@ -592,15 +466,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Asks compiler to always heavily optimize function.
*
* This keyword provides an alternative to build flag tuning, in cases
* where the compiler is reluctant to vectorize mathematical code that's
* written in standards-compliant C rather than GCC extensions.
*
* @todo this is dangerous delete?
*/
#ifndef optimizespeed
#if !defined(__STRICT_ANSI__) && \
((__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 407 || \
@ -611,9 +476,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Declares prototype that behaves similar to setjmp() or vfork().
*/
#ifndef returnstwice
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__returns_twice__) || \
@ -624,10 +486,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Asks compiler to not emit DWARF assembly for function.
* @see artificial
*/
#ifndef nodebuginfo
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__nodebug__) || defined(__llvm__))
@ -637,10 +495,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Associates debug information with call site.
* @see nodebuginfo
*/
#ifndef artificial
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__artificial__) || \
@ -651,11 +505,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Defines function as specially compiled for newer cpu model.
* @see -ftree-vectorize and consider assembly
* @see libc/dce.h
*/
#ifndef microarchitecture
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__target__) || \
@ -666,10 +515,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Compiles function multiple times for different cpu models.
* @see libc/dce.h
*/
#ifndef targetclones
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__target_clones__) || __GNUC__ >= 6)
@ -679,10 +524,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Defines function with prologue that fixes misaligned stack.
* @see nocallersavedregisters and consider assembly
*/
#if (__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 408 || \
__has_attribute(__force_align_arg_pointer__)
#define forcealignargpointer __attribute__((__force_align_arg_pointer__))
@ -690,12 +531,6 @@ typedef uint64_t uintmax_t;
#define forcealignargpointer "need modern compiler"
#endif
/**
* Declares prototype as never returning NULL.
*
* This is checked at compile-time for constexprs. It'll be checked at
* runtime too by synthetic code, only in MODE=dbg mode.
*/
#ifndef returnsnonnull
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__returns_nonnull__) || \
@ -706,13 +541,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Attests return value is aligned.
*
* @param (alignment)
* @param (alignment, misalignment)
* @see attributeallocalign(), returnspointerwithnoaliases, mallocesque
*/
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__assume_aligned__) || \
(__GNUC__ + 0) * 100 + (__GNUC_MINOR__ + 0) >= 409)
@ -721,10 +549,6 @@ typedef uint64_t uintmax_t;
#define returnsaligned(x)
#endif
/**
* Declares prototype as behaving similar to malloc().
* @see attributeallocsize(), attributeallocalign()
*/
#ifndef returnspointerwithnoaliases
#if !defined(__STRICT_ANSI__) && \
(__has_attribute(__malloc__) || \
@ -757,20 +581,6 @@ typedef uint64_t uintmax_t;
#endif
#endif
/**
* Defines variable as having same type as right-hand side.
*
* This enables safe, backwards-compatible, non-explosive macros, e.g.:
*
* #define bar(FOO) \
* ({ \
* autotype(FOO) Foo = (FOO); \
* Foo + Foo * 2; \
* })
*
* @param x must be identical to rhs
* @note typeof goes back to gcc 2.x
*/
#if __cplusplus + 0 >= 201103L
#define autotype(x) auto
#elif ((__has_builtin(auto_type) || defined(__llvm__) || \
@ -781,27 +591,16 @@ typedef uint64_t uintmax_t;
#define autotype(x) typeof(x)
#endif
/**
* Defines interrupt handler that can call non-interrupt functions.
* @see forcealignargpointer, -mgeneral-regs-only and consider assembly
*/
#if __GNUC__ >= 7 || __has_attribute(__no_caller_saved_registers__)
#define nocallersavedregisters __attribute__((__no_caller_saved_registers__))
#else
#define nocallersavedregisters "need modern compiler"
#endif
/**
* Attests that execution of statement is impossible.
*/
#ifndef unreachable
#define unreachable __builtin_unreachable()
#endif
/**
* Statement that does nothing.
* @note can help avoid drama w/ linters, warnings, formatters, etc.
*/
#define donothing \
do { \
} while (0)
@ -857,9 +656,6 @@ typedef uint64_t uintmax_t;
#define initarray _Section(".init_array")
#endif
/**
* Systemic suppressions.
*/
#ifndef __STRICT_ANSI__
#if defined(__GNUC__) || defined(__llvm__)
#pragma GCC diagnostic ignored "-Wsign-compare" /* lint needs to change */
@ -908,17 +704,6 @@ typedef uint64_t uintmax_t;
#endif /* !GCC && LLVM */
#endif /* ANSI */
/**
* Elevate warnings of material consequence.
*
* These aren't stylistic in nature; but are perfectly fine to disable,
* assuming we're ok with the compiler simply generating a runtime crash
* instead. Otherwise what usually happens with these is that a weakness
* is introduced, important optimizations can't be performed; or worst
* of all: the code will need patching if ported to a toy or any machine
* designed by an engineer who hadn't understood John von Neumann at the
* time, e.g. 1's complement, big endian, under 32bit word size, etc.
*/
#ifndef __W__
#ifndef __STRICT_ANSI__
#if defined(__GNUC__) || defined(__llvm__)
@ -965,10 +750,6 @@ typedef uint64_t uintmax_t;
#endif /* ANSI */
#endif /* -w */
/**
* Sets manual breakpoint.
* @see showcrashreports() for auto gdb attach
*/
#define DebugBreak() asm("int3")
#define VEIL(CONSTRAINT, EXPRESSION) \
@ -991,10 +772,6 @@ typedef uint64_t uintmax_t;
0; \
})
/**
* Pulls another module, by symbol, into linkage.
* @note nop is discarded by ape/ape.lds
*/
#define YOINK(SYMBOL) \
do { \
_Static_assert(!__builtin_types_compatible_p(typeof(SYMBOL), char[]), \
@ -1006,29 +783,15 @@ typedef uint64_t uintmax_t;
: "X"(SYMBOL)); \
} while (0)
/**
* Pulls another module into linkage from top-level scope.
* @note nop is discarded by ape/ape.lds
*/
#define STATIC_YOINK(SYMBOLSTR) \
asm(".pushsection .yoink\n\tnop\t\"" SYMBOLSTR "\"\n\t.popsection")
/**
* Pulls source file into ZIP portion of binary.
* @see build/rules.mk which defines the wildcard build rule %.zip.o
*/
#if !defined(IM_FEELING_NAUGHTY) && !defined(__STRICT_ANSI__)
#define STATIC_YOINK_SOURCE(PATH) STATIC_YOINK(PATH)
#else
#define STATIC_YOINK_SOURCE(PATH)
#endif
/**
* Pulls source of object being compiled into zip.
* @note automates most compliance with gpl terms
* @see libc/zipos/zipcentraldir.S
* @see ape/ape.lds
*/
#ifdef __BASE_FILE__
STATIC_YOINK_SOURCE(__BASE_FILE__);
#endif

View file

@ -67,4 +67,4 @@
#define __INT_FAST64_TYPE__ __INT64_TYPE__
#define __UINT_FAST64_TYPE__ __UINT64_TYPE__
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif

View file

@ -1,12 +1,3 @@
/**
* @fileoverview Cosmopolitan Preprocessor / Language Normalization.
*
* This is our lowest-level header file. You don't need to include it,
* since we require that compilers be configured to do so automatically,
* and the -include flag is the safest bet. Further note polyfills here
* shouldn't be taken as indicators of intent to support.
*/
#define __COSMOPOLITAN__ 1
#ifndef __COUNTER__

View file

@ -289,11 +289,6 @@ void sincosl(long double, long double *, long double *);
cosmopolitan § mathematics » x87
*/
#if 0
/**
* Asks FPU to push well-known numbers to its own stack.
*/
#endif
#define fldz() __X87_CONST(fldz, 0x0p+0)
#define fld1() __X87_CONST(fld1, 0x8p-3)
#define fldpi() __X87_CONST(fldpi, M_PI)

View file

@ -30,7 +30,7 @@
* @see xasprintf() for a better API
*/
int(vasprintf)(char **strp, const char *fmt, va_list va) {
/**
/*
* This implementation guarantees the smallest possible allocation,
* using an optimistic approach w/o changing asymptotic complexity.
*/

View file

@ -38,8 +38,8 @@
/ @asyncsignalsafe
ffs: .leafprologue
.profilable
bsf %edi,%eax
or $-1,%edx
bsf %edi,%eax
cmovz %edx,%eax
inc %eax
.leafepilogue

View file

@ -3,9 +3,29 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
/*
* BIT SCANNING 101
* ctz(𝑥) 31^clz(𝑥) clz(𝑥)
* uint32 𝑥 bsf(𝑥) tzcnt(𝑥) ffs(𝑥) bsr(𝑥) lzcnt(𝑥)
* 0x00000000 wut 32 0 wut 32
* 0x00000001 0 0 1 0 31
* 0x80000001 0 0 1 31 0
* 0x80000000 31 31 32 31 0
* 0x00000010 4 4 5 4 27
* 0x08000010 4 4 5 27 4
* 0x08000000 27 27 28 27 4
* 0xffffffff 0 0 1 31 0
*/
int ffs(int) pureconst;
int ffsl(long int) pureconst;
int ffsll(long long int) pureconst;
int ffsl(long) pureconst;
int ffsll(long long) pureconst;
#ifdef __GNUC__
#define ffs(u) __builtin_ffs(u)
#define ffsl(u) __builtin_ffsl(u)
#define ffsll(u) __builtin_ffsll(u)
#endif
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */

View file

@ -38,8 +38,8 @@
/ @asyncsignalsafe
ffsl: .leafprologue
.profilable
bsf %rdi,%rax
or $-1,%edx
bsf %rdi,%rax
cmovz %edx,%eax
inc %eax
.leafepilogue

View file

@ -29,13 +29,6 @@
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
/**
* Globally precomputed x86 CPUID values.
*
* @note Referencing Is Initialization (RII)
* @note Protected with PIRO
* @see X86_HAVE()
*/
extern const unsigned kCpuids[KCPUIDS_LEN][4];
COSMOPOLITAN_C_END_

View file

@ -2,6 +2,9 @@
#define COSMOPOLITAN_LIBC_NT_THUNK_MSABI_H_
#if !(__ASSEMBLER__ + __LINKER__ + 0)
#if !defined(__STRICT_ANSI__) && \
(__GNUC__ * 100 + __GNUC_MINOR__ >= 408 || \
(__has_attribute(__ms_abi__) || defined(__llvm__)))
/**
* Defines function as using Microsoft x64 calling convention.
*
@ -9,13 +12,10 @@
* generate code that calls MS ABI functions directly, without needing
* to jump through the assembly thunks.
*/
#if !defined(__STRICT_ANSI__) && \
(__GNUC__ * 100 + __GNUC_MINOR__ >= 408 || \
(__has_attribute(__ms_abi__) || defined(__llvm__)))
#define __msabi __attribute__((__ms_abi__))
#endif
/**
/*
* Returns true if header should provide MS-ABI overrides.
*/
#ifndef ShouldUseMsabiAttribute

View file

@ -35,7 +35,7 @@ nodebuginfo uint32_t(rand32)(void) {
} else {
devrand(&res, sizeof(res));
}
hidden extern uint32_t g_rando32;
extern uint32_t g_rando32 hidden;
res ^= MarsagliaXorshift32(&g_rando32);
}
return res;

View file

@ -42,9 +42,9 @@
/**
* Beseeches system for page-table entries.
*
* char *p = mmap(NULL, 65536, PROT_READ | PROT_WRITE,
* MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
* munmap(p, 65536);
* char *p = mmap(NULL, 65536, PROT_READ | PROT_WRITE,
* MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
* munmap(p, 65536);
*
* @param addr optionally requests a particular virtual base address,
* which needs to be 64kb aligned if passed (for NT compatibility)

View file

@ -157,29 +157,29 @@ static textwindows wontreturn void WinMainNew(void) {
* The Cosmopolitan Runtime provides the following services, which aim
* to bring Windows NT behavior closer in harmony with System Five:
*
* 1. We configure CMD.EXE for UTF-8 and enable ANSI colors on Win10.
* 1. We configure CMD.EXE for UTF-8 and enable ANSI colors on Win10.
*
* 2. Command line arguments are passed as a blob of UTF-16 text. We
* chop them up into an char *argv[] UTF-8 data structure, in
* accordance with the DOS conventions for argument quoting.
* 2. Command line arguments are passed as a blob of UTF-16 text. We
* chop them up into an char *argv[] UTF-8 data structure, in
* accordance with the DOS conventions for argument quoting.
*
* 3. Environment variables are passed to us as a sorted UTF-16 double
* NUL terminated list. We translate this to char ** using UTF-8.
* 3. Environment variables are passed to us as a sorted UTF-16 double
* NUL terminated list. We translate this to char ** using UTF-8.
*
* 4. Allocates new stack at a high address. NT likes to choose a
* stack address that's beneath the program image. We want to be
* able to assume that stack addresses are located at higher
* addresses than heap and program memory.
* 4. Allocates new stack at a high address. NT likes to choose a
* stack address that's beneath the program image. We want to be
* able to assume that stack addresses are located at higher
* addresses than heap and program memory.
*
* 5. Windows users are afraid of "drive-by downloads" where someone
* might accidentally an evil DLL to their Downloads folder which
* then overrides the behavior of a legitimate EXE being run from
* the downloads folder. Since we don't even use dynamic linking,
* we've cargo culted some API calls, that may harden against it.
* 5. Windows users are afraid of "drive-by downloads" where someone
* might accidentally an evil DLL to their Downloads folder which
* then overrides the behavior of a legitimate EXE being run from
* the downloads folder. Since we don't even use dynamic linking,
* we've cargo culted some API calls, that may harden against it.
*
* 6. Finally, we need fork. Microsoft designed Windows to prevent us
* from having fork() so we pass pipe handles in an environment
* variable literally copy all the memory.
* 6. Finally, we need fork. Microsoft designed Windows to prevent us
* from having fork() so we pass pipe handles in an environment
* variable literally copy all the memory.
*
* @param hInstance call GetModuleHandle(NULL) from main if you need it
*/

View file

@ -22,7 +22,11 @@
STATIC_YOINK("_init_g_stderr");
/**
* Pointer to standard error stream.
*/
FILE *stderr;
hidden FILE g_stderr;
hidden unsigned char g_stderr_buf[BUFSIZ] forcealign(PAGESIZE);

View file

@ -22,7 +22,11 @@
STATIC_YOINK("_init_g_stdin");
/**
* Pointer to standard input stream.
*/
FILE *stdin;
hidden FILE g_stdin;
hidden unsigned char g_stdin_buf[BUFSIZ] forcealign(PAGESIZE);

View file

@ -25,7 +25,11 @@
STATIC_YOINK("_init_g_stdout");
/**
* Pointer to standard output stream.
*/
FILE *stdout;
hidden FILE g_stdout;
hidden unsigned char g_stdout_buf[BUFSIZ] forcealign(PAGESIZE);

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is lower, alpha, or digit.
*/
int isalnum(int c) {
return ('0' <= c && c <= '9') || ('A' <= c && c <= 'Z') ||
('a' <= c && c <= 'z');

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is upper or lower.
*/
int isalpha(int c) {
return ('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z');
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is ascii.
*/
int isascii(int c) {
return 0x00 <= c && c <= 0x7F;
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is space or tab.
*/
int isblank(int c) {
return c == ' ' || c == '\t';
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is C0 ASCII control code or DEL.
*/
int iscntrl(int c) {
return (0x00 <= c && c <= 0x1F) || c == 0x7F;
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is decimal digit.
*/
int isdigit(int c) {
return '0' <= c && c <= '9';
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is lowercase alpha ascii character.
*/
int islower(int c) {
return 'a' <= c && c <= 'z';
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns true if c is space, \t, \r, \n, \f, or \v.
*/
int isspace(int c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' ||
c == '\v';

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if c is uppercase alpha ascii character.
*/
int isupper(int c) {
return 'A' <= c && c <= 'Z';
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns nonzero if wc is C0 or C1 control code.
*/
int iswcntrl(wint_t wc) {
return (0x00 <= wc && wc <= 0x1F) || (0x7F <= wc && wc <= 0x9F);
}

View file

@ -19,6 +19,9 @@
*/
#include "libc/str/str.h"
/**
* Returns true if c is hexadecimal digit.
*/
int isxdigit(int c) {
return ('0' <= c && c <= '9') || ('A' <= c && c <= 'F') ||
('a' <= c && c <= 'f');

View file

@ -28,17 +28,17 @@
*
* For example, strictly:
*
* char buf[16];
* CHECK_NOTNULL(memccpy(buf, s, '\0', sizeof(buf)));
* char buf[16];
* CHECK_NOTNULL(memccpy(buf, s, '\0', sizeof(buf)));
*
* Or unstrictly:
*
* if (!memccpy(buf, s, '\0', sizeof(buf))) strcpy(buf, "?");
* if (!memccpy(buf, s, '\0', sizeof(buf))) strcpy(buf, "?");
*
* Are usually more sensible than the following:
*
* char cstrbuf[16];
* snprintf(cstrbuf, sizeof(cstrbuf), "%s", CSTR);
* char cstrbuf[16];
* snprintf(cstrbuf, sizeof(cstrbuf), "%s", CSTR);
*
* @return 𝑑 + idx(𝑐) + 1, or NULL if 𝑐 𝑠
* @note 𝑑 and 𝑠 can't overlap

View file

@ -23,6 +23,7 @@
* Prepares static search buffer.
*
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
*
* 2. If SRC is too short, the remainder is zero-filled.
*
* Please note this function isn't designed to prevent untrustworthy

View file

@ -23,6 +23,7 @@
* Prepares static search buffer.
*
* 1. If SRC is too long, it's truncated and *not* NUL-terminated.
*
* 2. If SRC is too short, the remainder is zero-filled.
*
* Please note this function isn't designed to prevent untrustworthy

View file

@ -46,7 +46,7 @@ wontreturn void testlib_abort(void) {
*/
testonly void testlib_runtestcases(testfn_t *start, testfn_t *end,
testfn_t warmup) {
/**
/*
* getpid() calls are inserted to help visually see tests in traces
* which can be performed on Linux, FreeBSD, OpenBSD, and XNU:
*

View file

@ -370,13 +370,13 @@ static char *strftime_timefmt(char *p, const char *pe, const char *format,
/**
* Converts time to string, e.g.
*
* char b[64];
* int64_t sec;
* struct tm tm;
* time(&sec);
* localtime_r(&sec, &tm);
* strftime(b, sizeof(b), "%Y-%m-%dT%H:%M:%S%z", &tm); // ISO8601
* strftime(b, sizeof(b), "%a, %d %b %Y %H:%M:%S %Z", &tm); // RFC1123
* char b[64];
* int64_t sec;
* struct tm tm;
* time(&sec);
* localtime_r(&sec, &tm);
* strftime(b, sizeof(b), "%Y-%m-%dT%H:%M:%S%z", &tm); // ISO8601
* strftime(b, sizeof(b), "%a, %d %b %Y %H:%M:%S %Z", &tm); // RFC1123
*
* @return bytes copied excluding nul, or 0 on error
*/

View file

@ -25,7 +25,9 @@
* Returns monospace display width of UTF-8 string.
*
* - Control codes are discounted
*
* - ANSI escape sequences are discounted
*
* - East asian glyphs, emoji, etc. count as two
*
* @param s is NUL-terminated string

View file

@ -27,10 +27,10 @@
/**
* Decodes human-readable CP437 glyphs into binary, e.g.
*
* char binged[5];
* char golden[5] = "\0\1\2\3\4";
* unbingbuf(binged, sizeof(binged), u" ☺☻♥♦", -1);
* CHECK_EQ(0, memcmp(binged, golden, 5));
* char binged[5];
* char golden[5] = "\0\1\2\3\4";
* unbingbuf(binged, sizeof(binged), u" ☺☻♥♦", -1);
* CHECK_EQ(0, memcmp(binged, golden, 5));
*
* @param buf is caller owned
* @param size is byte length of buf

View file

@ -24,7 +24,7 @@
/**
* Decodes human-readable CP437 glyphs into binary, e.g.
*
* CHECK_EQ(0, memcmp(gc(unbingstr(u" ☺☻♥♦")), "\0\1\2\3\4", 5));
* CHECK_EQ(0, memcmp(gc(unbingstr(u" ☺☻♥♦")), "\0\1\2\3\4", 5));
*
* @param buf is caller owned
* @param size is byte length of buf

View file

@ -24,12 +24,12 @@
/**
* Joins paths, e.g.
*
* "a" + "b" "a/b"
* "a/" + "b" "a/b"
* "a" + "b/" "a/b/"
* "a" + "/b" "/b"
* "." + "b" "b"
* "" + "b" "b"
* "a" + "b" "a/b"
* "a/" + "b" "a/b"
* "a" + "b/" "a/b/"
* "a" + "/b" "/b"
* "." + "b" "b"
* "" + "b" "b"
*
* @return newly allocated string of resulting path
*/

View file

@ -26,8 +26,8 @@
/**
* Installs handler for kernel interrupt, e.g.:
*
* onctrlc(sig) { exit(128+sig); }
* CHECK_NE(-1, xsigaction(SIGINT, onctrlc, SA_RESETHAND, 0, 0));
* onctrlc(sig) { exit(128+sig); }
* CHECK_NE(-1, xsigaction(SIGINT, onctrlc, SA_RESETHAND, 0, 0));
*
* @param sig can be SIGINT, SIGTERM, etc.
* @param handler is SIG_DFL, SIG_IGN, or a pointer to a 0arity3