mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-27 15:52:28 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
61
examples/backtrace.c
Normal file
61
examples/backtrace.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/runtime/symbols.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/*
|
||||
|
||||
Your executables will try to find the addr2line tool, which is needed
|
||||
to decrypt gcc debug information, enabling backtraces like this:
|
||||
|
||||
0x0000000000403a7a: Hello at examples/backtrace.c:31
|
||||
0x0000000000403ac3: World at examples/backtrace.c:38
|
||||
0x0000000000401608: main at examples/backtrace.c:42
|
||||
0x0000000000401379: _start at libc/crt/crt.S:61
|
||||
|
||||
If that doesn't work, then your αcτµαlly pδrταblε εxεcµταblε will use
|
||||
its own builtin fallback solution:
|
||||
|
||||
0000ac2fa7e0 000000403a9b Hello+0x49
|
||||
0000ac2fa7f0 000000403ac4 World+0x22
|
||||
0000ac2fa800 000000401609 main+0x7
|
||||
0000ac2fa810 00000040137a _start+0x63
|
||||
|
||||
This is guaranteed to work if the .com.dbg file can be found.
|
||||
Otherwise it'll print numbers:
|
||||
|
||||
0000268a8390 000000403a90 (null)+0x403a8f
|
||||
0000268a83a0 000000403aef (null)+0x403aee
|
||||
0000268a83b0 0000004015fe (null)+0x4015fd
|
||||
0000268a83c0 00000040137a (null)+0x401379
|
||||
|
||||
*/
|
||||
|
||||
void hello(void) {
|
||||
gc(malloc(1));
|
||||
backtrace(stdout);
|
||||
setenv("ADDR2LINE", "", true);
|
||||
backtrace(stdout);
|
||||
}
|
||||
|
||||
void world(void) {
|
||||
gc(malloc(1));
|
||||
hello();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
world();
|
||||
return 0;
|
||||
}
|
101
examples/bigmem.c
Normal file
101
examples/bigmem.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/madv.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Overcommit tutorial.
|
||||
* You can allocate memory like a central banker prints money.
|
||||
*/
|
||||
|
||||
/* #define kHugeAmount (10LU * 1024LU * 1024LU * 1024LU * 1024LU) */
|
||||
#define kHugeAmount (1LU * 1024LU * 1024LU * 1024LU)
|
||||
|
||||
int copyfile2(const char *frompath, const char *topath, bool dontoverwrite) {
|
||||
struct stat st;
|
||||
ssize_t transferred;
|
||||
int rc, fromfd, tofd;
|
||||
int64_t inoffset, outoffset;
|
||||
rc = -1;
|
||||
if ((fromfd = open(frompath, O_RDONLY | O_DIRECT, 0)) != -1) {
|
||||
if (fstat(fromfd, &st) != -1 &&
|
||||
(tofd =
|
||||
open(topath,
|
||||
O_WRONLY | O_CREAT | O_DIRECT | (dontoverwrite ? O_EXCL : 0),
|
||||
st.st_mode & 0777)) != -1) {
|
||||
inoffset = 0;
|
||||
outoffset = 0;
|
||||
while (st.st_size &&
|
||||
(transferred = copy_file_range(fromfd, &inoffset, tofd, &outoffset,
|
||||
st.st_size, 0)) != -1) {
|
||||
st.st_size -= transferred;
|
||||
}
|
||||
if (!st.st_size) rc = 0;
|
||||
rc |= close(tofd);
|
||||
}
|
||||
rc |= close(fromfd);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd, pid;
|
||||
size_t size;
|
||||
long double t1, t2;
|
||||
const char *core, *core2, *core3;
|
||||
volatile unsigned char *mem;
|
||||
size = ROUNDUP(kHugeAmount, PAGESIZE);
|
||||
core = gc(xasprintf("%s.%s", getauxval(AT_EXECFN), "core"));
|
||||
core2 = gc(xasprintf("%s.%s", getauxval(AT_EXECFN), "core2"));
|
||||
core3 = gc(xasprintf("%s.%s", getauxval(AT_EXECFN), "core3"));
|
||||
CHECK_NE(-1, (fd = open(core, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0600)));
|
||||
CHECK_NE(-1, ftruncate(fd, size));
|
||||
CHECK_NE(MAP_FAILED,
|
||||
(mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
|
||||
strcpy(&mem[0], "hello\n\n\n\n\n\n\n\n\n\n");
|
||||
strcpy(&mem[kHugeAmount / 2], "hello\n\n\n\n\n\n\n\n\n\n");
|
||||
CHECK_NE(-1, munmap(mem, size));
|
||||
CHECK_NE(-1,
|
||||
(pid = spawnve(
|
||||
0, (int[3]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO},
|
||||
"o/examples/stat.com",
|
||||
(char *const[]){"o/examples/stat.com", core, NULL}, environ)));
|
||||
CHECK_NE(-1, waitpid(pid, NULL, 0));
|
||||
CHECK_NE(-1, close(fd));
|
||||
|
||||
t1 = dtime(CLOCK_REALTIME);
|
||||
CHECK_NE(-1, copyfile(core, core2, false));
|
||||
t2 = dtime(CLOCK_REALTIME);
|
||||
printf("%.6Lf\n", t2 - t1);
|
||||
|
||||
t1 = dtime(CLOCK_REALTIME);
|
||||
CHECK_NE(-1, copyfile2(core, core3, false));
|
||||
t2 = dtime(CLOCK_REALTIME);
|
||||
printf("%.6Lf\n", t2 - t1);
|
||||
|
||||
/* CHECK_NE(-1, unlink(core)); */
|
||||
return 0;
|
||||
}
|
23
examples/breakpoint.c
Normal file
23
examples/breakpoint.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
showcrashreports();
|
||||
if (IsDebuggerPresent(false)) {
|
||||
printf("debugger found!\r\n");
|
||||
DebugBreak();
|
||||
return 0;
|
||||
}
|
||||
printf("try running: gdb %s\r\n", argv[0]);
|
||||
return 1;
|
||||
}
|
48
examples/cplusplus.cc
Normal file
48
examples/cplusplus.cc
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*-*-mode:c++;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8-*-│
|
||||
│vi: set net ft=c++ ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
class Log {
|
||||
public:
|
||||
Log();
|
||||
~Log();
|
||||
int *x();
|
||||
|
||||
private:
|
||||
int *x_;
|
||||
};
|
||||
|
||||
Log::Log() { x_ = new int[64]; }
|
||||
Log::~Log() { delete x_; }
|
||||
int *Log::x() { return x_; }
|
||||
|
||||
class Log g_log;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int *x = new int[64];
|
||||
memset(x, 0, 64 * sizeof(int));
|
||||
for (int i = 0; i < min(64, argc); ++i) g_log.x()[i] += argc;
|
||||
printf("%p %d %d %d\n", (void *)(intptr_t)g_log.x(), g_log.x()[0],
|
||||
g_log.x()[0], g_log.x()[0]);
|
||||
delete x;
|
||||
return 0;
|
||||
}
|
89
examples/crashreport.c
Normal file
89
examples/crashreport.c
Normal file
|
@ -0,0 +1,89 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/pushpop.h"
|
||||
#include "libc/calls/ucontext.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/nt/enum/errormodeflags.h"
|
||||
#include "libc/nt/signals.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Demonstrates SEGFAULT via NULL pointer dereference.
|
||||
*
|
||||
* In MODE=dbg mode, UBSAN should catch this and display a backtrace.
|
||||
* In most other modes, e.g. MODE=balanced, the oncrash.c sig handler
|
||||
* will either launch GDB or display a very fancy report.
|
||||
*
|
||||
* make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com
|
||||
* o/opt/examples/crashreportdemo.com
|
||||
*
|
||||
* To prevent the GDB GUI from popping up:
|
||||
*
|
||||
* export GDB=""
|
||||
* make -j8 -O MODE=opt o/opt/examples/crashreportdemo.com
|
||||
* o/opt/examples/crashreportdemo.com
|
||||
*/
|
||||
|
||||
int boo;
|
||||
|
||||
void boop(void);
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int64_t res;
|
||||
showcrashreports();
|
||||
res = 0;
|
||||
|
||||
asm volatile(
|
||||
"mov\t$0x1111111111111111,%rax\n\t"
|
||||
"mov\t$0x3333333333333333,%rcx\n\t"
|
||||
"mov\t$0x4444444444444444,%rdx\n\t"
|
||||
"mov\t$0x8888888888888888,%r8\n\t"
|
||||
"mov\t$0x9999999999999999,%r9d\n\t"
|
||||
"mov\t$0xaaaaaaaaaaaaaaaa,%r10d\n\t"
|
||||
"mov\t$0xbbbbbbbbbbbbbbbb,%r11d\n\t"
|
||||
"mov\t$0x0000000000000000,%rax\n\t"
|
||||
"movd\t%rax,%xmm0\n\t"
|
||||
"mov\t$0x1111111111111111,%rax\n\t"
|
||||
"movd\t%rax,%xmm1\n\t"
|
||||
"mov\t$0x2222222222222222,%rax\n\t"
|
||||
"movd\t%rax,%xmm2\n\t"
|
||||
"mov\t$0x3333333333333333,%rax\n\t"
|
||||
"movd\t%rax,%xmm3\n\t"
|
||||
"mov\t$0x4444444444444444,%rax\n\t"
|
||||
"movd\t%rax,%xmm4\n\t"
|
||||
"mov\t$0x5555555555555555,%rax\n\t"
|
||||
"movd\t%rax,%xmm5\n\t"
|
||||
"mov\t$0x6666666666666666,%rax\n\t"
|
||||
"movd\t%rax,%xmm6\n\t"
|
||||
"mov\t$0x7777777777777777,%rax\n\t"
|
||||
"movd\t%rax,%xmm7\n\t"
|
||||
"mov\t$0x8888888888888888,%rax\n\t"
|
||||
"movd\t%rax,%xmm8\n\t"
|
||||
"mov\t$0x9999999999999999,%rax\n\t"
|
||||
"movd\t%rax,%xmm9\n\t"
|
||||
"mov\t$0xaaaaaaaaaaaaaaaa,%rax\n\t"
|
||||
"movd\t%rax,%xmm10\n\t"
|
||||
"mov\t$0xbbbbbbbbbbbbbbbb,%rax\n\t"
|
||||
"movd\t%rax,%xmm11\n\t"
|
||||
"mov\t$0xcccccccccccccccc,%rax\n\t"
|
||||
"movd\t%rax,%xmm12\n\t"
|
||||
"mov\t$0xdddddddddddddddd,%rax\n\t"
|
||||
"movd\t%rax,%xmm13\n\t"
|
||||
"mov\t$0xeeeeeeeeeeeeeeee,%rax\n\t"
|
||||
"movd\t%rax,%xmm14\n\t"
|
||||
"mov\t$0xffffffffffffffff,%rax\n\t"
|
||||
"movd\t%rax,%xmm15\n\t"
|
||||
"fldlg2\n\t");
|
||||
|
||||
res = *(int *)(intptr_t)boo / boo;
|
||||
return res;
|
||||
}
|
66
examples/ctrlc.c
Normal file
66
examples/ctrlc.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
#define kTutorialMessage "This echos stdio until Ctrl+C is pressed.\n"
|
||||
#define kVictoryMessage "\rGot Ctrl+C and longjmp() ran dtors (>'.')>\n"
|
||||
|
||||
jmp_buf jb;
|
||||
|
||||
void GotCtrlC(int sig) {
|
||||
gclongjmp(jb, 1);
|
||||
unreachable;
|
||||
}
|
||||
|
||||
size_t HowManyBytesOfHeapMemoryAreAllocated(void) {
|
||||
return mallinfo().uordblks;
|
||||
}
|
||||
|
||||
void ReadAndPrintLinesLoop(void) {
|
||||
ssize_t got;
|
||||
unsigned char *buf;
|
||||
buf = gc(malloc(BUFSIZ));
|
||||
CHECK_NE(0, HowManyBytesOfHeapMemoryAreAllocated());
|
||||
for (;;) {
|
||||
CHECK_NE(-1, (got = read(STDIN_FILENO, buf, BUFSIZ)));
|
||||
CHECK_EQ(got, write(STDOUT_FILENO, buf, got));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rc;
|
||||
rc = 0;
|
||||
showcrashreports();
|
||||
if (cancolor()) {
|
||||
CHECK_EQ(0 /* cosmo runtime doesn't link malloc */,
|
||||
HowManyBytesOfHeapMemoryAreAllocated());
|
||||
puts("This echos stdio until Ctrl+C is pressed.");
|
||||
if (!(rc = setjmp(jb))) {
|
||||
CHECK_NE(SIG_ERR, signal(SIGINT, GotCtrlC));
|
||||
ReadAndPrintLinesLoop();
|
||||
unreachable;
|
||||
} else {
|
||||
--rc;
|
||||
}
|
||||
CHECK_EQ(0, HowManyBytesOfHeapMemoryAreAllocated());
|
||||
puts("\rGot Ctrl+C and longjmp() ran dtors (>'.')>");
|
||||
}
|
||||
return rc;
|
||||
}
|
21
examples/date.c
Normal file
21
examples/date.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* @fileoverview ISO-8601 international high-precision timestamp printer.
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
puts(gc(xiso8601ts(NULL)));
|
||||
return 0;
|
||||
}
|
376
examples/dinlerp.c
Normal file
376
examples/dinlerp.c
Normal file
|
@ -0,0 +1,376 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "dsp/core/core.h"
|
||||
#include "dsp/core/twixt8.h"
|
||||
#include "dsp/scale/scale.h"
|
||||
#include "dsp/tty/itoa8.h"
|
||||
#include "dsp/tty/quant.h"
|
||||
#include "libc/alg/arraylist2.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/calls/struct/winsize.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/stb/stb_image.h"
|
||||
|
||||
/**
|
||||
* Hat tips go out to Hornet, CRTC, DESiRE, Hans Petter Jansson, Guihua
|
||||
* Cui, Ming Ronnier Luoand anyone else Mister Rogers would describe as
|
||||
* the The Helpers Of This World who've helped us learn more about the
|
||||
* cool yet exceedingly difficult things possible to do with graphics.
|
||||
*/
|
||||
|
||||
#define DIN99 1
|
||||
#define GAMMA 4.1
|
||||
#define GAMMA_A .05
|
||||
#define GAMMA_B 50.
|
||||
#define GAMMA_C .055
|
||||
#define COLORSPACE_SRC kSrgbD65ToXyzD50
|
||||
#define COLORSPACE_TTY kSrgbD65ToXyzD50
|
||||
|
||||
#define SQR(X) ((X) * (X))
|
||||
#define DEG(X) ((X)*M_PI / 180)
|
||||
|
||||
const double kXyzKappa = 24389 / 27.;
|
||||
const double kXyzEpsilon = 216 / 24389.;
|
||||
|
||||
const double kSrgbD65ToXyzD50[3][3] = {
|
||||
{.4360747, .3850649, .1430804},
|
||||
{.2225045, .7168786, .0606169},
|
||||
{.0139322, .0971045, .7141733},
|
||||
};
|
||||
|
||||
const double kCieRgbEToXyz[3][3] = {
|
||||
{.4887180, .3106803, .2006017},
|
||||
{.1762044, .8129847, .0108109},
|
||||
{.0000000, .0102048, .9897952},
|
||||
};
|
||||
|
||||
const unsigned char kShadePct[] = {0300, 0200, 0100};
|
||||
const unsigned short kShadeRune[] = {u'▓', u'▒', u'░'};
|
||||
|
||||
const unsigned char kAnsiTango[16][3] = {
|
||||
{46, 52, 54}, {204, 0, 0}, {78, 154, 6}, {196, 160, 0},
|
||||
{52, 101, 164}, {117, 80, 123}, {6, 152, 154}, {211, 215, 207},
|
||||
{85, 87, 83}, {239, 41, 41}, {138, 226, 52}, {252, 233, 79},
|
||||
{114, 159, 207}, {173, 127, 168}, {52, 226, 226}, {238, 238, 236},
|
||||
};
|
||||
|
||||
const unsigned char kCga[16][3] = {
|
||||
{0, 0, 0}, {170, 0, 0}, {0, 170, 0}, {170, 85, 0},
|
||||
{0, 0, 170}, {170, 0, 170}, {0, 170, 170}, {170, 170, 170},
|
||||
{85, 85, 85}, {255, 85, 85}, {85, 255, 85}, {255, 255, 85},
|
||||
{85, 85, 255}, {255, 85, 255}, {85, 255, 255}, {255, 255, 255},
|
||||
};
|
||||
|
||||
struct Blends {
|
||||
size_t i, n;
|
||||
struct Blend {
|
||||
unsigned char color[4];
|
||||
unsigned char bg, fg;
|
||||
unsigned short rune;
|
||||
} * p;
|
||||
} blends;
|
||||
|
||||
static double Gamma(double x) {
|
||||
if (x < GAMMA_A) return x / GAMMA_B;
|
||||
return pow(1 / (1 + GAMMA_C) * (x + GAMMA_C), GAMMA);
|
||||
}
|
||||
|
||||
static void *LoadRgb(double rgb[3], const unsigned char pix[3]) {
|
||||
rgb[0] = Gamma(1. / 255 * pix[0]);
|
||||
rgb[1] = Gamma(1. / 255 * pix[1]);
|
||||
rgb[2] = Gamma(1. / 255 * pix[2]);
|
||||
return rgb;
|
||||
}
|
||||
|
||||
static double Lab(double x) {
|
||||
return x > kXyzEpsilon ? cbrtf(x) : (kXyzKappa * x + 16) / 116;
|
||||
}
|
||||
|
||||
static void XyzToLab(double lab[3], const double d50xyz[3]) {
|
||||
double Y, L, a, b;
|
||||
Y = Lab(d50xyz[1]);
|
||||
L = 116 * Y - 16;
|
||||
a = 500 * (Lab(d50xyz[0]) - Y);
|
||||
b = 200 * (Y - Lab(d50xyz[2]));
|
||||
lab[0] = L, lab[1] = a, lab[2] = b;
|
||||
}
|
||||
|
||||
static void XyzToDin99d(unsigned char din99d[3], const double d50xyz[3]) {
|
||||
double e, f, G, C, h, xyz[3], lab[3];
|
||||
memcpy(xyz, d50xyz, sizeof(xyz));
|
||||
xyz[0] = 1.12f * xyz[0] - .12f * xyz[2];
|
||||
XyzToLab(lab, xyz);
|
||||
e = (+lab[1] * cosf(DEG(50)) + lab[2] * sinf(DEG(50)));
|
||||
f = (-lab[1] * sinf(DEG(50)) + lab[2] + cosf(DEG(50))) * 1.14;
|
||||
G = sqrtf(SQR(e) + SQR(f));
|
||||
C = logf(1 + .06 * G) * 22.5f;
|
||||
h = atan2f(f, e) + DEG(50);
|
||||
h = fmodf(h, DEG(360));
|
||||
if (h < 0) h += DEG(360);
|
||||
din99d[0] = MIN(255, MAX(0, 325.22f * logf(1 + .0036 * lab[0]) * 2.5f));
|
||||
din99d[1] = MIN(255, MAX(0, C * cos(h) * 2.5f + 128));
|
||||
din99d[2] = MIN(255, MAX(0, C * sin(h) * 2.5f + 128));
|
||||
}
|
||||
|
||||
static void AddColor(int bg, int fg, int rune, int r, int g, int b, int x) {
|
||||
int i;
|
||||
if (blends.i) {
|
||||
for (i = blends.i; --i;) {
|
||||
if (blends.p[i].color[0] == r && blends.p[i].color[1] == g &&
|
||||
blends.p[i].color[2] == b) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
CHECK_NE(
|
||||
-1,
|
||||
APPEND(&blends.p, &blends.i, &blends.n,
|
||||
(&(struct Blend){
|
||||
.bg = bg, .fg = fg, .rune = rune, .color = {r, g, b, x}})));
|
||||
}
|
||||
|
||||
static void AddBlend(int bgxterm, int fgxterm, int rune, int shade,
|
||||
const unsigned char bgrgb[4],
|
||||
const unsigned char fgrgb[4]) {
|
||||
AddColor(bgxterm, fgxterm, rune, twixt8(bgrgb[0], fgrgb[0], shade),
|
||||
twixt8(bgrgb[1], fgrgb[1], shade), twixt8(bgrgb[2], fgrgb[2], shade),
|
||||
0);
|
||||
}
|
||||
|
||||
static void MakeBlends(const unsigned char palette[16][3]) {
|
||||
int r, i, j, k;
|
||||
double rgb[3], xyz[3];
|
||||
unsigned char tab[256][4];
|
||||
unsigned char cube[6] = {0, 0137, 0207, 0257, 0327, 0377};
|
||||
unsigned char seqs[2][2] = {{16, 255}};
|
||||
for (i = 0; i < 16; ++i) {
|
||||
tab[i][0] = palette[i][0];
|
||||
tab[i][1] = palette[i][1];
|
||||
tab[i][2] = palette[i][2];
|
||||
tab[i][3] = i;
|
||||
}
|
||||
for (i = 16; i < 232; ++i) {
|
||||
tab[i][0] = cube[((i - 020) / 044) % 6];
|
||||
tab[i][1] = cube[((i - 020) / 6) % 6];
|
||||
tab[i][2] = cube[(i - 020) % 6];
|
||||
tab[i][3] = i;
|
||||
}
|
||||
for (i = 232; i < 256; ++i) {
|
||||
tab[i][0] = 8 + (i - 232) * 10;
|
||||
tab[i][1] = 8 + (i - 232) * 10;
|
||||
tab[i][2] = 8 + (i - 232) * 10;
|
||||
tab[i][3] = i;
|
||||
}
|
||||
#if DIN99
|
||||
for (i = 0; i < 256; ++i) {
|
||||
LoadRgb(rgb, tab[i]);
|
||||
vmatmul3(xyz, rgb, COLORSPACE_TTY);
|
||||
XyzToDin99d(tab[i], xyz);
|
||||
}
|
||||
#endif
|
||||
for (r = 0; r < ARRAYLEN(seqs); ++r) {
|
||||
for (i = seqs[r][0]; i <= seqs[r][1]; ++i) {
|
||||
for (j = seqs[r][0]; j <= seqs[r][1]; ++j) {
|
||||
if (i == j) {
|
||||
AddColor(i, 0, 0, tab[i][0], tab[i][1], tab[i][2], 0);
|
||||
} else {
|
||||
for (k = 0; k < ARRAYLEN(kShadeRune); ++k) {
|
||||
AddBlend(i, j, kShadeRune[k], kShadePct[k], tab[i], tab[j]);
|
||||
AddBlend(j, i, kShadeRune[k], kShadePct[k], tab[j], tab[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int PickColor(unsigned char color[3]) {
|
||||
int i, best, least, dist;
|
||||
best = -1;
|
||||
least = INT_MAX;
|
||||
for (i = 0; i < blends.i; ++i) {
|
||||
dist = SQR(blends.p[i].color[0] - color[0]) +
|
||||
SQR(blends.p[i].color[1] - color[1]) +
|
||||
SQR(blends.p[i].color[2] - color[2]);
|
||||
if (dist < least) {
|
||||
least = dist;
|
||||
best = i;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
static void SetBg(int x) {
|
||||
if (0 <= x && x < 16) {
|
||||
if (x < 8) {
|
||||
x += 40;
|
||||
} else {
|
||||
x -= 8;
|
||||
x *= 100;
|
||||
}
|
||||
printf("\e[%dm", x);
|
||||
} else {
|
||||
/* assert(false); */
|
||||
printf("\e[48;5;%dm", x);
|
||||
}
|
||||
}
|
||||
|
||||
static void SetFg(int x) {
|
||||
if (0 <= x && x < 16) {
|
||||
if (x < 8) {
|
||||
x += 30;
|
||||
} else {
|
||||
x -= 8;
|
||||
x *= 90;
|
||||
}
|
||||
printf("\e[%dm", x);
|
||||
} else {
|
||||
/* assert(false); */
|
||||
printf("\e[38;5;%dm", x);
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintImage(long yn, long xn, unsigned char src[4][yn][xn]) {
|
||||
int y, x, c;
|
||||
double rgb[3], xyz[3];
|
||||
unsigned char din99d[3];
|
||||
for (y = 0; y < yn; ++y) {
|
||||
printf("\n");
|
||||
for (x = 0; x < xn; ++x) {
|
||||
din99d[0] = src[0][y][x];
|
||||
din99d[1] = src[1][y][x];
|
||||
din99d[2] = src[2][y][x];
|
||||
#if DIN99
|
||||
LoadRgb(rgb, din99d);
|
||||
vmatmul3(xyz, rgb, COLORSPACE_SRC);
|
||||
XyzToDin99d(din99d, xyz);
|
||||
#endif
|
||||
c = PickColor(din99d);
|
||||
if (blends.p[c].rune) {
|
||||
SetBg(blends.p[c].bg);
|
||||
SetFg(blends.p[c].fg);
|
||||
printf("%hc", blends.p[c].rune);
|
||||
} else {
|
||||
SetBg(blends.p[c].bg);
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
printf("\e[0m");
|
||||
}
|
||||
printf("\r");
|
||||
}
|
||||
|
||||
static void *Deinterlace(long dcn, long dyn, long dxn,
|
||||
unsigned char dst[dcn][dyn][dxn], long syw, long sxw,
|
||||
long scw, const unsigned char src[syw][sxw][scw],
|
||||
long syn, long sxn, long sy0, long sx0, long sc0) {
|
||||
long y, x, c;
|
||||
for (y = 0; y < dyn; ++y) {
|
||||
for (x = 0; x < dxn; ++x) {
|
||||
for (c = 0; c < dcn; ++c) {
|
||||
dst[c][y][x] = src[sy0 + y][sx0 + x][sc0 + c];
|
||||
}
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
static void GetTermSize(int out_rows[1], int out_cols[1]) {
|
||||
struct winsize ws;
|
||||
ws.ws_row = 24;
|
||||
ws.ws_col = 80;
|
||||
if (ioctl(STDIN_FILENO, TIOCGWINSZ, &ws) == -1) {
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws);
|
||||
}
|
||||
out_rows[0] = ws.ws_row;
|
||||
out_cols[0] = ws.ws_col;
|
||||
}
|
||||
|
||||
static void ProcessImage(long syn, long sxn, unsigned char img[syn][sxn][4]) {
|
||||
int dyn, dxn;
|
||||
double ry, rx;
|
||||
GetTermSize(&dyn, &dxn);
|
||||
ry = syn, rx = sxn;
|
||||
ry /= dyn, rx /= dxn;
|
||||
PrintImage(
|
||||
dyn, dxn,
|
||||
EzGyarados(4, dyn, dxn, gc(xmemalign(32, dyn * dxn * 4)), 4, syn, sxn,
|
||||
Deinterlace(4, syn, sxn, gc(xmemalign(32, syn * sxn * 4)), syn,
|
||||
sxn, 4, img, syn, sxn, 0, 0, 0),
|
||||
0, 4, dyn, dxn, syn, sxn, ry, rx, 0, 0));
|
||||
}
|
||||
|
||||
static void WithImageFile(const char *path,
|
||||
void fn(long yn, long xn,
|
||||
unsigned char src[yn][xn][4])) {
|
||||
struct stat st;
|
||||
void *map, *data;
|
||||
int fd, yn, xn, cn;
|
||||
CHECK_NE(-1, (fd = open(path, O_RDONLY)), "%s", path);
|
||||
CHECK_NE(-1, fstat(fd, &st));
|
||||
CHECK_GT(st.st_size, 0);
|
||||
CHECK_LE(st.st_size, INT_MAX);
|
||||
CHECK_NE(MAP_FAILED,
|
||||
(map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0)));
|
||||
CHECK_NOTNULL(
|
||||
(data = stbi_load_from_memory(map, st.st_size, &xn, &yn, NULL, 4)), "%s",
|
||||
path);
|
||||
CHECK_NE(-1, munmap(map, st.st_size));
|
||||
CHECK_NE(-1, close(fd));
|
||||
fn(yn, xn, data);
|
||||
free(data);
|
||||
}
|
||||
|
||||
static void PrintData(void) {
|
||||
int i;
|
||||
for (i = 0; i < blends.i; ++i) {
|
||||
printf("%3d %3d %3d %3d %3d %d\n", blends.p[i].color[0],
|
||||
blends.p[i].color[1], blends.p[i].color[2], blends.p[i].bg,
|
||||
blends.p[i].fg, blends.p[i].rune);
|
||||
}
|
||||
}
|
||||
|
||||
void *OpenRgbMap(const char *path) {
|
||||
int fd;
|
||||
void *map;
|
||||
size_t size;
|
||||
size = 256 * 256 * 256 * 3;
|
||||
CHECK_NE(-1, (fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0644)));
|
||||
CHECK_NE(-1, ftruncate(fd, size));
|
||||
CHECK_NE(MAP_FAILED,
|
||||
(map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)));
|
||||
CHECK_NE(-1, close(fd));
|
||||
return map;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
MakeBlends(kCga);
|
||||
for (i = 1; i < argc; ++i) {
|
||||
WithImageFile(argv[i], ProcessImage);
|
||||
}
|
||||
return 0;
|
||||
}
|
118
examples/examples.mk
Normal file
118
examples/examples.mk
Normal file
|
@ -0,0 +1,118 @@
|
|||
#-*-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 += EXAMPLES
|
||||
|
||||
EXAMPLES_FILES := $(wildcard examples/*)
|
||||
EXAMPLES_MAINS_S = $(filter %.S,$(EXAMPLES_FILES))
|
||||
EXAMPLES_MAINS_C = $(filter %.c,$(EXAMPLES_FILES))
|
||||
EXAMPLES_MAINS_CC = $(filter %.cc,$(EXAMPLES_FILES))
|
||||
|
||||
EXAMPLES_SRCS = \
|
||||
$(EXAMPLES_MAINS_S) \
|
||||
$(EXAMPLES_MAINS_C) \
|
||||
$(EXAMPLES_MAINS_CC)
|
||||
|
||||
EXAMPLES_MAINS = \
|
||||
$(EXAMPLES_MAINS_S) \
|
||||
$(EXAMPLES_MAINS_C) \
|
||||
$(EXAMPLES_MAINS_CC)
|
||||
|
||||
EXAMPLES_OBJS = \
|
||||
$(EXAMPLES_SRCS:%=o/$(MODE)/%.zip.o) \
|
||||
$(EXAMPLES_MAINS_S:%.S=o/$(MODE)/%.o) \
|
||||
$(EXAMPLES_MAINS_C:%.c=o/$(MODE)/%.o) \
|
||||
$(EXAMPLES_MAINS_CC:%.cc=o/$(MODE)/%.o)
|
||||
|
||||
EXAMPLES_COMS = \
|
||||
$(EXAMPLES_OBJS:%.o=%.com)
|
||||
|
||||
EXAMPLES_ELFS = \
|
||||
$(EXAMPLES_OBJS:%.o=%.elf)
|
||||
|
||||
EXAMPLES_BINS = \
|
||||
$(EXAMPLES_ELFS) \
|
||||
$(EXAMPLES_COMS) \
|
||||
$(EXAMPLES_COMS:%=%.dbg)
|
||||
|
||||
EXAMPLES_DIRECTDEPS = \
|
||||
APE_LIB \
|
||||
DSP_CORE \
|
||||
DSP_SCALE \
|
||||
DSP_TTY \
|
||||
LIBC_ALG \
|
||||
LIBC_BITS \
|
||||
LIBC_CALLS \
|
||||
LIBC_CALLS_HEFTY \
|
||||
LIBC_CONV \
|
||||
LIBC_FMT \
|
||||
LIBC_LOG \
|
||||
LIBC_MATH \
|
||||
LIBC_MEM \
|
||||
LIBC_NEXGEN32E \
|
||||
LIBC_NT_KERNELBASE \
|
||||
LIBC_NT_NTDLL \
|
||||
LIBC_NT_USER32 \
|
||||
LIBC_RAND \
|
||||
LIBC_RUNTIME \
|
||||
LIBC_SOCK \
|
||||
LIBC_STDIO \
|
||||
LIBC_STR \
|
||||
LIBC_STUBS \
|
||||
LIBC_SYSV \
|
||||
LIBC_SYSV_CALLS \
|
||||
LIBC_TESTLIB \
|
||||
LIBC_TIME \
|
||||
LIBC_TINYMATH \
|
||||
LIBC_UNICODE \
|
||||
LIBC_X \
|
||||
THIRD_PARTY_COMPILER_RT \
|
||||
THIRD_PARTY_DLMALLOC \
|
||||
THIRD_PARTY_DTOA \
|
||||
THIRD_PARTY_DUKTAPE \
|
||||
THIRD_PARTY_GETOPT \
|
||||
THIRD_PARTY_MUSL \
|
||||
THIRD_PARTY_STB \
|
||||
THIRD_PARTY_XED \
|
||||
THIRD_PARTY_ZLIB \
|
||||
TOOL_VIZ_LIB
|
||||
|
||||
EXAMPLES_DEPS := \
|
||||
$(call uniq,$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x))))
|
||||
|
||||
o/$(MODE)/examples/examples.pkg: \
|
||||
$(EXAMPLES_OBJS) \
|
||||
$(foreach x,$(EXAMPLES_DIRECTDEPS),$($(x)_A).pkg)
|
||||
|
||||
o/$(MODE)/examples/unbourne.o: \
|
||||
OVERRIDE_CPPFLAGS += \
|
||||
-DSTACK_FRAME_UNLIMITED
|
||||
|
||||
o/$(MODE)/examples/%.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/%.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
o/$(MODE)/examples/%.elf: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/%.o \
|
||||
$(CRT) \
|
||||
$(ELF)
|
||||
@$(ELFLINK)
|
||||
|
||||
$(EXAMPLES_OBJS): examples/examples.mk
|
||||
|
||||
o/$(MODE)/examples/hellojs.com.dbg: \
|
||||
$(EXAMPLES_DEPS) \
|
||||
o/$(MODE)/examples/hellojs.o \
|
||||
o/$(MODE)/examples/hello.js.zip.o \
|
||||
o/$(MODE)/examples/examples.pkg \
|
||||
$(CRT) \
|
||||
$(APE)
|
||||
@$(APELINK)
|
||||
|
||||
.PHONY: o/$(MODE)/examples
|
||||
o/$(MODE)/examples: $(EXAMPLES_BINS)
|
64
examples/findprime.c
Normal file
64
examples/findprime.c
Normal file
|
@ -0,0 +1,64 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/itimerval.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/itimer.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
static const struct itimerval kTimer = {{0, 10000}, {0, 10000}}; /* 10ms */
|
||||
static volatile bool32 showprogress_;
|
||||
static const char *magic_;
|
||||
|
||||
void OnInterrupt(int sig) {
|
||||
showprogress_ = true;
|
||||
}
|
||||
void ShowProgress(uintmax_t i, uintmax_t j, uintmax_t n) {
|
||||
fprintf(stderr, "%s%,40jd%,40jd%,40jd\r\n", magic_, i, j, n);
|
||||
showprogress_ = false;
|
||||
}
|
||||
|
||||
static bool IsPrime(uintmax_t i) {
|
||||
uintmax_t j, n;
|
||||
for (j = 3, n = (unsigned long)floorl(sqrtl(i)); j <= n; j += 2) {
|
||||
if (showprogress_) ShowProgress(i, j, n);
|
||||
if (i % j == 0) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void TryNumber(uintmax_t x, uintmax_t i) {
|
||||
if (IsPrime(i)) {
|
||||
printf("%s%,jd%s%,jd\n", "the prime nearest ", x, " is ", i);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
uintmax_t x, i, j;
|
||||
CHECK_EQ(2, argc);
|
||||
signal(SIGALRM, OnInterrupt);
|
||||
setitimer(ITIMER_REAL, &kTimer, NULL);
|
||||
magic_ = cancolor() ? "\e[F\e[K" : "";
|
||||
if ((x = strtoumax(argv[1], NULL, 0)) % 2 == 0) ++x;
|
||||
TryNumber(x, x);
|
||||
for (i = x, j = x;;) {
|
||||
if (i < UINTMAX_MAX) TryNumber(x, i), i += 2;
|
||||
if (j > 1) TryNumber(x, j), j -= 2;
|
||||
}
|
||||
}
|
121
examples/fld.c
Normal file
121
examples/fld.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/inttypes.h"
|
||||
#include "libc/literal.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
|
||||
static const char kHeaderBin[] = "\
|
||||
/\t┌sign\n\
|
||||
/\t│ ┌exponent\n\
|
||||
/\t│ │ ┌intpart\n\
|
||||
/\t│ │ │ ┌fraction\n\
|
||||
/\t│ │ │ │\n\
|
||||
/\t│┌┴────────────┐│┌┴────────────────────────────────────────────────────────────┐\n";
|
||||
|
||||
static const char kHeaderHex[] = "\
|
||||
/\t ┌sign/exponent\n\
|
||||
/\t │ ┌intpart/fraction\n\
|
||||
/\t │ │\n\
|
||||
/\t┌┴─┐┌┴─────────────┐\n";
|
||||
|
||||
void dobin(const char *op, long double x, FILE *f) {
|
||||
uint16_t hi;
|
||||
uint64_t lo;
|
||||
uint8_t buf[16];
|
||||
memcpy(buf, &x, sizeof(x));
|
||||
memcpy(&lo, &buf[0], sizeof(lo));
|
||||
memcpy(&hi, &buf[8], sizeof(hi));
|
||||
fprintf(f, "/\t%016" PRIb16 "%064" PRIb64 " %-8s %19.19Lf\n", hi, lo, op, x);
|
||||
}
|
||||
|
||||
void dohex(const char *op, long double x, FILE *f) {
|
||||
uint16_t hi;
|
||||
uint64_t lo;
|
||||
uint8_t buf[16];
|
||||
memcpy(buf, &x, sizeof(x));
|
||||
memcpy(&lo, &buf[0], sizeof(lo));
|
||||
memcpy(&hi, &buf[8], sizeof(hi));
|
||||
fprintf(f, "/\t%04" PRIx16 "%016" PRIx64 " %-8s %19.19Lf\n", hi, lo, op, x);
|
||||
}
|
||||
|
||||
#define DOBIN(OP) \
|
||||
dobin(" " #OP, OP(), stdout); \
|
||||
dobin("-" #OP, -OP(), stdout)
|
||||
|
||||
#define DOHEX(OP) \
|
||||
dohex(" " #OP, OP(), stdout); \
|
||||
dohex("-" #OP, -OP(), stdout)
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
fputs(kHeaderBin, stdout);
|
||||
DOBIN(fldz);
|
||||
DOBIN(fld1);
|
||||
DOBIN(fldpi);
|
||||
DOBIN(fldl2t);
|
||||
DOBIN(fldlg2);
|
||||
DOBIN(fldln2);
|
||||
DOBIN(fldl2e);
|
||||
DOBIN(finit);
|
||||
fputc('\n', stdout);
|
||||
fputs(kHeaderHex, stdout);
|
||||
DOHEX(fldz);
|
||||
DOHEX(fld1);
|
||||
DOHEX(fldpi);
|
||||
DOHEX(fldl2t);
|
||||
DOHEX(fldlg2);
|
||||
DOHEX(fldln2);
|
||||
DOHEX(fldl2e);
|
||||
DOHEX(finit);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
//
|
||||
// ┌sign
|
||||
// │ ┌exponent
|
||||
// │ │ ┌intpart
|
||||
// │ │ │ ┌fraction
|
||||
// │ │ │ │
|
||||
// │┌┴────────────┐│┌┴────────────────────────────────────────────────────────────┐
|
||||
// 00000000000000000000000000000000000000000000000000000000000000000000000000000000 fldz 0.0000000000000000000
|
||||
// 10000000000000000000000000000000000000000000000000000000000000000000000000000000 -fldz -0.0000000000000000000
|
||||
// 00111111111111111000000000000000000000000000000000000000000000000000000000000000 fld1 1.0000000000000000000
|
||||
// 10111111111111111000000000000000000000000000000000000000000000000000000000000000 -fld1 -1.0000000000000000000
|
||||
// 01000000000000001100100100001111110110101010001000100001011010001100001000110101 fldpi 3.1415926540000000000
|
||||
// 11000000000000001100100100001111110110101010001000100001011010001100001000110101 -fldpi -3.1415926540000000000
|
||||
// 01000000000000001101010010011010011110000100101111001101000110111000101011111110 fldl2t 3.3219280950000000000
|
||||
// 11000000000000001101010010011010011110000100101111001101000110111000101011111110 -fldl2t -3.3219280950000000000
|
||||
// 00111111111111011001101000100000100110101000010011111011110011111111011110011001 fldlg2 0.3010299960000000000
|
||||
// 10111111111111011001101000100000100110101000010011111011110011111111011110011001 -fldlg2 -0.3010299960000000000
|
||||
// 00111111111111101011000101110010000101111111011111010001110011110111100110101100 fldln2 0.6931471810000000000
|
||||
// 10111111111111101011000101110010000101111111011111010001110011110111100110101100 -fldln2 -0.6931471810000000000
|
||||
// 00111111111111111011100010101010001110110010100101011100000101111111000010111100 fldl2e 1.4426950410000000000
|
||||
// 10111111111111111011100010101010001110110010100101011100000101111111000010111100 -fldl2e -1.4426950410000000000
|
||||
//
|
||||
// ┌sign/exponent
|
||||
// │ ┌intpart/fraction
|
||||
// │ │
|
||||
// ┌┴─┐┌┴─────────────┐
|
||||
// 00000000000000000000 fldz 0.0000000000000000000
|
||||
// 80000000000000000000 -fldz -0.0000000000000000000
|
||||
// 3fff8000000000000000 fld1 1.0000000000000000000
|
||||
// bfff8000000000000000 -fld1 -1.0000000000000000000
|
||||
// 4000c90fdaa22168c235 fldpi 3.1415926540000000000
|
||||
// c000c90fdaa22168c235 -fldpi -3.1415926540000000000
|
||||
// 4000d49a784bcd1b8afe fldl2t 3.3219280950000000000
|
||||
// c000d49a784bcd1b8afe -fldl2t -3.3219280950000000000
|
||||
// 3ffd9a209a84fbcff799 fldlg2 0.3010299960000000000
|
||||
// bffd9a209a84fbcff799 -fldlg2 -0.3010299960000000000
|
||||
// 3ffeb17217f7d1cf79ac fldln2 0.6931471810000000000
|
||||
// bffeb17217f7d1cf79ac -fldln2 -0.6931471810000000000
|
||||
// 3fffb8aa3b295c17f0bc fldl2e 1.4426950410000000000
|
||||
// bfffb8aa3b295c17f0bc -fldl2e -1.4426950410000000000
|
44
examples/forkrand.c
Normal file
44
examples/forkrand.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/nt/nt/process.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
noinline void dostuff(void) {
|
||||
srand(rand64()); /* seeds rand() w/ intel rdrnd, auxv, etc. */
|
||||
for (unsigned i = 0; i < 5; ++i) {
|
||||
int us = rand() % 500000;
|
||||
usleep(us);
|
||||
printf("%s%u%s%u [%s=%d]\n", "hello no. ", i, " from ", getpid(), "us", us);
|
||||
fflush(stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
fprintf(stderr, "%p\n", RtlCloneUserProcess);
|
||||
int child;
|
||||
if ((child = fork()) == -1) perror("fork"), exit(1);
|
||||
if (!child) {
|
||||
/* child process */
|
||||
dostuff();
|
||||
return 0;
|
||||
} else {
|
||||
/* parent process */
|
||||
dostuff();
|
||||
/* note: abandoned children become zombies */
|
||||
int rc, wstatus;
|
||||
if ((rc = wait(&wstatus)) == -1) perror("wait"), exit(1);
|
||||
return WEXITSTATUS(wstatus);
|
||||
}
|
||||
}
|
51
examples/forky.c
Normal file
51
examples/forky.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/calls/internal.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/enum/filemapflags.h"
|
||||
#include "libc/nt/enum/pageflags.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int pid;
|
||||
long *addr;
|
||||
int64_t fh;
|
||||
if (argc == 1) {
|
||||
fh = CreateFileMappingNuma(-1, &kNtIsInheritable, kNtPageReadwrite, 0,
|
||||
FRAMESIZE, NULL, kNtNumaNoPreferredNode);
|
||||
addr = MapViewOfFileExNuma(fh, kNtFileMapRead | kNtFileMapWrite, 0, 0,
|
||||
FRAMESIZE, NULL, kNtNumaNoPreferredNode);
|
||||
*addr = 0x31337;
|
||||
CHECK_NE(-1, (pid = spawnve(
|
||||
0, (int[3]){STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO},
|
||||
"o/examples/forky.com",
|
||||
(char *const[]){"o/examples/forky.com",
|
||||
gc(xasprintf("%#lx", (intptr_t)addr)),
|
||||
gc(xasprintf("%#lx", fh)), NULL},
|
||||
environ)));
|
||||
CHECK_NE(-1, waitpid(pid, NULL, 0));
|
||||
} else {
|
||||
addr = (long *)(intptr_t)strtoul(argv[1], NULL, 0);
|
||||
fh = strtoul(argv[2], NULL, 0);
|
||||
addr = MapViewOfFileExNuma(fh, kNtFileMapRead | kNtFileMapWrite, 0, 0,
|
||||
FRAMESIZE, addr, kNtNumaNoPreferredNode);
|
||||
printf("%#lx\n", *addr);
|
||||
}
|
||||
return 0;
|
||||
}
|
52
examples/generalized-automatic-datastructure-printing.c
Normal file
52
examples/generalized-automatic-datastructure-printing.c
Normal file
|
@ -0,0 +1,52 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/log/gdb.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
/**
|
||||
* @fileovierview gdbexec(s) demo
|
||||
* It basically launches an ephemeral `gdb -p $PID -ex "$s"`.
|
||||
*/
|
||||
|
||||
int i;
|
||||
int M[8][8] = {
|
||||
{772549, 921569, 407843, 352941, 717647, 78431, 666667, 627451},
|
||||
{321569, 419608, 227451, 396078, 223529, 882353, 952941, 937255},
|
||||
{15686, 545098, 31373, 7843, 15686, 298039, 976471, 352941},
|
||||
{70588, 858824, 415686, 184314, 25098, 5098, 141176, 47059},
|
||||
{141176, 541176, 658824, 227451, 490196, 301961, 937255, 678431},
|
||||
{188235, 823529, 858824, 87451, 545098, 611765, 188235, 576471},
|
||||
{580392, 913725, 996078, 592157, 7451, 176471, 862745, 784314},
|
||||
{278431, 945098, 843137, 439216, 878431, 529412, 262745, 43137},
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int y, x;
|
||||
for (i = 0;; ++i) {
|
||||
for (y = 0; y < 8; ++y) {
|
||||
for (x = 0; x < 8; ++x) {
|
||||
if (!(M[y][x] % 2)) {
|
||||
M[y][x] /= 2;
|
||||
} else {
|
||||
M[y][x] *= 3;
|
||||
M[y][x] += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rand() % 10000 == 0) {
|
||||
gdbexec("print i");
|
||||
gdbexec("print M");
|
||||
break;
|
||||
}
|
||||
}
|
||||
printf("quitting\n");
|
||||
return 0;
|
||||
}
|
15
examples/gui.c
Normal file
15
examples/gui.c
Normal file
|
@ -0,0 +1,15 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/nt/enum/messageboxtype.h"
|
||||
#include "libc/nt/messagebox.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
return MessageBox(0, u"hello world", u"cosmopolitan", kNtMbOk) ? 0 : 1;
|
||||
}
|
23
examples/hello.c
Normal file
23
examples/hello.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/errno.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main() {
|
||||
/*
|
||||
* Cosmopolitan's "Hello World" demonstrates a best practice.
|
||||
*
|
||||
* Since we conditionally link heavyweight features based on which
|
||||
* characters are present in the format string, it's a good idea to
|
||||
* have that string consist solely of directives.
|
||||
*/
|
||||
printf("%s\n", "hello world");
|
||||
return errno;
|
||||
}
|
2
examples/hello.js
Normal file
2
examples/hello.js
Normal file
|
@ -0,0 +1,2 @@
|
|||
NativePrint('Hello world!\n');
|
||||
NativePrint('2+3=' + NativeAdd(2, 3) + '\n');
|
28
examples/hello2.c
Normal file
28
examples/hello2.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
|
||||
#define kMessage "hello world\r\n"
|
||||
|
||||
int main() {
|
||||
/*
|
||||
* Cosmopolitan "Hello World" using system calls.
|
||||
*
|
||||
* Another Cosmopolitan best practice is to use the standard symbolic
|
||||
* names for file descriptors 0, 1, and 2. This is a good idea because
|
||||
* on Windows the numbers are actually different. Because Cosmopolitan
|
||||
* is a zero-emulation library, we address that problem by turning
|
||||
* traditional #define's into variables, which the runtime determines
|
||||
* automatically.
|
||||
*/
|
||||
return write(STDOUT_FILENO, kMessage, strlen(kMessage)) != -1 ? 0 : 1;
|
||||
}
|
19
examples/hello3.c
Normal file
19
examples/hello3.c
Normal file
|
@ -0,0 +1,19 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
int main() {
|
||||
dprintf(STDOUT_FILENO, "%s\n", gc(xasprintf("%'s", "(╯°□°)╯︵' ┻━┻")));
|
||||
return errno;
|
||||
}
|
16
examples/hello4.c
Normal file
16
examples/hello4.c
Normal file
|
@ -0,0 +1,16 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/errno.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main() {
|
||||
printf("%s \n", "hello world");
|
||||
return errno;
|
||||
}
|
56
examples/hellojs.c
Normal file
56
examples/hellojs.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "third_party/duktape/duktape.h"
|
||||
|
||||
static duk_ret_t NativePrint(duk_context *ctx) {
|
||||
duk_push_string(ctx, " ");
|
||||
duk_insert(ctx, 0);
|
||||
duk_join(ctx, duk_get_top(ctx) - 1);
|
||||
fputs(duk_safe_to_string(ctx, -1), stdout);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static duk_ret_t NativeAdd(duk_context *ctx) {
|
||||
int i, n;
|
||||
double r;
|
||||
n = duk_get_top(ctx);
|
||||
for (r = i = 0; i < n; i++) r += duk_to_number(ctx, i);
|
||||
duk_push_number(ctx, r);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd;
|
||||
struct stat st;
|
||||
const char *code;
|
||||
duk_context *ctx;
|
||||
ctx = duk_create_heap_default();
|
||||
duk_push_c_function(ctx, NativePrint, DUK_VARARGS);
|
||||
duk_put_global_string(ctx, "NativePrint");
|
||||
duk_push_c_function(ctx, NativeAdd, DUK_VARARGS);
|
||||
duk_put_global_string(ctx, "NativeAdd");
|
||||
|
||||
CHECK_NE(-1, (fd = open("zip:examples/hello.js", O_RDONLY)));
|
||||
CHECK_NE(-1, fstat(fd, &st));
|
||||
CHECK_NOTNULL((code = gc(malloc(st.st_size))));
|
||||
CHECK_EQ(st.st_size, read(fd, code, st.st_size));
|
||||
CHECK_NE(-1, close(fd));
|
||||
|
||||
duk_eval_string(ctx, code);
|
||||
duk_pop(ctx);
|
||||
duk_destroy_heap(ctx);
|
||||
return 0;
|
||||
}
|
26
examples/hidecursor.c
Normal file
26
examples/hidecursor.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/nt/console.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/nt/struct/consolecursorinfo.h"
|
||||
#include "libc/nt/synchronization.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct NtConsoleCursorInfo ntcursor;
|
||||
SleepEx(1000, false);
|
||||
GetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
|
||||
ntcursor.bVisible = false;
|
||||
SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
|
||||
SleepEx(1000, false);
|
||||
ntcursor.bVisible = true;
|
||||
SetConsoleCursorInfo(GetStdHandle(kNtStdOutputHandle), &ntcursor);
|
||||
SleepEx(1000, false);
|
||||
return 0;
|
||||
}
|
77
examples/invtsc.c
Normal file
77
examples/invtsc.c
Normal file
|
@ -0,0 +1,77 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/x86feature.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
|
||||
/**
|
||||
* @fileoverview Measure CPU clock mystery constants.
|
||||
* @note CPUID EAX=15h/16h is a joke
|
||||
*/
|
||||
|
||||
const long double kInterval = 0.001L;
|
||||
|
||||
long double start_;
|
||||
char dtoabuf_[3][32];
|
||||
volatile bool isdone_;
|
||||
|
||||
void OnCtrlC(int sig) {
|
||||
isdone_ = true;
|
||||
}
|
||||
|
||||
long double now(void) {
|
||||
return dtime(CLOCK_MONOTONIC);
|
||||
}
|
||||
|
||||
long double GetSample(void) {
|
||||
uint64_t tick1, tick2;
|
||||
long double time1, time2;
|
||||
time1 = now();
|
||||
tick1 = rdtsc();
|
||||
nanosleep(&(struct timespec){0, 100000}, NULL);
|
||||
time2 = now();
|
||||
tick2 = rdtsc();
|
||||
return ((time2 - time1) * 1e9L) / (long double)(tick2 - tick1);
|
||||
}
|
||||
|
||||
void MeasureNanosecondsPerAlwaysRunningTimerCycle(void) {
|
||||
int i;
|
||||
long double avg, samp;
|
||||
start_ = now();
|
||||
for (i = 1, avg = 1.0L; !isdone_; ++i) {
|
||||
samp = GetSample();
|
||||
avg += (samp - avg) / i;
|
||||
dsleep(kInterval);
|
||||
printf("1c = %sns (last=%sns spent=%ss)\n", g_fmt(dtoabuf_[0], (double)avg),
|
||||
g_fmt(dtoabuf_[1], (double)samp),
|
||||
g_fmt(dtoabuf_[2], (double)(now() - start_)));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (!X86_HAVE(INVTSC)) {
|
||||
fprintf(stderr, "warning: html can reprogram your microcode\n");
|
||||
}
|
||||
if (X86_HAVE(HYPERVISOR)) {
|
||||
fprintf(stderr, "warning: virtual machine rdtsc isn't great\n");
|
||||
}
|
||||
CHECK_NE(-1, xsigaction(SIGINT, OnCtrlC, 0, 0, NULL));
|
||||
MeasureNanosecondsPerAlwaysRunningTimerCycle();
|
||||
return 0;
|
||||
}
|
1372
examples/kilo.c
Normal file
1372
examples/kilo.c
Normal file
File diff suppressed because it is too large
Load diff
11
examples/life.c
Normal file
11
examples/life.c
Normal file
|
@ -0,0 +1,11 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
|
||||
int main() { return 42; }
|
49
examples/mappy.c
Normal file
49
examples/mappy.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/map.h"
|
||||
#include "libc/sysv/consts/prot.h"
|
||||
|
||||
/*
|
||||
OpenBSD
|
||||
00025ff61000 000000000000 65536
|
||||
00026cf1d000 00000cfbc000 65536
|
||||
000254d83000 ffffe7e66000 65536
|
||||
0002c7bde000 000072e5b000 65536
|
||||
000253ff9000 ffff8c41b000 65536
|
||||
0002e96f3000 0000956fa000 65536
|
||||
000236346000 ffff4cc53000 65536
|
||||
0002ce744000 0000983fe000 65536
|
||||
0002fe0b8000 00002f974000 65536
|
||||
000225cd7000 ffff27c1f000 65536
|
||||
*/
|
||||
|
||||
struct Mapping {
|
||||
uint8_t *map;
|
||||
size_t mapsize;
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
size_t i;
|
||||
struct Mapping m[10];
|
||||
for (i = 0; i < ARRAYLEN(m); ++i) {
|
||||
m[i].mapsize = FRAMESIZE;
|
||||
m[i].map = mmap(NULL, m[i].mapsize, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
}
|
||||
for (i = 0; i < ARRAYLEN(m); ++i) {
|
||||
printf("%p %p %zu\n", m[i].map, i ? m[i].map - m[i - 1].map : 0,
|
||||
m[i].mapsize);
|
||||
}
|
||||
return 0;
|
||||
}
|
34
examples/now.c
Normal file
34
examples/now.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/bits/safemacros.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/clock.h"
|
||||
#include "libc/time/time.h"
|
||||
#include "third_party/dtoa/dtoa.h"
|
||||
|
||||
char dtoabuf_[3][32];
|
||||
|
||||
static long double avg;
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
long double t2, t1 = nowl();
|
||||
dsleep(0.3);
|
||||
for (;;) {
|
||||
t2 = nowl();
|
||||
printf("%s %s avg=%s\n", g_fmt(dtoabuf_[0], t2),
|
||||
g_fmt(dtoabuf_[1], t2 - t1), g_fmt(dtoabuf_[2], avg));
|
||||
t1 = t2;
|
||||
dsleep(0.3);
|
||||
}
|
||||
return 0;
|
||||
}
|
37
examples/ntdll.c
Normal file
37
examples/ntdll.c
Normal file
|
@ -0,0 +1,37 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/dce.h"
|
||||
#include "libc/nt/dll.h"
|
||||
#include "libc/nt/nt/process.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
|
||||
int main() {
|
||||
if (IsWindows()) {
|
||||
/*
|
||||
* Cosmopolitan imports this automatically if it's referenced the
|
||||
* normal way. But Microsoft wants us to use loose coupling when
|
||||
* referencing their internal APIs. Don't think for a moment they
|
||||
* won't break open source projects that fail to heed the warning.
|
||||
*/
|
||||
typeof(NtTerminateProcess) *NtTerminateProcess_ =
|
||||
GetProcAddress(GetModuleHandle("ntdll.dll"), "NtTerminateProcess");
|
||||
printf("%ld\n", GetModuleHandle("ntdll.dll"));
|
||||
printf("%p\n", NtTerminateProcess_);
|
||||
if (NtTerminateProcess_) {
|
||||
fflush(stdout);
|
||||
for (;;) NtTerminateProcess_(-1, 42);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "error: intended for windows\n");
|
||||
}
|
||||
return EXIT_FAILURE;
|
||||
}
|
38
examples/peek.c
Normal file
38
examples/peek.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/runtime/interruptiblecall.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
|
||||
struct InterruptibleCall icall;
|
||||
|
||||
static intptr_t peek(intptr_t *addr) { return *addr; }
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
intptr_t addr = strtoul(argv[i], NULL, 0);
|
||||
icall.sig = SIGSEGV;
|
||||
printf("%#p → %#lx\n", addr,
|
||||
interruptiblecall(&icall, (void *)peek, addr, 0, 0, 0));
|
||||
}
|
||||
return 0;
|
||||
}
|
28
examples/pipe.c
Normal file
28
examples/pipe.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ Copyright 2020 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int pipefds[2] = {-1, -1};
|
||||
int rc = pipe(pipefds);
|
||||
printf("%d → %ld %ld\n", rc, pipefds[0], pipefds[1]);
|
||||
return 0;
|
||||
}
|
26
examples/poll.c
Normal file
26
examples/poll.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/sock/sock.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/poll.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rc;
|
||||
int pollms = 1;
|
||||
struct pollfd fds[] = {{-1, 0}, {STDIN_FILENO, POLLIN}};
|
||||
if ((rc = poll(fds, ARRAYLEN(fds), pollms)) != -1) {
|
||||
printf("toto=%d\n", rc);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
73
examples/printargs.c
Normal file
73
examples/printargs.c
Normal file
|
@ -0,0 +1,73 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/bits/progn.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/macros.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
|
||||
const struct AuxiliaryValue {
|
||||
const char *fmt;
|
||||
long *id;
|
||||
const char *name;
|
||||
const char *description;
|
||||
} kAuxiliaryValues[] = {
|
||||
{"%p", &AT_EXECFD, "AT_EXECFD", "file descriptor of program"},
|
||||
{"%p", &AT_PHDR, "AT_PHDR", "address of elf program headers"},
|
||||
{"%p", &AT_PHENT, "AT_PHENT", "size of program header entry"},
|
||||
{"%p", &AT_PHNUM, "AT_PHNUM", "number of program headers"},
|
||||
{"%p", &AT_PAGESZ, "AT_PAGESZ", "system page size"},
|
||||
{"%p", &AT_BASE, "AT_BASE", "base address of the program interpreter"},
|
||||
{"%p", &AT_ENTRY, "AT_ENTRY", "entry address of executable"},
|
||||
{"%p", &AT_NOTELF, "AT_NOTELF", "set if not an elf"},
|
||||
{"%-12d", &AT_UID, "AT_UID", "real user id of thread"},
|
||||
{"%-12d", &AT_EUID, "AT_EUID", "effective user id of thread"},
|
||||
{"%-12d", &AT_GID, "AT_GID", "real group id of thread"},
|
||||
{"%-12d", &AT_EGID, "AT_EGID", "effective group id of thread"},
|
||||
{"%-12d", &AT_CLKTCK, "AT_CLKTCK", "frequency of times() counts"},
|
||||
{"%p", &AT_OSRELDATE, "AT_OSRELDATE",
|
||||
"freebsd release number, e.g. 1200086"},
|
||||
{"%p", &AT_PLATFORM, "AT_PLATFORM", "string identifying hardware platform"},
|
||||
{"%p", &AT_DCACHEBSIZE, "AT_DCACHEBSIZE", "data cache block size"},
|
||||
{"%p", &AT_ICACHEBSIZE, "AT_ICACHEBSIZE", "instruction cache block size"},
|
||||
{"%p", &AT_UCACHEBSIZE, "AT_UCACHEBSIZE", "unified cache block size"},
|
||||
{"%p", &AT_SECURE, "AT_SECURE", "for set{u,g}id binz & security blankets"},
|
||||
{"%-12s", &AT_BASE_PLATFORM, "AT_BASE_PLATFORM",
|
||||
"string identifying real platform"},
|
||||
{"%p", &AT_RANDOM, "AT_RANDOM", "address of sixteen random bytes"},
|
||||
{"%-12s", &AT_EXECFN, "AT_EXECFN", "pathname used to execute program"},
|
||||
{"%p", &AT_SYSINFO_EHDR, "AT_SYSINFO_EHDR",
|
||||
"linux virtual dso page address"},
|
||||
};
|
||||
|
||||
int main(int argc, char *argv[], char **envp) {
|
||||
printf("\nArguments:\n");
|
||||
for (unsigned i = 0; i < argc; ++i) {
|
||||
printf(" ☼ %s\n", argv[i]);
|
||||
}
|
||||
printf("\nEnvironment:\n");
|
||||
for (char **env = envp; *env; ++env) {
|
||||
printf(" ☼ %s\n", *env);
|
||||
}
|
||||
printf("\nAuxiliary Values:\n");
|
||||
for (unsigned i = 0; i < ARRAYLEN(kAuxiliaryValues); ++i) {
|
||||
long key = *kAuxiliaryValues[i].id;
|
||||
unsigned long val = getauxval(key);
|
||||
char fmt[64];
|
||||
printf(PROGN(stpcpy(stpcpy(stpcpy(fmt, "%16s[%p] = "),
|
||||
kAuxiliaryValues[i].fmt),
|
||||
" # %s\n"),
|
||||
fmt),
|
||||
kAuxiliaryValues[i].name, key, val, kAuxiliaryValues[i].description);
|
||||
}
|
||||
return 0;
|
||||
}
|
34
examples/printmysymbols.c
Normal file
34
examples/printmysymbols.c
Normal file
|
@ -0,0 +1,34 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/elf/elf.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/symbols.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rc = 0;
|
||||
char *filename;
|
||||
struct SymbolTable *tab = NULL;
|
||||
if ((filename = finddebugbinary()) != NULL &&
|
||||
(tab = opensymboltable(filename))) {
|
||||
for (unsigned i = 0; i < tab->count; ++i) {
|
||||
printf("%p %s\n", tab->addr_base + tab->symbols[i].addr_rva,
|
||||
getelfstring(tab->elf, tab->elfsize, tab->name_base,
|
||||
tab->symbols[i].name_rva));
|
||||
}
|
||||
} else {
|
||||
perror("printmysymbols");
|
||||
backtrace(stderr);
|
||||
rc = 1;
|
||||
}
|
||||
closesymboltable(&tab);
|
||||
return rc;
|
||||
}
|
39
examples/printprimes.c
Normal file
39
examples/printprimes.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/conv/itoa.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
char buf[32];
|
||||
bool isprime;
|
||||
long i, j, k, n, m;
|
||||
k = 0;
|
||||
n = pow(2, 32);
|
||||
printf("2\n");
|
||||
for (i = 3; i < n; ++i) {
|
||||
isprime = true;
|
||||
for (m = sqrt(i) + 1, j = 2; j < m; ++j) {
|
||||
if (i % j == 0) {
|
||||
isprime = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isprime) {
|
||||
int64toarray_radix10(i, buf);
|
||||
fputs(buf, stdout);
|
||||
fputc('\n', stdout);
|
||||
if (k++ % 100 == 0) {
|
||||
fprintf(stderr, "\r%20d", i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
49
examples/raw-linux-hello.S
Normal file
49
examples/raw-linux-hello.S
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*-*- mode:asm; 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 │
|
||||
│ │
|
||||
│ This program is free software; you can redistribute it and/or modify │
|
||||
│ it under the terms of the GNU General Public License as published by │
|
||||
│ the Free Software Foundation; version 2 of the License. │
|
||||
│ │
|
||||
│ This program is distributed in the hope that it will be useful, but │
|
||||
│ WITHOUT ANY WARRANTY; without even the implied warranty of │
|
||||
│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │
|
||||
│ General Public License for more details. │
|
||||
│ │
|
||||
│ You should have received a copy of the GNU General Public License │
|
||||
│ along with this program; if not, write to the Free Software │
|
||||
│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │
|
||||
│ 02110-1301 USA │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/macros.h"
|
||||
|
||||
/ Raw Linux Assembly Binary Tutorial
|
||||
/
|
||||
/ i.e. how to not use cosmopolitan runtimes at all
|
||||
/ cosmopolitan basically abstracts this
|
||||
/ except for all major platforms
|
||||
/
|
||||
/ make o//examples/raw-linux-hello.elf
|
||||
/ o//examples/raw-linux-hello.elf # about 6kb
|
||||
/
|
||||
/ Next consider doing it in C with fancy build tuning
|
||||
/
|
||||
/ make -j8 -O \
|
||||
/ MODE=tiny \
|
||||
/ LDFLAGS=-s \
|
||||
/ CPPFLAGS=-DSUPPORT_VECTOR=0b00000001 \
|
||||
/ o/tiny/examples/hello2.elf
|
||||
/ o/tiny/examples/hello2.elf # about 8kb
|
||||
/
|
||||
/ @noreturn
|
||||
_start: mov $12,%rdx # arg no. 3 is length
|
||||
getstr "hello world\n",%rsi,%esi # arg no. 2 is memory
|
||||
mov $1,%edi # arg no. 1 is stdout
|
||||
mov $1,%eax # write()
|
||||
syscall # see libc/sysv/syscalls.sh
|
||||
mov $0,%edi # arg no. 1 is success status
|
||||
mov $0xE7,%eax # exit_group()
|
||||
syscall
|
||||
.endfn _start,globl
|
26
examples/rawmode.c
Normal file
26
examples/rawmode.c
Normal file
|
@ -0,0 +1,26 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
setenv("GDB", "nopenopenope", true);
|
||||
showcrashreports();
|
||||
ttyraw(kTtyLfToCrLf | kTtySigs);
|
||||
printf("hi\n"), sleep(1);
|
||||
if (argc > 1 && strstr(argv[1], "crash")) abort();
|
||||
printf("there\n"), sleep(1);
|
||||
return 0;
|
||||
}
|
60
examples/rusage.c
Normal file
60
examples/rusage.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/calls/struct/rusage.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/time/time.h"
|
||||
|
||||
void Show(const char *name, long measurement, const char *unit) {
|
||||
fprintf(stderr, "%-*s%,*d %s\n", 32, name, 32, measurement, unit);
|
||||
}
|
||||
|
||||
long TvToUs(struct timeval tv) {
|
||||
return 1000000l * tv.tv_usec + tv.tv_sec;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
const char *exe;
|
||||
int pid, wstatus;
|
||||
long double ts1, ts2;
|
||||
struct rusage rusage;
|
||||
memset(&rusage, -1, sizeof(rusage));
|
||||
CHECK_GT(argc, 1);
|
||||
CHECK_NOTNULL((exe = commandv(argv[1])));
|
||||
ts1 = nowl();
|
||||
CHECK_NE(-1, (pid = spawnve(0, NULL, exe, &argv[1], environ)));
|
||||
CHECK_NE(-1, wait4(pid, &wstatus, 0, &rusage));
|
||||
ts2 = nowl();
|
||||
Show("wall time", lroundl((ts2 - ts1) * 1e9l), "ns");
|
||||
Show("user time", TvToUs(rusage.ru_utime), "µs");
|
||||
Show("sys time", TvToUs(rusage.ru_stime), "µs");
|
||||
Show("maximum resident set size", rusage.ru_maxrss, "");
|
||||
Show("integral shared memory size", rusage.ru_ixrss, "");
|
||||
Show("integral unshared data size", rusage.ru_idrss, "");
|
||||
Show("integral unshared stack size", rusage.ru_isrss, "");
|
||||
Show("minor page faults", rusage.ru_minflt, "");
|
||||
Show("major page faults", rusage.ru_majflt, "");
|
||||
Show("swaps", rusage.ru_nswap, "");
|
||||
Show("block input ops", rusage.ru_inblock, "");
|
||||
Show("block output ops", rusage.ru_oublock, "");
|
||||
Show("ipc messages sent", rusage.ru_msgsnd, "");
|
||||
Show("ipc messages received", rusage.ru_msgrcv, "");
|
||||
Show("signals received", rusage.ru_nsignals, "");
|
||||
Show("voluntary context switches", rusage.ru_nvcsw, "");
|
||||
Show("involuntary context switches", rusage.ru_nivcsw, "");
|
||||
return WEXITSTATUS(wstatus);
|
||||
}
|
61
examples/stat.c
Normal file
61
examples/stat.c
Normal file
|
@ -0,0 +1,61 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/struct/stat.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* @fileoverview File metadata viewer.
|
||||
*
|
||||
* This demonstrates the more powerful aspects of the printf() DSL.
|
||||
*/
|
||||
|
||||
void PrintFileMetadata(const char *pathname, struct stat *st) {
|
||||
printf("\n%s:", pathname);
|
||||
if (stat(pathname, st) != -1) {
|
||||
printf(
|
||||
"\n"
|
||||
"%-32s%,ld\n"
|
||||
"%-32s%,ld\n"
|
||||
"%-32s%#lx\n"
|
||||
"%-32s%#lx\n"
|
||||
"%-32s%ld\n"
|
||||
"%-32s%#o\n"
|
||||
"%-32s%d\n"
|
||||
"%-32s%d\n"
|
||||
"%-32s%d\n"
|
||||
"%-32s%ld\n"
|
||||
"%-32s%s\n"
|
||||
"%-32s%s\n"
|
||||
"%-32s%s\n",
|
||||
"bytes in file", st->st_size, "physical bytes", st->st_blocks * 512,
|
||||
"device id w/ file", st->st_dev, "inode", st->st_ino, "hard link count",
|
||||
st->st_nlink, "mode / permissions", st->st_mode, "owner id", st->st_uid,
|
||||
"group id", st->st_gid, "device id (if special)", st->st_rdev,
|
||||
"block size", st->st_blksize, "access time", gc(xiso8601(&st->st_atim)),
|
||||
"modified time", gc(xiso8601(&st->st_mtim)), "c[omplicated]time",
|
||||
gc(xiso8601(&st->st_ctim)));
|
||||
} else {
|
||||
printf(" %s\n", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
size_t i;
|
||||
struct stat st;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
PrintFileMetadata(argv[i], &st);
|
||||
}
|
||||
return 0;
|
||||
}
|
60
examples/subprocess.c
Normal file
60
examples/subprocess.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/alg/alg.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/hefty/spawn.h"
|
||||
#include "libc/conv/conv.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
const char kProgram[] = "o/default/examples/hello.com";
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
/**
|
||||
* Runs make if hello.com doesn't exist.
|
||||
*
|
||||
* 1. gc() automates calling free() on return.
|
||||
* 2. xasprintf("foo %s", "bar") is our version of "foo %s" % ("bar")
|
||||
* 3. Demonstrates correct escaping for bourne shell cf. xaescapeshq()
|
||||
*/
|
||||
if (!fileexists(kProgram)) {
|
||||
system(gc(xasprintf("%s '%s'", "make -j4",
|
||||
gc(replacestr(kProgram, "'", "'\"'\"'")))));
|
||||
}
|
||||
|
||||
/**
|
||||
* Our version of subprocess.Popen
|
||||
* 1. Doesn't require fork() so pain-free on NT
|
||||
* 2. Google checks are like assert() but better
|
||||
*/
|
||||
ssize_t transferred;
|
||||
int child, wstatus, procfds[3] = {STDIN_FILENO, -1, STDERR_FILENO};
|
||||
CHECK_NE(-1,
|
||||
(child = spawnve(0, procfds, /* run w/o shell */ kProgram,
|
||||
(char *const[]){/* argv[0] */ basename(kProgram),
|
||||
/* argv[1] */ "boop",
|
||||
/* sentinel */ NULL},
|
||||
environ)));
|
||||
printf("%s %s: ", kProgram, "says");
|
||||
fflush(stdout);
|
||||
for (;;) {
|
||||
transferred = copyfd(procfds[1], NULL, fileno(stdout), NULL, INT_MAX, 0);
|
||||
CHECK_NE(-1, transferred);
|
||||
if (!transferred) break;
|
||||
}
|
||||
CHECK_NE(-1, waitpid(child, &wstatus, 0));
|
||||
CHECK_EQ(0, WEXITSTATUS(wstatus));
|
||||
|
||||
return 0;
|
||||
}
|
108
examples/ttyinfo.c
Normal file
108
examples/ttyinfo.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "dsp/tty/tty.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/ioctl.h"
|
||||
#include "libc/calls/struct/sigaction.h"
|
||||
#include "libc/calls/termios.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/fmt.h"
|
||||
#include "libc/log/check.h"
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/gc.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/sysv/consts/fileno.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "libc/sysv/consts/sig.h"
|
||||
#include "libc/sysv/consts/termios.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/*
|
||||
"\e[c" → "\e[?1;2c"
|
||||
"\e[x" → "\e[2;1;1;112;112;1;0x"
|
||||
"\e[>c" → "\e[>83;40500;0c"
|
||||
"\e[6n" → "\e[52;1R"
|
||||
*/
|
||||
|
||||
#define CTRL(C) ((C) ^ 0b01000000)
|
||||
#define PROBE_VT100 "\e[c" /* e.g. "\e[?1;2c", "\e[>0c" */
|
||||
#define PROBE_SECONDARY "\e[>c" /* "\e[>83;40500;0c" (Screen v4.05.00) */
|
||||
#define PROBE_PARAMETERS "\e[x" /* e.g. "\e[2;1;1;112;112;1;0x" */
|
||||
#define PROBE_CURSOR_POSITION "\e[6n" /* e.g. "\e[𝑦;𝑥R" */
|
||||
#define PROBE_SUN_DTTERM_SIZE "\e[14t" /* e.g. "\e[𝑦;𝑥R" */
|
||||
|
||||
int fd_;
|
||||
jmp_buf jb_;
|
||||
ssize_t got_;
|
||||
uint8_t buf_[128];
|
||||
struct TtyIdent ti_;
|
||||
struct winsize wsize_;
|
||||
volatile bool resized_;
|
||||
|
||||
void OnResize(void) {
|
||||
resized_ = true;
|
||||
}
|
||||
void OnKilled(int sig) {
|
||||
longjmp(jb_, 128 + sig + 1);
|
||||
}
|
||||
|
||||
void getsome(void) {
|
||||
if ((got_ = read(fd_, buf_, sizeof(buf_))) == -1 && errno != EINTR) {
|
||||
printf("%s%s\r\n", "error: ", strerror(errno));
|
||||
longjmp(jb_, EXIT_FAILURE + 1);
|
||||
}
|
||||
if (got_ >= 0) {
|
||||
printf("%`'.*s\r\n", got_, buf_);
|
||||
if (got_ > 0 && buf_[0] == CTRL('C')) {
|
||||
longjmp(jb_, EXIT_SUCCESS + 1);
|
||||
}
|
||||
}
|
||||
if (resized_) {
|
||||
CHECK_NE(-1, getttysize(fd_, &wsize_));
|
||||
printf("SIGWINCH → %hu×%hu\r\n", wsize_.ws_row, wsize_.ws_col);
|
||||
resized_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
void probe(const char *s) {
|
||||
printf("%`'s → ", s);
|
||||
write(fd_, s, strlen(s));
|
||||
getsome();
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int rc;
|
||||
char ttyname[64];
|
||||
struct termios old;
|
||||
CHECK_NE(-1, (fd_ = open("/dev/tty", O_RDWR)));
|
||||
CHECK_NE(-1, ttyconfig(fd_, ttysetrawmode, 0, &old));
|
||||
if (!(rc = setjmp(jb_))) {
|
||||
xsigaction(SIGTERM, OnKilled, 0, 0, NULL);
|
||||
xsigaction(SIGWINCH, OnResize, 0, 0, NULL);
|
||||
if (ttyident(&ti_, STDIN_FILENO, STDOUT_FILENO) != -1) {
|
||||
ttysendtitle(fd_, "justine was here", &ti_);
|
||||
fputs(ttydescribe(ttyname, sizeof(ttyname), &ti_), stdout);
|
||||
}
|
||||
fputs("\r\n", stdout);
|
||||
probe(PROBE_VT100);
|
||||
probe(PROBE_SECONDARY);
|
||||
probe(PROBE_PARAMETERS);
|
||||
probe(PROBE_CURSOR_POSITION);
|
||||
/* probe(PROBE_SUN_DTTERM_SIZE); */
|
||||
getsome();
|
||||
for (;;) getsome();
|
||||
}
|
||||
ttyrestore(fd_, &old);
|
||||
ttyidentclear(&ti_);
|
||||
return rc - 1;
|
||||
}
|
67
examples/uname.c
Normal file
67
examples/uname.c
Normal file
|
@ -0,0 +1,67 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/log/log.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/calls/struct/utsname.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "third_party/getopt/getopt.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
unsigned need = 0;
|
||||
int opt;
|
||||
while ((opt = getopt(argc, argv, "hasnrvmd")) != -1) {
|
||||
switch (opt) {
|
||||
case 'a':
|
||||
need |= 0b111111;
|
||||
break;
|
||||
case 's':
|
||||
need |= 0b000001;
|
||||
break;
|
||||
case 'n':
|
||||
need |= 0b000010;
|
||||
break;
|
||||
case 'r':
|
||||
need |= 0b000100;
|
||||
break;
|
||||
case 'v':
|
||||
need |= 0b001000;
|
||||
break;
|
||||
case 'm':
|
||||
need |= 0b010000;
|
||||
break;
|
||||
case 'd':
|
||||
need |= 0b100000;
|
||||
break;
|
||||
default: /* -? or -h */
|
||||
fprintf(stderr, "%s: %s [%s]\n%s", "Usage", argv[0], "FLAGS",
|
||||
" -a\tprint all\n"
|
||||
" -s\tprint sysname\n"
|
||||
" -n\tprint nodename\n"
|
||||
" -r\tprint release\n"
|
||||
" -v\tprint version\n"
|
||||
" -m\tprint machine\n"
|
||||
" -d\tprint domainname\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (!need) need = 0b000001;
|
||||
struct utsname data;
|
||||
if (uname(&data) == -1) perror("uname"), exit(EXIT_FAILURE);
|
||||
if (need & 0b000001) printf("%s ", data.sysname);
|
||||
if (need & 0b000010) printf("%s ", data.nodename);
|
||||
if (need & 0b000100) printf("%s ", data.release);
|
||||
if (need & 0b001000) printf("%s ", data.version);
|
||||
if (need & 0b010000) printf("%s ", data.machine);
|
||||
if (need & 0b100000) printf("%s ", data.domainname);
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
10822
examples/unbourne.c
Normal file
10822
examples/unbourne.c
Normal file
File diff suppressed because it is too large
Load diff
53
examples/x86split.c
Normal file
53
examples/x86split.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
#if 0
|
||||
/*─────────────────────────────────────────────────────────────────╗
|
||||
│ To the extent possible under law, Justine Tunney has waived │
|
||||
│ all copyright and related or neighboring rights to this file, │
|
||||
│ as it is written in the following disclaimers: │
|
||||
│ • http://unlicense.org/ │
|
||||
│ • http://creativecommons.org/publicdomain/zero/1.0/ │
|
||||
╚─────────────────────────────────────────────────────────────────*/
|
||||
#endif
|
||||
#include "libc/errno.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/xed/x86.h"
|
||||
|
||||
/**
|
||||
* @fileoverview x86 instruction length decoder by way of hex pipe.
|
||||
*/
|
||||
|
||||
int main(int argc, char *argv[argc]) {
|
||||
unsigned c, i, j, l;
|
||||
enum XedError err;
|
||||
struct XedDecodedInst xedd;
|
||||
unsigned char buf[XED_MAX_INSTRUCTION_BYTES];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
for (i = 0;;) {
|
||||
if (i < XED_MAX_INSTRUCTION_BYTES) {
|
||||
c = fgethex(stdin);
|
||||
if (c != -1) {
|
||||
buf[i++] = c;
|
||||
continue;
|
||||
} else if (i == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((err = xed_instruction_length_decode(
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64),
|
||||
buf, i))) {
|
||||
errno = err;
|
||||
break;
|
||||
}
|
||||
l = xedd.decoded_length;
|
||||
if (l <= 0 || l > i) abort();
|
||||
for (j = 0; j < l; ++j) {
|
||||
if (fputhex(buf[j], stdout) == -1) {
|
||||
return errno;
|
||||
}
|
||||
}
|
||||
putchar('\n');
|
||||
memcpy(&buf[0], &buf[l], i -= l);
|
||||
}
|
||||
return errno;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue