mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Delete more dead code
This commit is contained in:
parent
0a24b4fc3c
commit
00acd81b2f
63 changed files with 75 additions and 1220 deletions
5
Makefile
5
Makefile
|
@ -118,9 +118,8 @@ include libc/nexgen32e/nexgen32e.mk #─┐
|
|||
include libc/sysv/sysv.mk # ├──SYSTEM SUPPORT
|
||||
include libc/nt/nt.mk # │ You can do math
|
||||
include libc/intrin/intrin.mk # │ You can use the stack
|
||||
include libc/linux/linux.mk # │ You can manipulate arrays
|
||||
include third_party/compiler_rt/compiler_rt.mk # │ You can issue raw system calls
|
||||
include libc/tinymath/tinymath.mk # │
|
||||
include third_party/compiler_rt/compiler_rt.mk # │ You can manipulate arrays
|
||||
include libc/tinymath/tinymath.mk # │ You can issue raw system calls
|
||||
include libc/str/str.mk # │
|
||||
include third_party/xed/xed.mk # │
|
||||
include third_party/puff/puff.mk # │
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/fileflagandattributes.h"
|
||||
#include "libc/nt/enum/fileinfobyhandleclass.h"
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "libc/calls/struct/statfs.h"
|
||||
#include "libc/calls/struct/statfs.internal.h"
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/enum/fsinformationclass.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nt/files.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/syscall_support-nt.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/mem/alloca.h"
|
||||
#include "libc/nt/createfile.h"
|
||||
#include "libc/nt/enum/creationdisposition.h"
|
||||
|
|
|
@ -189,6 +189,56 @@ static int unveil_init(void) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins paths, e.g.
|
||||
*
|
||||
* 0 + 0 → 0
|
||||
* "" + "" → ""
|
||||
* "a" + 0 → "a"
|
||||
* "a" + "" → "a/"
|
||||
* 0 + "b" → "b"
|
||||
* "" + "b" → "b"
|
||||
* "." + "b" → "./b"
|
||||
* "b" + "." → "b/."
|
||||
* "a" + "b" → "a/b"
|
||||
* "a/" + "b" → "a/b"
|
||||
* "a" + "b/" → "a/b/"
|
||||
* "a" + "/b" → "/b"
|
||||
*
|
||||
* @return joined path, which may be `buf`, `path`, or `other`, or null
|
||||
* if (1) `buf` didn't have enough space, or (2) both `path` and
|
||||
* `other` were null
|
||||
*/
|
||||
static char *JoinPaths(char *buf, size_t size, const char *path,
|
||||
const char *other) {
|
||||
size_t pathlen, otherlen;
|
||||
if (!other) return path;
|
||||
if (!path) return other;
|
||||
pathlen = strlen(path);
|
||||
if (!pathlen || *other == '/') {
|
||||
return (/*unconst*/ char *)other;
|
||||
}
|
||||
otherlen = strlen(other);
|
||||
if (path[pathlen - 1] == '/') {
|
||||
if (pathlen + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
memmove(buf + pathlen, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (pathlen + 1 + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
buf[pathlen] = '/';
|
||||
memmove(buf + pathlen + 1, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int sys_unveil_linux(const char *path, const char *permissions) {
|
||||
int rc;
|
||||
const char *dir;
|
||||
|
@ -250,7 +300,7 @@ int sys_unveil_linux(const char *path, const char *permissions) {
|
|||
// next = join(dirname(next), link)
|
||||
strcpy(b.buf2, next);
|
||||
dir = dirname(b.buf2);
|
||||
if ((next = _joinpaths(b.buf3, PATH_MAX, dir, b.lbuf))) {
|
||||
if ((next = JoinPaths(b.buf3, PATH_MAX, dir, b.lbuf))) {
|
||||
// next now points to either: buf3, buf2, lbuf, rodata
|
||||
strcpy(b.buf4, next);
|
||||
next = b.buf4;
|
||||
|
|
|
@ -6,8 +6,6 @@ int bing(int, int) nosideeffect;
|
|||
int unbing(int) nosideeffect;
|
||||
void *unbingbuf(void *, size_t, const char16_t *, int);
|
||||
void *unbingstr(const char16_t *) paramsnonnull() mallocesque;
|
||||
void *unhexbuf(void *, size_t, const char *);
|
||||
void *unhexstr(const char *) mallocesque;
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_FMT_BING_H_ */
|
||||
|
|
|
@ -1,71 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/str/path.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Joins paths, e.g.
|
||||
*
|
||||
* 0 + 0 → 0
|
||||
* "" + "" → ""
|
||||
* "a" + 0 → "a"
|
||||
* "a" + "" → "a/"
|
||||
* 0 + "b" → "b"
|
||||
* "" + "b" → "b"
|
||||
* "." + "b" → "./b"
|
||||
* "b" + "." → "b/."
|
||||
* "a" + "b" → "a/b"
|
||||
* "a/" + "b" → "a/b"
|
||||
* "a" + "b/" → "a/b/"
|
||||
* "a" + "/b" → "/b"
|
||||
*
|
||||
* @return joined path, which may be `buf`, `path`, or `other`, or null
|
||||
* if (1) `buf` didn't have enough space, or (2) both `path` and
|
||||
* `other` were null
|
||||
*/
|
||||
char *_joinpaths(char *buf, size_t size, const char *path, const char *other) {
|
||||
size_t pathlen, otherlen;
|
||||
if (!other) return path;
|
||||
if (!path) return other;
|
||||
pathlen = strlen(path);
|
||||
if (!pathlen || *other == '/') {
|
||||
return (/*unconst*/ char *)other;
|
||||
}
|
||||
otherlen = strlen(other);
|
||||
if (path[pathlen - 1] == '/') {
|
||||
if (pathlen + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
memmove(buf + pathlen, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (pathlen + 1 + otherlen + 1 <= size) {
|
||||
memmove(buf, path, pathlen);
|
||||
buf[pathlen] = '/';
|
||||
memmove(buf + pathlen + 1, other, otherlen + 1);
|
||||
return buf;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/fmt/bing.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
void *unhexbuf(void *buf, size_t size, const char *hexdigs) {
|
||||
size_t i;
|
||||
unsigned char *p;
|
||||
_npassert(size * 2 == strlen(hexdigs));
|
||||
p = buf;
|
||||
for (i = 0; i < size; ++i) {
|
||||
_npassert(isxdigit(hexdigs[i / 2 + 0]) && isxdigit(hexdigs[i / 2 + 1]));
|
||||
}
|
||||
for (i = 0; i < size; ++i) {
|
||||
p[i] = hextoint(hexdigs[i * 2 + 0]) * 16 + hextoint(hexdigs[i * 2 + 1]);
|
||||
}
|
||||
return buf;
|
||||
}
|
|
@ -29,7 +29,6 @@
|
|||
#include "libc/intrin/leaky.internal.h"
|
||||
#include "libc/intrin/likely.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/log/libfatal.internal.h"
|
||||
#include "libc/log/log.h"
|
||||
|
@ -43,6 +42,7 @@
|
|||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.internal.h"
|
||||
#include "libc/stdckdint.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/tab.internal.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_RUNTIME_FSGSBASE_H_
|
||||
#define COSMOPOLITAN_LIBC_RUNTIME_FSGSBASE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
void *_rdfsbase(void);
|
||||
void *_rdgsbase(void);
|
||||
void *_wrfsbase(void *);
|
||||
void *_wrgsbase(void *);
|
||||
int _have_fsgsbase(void);
|
||||
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && defined(__x86_64__)
|
||||
#define _rdfsbase() \
|
||||
({ \
|
||||
void *_p; \
|
||||
asm("rdfsbase\t%0" : "=r"(_p)); \
|
||||
_p; \
|
||||
})
|
||||
#define _rdgsbase() \
|
||||
({ \
|
||||
void *_p; \
|
||||
asm("rdgsbase\t%0" : "=r"(_p)); \
|
||||
_p; \
|
||||
})
|
||||
#define _wrfsbase(p) \
|
||||
({ \
|
||||
void *_p = p; \
|
||||
asm volatile("wrfsbase\t%0" \
|
||||
: /* no outputs */ \
|
||||
: "r"(_p) \
|
||||
: "memory"); \
|
||||
_p; \
|
||||
})
|
||||
#define _wrgsbase(p) \
|
||||
({ \
|
||||
void *_p = p; \
|
||||
asm volatile("wrgsbase\t%0" \
|
||||
: /* no outputs */ \
|
||||
: "r"(_p) \
|
||||
: "memory"); \
|
||||
_p; \
|
||||
})
|
||||
#endif /* GNUC && !ANSI */
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_RUNTIME_FSGSBASE_H_ */
|
|
@ -1,66 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/dce.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/fsgsbase.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
/**
|
||||
* Returns true if FSGSBASE ISA can be used.
|
||||
*
|
||||
* If this function returns true (Linux 5.9+ or FreeBSD) then you should
|
||||
* be able to read/write to the %gs / %fs x86 segment registers in about
|
||||
* one or two clock cycles which gives you a free addition operation for
|
||||
* all assembly ops that reference memory.
|
||||
*
|
||||
* The FSGSBASE ISA was introduced by Intel with Ivybridge (c. 2012) but
|
||||
* the Linux Kernel didn't authorize us to use it until 2020, once Intel
|
||||
* had to start backdooring customer kernels so that they could have it.
|
||||
* AMD introduced support for the FSGSBASE ISA in Excavator, aka bdver4.
|
||||
*
|
||||
* @return boolean indicating if feature can be used
|
||||
* @see _rdfsbase()
|
||||
* @see _rdgsbase()
|
||||
* @see _wrfsbase()
|
||||
* @see _wrgsbase()
|
||||
*/
|
||||
privileged int _have_fsgsbase(void) {
|
||||
// Linux 5.9 (c. 2020) introduced close_range() and fsgsbase support.
|
||||
// it's cheaper to test for close_range() than handle an op crashing.
|
||||
// Windows lets us use these instructions but they don't really work.
|
||||
int ax;
|
||||
if (X86_HAVE(FSGSBASE)) {
|
||||
if (IsLinux()) {
|
||||
asm volatile("syscall"
|
||||
: "=a"(ax)
|
||||
: "0"(436 /* close_range */), "D"(-1), "S"(-2), "d"(0)
|
||||
: "rcx", "r11", "memory");
|
||||
return ax == -22; // EINVAL
|
||||
} else if (IsFreebsd()) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -1,31 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/fsgsbase.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
/**
|
||||
* Reads `%fs` base address.
|
||||
*
|
||||
* @see _have_fsgsbase()
|
||||
*/
|
||||
void *(_rdfsbase)(void) {
|
||||
return _rdfsbase();
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -1,31 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/fsgsbase.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
/**
|
||||
* Reads `%gs` base address.
|
||||
*
|
||||
* @see _have_fsgsbase()
|
||||
*/
|
||||
void *(_rdgsbase)(void) {
|
||||
return _rdgsbase();
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -1,68 +0,0 @@
|
|||
/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│
|
||||
│vi: set et ft=asm ts=8 tw=8 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
|
||||
// Encodes Thompson-Pike varint.
|
||||
//
|
||||
// @param edi is int to encode
|
||||
// @return rax is word-encoded byte buffer
|
||||
// @note invented on a napkin in a new jersey diner
|
||||
.ftrace1
|
||||
_tpenc: .ftrace2
|
||||
.leafprologue
|
||||
mov %edi,%edi
|
||||
xor %eax,%eax
|
||||
cmp $127,%edi
|
||||
jbe 3f
|
||||
bsr %edi,%ecx
|
||||
mov kTpenc-7*(1+1)(,%rcx,2),%ecx
|
||||
1: mov %edi,%edx
|
||||
shr $6,%edi
|
||||
and $0b00111111,%dl
|
||||
or $0b10000000,%al
|
||||
or %dl,%al
|
||||
shl $8,%rax
|
||||
dec %cl
|
||||
jnz 1b
|
||||
2: or %ch,%al
|
||||
3: or %rdi,%rax
|
||||
.leafepilogue
|
||||
.endfn _tpenc,globl
|
||||
|
||||
.rodata
|
||||
.balign 4
|
||||
.underrun
|
||||
kTpenc: .rept 4 // MSB≤10 (0x7FF)
|
||||
.byte 1,0b11000000 // len,mark
|
||||
.endr
|
||||
.rept 5 // MSB≤15 (0xFFFF)
|
||||
.byte 2,0b11100000 // len,mark
|
||||
.endr
|
||||
.rept 5 // MSB≤20 (0x1FFFFF)
|
||||
.byte 3,0b11110000 // len,mark
|
||||
.endr
|
||||
.rept 5 // MSB≤25 (0x3FFFFFF)
|
||||
.byte 4,0b11111000 // len,mark
|
||||
.endr
|
||||
.rept 6 // MSB≤31 (0xffffffff)
|
||||
.byte 5,0b11111100 // len,mark
|
||||
.endr
|
||||
.zero 2
|
||||
.endobj kTpenc
|
||||
.overrun
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bsr.h"
|
||||
#ifndef __x86_64__
|
||||
|
||||
static const uint16_t kTpEnc[32 - 7] = {
|
||||
1 | 0300 << 8, 1 | 0300 << 8, 1 | 0300 << 8, 1 | 0300 << 8, 2 | 0340 << 8,
|
||||
|
@ -27,6 +26,9 @@ static const uint16_t kTpEnc[32 - 7] = {
|
|||
5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8, 5 | 0374 << 8,
|
||||
};
|
||||
|
||||
/**
|
||||
* Encodes Thompson-Pike variable-length integer.
|
||||
*/
|
||||
uint64_t _tpenc(uint32_t c) {
|
||||
int e, n;
|
||||
uint64_t w;
|
||||
|
@ -41,5 +43,3 @@ uint64_t _tpenc(uint32_t c) {
|
|||
} while (--n);
|
||||
return c | w | e >> 8;
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -1,23 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_STR_TPENC_H_
|
||||
#define COSMOPOLITAN_LIBC_STR_TPENC_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
uint64_t _tpenc(uint32_t) pureconst;
|
||||
|
||||
#if defined(__x86_64__) && defined(__MNO_RED_ZONE__) && defined(__GNUC__) && \
|
||||
!defined(__STRICT_ANSI__)
|
||||
#define _tpenc(CODE) \
|
||||
({ \
|
||||
long Edi, Buf; \
|
||||
asm("call\t_tpenc" \
|
||||
: "=a"(Buf), "=D"(Edi) \
|
||||
: "1"((int)(CODE)) \
|
||||
: "rcx", "rdx", "cc"); \
|
||||
Buf; \
|
||||
})
|
||||
#endif
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_STR_TPENC_H_ */
|
|
@ -1,31 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/fsgsbase.h"
|
||||
#ifdef __x86_64__
|
||||
|
||||
/**
|
||||
* Changes `%fs` base address.
|
||||
*
|
||||
* @see _have_fsgsbase()
|
||||
*/
|
||||
void *(_wrfsbase)(void *p) {
|
||||
return _wrfsbase(p);
|
||||
}
|
||||
|
||||
#endif /* __x86_64__ */
|
|
@ -1,28 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/fsgsbase.h"
|
||||
|
||||
/**
|
||||
* Changes `%gs` base address.
|
||||
*
|
||||
* @see _have_fsgsbase()
|
||||
*/
|
||||
void *(_wrgsbase)(void *p) {
|
||||
return _wrgsbase(p);
|
||||
}
|
|
@ -65,6 +65,9 @@ textwindows int WSARecv(
|
|||
rc = __imp_WSARecv(s, inout_lpBuffers, dwBufferCount,
|
||||
opt_out_lpNumberOfBytesRecvd, inout_lpFlags,
|
||||
opt_inout_lpOverlapped, opt_lpCompletionRoutine);
|
||||
if (rc == -1) {
|
||||
__winerr();
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,9 @@ textwindows int WSARecvFrom(
|
|||
opt_out_lpNumberOfBytesRecvd, inout_lpFlags,
|
||||
opt_out_fromsockaddr, opt_inout_fromsockaddrlen,
|
||||
opt_inout_lpOverlapped, opt_lpCompletionRoutine);
|
||||
if (rc == -1) {
|
||||
__winerr();
|
||||
}
|
||||
#endif
|
||||
return rc;
|
||||
}
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "libc/intrin/dll.h"
|
||||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/likely.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/mem/critbit0.h"
|
||||
#include "libc/mem/gc.h"
|
||||
|
|
|
@ -15,7 +15,6 @@ o/$(MODE)/libc: o/$(MODE)/libc/calls \
|
|||
o/$(MODE)/libc/elf \
|
||||
o/$(MODE)/libc/fmt \
|
||||
o/$(MODE)/libc/intrin \
|
||||
o/$(MODE)/libc/linux \
|
||||
o/$(MODE)/libc/log \
|
||||
o/$(MODE)/libc/mem \
|
||||
o/$(MODE)/libc/nexgen32e \
|
||||
|
|
|
@ -1,19 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_CLONE_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_CLONE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxClone(unsigned long flags, void* stack, int* parent_tid,
|
||||
int* child_tid, void* tls) {
|
||||
long rc;
|
||||
register int* child_tid_ asm("r10") = child_tid;
|
||||
register void* tls_ asm("r8") = tls;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(56), "D"(flags), "S"(stack), "d"(parent_tid),
|
||||
"r"(child_tid_), "r"(tls_)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_MMAP_H_ */
|
|
@ -1,12 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_CLOSE_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_CLOSE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxClose(long fd) {
|
||||
long rc;
|
||||
asm volatile("syscall" : "=a"(rc) : "0"(3), "D"(fd) : "rcx", "r11", "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_CLOSE_H_ */
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_EXECVE_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_EXECVE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxExecve(const char *program, char *const argv[],
|
||||
char *const envp[]) {
|
||||
long rc;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(59), "D"(program), "S"(argv), "d"(envp)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_EXECVE_H_ */
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_EXIT_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_EXIT_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
COSMOPOLITAN_C_START_
|
||||
|
||||
forceinline wontreturn long LinuxExit(long rc) {
|
||||
asm volatile("syscall"
|
||||
: /* no outputs */
|
||||
: "a"(0xE7), "D"(rc)
|
||||
: "memory");
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_EXIT_H_ */
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_FSTAT_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_FSTAT_H_
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxFstat(long fd, struct stat *st) {
|
||||
long rc;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(5), "D"(fd), "S"(st)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_FSTAT_H_ */
|
|
@ -1,27 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_FUTEX_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_FUTEX_H_
|
||||
#include "libc/calls/struct/timespec.h"
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline int LinuxFutexWait(void *addr, int expect,
|
||||
struct timespec *timeout) {
|
||||
int ax;
|
||||
asm volatile("mov\t%5,%%r10\n\t"
|
||||
"syscall"
|
||||
: "=a"(ax)
|
||||
: "0"(202), "D"(addr), "S"(0), "d"(expect), "g"(timeout)
|
||||
: "rcx", "r10", "r11", "memory");
|
||||
return ax;
|
||||
}
|
||||
|
||||
forceinline int LinuxFutexWake(void *addr, int count) {
|
||||
int ax;
|
||||
asm volatile("syscall"
|
||||
: "=a"(ax)
|
||||
: "0"(202), "D"(addr), "S"(1), "d"(count)
|
||||
: "rcx", "r11", "memory");
|
||||
return ax;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_FUTEX_H_ */
|
|
@ -1,11 +0,0 @@
|
|||
#-*-mode:makefile-gmake;indent-tabs-mode:t;tab-width:8;coding:utf-8-*-┐
|
||||
#───vi: set et ft=make ts=8 tw=8 fenc=utf-8 :vi───────────────────────┘
|
||||
|
||||
PKGS += LIBC_LINUX
|
||||
|
||||
LIBC_LINUX_HDRS = $(filter %.h,$(LIBC_LINUX_FILES))
|
||||
LIBC_LINUX_FILES := $(wildcard libc/linux/*)
|
||||
LIBC_LINUX_CHECKS = $(LIBC_LINUX_HDRS:%=o/$(MODE)/%.ok)
|
||||
|
||||
.PHONY: o/$(MODE)/libc/linux
|
||||
o/$(MODE)/linux: $(LIBC_LINUX_CHECKS)
|
|
@ -1,38 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_MMAP_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_MMAP_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxMmap(void *addr, size_t size, long prot, long flags,
|
||||
long fd, long off) {
|
||||
#ifdef __x86_64__
|
||||
long rc;
|
||||
register long flags_ asm("r10") = flags;
|
||||
register long fd_ asm("r8") = fd;
|
||||
register long off_ asm("r9") = off;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(9), "D"(addr), "S"(size), "d"(prot), "r"(flags_), "r"(fd_),
|
||||
"r"(off_)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = (long)addr;
|
||||
register long r1 asm("x1") = (long)size;
|
||||
register long r2 asm("x2") = (long)prot;
|
||||
register long r3 asm("x3") = (long)flags;
|
||||
register long r4 asm("x4") = (long)fd;
|
||||
register long r5 asm("x5") = (long)off;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(222), "r"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5)
|
||||
: "x8", "memory");
|
||||
return res_x0;
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_MMAP_H_ */
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_MUNMAP_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_MUNMAP_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxMunmap(void *addr, size_t size) {
|
||||
#ifdef __x86_64__
|
||||
long rc;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(0xb), "D"(addr), "S"(size)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
#elif defined(__aarch64__)
|
||||
register long r0 asm("x0") = (long)addr;
|
||||
register long r1 asm("x1") = (long)size;
|
||||
register long res_x0 asm("x0");
|
||||
asm volatile("mov\tx8,%1\n\t"
|
||||
"svc\t0"
|
||||
: "=r"(res_x0)
|
||||
: "i"(215), "r"(r0), "r"(r1)
|
||||
: "x8", "memory");
|
||||
return res_x0;
|
||||
#else
|
||||
#error "unsupported architecture"
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_MUNMAP_H_ */
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_OPEN_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_OPEN_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxOpen(const char *path, long flags, long mode) {
|
||||
long rc;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(2), "D"(path), "S"(flags), "d"(mode)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_OPEN_H_ */
|
|
@ -1,15 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_READ_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_READ_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxRead(long fd, void *data, unsigned long size) {
|
||||
long rc;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc), "=m"(*(char(*)[size])data)
|
||||
: "0"(0), "D"(fd), "S"(data), "d"(size)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_READ_H_ */
|
|
@ -1,16 +0,0 @@
|
|||
#ifndef COSMOPOLITAN_LIBC_LINUX_WRITE_H_
|
||||
#define COSMOPOLITAN_LIBC_LINUX_WRITE_H_
|
||||
#if !(__ASSEMBLER__ + __LINKER__ + 0)
|
||||
|
||||
forceinline long LinuxWrite(long fd, const void *data, unsigned long size) {
|
||||
long rc;
|
||||
asm volatile("syscall"
|
||||
: "=a"(rc)
|
||||
: "0"(1), "D"(fd), "S"(data), "d"(size),
|
||||
"m"(*(char(*)[size])data)
|
||||
: "rcx", "r11", "memory");
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
#endif /* COSMOPOLITAN_LIBC_LINUX_WRITE_H_ */
|
|
@ -26,14 +26,9 @@ int heapsort_r(void *, size_t, size_t,
|
|||
int mergesort(void *, size_t, size_t, int (*)(const void *, const void *));
|
||||
int mergesort_r(void *, size_t, size_t,
|
||||
int (*)(const void *, const void *, void *), void *);
|
||||
int _tarjan(int, const int (*)[2], int, int[], int[], int *)
|
||||
paramsnonnull((2, 4)) nocallback dontthrow;
|
||||
|
||||
#define __algalloc returnspointerwithnoaliases dontthrow nocallback dontdiscard
|
||||
|
||||
char *_replacestr(const char *, const char *, const char *)
|
||||
paramsnonnull() __algalloc;
|
||||
|
||||
bool radix_sort_int32(int32_t *, size_t);
|
||||
bool radix_sort_int64(int64_t *, size_t);
|
||||
|
||||
|
|
|
@ -1,64 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/errfuns.h"
|
||||
|
||||
/**
|
||||
* Replaces all instances of NEEDLE in S with REPLACEMENT.
|
||||
*
|
||||
* @param needle can't be empty
|
||||
* @return newly allocated memory that must be free()'d or NULL w/ errno
|
||||
* @error ENOMEM, EINVAL
|
||||
*/
|
||||
char *_replacestr(const char *s, const char *needle, const char *replacement) {
|
||||
char *p1, *p2, *res_p;
|
||||
size_t left, nlen, rlen, res_i, res_n;
|
||||
if (*needle) {
|
||||
p1 = s;
|
||||
left = strlen(s);
|
||||
nlen = strlen(needle);
|
||||
rlen = strlen(replacement);
|
||||
res_i = 0;
|
||||
res_n = MAX(left, 32);
|
||||
if ((res_p = malloc(res_n * sizeof(char)))) {
|
||||
do {
|
||||
if (!(p2 = memmem(p1, left, needle, nlen))) break;
|
||||
if (CONCAT(&res_p, &res_i, &res_n, p1, p2 - p1) == -1 ||
|
||||
CONCAT(&res_p, &res_i, &res_n, replacement, rlen) == -1) {
|
||||
goto oom;
|
||||
}
|
||||
p2 += nlen;
|
||||
left -= p2 - p1;
|
||||
p1 = p2;
|
||||
} while (left);
|
||||
if (CONCAT(&res_p, &res_i, &res_n, p1, left + 1) != -1) {
|
||||
return res_p;
|
||||
}
|
||||
}
|
||||
oom:
|
||||
free(res_p);
|
||||
} else {
|
||||
einval();
|
||||
}
|
||||
return NULL;
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Tarjan's Strongly Connected Components Algorithm.
|
||||
*
|
||||
* “The data structures that [Tarjan] devised for this problem fit
|
||||
* together in an amazingly beautiful way, so that the quantities
|
||||
* you need to look at while exploring a directed graph are always
|
||||
* magically at your fingertips. And his algorithm also does
|
||||
* topological sorting as a byproduct.” ──D.E. Knuth
|
||||
*/
|
||||
|
||||
struct Tarjan {
|
||||
int Vn, En, Ci, Ri, *R, *C, index;
|
||||
const int (*E)[2];
|
||||
struct Vertex {
|
||||
int Vi;
|
||||
int Ei;
|
||||
int index;
|
||||
int lowlink;
|
||||
bool onstack;
|
||||
bool selfreferential;
|
||||
} * V;
|
||||
struct TarjanStack {
|
||||
int i;
|
||||
int n;
|
||||
int *p;
|
||||
} S;
|
||||
};
|
||||
|
||||
static bool TarjanPush(struct Tarjan *t, int v) {
|
||||
int *q;
|
||||
_unassert(t->S.i >= 0);
|
||||
_unassert(t->S.n >= 0);
|
||||
_unassert(0 <= v && v < t->Vn);
|
||||
if (t->S.i == t->S.n) {
|
||||
if ((q = realloc(t->S.p, (t->S.n + (t->S.n >> 1) + 8) * sizeof(*t->S.p)))) {
|
||||
t->S.p = q;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
t->S.p[t->S.i++] = v;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int TarjanPop(struct Tarjan *t) {
|
||||
_unassert(t->S.i > 0);
|
||||
return t->S.p[--t->S.i];
|
||||
}
|
||||
|
||||
static bool TarjanConnect(struct Tarjan *t, int v) {
|
||||
int fs, w, e;
|
||||
_unassert(0 <= v && v < t->Vn);
|
||||
t->V[v].index = t->index;
|
||||
t->V[v].lowlink = t->index;
|
||||
t->V[v].onstack = true;
|
||||
t->index++;
|
||||
if (!TarjanPush(t, v)) return false;
|
||||
fs = t->V[v].Ei;
|
||||
if (fs != -1) {
|
||||
for (e = fs; e < t->En && v == t->E[e][0]; ++e) {
|
||||
w = t->E[e][1];
|
||||
if (!t->V[w].index) {
|
||||
if (!TarjanConnect(t, t->V[w].Vi)) return false;
|
||||
t->V[v].lowlink = MIN(t->V[v].lowlink, t->V[w].lowlink);
|
||||
} else if (t->V[w].onstack) {
|
||||
t->V[v].lowlink = MIN(t->V[v].lowlink, t->V[w].index);
|
||||
}
|
||||
if (w == v) {
|
||||
t->V[w].selfreferential = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (t->V[v].lowlink == t->V[v].index) {
|
||||
do {
|
||||
w = TarjanPop(t);
|
||||
t->V[w].onstack = false;
|
||||
t->R[t->Ri++] = t->V[w].Vi;
|
||||
} while (w != v);
|
||||
if (t->C) t->C[t->Ci++] = t->Ri;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines order of things in network and finds tangled clusters too.
|
||||
*
|
||||
* @param vertices is an array of vertex values, which isn't passed to
|
||||
* this function, since the algorithm only needs to consider indices
|
||||
* @param vertex_count is the number of items in the vertices array
|
||||
* @param edges are grouped directed links between indices of vertices,
|
||||
* which can be thought of as "edge[i][0] depends on edge[i][1]" or
|
||||
* "edge[i][1] must come before edge[i][0]" in topological order
|
||||
* @param edge_count is the number of items in edges, which may be 0 if
|
||||
* there aren't any connections between vertices in the graph
|
||||
* @param out_sorted receives indices into the vertices array in
|
||||
* topologically sorted order, and must be able to store
|
||||
* vertex_count items, and that's always how many are stored
|
||||
* @param out_opt_components receives indices into the out_sorted array,
|
||||
* indicating where each strongly-connected component ends; must be
|
||||
* able to store vertex_count items; and it may be NULL
|
||||
* @param out_opt_componentcount receives the number of cycle indices
|
||||
* written to out_opt_components, which will be vertex_count if
|
||||
* there aren't any cycles in the graph; and may be NULL if
|
||||
* out_opt_components is NULL
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @error ENOMEM
|
||||
* @note Tarjan's Algorithm is O(|V|+|E|)
|
||||
*/
|
||||
int _tarjan(int vertex_count, const int (*edges)[2], int edge_count,
|
||||
int out_sorted[], int out_opt_components[],
|
||||
int *out_opt_componentcount) {
|
||||
int i, rc, v, e;
|
||||
struct Tarjan *t;
|
||||
_unassert(0 <= edge_count && edge_count <= INT_MAX);
|
||||
_unassert(0 <= vertex_count && vertex_count <= INT_MAX);
|
||||
for (i = 0; i < edge_count; ++i) {
|
||||
if (i) _unassert(edges[i - 1][0] <= edges[i][0]);
|
||||
_unassert(edges[i][0] < vertex_count);
|
||||
_unassert(edges[i][1] < vertex_count);
|
||||
}
|
||||
if (!(t = calloc(1, (sizeof(struct Tarjan) +
|
||||
sizeof(struct Vertex) * vertex_count)))) {
|
||||
return -1;
|
||||
}
|
||||
t->V = (struct Vertex *)((char *)t + sizeof(struct Tarjan));
|
||||
t->Vn = vertex_count;
|
||||
t->E = edges;
|
||||
t->En = edge_count;
|
||||
t->R = out_sorted;
|
||||
t->C = out_opt_components;
|
||||
t->index = 1;
|
||||
for (v = 0; v < t->Vn; ++v) {
|
||||
t->V[v].Vi = v;
|
||||
t->V[v].Ei = -1;
|
||||
}
|
||||
for (e = 0, v = -1; e < t->En; ++e) {
|
||||
if (t->E[e][0] == v) continue;
|
||||
v = t->E[e][0];
|
||||
t->V[v].Ei = e;
|
||||
}
|
||||
rc = 0;
|
||||
for (v = 0; v < t->Vn; ++v) {
|
||||
if (!t->V[v].index) {
|
||||
if (!TarjanConnect(t, v)) {
|
||||
free(t->S.p);
|
||||
free(t);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (out_opt_components) {
|
||||
*out_opt_componentcount = t->Ci;
|
||||
}
|
||||
_unassert(t->Ri == vertex_count);
|
||||
free(t->S.p);
|
||||
free(t);
|
||||
return rc;
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/fmt/bing.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
dontdiscard void *unhexstr(const char *hexdigs) {
|
||||
_unassert(strlen(hexdigs) % 2 == 0);
|
||||
return unhexbuf(malloc(strlen(hexdigs) / 2), strlen(hexdigs) / 2, hexdigs);
|
||||
}
|
|
@ -83,7 +83,7 @@ static wontreturn void UnsupportedSyntax(unsigned char c) {
|
|||
char ibuf[13], cbuf[2] = {c};
|
||||
FormatOctal32(ibuf, c, true);
|
||||
tinyprint(2, prog, ": unsupported syntax '", cbuf, "' (", ibuf, "): ", cmd,
|
||||
"\n", 0);
|
||||
"\n", NULL);
|
||||
_Exit(4);
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ static wontreturn void SysExit(int rc, const char *call, const char *thing) {
|
|||
FormatInt32(ibuf, err);
|
||||
estr = _strerdoc(err);
|
||||
if (!estr) estr = "EUNKNOWN";
|
||||
tinyprint(2, thing, ": ", call, "() failed: ", estr, " (", ibuf, ")\n", 0);
|
||||
tinyprint(2, thing, ": ", call, "() failed: ", estr, " (", ibuf, ")\n", NULL);
|
||||
_Exit(rc);
|
||||
}
|
||||
|
||||
|
@ -110,7 +110,7 @@ static void Open(const char *path, int fd, int flags) {
|
|||
static wontreturn void Exec(void) {
|
||||
_unassert(args[0][0]);
|
||||
if (!n) {
|
||||
tinyprint(2, prog, ": error: too few args\n", 0);
|
||||
tinyprint(2, prog, ": error: too few args\n", NULL);
|
||||
_Exit(5);
|
||||
}
|
||||
execvpe(args[0], args, envs);
|
||||
|
@ -594,7 +594,7 @@ static char *Tokenize(void) {
|
|||
break;
|
||||
|
||||
UnterminatedString:
|
||||
tinyprint(2, "cmd: error: unterminated string\n", 0);
|
||||
tinyprint(2, "cmd: error: unterminated string\n", NULL);
|
||||
_Exit(6);
|
||||
|
||||
case STATE_QUOTED_VAR:
|
||||
|
@ -642,7 +642,7 @@ static const char *GetRedirectArg(const char *prog, const char *arg, int n) {
|
|||
} else if ((arg = Tokenize())) {
|
||||
return arg;
|
||||
} else {
|
||||
tinyprint(2, prog, ": error: redirect missing path\n", 0);
|
||||
tinyprint(2, prog, ": error: redirect missing path\n", NULL);
|
||||
_Exit(14);
|
||||
}
|
||||
}
|
||||
|
@ -675,18 +675,18 @@ int _cocmd(int argc, char **argv, char **envp) {
|
|||
}
|
||||
|
||||
if (argc != 3) {
|
||||
tinyprint(2, prog, ": error: wrong number of args\n", 0);
|
||||
tinyprint(2, prog, ": error: wrong number of args\n", NULL);
|
||||
_Exit(10);
|
||||
}
|
||||
|
||||
if (strcmp(argv[1], "-c")) {
|
||||
tinyprint(2, prog, ": error: argv[1] should -c\n", 0);
|
||||
tinyprint(2, prog, ": error: argv[1] should -c\n", NULL);
|
||||
_Exit(11);
|
||||
}
|
||||
|
||||
p = cmd = argv[2];
|
||||
if (strlen(cmd) >= ARG_MAX) {
|
||||
tinyprint(2, prog, ": error: cmd too long: ", cmd, "\n", 0);
|
||||
tinyprint(2, prog, ": error: cmd too long: ", cmd, "\n", NULL);
|
||||
_Exit(12);
|
||||
}
|
||||
|
||||
|
@ -732,7 +732,7 @@ int _cocmd(int argc, char **argv, char **envp) {
|
|||
args[n++] = globTheBuilder.gl_pathv[globCount];
|
||||
}
|
||||
} else if (globrc != GLOB_NOMATCH) {
|
||||
tinyprint(2, prog, ": error: with glob\n", 0);
|
||||
tinyprint(2, prog, ": error: with glob\n", NULL);
|
||||
_Exit(16);
|
||||
}
|
||||
globFlags |= GLOB_APPEND;
|
||||
|
@ -743,7 +743,7 @@ int _cocmd(int argc, char **argv, char **envp) {
|
|||
args[n] = 0;
|
||||
}
|
||||
} else {
|
||||
tinyprint(2, prog, ": error: too many args\n", 0);
|
||||
tinyprint(2, prog, ": error: too many args\n", NULL);
|
||||
_Exit(13);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/nt/thunk/msabi.h"
|
||||
#include "libc/runtime/internal.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/utf16.h"
|
||||
|
|
|
@ -48,7 +48,6 @@
|
|||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/nomultics.internal.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
/**
|
||||
* Writes wide character to stream.
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ COSMOPOLITAN_C_START_
|
|||
int _classifypath(const char *) libcesque nosideeffect;
|
||||
bool _isabspath(const char *) libcesque strlenesque;
|
||||
bool _isdirsep(int) libcesque pureconst;
|
||||
char *_joinpaths(char *, size_t, const char *, const char *);
|
||||
|
||||
COSMOPOLITAN_C_END_
|
||||
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
|
||||
|
|
|
@ -171,6 +171,7 @@ bool _escapedos(char16_t *, unsigned, const char16_t *, unsigned) libcesque;
|
|||
|
||||
typedef unsigned mbstate_t;
|
||||
|
||||
uint64_t _tpenc(uint32_t) pureconst;
|
||||
axdx_t tprecode8to16(char16_t *, size_t, const char *);
|
||||
axdx_t tprecode16to8(char *, size_t, const char16_t *);
|
||||
wchar_t *wcsncpy(wchar_t *, const wchar_t *, size_t);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "libc/intrin/pandn.h"
|
||||
#include "libc/intrin/pcmpgtw.h"
|
||||
#include "libc/intrin/pmovmskb.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/utf16.h"
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
#include "libc/intrin/pmovmskb.h"
|
||||
#include "libc/intrin/punpckhbw.h"
|
||||
#include "libc/intrin/punpcklbw.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/thompike.h"
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/x/x.h"
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/pcmpgtb.h"
|
||||
#include "libc/intrin/pmovmskb.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/thompike.h"
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/str/thompike.h"
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2022 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/path.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
char b[PATH_MAX];
|
||||
|
||||
TEST(xjoinpaths, test) {
|
||||
EXPECT_EQ(NULL, _joinpaths(b, sizeof(b), 0, 0));
|
||||
EXPECT_STREQ("x", _joinpaths(b, sizeof(b), "x", 0));
|
||||
EXPECT_STREQ("x", _joinpaths(b, sizeof(b), 0, "x"));
|
||||
EXPECT_STREQ("", _joinpaths(b, sizeof(b), "", ""));
|
||||
EXPECT_STREQ("", _joinpaths(b, sizeof(b), "", 0));
|
||||
EXPECT_STREQ("", _joinpaths(b, sizeof(b), 0, ""));
|
||||
EXPECT_STREQ("", _joinpaths(b, sizeof(b), "", ""));
|
||||
EXPECT_STREQ("b", _joinpaths(b, sizeof(b), "", "b"));
|
||||
EXPECT_STREQ("a/", _joinpaths(b, sizeof(b), "a", ""));
|
||||
EXPECT_STREQ("a/b", _joinpaths(b, sizeof(b), "a", "b"));
|
||||
EXPECT_STREQ("a/b", _joinpaths(b, sizeof(b), "a/", "b"));
|
||||
EXPECT_STREQ("a/b/", _joinpaths(b, sizeof(b), "a", "b/"));
|
||||
EXPECT_STREQ("/b", _joinpaths(b, sizeof(b), "a", "/b"));
|
||||
EXPECT_STREQ("./b", _joinpaths(b, sizeof(b), ".", "b"));
|
||||
EXPECT_STREQ("b/.", _joinpaths(b, sizeof(b), "b", "."));
|
||||
EXPECT_EQ(NULL, _joinpaths(b, 3, "a", "b/"));
|
||||
EXPECT_EQ(NULL, _joinpaths(b, 4, "a", "b/"));
|
||||
EXPECT_STREQ("a/b", _joinpaths(b, 4, "a/", "b"));
|
||||
EXPECT_STREQ("a/b/", _joinpaths(b, 5, "a", "b/"));
|
||||
}
|
||||
|
||||
BENCH(joinpaths, bench) {
|
||||
EZBENCH2("_joinpaths", donothing, _joinpaths(b, sizeof(b), "care", "bear"));
|
||||
EZBENCH2("xjoinpaths", donothing, free(xjoinpaths("care", "bear")));
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
TEST(_replacestr, demo) {
|
||||
EXPECT_STREQ("hello friends",
|
||||
_gc(_replacestr("hello world", "world", "friends")));
|
||||
EXPECT_STREQ("bbbbbbbb", _gc(_replacestr("aaaa", "a", "bb")));
|
||||
}
|
||||
|
||||
TEST(_replacestr, emptyString) {
|
||||
EXPECT_STREQ("", _gc(_replacestr("", "x", "y")));
|
||||
}
|
||||
|
||||
TEST(_replacestr, emptyNeedle) {
|
||||
EXPECT_EQ(NULL, _gc(_replacestr("a", "", "a")));
|
||||
EXPECT_EQ(EINVAL, errno);
|
||||
}
|
||||
|
||||
TEST(_replacestr, needleInReplacement_doesntExplode) {
|
||||
EXPECT_STREQ("xxxxxxx", _gc(_replacestr("x", "x", "xxxxxxx")));
|
||||
}
|
|
@ -1,123 +0,0 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/alg.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
STATIC_YOINK("realloc");
|
||||
|
||||
TEST(tarjan, empty_doesNothing) {
|
||||
int sorted_vertices[1] = {-1};
|
||||
int edges[][2] = {{0, 0}};
|
||||
int vertex_count = 0;
|
||||
int edge_count = 0;
|
||||
_tarjan(vertex_count, (void *)edges, edge_count, sorted_vertices, NULL, NULL);
|
||||
ASSERT_EQ(-1, sorted_vertices[0]);
|
||||
}
|
||||
|
||||
TEST(tarjan, topologicalSort_noCycles) {
|
||||
enum VertexIndex { A = 0, B = 1, C = 2, D = 3 };
|
||||
const char *const vertices[] = {[A] = "A", [B] = "B", [C] = "C", [D] = "D"};
|
||||
int edges[][2] = {{A /* depends on → */, B /* which must come before A */},
|
||||
{A /* depends on → */, C /* which must come before A */},
|
||||
{A /* depends on → */, D /* which must come before A */},
|
||||
{B /* depends on → */, C /* which must come before B */},
|
||||
{B /* depends on → */, D /* which must come before B */}};
|
||||
/*
|
||||
$ tsort <<EOF
|
||||
B A
|
||||
C A
|
||||
D A
|
||||
C B
|
||||
D B
|
||||
EOF
|
||||
C
|
||||
D
|
||||
B
|
||||
A
|
||||
*/
|
||||
int sorted[4], components[4], componentcount;
|
||||
ASSERT_EQ(0, _tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
|
||||
sorted, components, &componentcount));
|
||||
EXPECT_EQ(C, sorted[0]);
|
||||
EXPECT_EQ(D, sorted[1]);
|
||||
EXPECT_EQ(B, sorted[2]);
|
||||
EXPECT_EQ(A, sorted[3]);
|
||||
ASSERT_EQ(4, componentcount);
|
||||
EXPECT_EQ(1, components[0]);
|
||||
EXPECT_EQ(2, components[1]);
|
||||
EXPECT_EQ(3, components[2]);
|
||||
EXPECT_EQ(4, components[3]);
|
||||
}
|
||||
|
||||
TEST(tarjan, testOneBigCycle_isDetected_weDontCareAboutOrderInsideTheCycle) {
|
||||
enum VertexIndex { A = 0, B = 1, C = 2, D = 3 };
|
||||
const char *const vertices[] = {[A] = "A", [B] = "B", [C] = "C", [D] = "D"};
|
||||
/* ┌─────────┐
|
||||
└→A→B→C→D─┘ */
|
||||
int edges[][2] = {{A /* depends on → */, B /* which must come before A */},
|
||||
{B /* depends on → */, C /* which must come before B */},
|
||||
{C /* depends on → */, D /* which must come before C */},
|
||||
{D /* depends on → */, A /* which must come before D */}};
|
||||
int sorted[4], components[4], componentcount;
|
||||
ASSERT_EQ(0, _tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
|
||||
sorted, components, &componentcount));
|
||||
ASSERT_EQ(1, componentcount);
|
||||
EXPECT_EQ(4, components[0]);
|
||||
}
|
||||
|
||||
TEST(tarjan, testHeaders) {
|
||||
enum Headers {
|
||||
LIBC_STR_STR,
|
||||
LIBC_BITS_BITS,
|
||||
LIBC_INTEGRAL,
|
||||
LIBC_KEYWORDS,
|
||||
LIBC_DCE,
|
||||
LIBC_MACROS,
|
||||
LIBC_MACROS_CPP,
|
||||
};
|
||||
const char *const vertices[] = {
|
||||
[LIBC_STR_STR] = "libc/str/str.h",
|
||||
[LIBC_BITS_BITS] = "libc/intrin/bits.h",
|
||||
[LIBC_INTEGRAL] = "libc/integral.h",
|
||||
[LIBC_KEYWORDS] = "libc/keywords.h",
|
||||
[LIBC_DCE] = "libc/dce.h",
|
||||
[LIBC_MACROS] = "libc/macros.internal.h",
|
||||
[LIBC_MACROS_CPP] = "libc/macros-cpp.inc",
|
||||
};
|
||||
int edges[][2] = {
|
||||
{LIBC_STR_STR, LIBC_BITS_BITS}, {LIBC_STR_STR, LIBC_INTEGRAL},
|
||||
{LIBC_STR_STR, LIBC_KEYWORDS}, {LIBC_BITS_BITS, LIBC_DCE},
|
||||
{LIBC_BITS_BITS, LIBC_INTEGRAL}, {LIBC_BITS_BITS, LIBC_KEYWORDS},
|
||||
{LIBC_BITS_BITS, LIBC_MACROS}, {LIBC_MACROS, LIBC_MACROS_CPP},
|
||||
};
|
||||
int sorted[ARRAYLEN(vertices)];
|
||||
int components[ARRAYLEN(vertices)];
|
||||
int componentcount;
|
||||
ASSERT_EQ(0, _tarjan(ARRAYLEN(vertices), (void *)edges, ARRAYLEN(edges),
|
||||
sorted, components, &componentcount));
|
||||
ASSERT_EQ(ARRAYLEN(vertices), componentcount);
|
||||
EXPECT_STREQ("libc/dce.h", vertices[sorted[0]]);
|
||||
EXPECT_STREQ("libc/integral.h", vertices[sorted[1]]);
|
||||
EXPECT_STREQ("libc/keywords.h", vertices[sorted[2]]);
|
||||
EXPECT_STREQ("libc/macros-cpp.inc", vertices[sorted[3]]);
|
||||
EXPECT_STREQ("libc/macros.internal.h", vertices[sorted[4]]);
|
||||
EXPECT_STREQ("libc/intrin/bits.h", vertices[sorted[5]]);
|
||||
EXPECT_STREQ("libc/str/str.h", vertices[sorted[6]]);
|
||||
}
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/linux/mmap.h"
|
||||
#include "ape/sections.internal.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
|
@ -28,7 +27,6 @@
|
|||
#include "libc/intrin/kprintf.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/xchg.internal.h"
|
||||
#include "libc/linux/munmap.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/gc.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
@ -461,22 +459,3 @@ BENCH(mmap, bench) {
|
|||
EZBENCH2("mmap", donothing, BenchMmapPrivate());
|
||||
EZBENCH2("munmap", donothing, BenchUnmap());
|
||||
}
|
||||
|
||||
void BenchUnmapLinux(void) {
|
||||
ASSERT_EQ(0, LinuxMunmap(ptrs[count++], FRAMESIZE));
|
||||
}
|
||||
|
||||
void BenchMmapPrivateLinux(void) {
|
||||
void *p;
|
||||
p = (void *)LinuxMmap(0, FRAMESIZE, PROT_READ | PROT_WRITE,
|
||||
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if (p == MAP_FAILED) abort();
|
||||
ptrs[count++] = p;
|
||||
}
|
||||
|
||||
BENCH(mmap, benchLinux) {
|
||||
void *p;
|
||||
if (!IsLinux()) return;
|
||||
EZBENCH2("mmap (linux)", donothing, BenchMmapPrivateLinux());
|
||||
EZBENCH2("munmap (linux)", donothing, BenchUnmapLinux());
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "libc/stdio/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/testlib/ezbench.h"
|
||||
#include "libc/testlib/testlib.h"
|
||||
|
||||
|
|
1
third_party/linenoise/linenoise.c
vendored
1
third_party/linenoise/linenoise.c
vendored
|
@ -144,7 +144,6 @@
|
|||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/nomultics.internal.h"
|
||||
#include "libc/intrin/strace.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/arraylist2.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "libc/fmt/itoa.h"
|
||||
#include "libc/intrin/bits.h"
|
||||
#include "libc/intrin/bsr.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "libc/calls/termios.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
#include "libc/intrin/hilbert.h"
|
||||
#include "libc/intrin/morton.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/tpenc.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
|
|
Loading…
Reference in a new issue