mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-28 15:28:30 +00:00
Auto-generate some documentation
This commit is contained in:
parent
117d0111ab
commit
13437dd19b
97 changed files with 2033 additions and 661 deletions
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/bits.h"
|
||||
|
||||
/**
|
||||
* Reverses bits in 8-bit word.
|
||||
*/
|
||||
uint8_t(bitreverse8)(uint8_t x) {
|
||||
return kReverseBits[x];
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 : "";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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; \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
/**
|
||||
* Rounds up 𝑤 to next two power 𝑘.
|
||||
*/
|
||||
long(roundup)(long w, long k) {
|
||||
return ROUNDUP(w, k);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
* Returns 𝑥 rounded up to next two power.
|
||||
*
|
||||
* @define (𝑥>0→2^⌈log₂x⌉, x=0→0, 𝑇→⊥)
|
||||
* @see rounddown2pow)()
|
||||
* @see rounddown2pow()
|
||||
*/
|
||||
unsigned long roundup2pow(unsigned long x) {
|
||||
return x > 1 ? 1ul << (bsrl(x - 1) + 1) : x ? 1 : 0;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)};
|
||||
|
|
|
@ -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 ;-)
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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[]) {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. "")
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -67,4 +67,4 @@
|
|||
#define __INT_FAST64_TYPE__ __INT64_TYPE__
|
||||
#define __UINT_FAST64_TYPE__ __UINT64_TYPE__
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
/ @asyncsignalsafe
|
||||
ffs: .leafprologue
|
||||
.profilable
|
||||
bsf %edi,%eax
|
||||
or $-1,%edx
|
||||
bsf %edi,%eax
|
||||
cmovz %edx,%eax
|
||||
inc %eax
|
||||
.leafepilogue
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
/ @asyncsignalsafe
|
||||
ffsl: .leafprologue
|
||||
.profilable
|
||||
bsf %rdi,%rax
|
||||
or $-1,%edx
|
||||
bsf %rdi,%rax
|
||||
cmovz %edx,%eax
|
||||
inc %eax
|
||||
.leafepilogue
|
||||
|
|
|
@ -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_
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Returns nonzero if c is ascii.
|
||||
*/
|
||||
int isascii(int c) {
|
||||
return 0x00 <= c && c <= 0x7F;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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:
|
||||
*
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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 0≤arity≤3
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue