diff --git a/libc/assert.h b/libc/assert.h index 26a915306..dc587df3c 100644 --- a/libc/assert.h +++ b/libc/assert.h @@ -3,8 +3,7 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -extern bool __assert_disable; -void __assert_fail(const char *, const char *, int) _Hide relegated; +void __assert_fail(const char *, const char *, int) relegated; #ifdef NDEBUG #define assert(x) ((void)0) @@ -16,6 +15,8 @@ void __assert_fail(const char *, const char *, int) _Hide relegated; #define static_assert _Static_assert #endif +#ifdef COSMO +extern bool __assert_disable; #ifndef NDEBUG #define _unassert(x) __assert_macro(x, #x) #define _npassert(x) __assert_macro(x, #x) @@ -42,7 +43,8 @@ void __assert_fail(const char *, const char *, int) _Hide relegated; } \ (void)0; \ }) -#endif +#endif /* NDEBUG */ +#endif /* COSMO */ COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/tool/decode/dumpvdso.c b/libc/calls/assertfail.c similarity index 82% rename from tool/decode/dumpvdso.c rename to libc/calls/assertfail.c index 49d88165d..5468e1ade 100644 --- a/tool/decode/dumpvdso.c +++ b/libc/calls/assertfail.c @@ -1,7 +1,7 @@ /*-*- 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 │ +│ Copyright 2023 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 │ @@ -16,18 +16,19 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ +#include "libc/assert.h" #include "libc/calls/calls.h" -#include "libc/elf/struct/ehdr.h" +#include "libc/fmt/itoa.h" #include "libc/runtime/runtime.h" -#include "libc/sysv/consts/auxv.h" -noasan int main(int argc, char *argv[]) { - int i = 0; - Elf64_Ehdr *ehdr; - ehdr = (Elf64_Ehdr *)getauxval(AT_SYSINFO_EHDR); - if (isatty(1)) exit(1); - for (;;) { - write(1, ((char *)ehdr) + i++, 1); +/** + * Handles assert() failure. + */ +void __assert_fail(const char *expr, const char *file, int line) { + char ibuf[12]; + if (!__assert_disable) { + FormatInt32(ibuf, line); + tinyprint(2, file, ":", ibuf, ": assert(", expr, ") failed\n", NULL); + abort(); } - return 0; } diff --git a/libc/calls/calls.h b/libc/calls/calls.h index 6947231f6..77c9884f7 100644 --- a/libc/calls/calls.h +++ b/libc/calls/calls.h @@ -62,7 +62,7 @@ COSMOPOLITAN_C_START_ typedef int sig_atomic_t; -bool32 isatty(int) nosideeffect; +bool32 isatty(int); char *get_current_dir_name(void) dontdiscard; char *getcwd(char *, size_t); char *realpath(const char *, char *); diff --git a/libc/log/perror.c b/libc/calls/perror.c similarity index 89% rename from libc/log/perror.c rename to libc/calls/perror.c index 348d3921e..b691c03a9 100644 --- a/libc/log/perror.c +++ b/libc/calls/perror.c @@ -24,11 +24,8 @@ /** * Writes error messages to standard error. */ -void perror(const char *message) { - int err; - const char *estr; - estr = _strerdoc(errno); - if (!message) message = ""; - if (!estr) estr = "Unknown error"; - tinyprint(2, message, *message ? ": " : "", estr, "\n", NULL); +void perror(const char *thing) { + const char *reason; + if (!(reason = _strerdoc(errno))) reason = "Unknown error"; + tinyprint(2, thing ? thing : "", thing ? ": " : "", reason, "\n", NULL); } diff --git a/libc/intrin/abort.c b/libc/intrin/abort.c index 76575c4b8..358082a33 100644 --- a/libc/intrin/abort.c +++ b/libc/intrin/abort.c @@ -17,7 +17,7 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -// stub version of abort() for low-dependency apps +// stub version of abort() to keep the build a dag __attribute__((__noreturn__, __weak__)) void abort(void) { __builtin_trap(); } diff --git a/tool/viz/rsastrength.c b/libc/intrin/assertfail.c similarity index 80% rename from tool/viz/rsastrength.c rename to libc/intrin/assertfail.c index 66845245f..f8740a96c 100644 --- a/tool/viz/rsastrength.c +++ b/libc/intrin/assertfail.c @@ -1,7 +1,7 @@ /*-*- 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 2021 Justine Alexandra Roberts Tunney │ +│ Copyright 2023 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 │ @@ -16,19 +16,9 @@ │ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ -#include "libc/fmt/conv.h" -#include "libc/math.h" -#include "libc/stdio/stdio.h" -int main(int argc, char *argv[]) { - int i, x, y; - for (i = 1; i < argc; ++i) { - x = atoi(argv[i]); - y = round( - (1.923 * cbrt(x * log(2)) * cbrt(log(x * log(2)) * log(x * log(2))) - - 4.69) / - log(2)); - printf("%4d %4d\n", x, y); - } - return 0; +// stub version of assert() to keep the build a dag +__attribute__((__weak__)) void __assert_fail(const char *expr, const char *file, + int line) { + __builtin_trap(); } diff --git a/libc/intrin/assertfail.greg.c b/libc/intrin/assertfail.greg.c deleted file mode 100644 index b84640c34..000000000 --- a/libc/intrin/assertfail.greg.c +++ /dev/null @@ -1,33 +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/atomic.h" -#include "libc/intrin/atomic.h" -#include "libc/intrin/kprintf.h" -#include "libc/runtime/runtime.h" - -privileged void __assert_fail(const char *expr, const char *file, int line) { - static atomic_bool once; - if (!__assert_disable) { - if (!atomic_exchange(&once, true)) { - kprintf("%s:%d: assert(%s) failed (tid %P) %m\n", file, line, expr); - } - __builtin_trap(); - } -} diff --git a/libc/isystem/alloca.h b/libc/isystem/alloca.h index 4da83c814..5c99641a7 100644 --- a/libc/isystem/alloca.h +++ b/libc/isystem/alloca.h @@ -1,4 +1,4 @@ -#ifndef COSMOPOLITAN_LIBC_ISYSTEM_ALLOCA_H_ -#define COSMOPOLITAN_LIBC_ISYSTEM_ALLOCA_H_ +#ifndef _ALLOCA_H +#define _ALLOCA_H #include "libc/mem/alloca.h" -#endif /* COSMOPOLITAN_LIBC_ISYSTEM_ALLOCA_H_ */ +#endif /* _ALLOCA_H */ diff --git a/libc/isystem/ar.h b/libc/isystem/ar.h index e9ba7b694..13d9e9b60 100644 --- a/libc/isystem/ar.h +++ b/libc/isystem/ar.h @@ -1,4 +1,4 @@ -#ifndef COSMOPOLITAN_LIBC_ISYSTEM_AR_H_ -#define COSMOPOLITAN_LIBC_ISYSTEM_AR_H_ +#ifndef _AR_H +#define _AR_H #include "libc/ar.h" -#endif /* COSMOPOLITAN_LIBC_ISYSTEM_AR_H_ */ +#endif /* _AR_H */ diff --git a/libc/isystem/cosmo.h b/libc/isystem/cosmo.h index 548253148..18db08f76 100644 --- a/libc/isystem/cosmo.h +++ b/libc/isystem/cosmo.h @@ -1,5 +1,5 @@ -#ifndef COSMOPOLITAN_LIBC_ISYSTEM_COSMO_H_ -#define COSMOPOLITAN_LIBC_ISYSTEM_COSMO_H_ +#ifndef _COSMO_H +#define _COSMO_H #ifdef COSMO #define COSMO_ALREADY_DEFINED @@ -65,4 +65,4 @@ #undef COSMO #endif -#endif /* COSMOPOLITAN_LIBC_ISYSTEM_COSMO_H_ */ +#endif /* _COSMO_H */ diff --git a/libc/mem/alloca.h b/libc/mem/alloca.h index 38713db1f..63cf3a61d 100644 --- a/libc/mem/alloca.h +++ b/libc/mem/alloca.h @@ -1,8 +1,6 @@ #ifndef COSMOPOLITAN_LIBC_MEM_ALLOCA_H_ #define COSMOPOLITAN_LIBC_MEM_ALLOCA_H_ -#if !(__ASSEMBLER__ + __LINKER__ + 0) #define alloca(size) __builtin_alloca(size) -#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ #endif /* COSMOPOLITAN_LIBC_MEM_ALLOCA_H_ */ diff --git a/libc/runtime/cosmo2.c b/libc/runtime/cosmo2.c index fda50e02f..c5353ce99 100644 --- a/libc/runtime/cosmo2.c +++ b/libc/runtime/cosmo2.c @@ -153,7 +153,7 @@ textstartup void cosmo(long *sp, struct Syslib *m1) { __envp = envp; __auxv = auxv; environ = envp; - if (argc) program_invocation_name = argv[0]; + program_invocation_name = argv[0]; // initialize program _init(); diff --git a/libc/stdckdint.h b/libc/stdckdint.h index ad6221bea..de9f7c055 100644 --- a/libc/stdckdint.h +++ b/libc/stdckdint.h @@ -60,8 +60,8 @@ ? __ckd_##op##ll((__ckd_dword *)(res), (x), (y)) \ : __ckd_trap())) -__funline wontreturn int __ckd_trap(void) { - *(volatile int *)0 = 0; +__funline int __ckd_trap(void) { + return *(volatile int *)0 = 0; } /* diff --git a/libc/stdio/fmt.c b/libc/stdio/fmt.c index 7fa2cbb10..ebbf36ed8 100644 --- a/libc/stdio/fmt.c +++ b/libc/stdio/fmt.c @@ -240,9 +240,10 @@ static int __fmt_ntoa_format(int out(const char *, void *, size_t), void *arg, return 0; } -static int ntoa2(int out(const char *, void *, size_t), void *arg, - uint128_t value, bool neg, unsigned log2base, unsigned prec, - unsigned width, unsigned flags, const char *alphabet) { +static int __fmt_ntoa2(int out(const char *, void *, size_t), void *arg, + uint128_t value, bool neg, unsigned log2base, + unsigned prec, unsigned width, unsigned flags, + const char *alphabet) { uint128_t remainder; unsigned len, count, digit; char buf[BUFFER_SIZE]; @@ -314,7 +315,7 @@ static int __fmt_ntoa(int out(const char *, void *, size_t), void *arg, } } - return ntoa2(out, arg, value, neg, log2base, prec, width, flags, lang); + return __fmt_ntoa2(out, arg, value, neg, log2base, prec, width, flags, lang); } /** diff --git a/third_party/getopt/getopt.c b/third_party/getopt/getopt.c index e6570fa46..967bcd062 100644 --- a/third_party/getopt/getopt.c +++ b/third_party/getopt/getopt.c @@ -41,56 +41,27 @@ getopt (BSD-3)\\n\ Copyright 1987, 1993, 1994 The Regents of the University of California\""); asm(".include \"libc/disclaimer.inc\""); -#define BADCH (int)'?' -#define BADARG (int)':' +#define BADCH '?' +#define BADARG ':' -/** - * If error message should be printed. - * @see getopt() - */ -int opterr; +int opterr; // If error message should be printed. +int optind; // Index into parent argv vector. +int optopt; // Character checked for validity. +int optreset; // Reset getopt. +char *optarg; // Argument associated with option. -/** - * Index into parent argv vector. - * @see getopt() - */ -int optind; +static struct { + char once; + char emsg[1]; + char *place; +} optglob; -/** - * Character checked for validity. - * @see getopt() - */ -int optopt; - -/** - * Reset getopt. - * @see getopt() - */ -int optreset; - -/** - * Argument associated with option. - * @see getopt() - */ -char *optarg; - -char *getopt_place; -static char kGetoptEmsg[1]; - -static void getopt_print_badch(const char *s) { - char b1[512]; - char b2[8] = " -- "; - b1[0] = 0; - if (program_invocation_name) { - strlcat(b1, program_invocation_name, sizeof(b1)); - strlcat(b1, ": ", sizeof(b1)); - } - strlcat(b1, s, sizeof(b1)); - b2[4] = optopt; - b2[5] = '\n'; - b2[6] = 0; - strlcat(b1, b2, sizeof(b1)); - write(2, b1, strlen(b1)); +static void getopt_print(const char *s) { + const char *prog; + char b[8] = " -- ?\n"; + prog = program_invocation_short_name; + b[4] = optopt; + tinyprint(2, prog ? prog : "", prog ? ": " : "", s, b, NULL); } /** @@ -116,69 +87,74 @@ static void getopt_print_badch(const char *s) { */ int getopt(int nargc, char *const nargv[], const char *ostr) { char *oli; /* option letter list index */ - static bool once; - if (!once) { + if (!optglob.once) { opterr = 1; optind = 1; - getopt_place = kGetoptEmsg; - once = true; + optglob.place = optglob.emsg; + optglob.once = 1; } /* * Some programs like cvs expect optind = 0 to trigger * a reset of getopt. */ - if (optind == 0) optind = 1; - if (optreset || *getopt_place == 0) { /* update scanning pointer */ + if (!optind) optind = 1; + if (optreset || !*optglob.place) { /* update scanning pointer */ optreset = 0; - getopt_place = nargv[optind]; - if (optind >= nargc || *getopt_place++ != '-') { + optglob.place = nargv[optind]; + if (optind >= nargc || *optglob.place++ != '-') { /* Argument is absent or is not an option */ - getopt_place = kGetoptEmsg; + optglob.place = optglob.emsg; return -1; } - optopt = *getopt_place++; - if (optopt == '-' && *getopt_place == 0) { + optopt = *optglob.place++; + if (optopt == '-' && !*optglob.place) { /* "--" => end of options */ ++optind; - getopt_place = kGetoptEmsg; + optglob.place = optglob.emsg; return -1; } - if (optopt == 0) { + if (!optopt) { /* Solitary '-', treat as a '-' option if the program (eg su) is looking for it. */ - getopt_place = kGetoptEmsg; - if (strchr(ostr, '-') == NULL) return -1; + optglob.place = optglob.emsg; + if (!strchr(ostr, '-')) return -1; optopt = '-'; } } else { - optopt = *getopt_place++; + optopt = *optglob.place++; } /* See if option letter is one the caller wanted... */ - if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) { - if (*getopt_place == 0) ++optind; - if (opterr && *ostr != ':') getopt_print_badch("illegal option"); + if (optopt == ':' || !(oli = strchr(ostr, optopt))) { + if (!*optglob.place) ++optind; + if (opterr && *ostr != ':') { + getopt_print("illegal option"); + } return BADCH; } /* Does this option need an argument? */ if (oli[1] != ':') { /* don't need argument */ - optarg = NULL; - if (*getopt_place == 0) ++optind; + optarg = 0; + if (!*optglob.place) ++optind; } else { /* Option-argument is either the rest of this argument or the entire next argument. */ - if (*getopt_place) { - optarg = getopt_place; + if (*optglob.place) { + optarg = optglob.place; } else if (nargc > ++optind) { optarg = nargv[optind]; } else { /* option-argument absent */ - getopt_place = kGetoptEmsg; - if (*ostr == ':') return BADARG; - if (opterr) getopt_print_badch("option requires an argument"); + optglob.place = optglob.emsg; + if (*ostr == ':') { + return BADARG; + } + if (opterr) { + getopt_print("option requires an argument"); + } return BADCH; } - getopt_place = kGetoptEmsg; + optglob.place = optglob.emsg; ++optind; } return optopt; /* return option letter */ diff --git a/third_party/musl/crypt.internal.h b/third_party/musl/crypt.internal.h index 7a09769a6..29e70a8a3 100644 --- a/third_party/musl/crypt.internal.h +++ b/third_party/musl/crypt.internal.h @@ -4,11 +4,11 @@ #if !(__ASSEMBLER__ + __LINKER__ + 0) COSMOPOLITAN_C_START_ -_Hide char *__crypt_des(const char *, const char *, char *); -_Hide char *__crypt_md5(const char *, const char *, char *); -_Hide char *__crypt_blowfish(const char *, const char *, char *); -_Hide char *__crypt_sha256(const char *, const char *, char *); -_Hide char *__crypt_sha512(const char *, const char *, char *); +char *__crypt_des(const char *, const char *, char *); +char *__crypt_md5(const char *, const char *, char *); +char *__crypt_blowfish(const char *, const char *, char *); +char *__crypt_sha256(const char *, const char *, char *); +char *__crypt_sha512(const char *, const char *, char *); COSMOPOLITAN_C_END_ #endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */ diff --git a/third_party/nsync/panic.c b/third_party/nsync/panic.c index bb7354e42..8028a7b5c 100644 --- a/third_party/nsync/panic.c +++ b/third_party/nsync/panic.c @@ -23,9 +23,6 @@ /* Aborts after printing the nul-terminated string s[]. */ void nsync_panic_ (const char *s) { - char b[256], *p = b; - p = stpcpy (p, "panic: "); - p = stpcpy (p, s); - write (2, b, p - b); + tinyprint (2, "nsync panic: ", s, NULL); notpossible; } diff --git a/tool/build/build.mk b/tool/build/build.mk index 21b5f0110..dc7c404b5 100644 --- a/tool/build/build.mk +++ b/tool/build/build.mk @@ -6,7 +6,6 @@ PKGS += TOOL_BUILD TOOL_BUILD_FILES := $(wildcard tool/build/*) TOOL_BUILD_SRCS = $(filter %.c,$(TOOL_BUILD_FILES)) TOOL_BUILD_HDRS = $(filter %.h,$(TOOL_BUILD_FILES)) -TOOL_BUILD_CTESTS = $(filter %.ctest,$(TOOL_BUILD_FILES)) TOOL_BUILD_BINS = \ $(TOOL_BUILD_COMS) \ @@ -21,8 +20,6 @@ TOOL_BUILD_BINS = \ o/$(MODE)/tool/build/printf \ o/$(MODE)/tool/build/dd -TOOL_BUILD_CALCULATOR = o/$(MODE)/tool/build/calculator.com - TOOL_BUILD_OBJS = \ $(TOOL_BUILD_SRCS:%.c=o/$(MODE)/%.o) @@ -31,8 +28,7 @@ TOOL_BUILD_COMS = \ TOOL_BUILD_CHECKS = \ $(TOOL_BUILD).pkg \ - $(TOOL_BUILD_HDRS:%=o/$(MODE)/%.ok) \ - $(TOOL_BUILD_CTESTS:%=o/$(MODE)/%.ok) + $(TOOL_BUILD_HDRS:%=o/$(MODE)/%.ok) TOOL_BUILD_DIRECTDEPS = \ DSP_CORE \ @@ -80,12 +76,6 @@ o/$(MODE)/tool/build/build.pkg: \ $(TOOL_BUILD_OBJS) \ $(foreach x,$(TOOL_BUILD_DIRECTDEPS),$($(x)_A).pkg) -o/$(MODE)/%.ctest.ok: \ - %.ctest \ - $(TOOL_BUILD_CALCULATOR) \ - $(VM) - @$(COMPILE) -AMKWIDES -wtT$@ $(VM) $(TOOL_BUILD_CALCULATOR) $< - o/$(MODE)/tool/build/%.com.dbg: \ $(TOOL_BUILD_DEPS) \ o/$(MODE)/tool/build/build.pkg \ diff --git a/tool/build/calculator.c b/tool/build/calculator.c deleted file mode 100644 index ef5b8b092..000000000 --- a/tool/build/calculator.c +++ /dev/null @@ -1,760 +0,0 @@ -#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/assert.h" -#include "libc/calls/calls.h" -#include "libc/errno.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/fmt.h" -#include "libc/fmt/itoa.h" -#include "libc/intrin/bits.h" -#include "libc/intrin/morton.h" -#include "libc/intrin/popcnt.h" -#include "libc/limits.h" -#include "libc/log/color.internal.h" -#include "libc/log/internal.h" -#include "libc/log/log.h" -#include "libc/macros.internal.h" -#include "libc/math.h" -#include "libc/mem/arraylist2.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/rand.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "libc/sysv/consts/sig.h" -#include "libc/tinymath/emodl.h" -#include "libc/x/xsigaction.h" -#include "third_party/gdtoa/gdtoa.h" -#include "third_party/getopt/getopt.internal.h" - -#define INT int128_t -#define FLOAT long double -#define EPSILON 1e-16l - -#define BANNER \ - "\ -Reverse Polish Notation Calculator\n\ -Copyright 2020 Justine Alexandra Roberts Tunney\n\ -This is fast portable lightweight software. You have the freedom to build\n\ -software just like it painlessly. See http://github.com/jart/cosmopolitan\n\ -" - -#define USAGE1 \ - "SYNOPSIS\n\ -\n\ - Reverse Polish Notation Calculator\n\ -\n\ -USAGE\n\ -\n" - -#define USAGE2 \ - " [FLAGS] [FILE...]\n\ -\n\ -FLAGS\n\ -\n\ - -h\n\ - -? shows this information\n\ - -i force interactive mode\n\ -\n\ -KEYBOARD SHORTCUTS\n\ -\n\ - CTRL-D Closes standard input\n\ - CTRL-C Sends SIGINT to program\n\ - CTRL-U Redraw line\n\ - CTRL-L Redraw display\n\ -\n\ -FUNCTIONS\n\ -\n" - -#define USAGE3 \ - "\n\ -EXAMPLES\n\ -\n\ - calculator.com\n\ - 40 2 +\n\ - 42\n\ -\n\ - echo '2 2 + . cr' | calculator.com\n\ - 4\n\ -\n\ - calculator.com <\n\ - https://github.com/jart/cosmooplitan\n\ -\n\ -" - -#define CTRL(C) ((C) ^ 0100) -#define Fatal(...) Log(kFatal, __VA_ARGS__) -#define Warning(...) Log(kWarning, __VA_ARGS__) - -enum Severity { - kFatal, - kWarning, -}; - -enum Exception { - kUnderflow = 1, - kDivideError, -}; - -struct Bytes { - size_t i, n; - char *p; -}; - -struct History { - size_t i, n; - struct Bytes *p; -}; - -struct Value { - enum Type { - kInt, - kFloat, - } t; - union { - INT i; - FLOAT f; - }; -}; - -struct Function { - const char sym[16]; - void (*fun)(void); - const char *doc; -}; - -jmp_buf thrower; -const char *file; -struct Bytes token; -struct History history; -struct Value stack[128]; -int sp, comment, line, column, interactive; - -uint32_t gray(uint32_t x) { - return x ^ (x >> 1); -} - -uint32_t ungray(uint32_t x) { - x ^= x >> 16; - x ^= x >> 8; - x ^= x >> 4; - x ^= x >> 2; - x ^= x >> 1; - return x; -} - -INT Popcnt(INT x) { - uint128_t word = x; - return popcnt(word >> 64) + popcnt(word); -} - -char *Repr(struct Value x) { - static char buf[64]; - if (x.t == kFloat) { - g_xfmt_p(buf, &x.f, 16, sizeof(buf), 0); - } else { - sprintf(buf, "%jjd", x.i); - } - return buf; -} - -char *ReprStack(void) { - int i, j, l; - char *s, *p; - static char buf[80]; - p = memset(buf, 0, sizeof(buf)); - for (i = 0; i < sp; ++i) { - s = Repr(stack[i]); - l = strlen(s); - if (p + l + 2 > buf + sizeof(buf)) break; - p = mempcpy(p, s, l); - *p++ = ' '; - } - return buf; -} - -void ShowStack(void) { - if (interactive) { - printf("\r\e[K"); - fputs(ReprStack(), stdout); - } -} - -void Cr(FILE *f) { - fputs(interactive || IsWindows() ? "\r\n" : "\n", f); -} - -void Log(enum Severity l, const char *fmt, ...) { - va_list va; - const char *severity[] = {"FATAL", "WARNING"}; - if (interactive) fflush(/* key triggering throw not echo'd yet */ stdout); - fprintf(stderr, "%s:%d:%d:%s: ", file, line + 1, column, severity[l & 1]); - va_start(va, fmt); - vfprintf(stderr, fmt, va); - va_end(va); - Cr(stderr); - if (l == kFatal) exit(EXIT_FAILURE); - if (interactive) ShowStack(); -} - -void __on_arithmetic_overflow(void) { - Warning("arithmetic overflow"); -} - -void OnDivideError(void) { - longjmp(thrower, kDivideError); -} - -struct Value Push(struct Value x) { - if (sp >= ARRAYLEN(stack)) Fatal("stack overflow"); - return (stack[sp++] = x); -} - -struct Value Pop(void) { - if (sp) { - return stack[--sp]; - } else { - longjmp(thrower, kUnderflow); - } -} - -INT Popi(void) { - struct Value x = Pop(); - return x.t == kInt ? x.i : x.f; -} - -void Pushi(INT i) { - struct Value x; - x.t = kInt; - x.i = i; - Push(x); -} - -FLOAT Popf(void) { - struct Value x = Pop(); - return x.t == kInt ? x.i : x.f; -} - -void Pushf(FLOAT f) { - struct Value x; - x.t = kFloat; - x.f = f; - Push(x); -} - -void OpDrop(void) { - Pop(); -} - -void OpDup(void) { - Push(Push(Pop())); -} - -void OpExit(void) { - exit(Popi()); -} - -void OpSrand(void) { - srand(Popi()); -} - -void OpEmit(void) { - fputwc(Popi(), stdout); -} - -void OpCr(void) { - Cr(stdout); -} - -void OpPrint(void) { - printf("%s ", Repr(Pop())); -} - -void OpComment(void) { - comment = true; -} - -void Glue0f(FLOAT fn(void)) { - Pushf(fn()); -} - -void Glue0i(INT fn(void)) { - Pushi(fn()); -} - -void Glue1f(FLOAT fn(FLOAT)) { - Pushf(fn(Popf())); -} - -void Glue1i(INT fn(INT)) { - Pushi(fn(Popi())); -} - -void OpSwap(void) { - struct Value a, b; - b = Pop(); - a = Pop(); - Push(b); - Push(a); -} - -void OpOver(void) { - struct Value a, b; - b = Pop(); - a = Pop(); - Push(a); - Push(b); - Push(a); -} - -void OpKey(void) { - wint_t c; - ttyraw(kTtyCursor | kTtySigs | kTtyLfToCrLf); - c = fgetwc(stdin); - ttyraw(-1); - if (c != -1) Pushi(c); -} - -void OpAssert(void) { - if (!Popi()) Fatal("assert failed"); -} - -void OpExpect(void) { - if (!Popi()) Warning("expect failed"); -} - -void OpMeminfo(void) { - OpCr(); - OpCr(); - fflush(stdout); - _meminfo(fileno(stdout)); -} - -void Glue2f(FLOAT fn(FLOAT, FLOAT)) { - FLOAT x, y; - y = Popf(); - x = Popf(); - Pushf(fn(x, y)); -} - -void Glue2i(INT fn(INT, INT)) { - INT x, y; - y = Popi(); - x = Popi(); - Pushi(fn(x, y)); -} - -void Glue1g(FLOAT fnf(FLOAT), INT fni(INT)) { - struct Value x; - x = Pop(); - switch (x.t) { - case kInt: - Pushi(fni(x.i)); - break; - case kFloat: - Pushf(fnf(x.f)); - break; - default: - Warning("type mismatch"); - } -} - -void Glue2g(FLOAT fnf(FLOAT, FLOAT), INT fni(INT, INT)) { - struct Value x, y; - y = Pop(); - x = Pop(); - if (x.t == kInt && y.t == kInt) { - Pushi(fni(x.i, y.i)); - } else if (x.t == kFloat && y.t == kFloat) { - Pushf(fnf(x.f, y.f)); - } else if (x.t == kInt && y.t == kFloat) { - Pushf(fnf(x.i, y.f)); - } else if (x.t == kFloat && y.t == kInt) { - Pushf(fnf(x.f, y.i)); - } else { - Warning("type mismatch"); - } -} - -#define LB { -#define RB } -#define SEMI ; -#define FNTYPEi INT -#define FNTYPEf FLOAT -#define FORM(F) LB F SEMI RB -#define FNPL0(T) void -#define FNPL1(T) FNTYPE##T x -#define FNPL2(T) FNTYPE##T x, FNTYPE##T y -#define FNDEF(A, T, S, C) FNTYPE##T Fn##S##T(FNPL##A(T)) FORM(return C) -#define FNDEFf(A, S, C) FNDEF(A, f, S, C) -#define FNDEFi(A, S, C) FNDEF(A, i, S, C) -#define FNDEFg(A, S, C) FNDEF(A, f, S, C) FNDEF(A, i, S, C) -#define OPDEF(A, T, S, C) void Op##S(void) FORM(Glue##A##T(Fn##S##T)) -#define OPDEFf(A, S, C) OPDEF(A, f, S, C) -#define OPDEFi(A, S, C) OPDEF(A, i, S, C) -#define OPDEFg(A, S, C) void Op##S(void) FORM(Glue##A##g(Fn##S##f, Fn##S##i)) -#define M(A, T, N, S, C, D) FNDEF##T(A, S, C) OPDEF##T(A, S, C) -#include "tool/build/calculator.inc" -#undef M - -const struct Function kFunctions[] = { - {".", OpPrint, "pops prints value repr"}, - {"#", OpComment, "line comment"}, -#define M(A, T, N, S, C, D) {N, Op##S, D}, -#include "tool/build/calculator.inc" -#undef M - {"dup", OpDup, "pushes copy of last item on stack"}, - {"drop", OpDrop, "pops and discards"}, - {"swap", OpSwap, "swaps last two items on stack"}, - {"over", OpOver, "pushes second item on stack"}, - {"cr", OpCr, "prints newline"}, - {"key", OpKey, "reads and pushes unicode character from keyboard"}, - {"emit", OpEmit, "pops and writes unicode character to output"}, - {"assert", OpAssert, "crashes if top of stack isn't nonzero"}, - {"expect", OpExpect, "prints warning if top of stack isn't nonzero"}, - {"meminfo", OpMeminfo, "prints memory mappings"}, - {"exit", OpExit, "exits program with status"}, -}; - -bool CallFunction(const char *sym) { - int i; - char s[16]; - strncpy(s, sym, sizeof(s)); - for (i = 0; i < ARRAYLEN(kFunctions); ++i) { - if (memcmp(kFunctions[i].sym, s, sizeof(s)) == 0) { - kFunctions[i].fun(); - return true; - } - } - return false; -} - -volatile const char *literal_; -bool ConsumeLiteral(const char *literal) { - bool r; - char *e; - struct Value x; - literal_ = literal; - errno = 0; - x.t = kInt; - x.i = strtoi128(literal, &e, 0); - if (*e) { - x.t = kFloat; - x.f = strtod(literal, &e); - r = !(!e || *e); - } else if (errno == ERANGE) { - r = false; - } else { - r = true; - } - Push(x); - return r; -} - -void ConsumeToken(void) { - enum Exception ex; - if (!token.i) return; - token.p[token.i] = 0; - token.i = 0; - if (history.i) history.p[history.i - 1].i = 0; - if (comment) return; - if (_startswith(token.p, "#!")) return; - switch (setjmp(thrower)) { - default: - if (CallFunction(token.p)) return; - if (ConsumeLiteral(token.p)) return; - Warning("bad token: %`'s", token.p); - break; - case kUnderflow: - Warning("stack underflow"); - break; - case kDivideError: - Warning("divide error"); - break; - } -} - -void CleanupRepl(void) { - if (sp && interactive) { - Cr(stdout); - } -} - -void AppendByte(struct Bytes *a, char b) { - APPEND(&a->p, &a->i, &a->n, &b); -} - -void AppendHistory(void) { - struct Bytes line; - if (interactive) { - bzero(&line, sizeof(line)); - APPEND(&history.p, &history.i, &history.n, &line); - } -} - -void AppendLine(char b) { - if (interactive) { - if (!history.i) AppendHistory(); - AppendByte(&history.p[history.i - 1], b); - } -} - -void Echo(int c) { - if (interactive) { - fputc(c, stdout); - } -} - -void Backspace(int c) { - struct Bytes *line; - if (interactive) { - if (history.i) { - line = &history.p[history.i - 1]; - if (line->i && token.i) { - do { - line->i--; - token.i--; - } while (line->i && token.i && (line->p[line->i] & 0x80)); - fputs("\e[D \e[D", stdout); - } - } - } -} - -void NewLine(void) { - line++; - column = 0; - comment = false; - if (interactive) { - Cr(stdout); - AppendHistory(); - ShowStack(); - } -} - -void KillLine(void) { - if (interactive) { - if (history.i) { - history.p[history.i - 1].i--; - } - } -} - -void ClearLine(void) { - if (interactive) { - if (token.i) sp = 0; - ShowStack(); - } -} - -void RedrawDisplay(void) { - int i; - struct Bytes *line; - if (interactive) { - printf("\e[H\e[2J%s", BANNER); - ShowStack(); - if (history.i) { - line = &history.p[history.i - 1]; - for (i = 0; i < line->i; ++i) { - fputc(line->p[i], stdout); - } - } - } -} - -void GotoStartOfLine(void) { - if (interactive) { - printf("\r"); - } -} - -void GotoEndOfLine(void) { -} - -void GotoPrevLine(void) { -} - -void GotoNextLine(void) { -} - -void GotoPrevChar(void) { -} - -void GotoNextChar(void) { -} - -void Calculator(FILE *f) { - int c; - while (!feof(f)) { - switch ((c = getc(f))) { - case -1: - case CTRL('D'): - goto Done; - case CTRL('@'): - break; - case ' ': - column++; - Echo(c); - AppendLine(c); - ConsumeToken(); - break; - case '\t': - column = ROUNDUP(column, 8); - Echo(c); - AppendLine(c); - ConsumeToken(); - break; - case '\r': - case '\n': - ConsumeToken(); - NewLine(); - break; - case CTRL('A'): - GotoStartOfLine(); - break; - case CTRL('E'): - GotoEndOfLine(); - break; - case CTRL('P'): - GotoPrevLine(); - break; - case CTRL('N'): - GotoNextLine(); - break; - case CTRL('B'): - GotoPrevChar(); - break; - case CTRL('F'): - GotoNextChar(); - break; - case CTRL('L'): - RedrawDisplay(); - break; - case CTRL('U'): - ClearLine(); - break; - case CTRL('K'): - KillLine(); - break; - case CTRL('?'): - case CTRL('H'): - Backspace(c); - break; - default: - column++; - /* fallthrough */ - case 0x80 ... 0xff: - Echo(c); - AppendLine(c); - AppendByte(&token, c); - break; - } - fflush(/* needed b/c this is event loop */ stdout); - } -Done: - CleanupRepl(); -} - -int Calculate(const char *path) { - FILE *f; - file = path; - line = column = 0; - if (!(f = fopen(file, "r"))) Fatal("file not found: %s", file); - Calculator(f); - return fclose(f); -} - -void CleanupTerminal(void) { - ttyraw(-1); -} - -void StartInteractive(void) { - if (!interactive && !__nocolor && isatty(fileno(stdin)) && - isatty(fileno(stdout)) && !__nocolor) { - interactive = true; - } - errno = 0; - if (interactive) { - fputs(BANNER, stdout); - fflush(/* needed b/c entering tty mode */ stdout); - ttyraw(kTtyCursor | kTtySigs); - atexit(CleanupTerminal); - } -} - -void PrintUsage(int rc, FILE *f) { - char c; - int i, j; - fprintf(f, "%s %s%s", USAGE1, program_invocation_name, USAGE2); - for (i = 0; i < ARRAYLEN(kFunctions); ++i) { - fputs(" ", f); - for (j = 0; j < ARRAYLEN(kFunctions[i].sym); ++j) { - c = kFunctions[i].sym[j]; - fputc(c ? c : ' ', f); - } - fprintf(f, " %s\n", kFunctions[i].doc); - } - fputs(USAGE3, f); - exit(rc); -} - -void GetOpts(int argc, char *argv[]) { - int opt; - while ((opt = getopt(argc, argv, "?hi")) != -1) { - switch (opt) { - case 'i': - interactive = true; - break; - case 'h': - case '?': - PrintUsage(EXIT_SUCCESS, stdout); - default: - PrintUsage(EX_USAGE, stderr); - } - } -} - -int main(int argc, char *argv[]) { - int i, rc; - ShowCrashReports(); - GetOpts(argc, argv); - xsigaction(SIGFPE, OnDivideError, 0, 0, 0); - if (optind == argc) { - file = "/dev/stdin"; - StartInteractive(); - Calculator(stdin); - return fclose(stdin); - } else { - for (i = optind; i < argc; ++i) { - if (Calculate(argv[i]) == -1) { - return -1; - } - } - } - return 0; -} diff --git a/tool/build/calculator.ctest b/tool/build/calculator.ctest deleted file mode 100755 index 99de88017..000000000 --- a/tool/build/calculator.ctest +++ /dev/null @@ -1,91 +0,0 @@ -# INTEGER -2 3 + 5 = assert -3 2 + 5 = assert -5 2 - 3 = assert -2 5 - -3 = assert -81 3 / 27 = assert -81 3 // 27 = assert -2 8 ** 256 = assert -17 10 % 7 = assert -17 10 fmod 7 = assert - -# FLOATING POINT -.1 .2 + .3 - abs epsilon < assert -pi sqrt pi sqrt * pi - abs epsilon < assert -3 2 / 1.5 = assert -pi pi = assert -pi cos -1 = assert -pi 2 / sin 1 = assert -81 3 / 27 = assert -inf isinf assert -inf isnormal ! assert -nan isnormal ! assert -1 0 / isnormal ! assert -0 signbit ! assert --.5 round -1 = assert --.5 floor -1 = assert --.5 rint dup 0 = assert signbit assert --.5 nearbyint dup 0 = assert signbit assert --.5 ceil dup 0 = assert signbit assert --.5 trunc dup 0 = assert signbit assert -0 0 / dup isnan assert signbit assert # is this right? -1 0 / dup isinf assert signbit ! assert # is this right? - nan nan != assert # is this right? -# -nan -nan != assert # is this right? - inf inf = assert # is this right? --inf -inf = assert # is this right? - -# BIT ARITHMETIC --1 ~ 0 = assert -0 0x7fffffffffffffffffffffffffffffff - -0x7fffffffffffffffffffffffffffffff = assert -0b1010101 popcnt 4 = assert -0b1010101 0b0110101 ^ 0b1100000 = assert -0b1010101 0b0110101 | 0b1110101 = assert -0b1010101 0b0110101 & 0b0010101 = assert -0b1010101 1 >> 0b000101010 = assert -0b1010101 2 >> 0b000010101 = assert -0b1010101 1 << 0b010101010 = assert -0b1010101 2 << 0b101010100 = assert - -# BOOLEAN -true assert -false ! assert -true ! ! assert -true true && assert -true false && ! assert -false true && ! assert -true false && ! assert -false true && ! assert -true true || assert -false true || assert -true false || assert -false false || ! assert -4 5 < assert -5 4 < ! assert --5 4 < assert -5 5 < ! assert -5 5 <= assert -5 4 > assert -4 5 > ! assert -4 -5 > assert -5 5 > ! assert -5 5 >= assert - -# MISC -1 abs 1 = assert --1 abs 1 = assert --1 1 max 1 = assert -1 -1 max 1 = assert -1 2 max 2 = assert --1 1 min -1 = assert -1 -1 min -1 = assert -1 2 min 1 = assert -rand64 rand64 rand64 rand64 != != && assert - -# HEX SIGN - -0x80000000 -2147483648 = assert - 0x80000000 2147483648 = assert - 0x80000001 2147483649 = assert - 0xffffffff 4294967295 = assert - 0x100000000 4294967296 = assert --0x100000000 -4294967296 = assert diff --git a/tool/build/calculator.inc b/tool/build/calculator.inc deleted file mode 100644 index 5507cb281..000000000 --- a/tool/build/calculator.inc +++ /dev/null @@ -1,100 +0,0 @@ -M(2, g, "+", Add, x + y, "add") -M(2, g, "-", Sub, x - y, "sub") -M(2, g, "*", Mul, x *y, "multiply") -M(2, f, "/", Div, x / y, "division") -M(2, i, "%", Rem, x % y, "integer remainder") -M(2, i, "//", Idiv, x / y, "integer division") -M(2, g, "**", Expo, powl(x, y), "exponentiation") - -M(1, i, "~", Not, ~x, "bitwise not") -M(2, i, "^", Xor, x ^ y, "bitwise xor") -M(2, i, "|", Or, x | y, "bitwise or") -M(2, i, "&", And, x &y, "bitwise and") -M(2, i, ">>", Shr, x >> y, "shift right") -M(2, i, "<<", Shl, x << y, "shift left") - -M(1, i, "!", LogicalNot, !x, "logical not") -M(2, i, "||", LogicalOr, x || y, "logical or") -M(2, i, "&&", LogicalAnd, x &&y, "logical and") - -M(2, g, "=", Equal1, x == y, "equal to") -M(2, g, "!=", Notequal, x != y, "not equal to") -M(2, g, "<", LessThan, x < y, "less than") -M(2, g, ">", GreaterThan, x > y, "greater than") -M(2, g, "<=", LessThanEqual, x <= y, "less than or equal to") -M(2, g, ">=", GreaterThanEqual, x >= y, "greater than or equal to") - -M(1, i, "gray", Gray, gray(x), "gray coding") -M(1, i, "ungray", Ungray, ungray(x), "inverse gray coding") -M(1, i, "popcnt", Popcnt, Popcnt(x), "count bits") - -M(1, g, "abs", Abs, fabsl(x), "absolute value") -M(2, g, "min", Min, fminl(x, y), "pops two values and pushes minimum") -M(2, g, "max", Max, fmaxl(x, y), "pops two values and pushes maximum") - -M(2, g, "fmod", Fmod, fmodl(x, y), "trunc remainder") -M(2, g, "emod", Emod, emodl(x, y), "euclidean remainder") -M(2, g, "remainder", Remainder, remainderl(x, y), "rint remainder") -M(2, g, "hypot", Hypot, hypotl(x, y), "euclidean distance") - -M(0, i, "false", False, 0, "0") -M(0, i, "true", True, 1, "1") -M(0, i, "intmin", IntMin, INT128_MIN, "native integer minimum") -M(0, i, "intmax", IntMax, INT128_MAX, "native integer maximum") -M(0, f, "e", Euler, M_E, "𝑒") -M(0, f, "pi", Fldpi, M_PI, "π") -M(0, f, "epsilon", Epsilon, EPSILON, "ɛ") -M(0, f, "inf", Inf, INFINITY, "∞") -M(0, f, "nan", Nan, NAN, "NAN") -M(0, f, "-0", Negzero, -0., "wut") -M(0, f, "l2t", Fldl2t, M_LOG2_10, "log₂10") -M(0, f, "lg2", Fldlg2, M_LOG10_2, "log₁₀2") -M(0, f, "ln2", Fldln2, M_LN2, "logₑ2") -M(0, f, "l2e", Fldl2e, M_LOG2E, "logₑ10") -M(2, f, "nextafter", Nextafter, nextafterl(x, y), "next ulp") -M(1, f, "significand", Significand, significandl(x), "mantissa") - -M(1, f, "sqrt", Sqrt, sqrtl(x), "√𝑥") -M(1, f, "exp", Exp, expl(x), "𝑒ˣ") -M(1, g, "expm1", Expm1, expm1l(x), "𝑒ˣ-1") -M(1, g, "exp2", Exp2, exp2l(x), "2ˣ") -M(1, g, "exp10", Exp10, exp10l(x), "10ˣ") -M(2, g, "ldexp", Ldexp, ldexpl(x, y), "𝑥×2ʸ") - -M(1, f, "log", Log, logl(x), "logₑ𝑥") -M(1, g, "log2", Log2, log2l(x), "log₂𝑥") -M(1, g, "log10", Log10, log10l(x), "log₁₀𝑥") -M(1, g, "ilogb", Ilogb, ilogbl(x), "exponent") - -M(1, g, "sin", Sin, sinl(x), "sine") -M(1, g, "cos", Cos, cosl(x), "cosine") -M(1, g, "tan", Tan, tanl(x), "tangent") -M(1, g, "asin", Asin, asinl(x), "arcsine") -M(1, g, "acos", Acos, acosl(x), "arccosine") -M(1, g, "atan", Atan, atanl(x), "arctangent") -M(2, g, "atan2", Atan2, atan2l(x, y), "arctangent of 𝑥/𝑦") - -M(1, g, "sinh", Sinh, sinhl(x), "hyperbolic sine") -M(1, g, "cosh", Cosh, coshl(x), "hyperbolic cosine") -M(1, g, "tanh", Tanh, tanhl(x), "hyperbolic tangent") -M(1, g, "asinh", Asinh, asinhl(x), "hyperbolic arcsine") -M(1, g, "acosh", Acosh, acoshl(x), "hyperbolic arccosine") -M(1, g, "atanh", Atanh, atanhl(x), "hyperbolic arctangent") - -M(1, g, "round", Round, roundl(x), "round away from zero") -M(1, g, "trunc", Trunc, truncl(x), "round towards zero") -M(1, g, "rint", Rint, rintl(x), "round to even") -M(1, g, "nearbyint", Nearbyint, nearbyintl(x), "round to nearest integer") -M(1, g, "ceil", Ceil, ceill(x), "smallest integral not less than 𝑥") -M(1, g, "floor", Floor, floorl(x), "largest integral not greater than 𝑥") - -M(1, f, "isnan", Isnan, isnan(x), "returns true if 𝑥=NAN") -M(1, f, "isinf", Isinf, isinf(x), "returns true if 𝑥=INFINITY") -M(1, f, "signbit", Signbit, signbit(x), "clears all bits but sign bit") -M(1, f, "isfinite", Isfinite, isfinite(x), "returns true if 𝑥≠INFINITY") -M(1, f, "isnormal", Isnormal, isnormal(x), "returns true if not denormal") -M(1, f, "fpclassify", Fpclassify, fpclassify(x), - "nan=0,inf=1,zero=2,subnorm=3,normal=4") - -M(0, i, "rand", Rand, rand(), "deterministic random number") -M(0, i, "rand64", _Rand64, _rand64(), "64-bit random number") diff --git a/tool/build/chmod.c b/tool/build/chmod.c index 4f874613b..8c0562ab7 100644 --- a/tool/build/chmod.c +++ b/tool/build/chmod.c @@ -21,6 +21,7 @@ #include "libc/fmt/conv.h" #include "libc/fmt/magnumstrs.internal.h" #include "libc/runtime/runtime.h" +#include "libc/stdio/stdio.h" #include "libc/str/str.h" #include "third_party/getopt/getopt.internal.h" @@ -33,42 +34,21 @@ SYNOPSIS\n\ \n\ FLAGS\n\ \n\ - -?\n\ -h help\n\ \n" const char *prog; -nullterminated() static void Print(int fd, const char *s, ...) { - va_list va; - char buf[2048]; - va_start(va, s); - buf[0] = 0; - do { - strlcat(buf, s, sizeof(buf)); - } while ((s = va_arg(va, const char *))); - write(fd, buf, strlen(buf)); - va_end(va); -} - -static wontreturn void SysExit(const char *path, const char *func) { - const char *errstr; - if (!(errstr = _strerdoc(errno))) errstr = "EUNKNOWN"; - Print(2, path, ": ", func, " failed with ", errstr, "\n", NULL); - exit(1); -} - static wontreturn void PrintUsage(int fd, int rc) { - Print(fd, "USAGE\n\n ", program_invocation_name, USAGE, NULL); + tinyprint(fd, "USAGE\n\n ", prog, USAGE, NULL); exit(rc); } static void GetOpts(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "?h")) != -1) { + while ((opt = getopt(argc, argv, "h")) != -1) { switch (opt) { case 'h': - case '?': PrintUsage(1, 0); default: PrintUsage(2, 1); @@ -79,18 +59,22 @@ static void GetOpts(int argc, char *argv[]) { int main(int argc, char *argv[]) { int i, mode; char buf[PATH_MAX], *endptr; + prog = argv[0]; + if (!prog) prog = "chmod"; GetOpts(argc, argv); if (argc - optind < 2) { - PrintUsage(2, 1); + tinyprint(2, prog, ": missing operand\n", NULL); + exit(1); } mode = strtol(argv[optind], &endptr, 8) & 07777; if (*endptr) { - Print(2, "chmod: invalid mode octal\n", NULL); + tinyprint(2, prog, ": invalid mode octal\n", NULL); exit(1); } for (i = optind + 1; i < argc; ++i) { if (chmod(argv[i], mode) == -1) { - SysExit(argv[i], "chmod"); + perror(argv[i]); + exit(1); } } return 0; diff --git a/tool/build/cp.c b/tool/build/cp.c index 372c3247a..44f34ef4e 100644 --- a/tool/build/cp.c +++ b/tool/build/cp.c @@ -24,6 +24,7 @@ #include "libc/fmt/fmt.h" #include "libc/fmt/libgen.h" #include "libc/fmt/magnumstrs.internal.h" +#include "libc/intrin/kprintf.h" #include "libc/mem/gc.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" @@ -91,16 +92,14 @@ bool IsSymlink(const char *path) { return res; } -wontreturn void PrintUsage(int rc, FILE *f) { - fputs("usage: ", f); - fputs(prog, f); - fputs(USAGE, f); +wontreturn void PrintUsage(int rc, int fd) { + tinyprint(fd, "USAGE\n\n ", prog, USAGE, NULL); exit(rc); } void GetOpts(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "?hfnaprR")) != -1) { + while ((opt = getopt(argc, argv, "hfnaprR")) != -1) { switch (opt) { case 'f': force = true; @@ -118,10 +117,9 @@ void GetOpts(int argc, char *argv[]) { flags |= COPYFILE_PRESERVE_TIMESTAMPS; break; case 'h': - case '?': - PrintUsage(EXIT_SUCCESS, stdout); + PrintUsage(0, 1); default: - PrintUsage(EX_USAGE, stderr); + PrintUsage(1, 2); } } } @@ -146,8 +144,7 @@ int Visit(const char *fpath, const struct stat *sb, int tflag, Cp(srcfile, dstfile); return 0; default: - fputs(fpath, stderr); - fputs(": can't handle file type\n", stderr); + tinyprint(2, fpath, ": bad file type\n", NULL); exit(1); } } @@ -157,7 +154,7 @@ char *Join(const char *a, const char *b) { n = strlen(a); m = strlen(b); if (n + 1 + m + 1 > sizeof(dstfile)) { - fputs("error: cp: path too long\n", stderr); + tinyprint(2, prog, ": path too long\n", NULL); exit(1); } stpcpy(stpcpy(stpcpy(dstfile, a), "/"), b); @@ -191,8 +188,7 @@ void Cp(char *src, char *dst) { basename(dst); if (IsDirectory(src)) { if (!recursive) { - fputs(prog, stderr); - fputs(": won't copy directory without -r flag.\n", stderr); + tinyprint(2, prog, ": won't copy directory without -r flag\n", NULL); exit(1); } strcpy(dstdir, dst); @@ -208,10 +204,7 @@ void Cp(char *src, char *dst) { strcpy(srcdir, ""); } if (nftw(src, Visit, 20, 0) == -1) { - fputs(prog, stderr); - fputs(": nftw failed: ", stderr); - fputs(_strerdoc(errno), stderr); - fputs("\n", stderr); + perror(src); exit(1); } return; @@ -219,37 +212,49 @@ void Cp(char *src, char *dst) { if (IsDirectory(dst)) { dst = Join(dst, basename(src)); } - if (!force && access(dst, W_OK) == -1 && errno != ENOENT) goto OnFail; - strcpy(mkbuf, dst); - if (makedirs(dirname(mkbuf), 0755) == -1) goto OnFail; - if (IsSymlink(src)) { - if ((rc = readlink(src, linkbuf, sizeof(linkbuf) - 1)) == -1) goto OnFail; - linkbuf[rc] = 0; - if (symlink(linkbuf, dst) == -1) goto OnFail; - } else { - if (!MovePreservingDestinationInode(src, dst)) goto OnFail; + if (!force && access(dst, W_OK) == -1 && errno != ENOENT) { + perror(dst); + exit(1); + } + strcpy(mkbuf, dst); + if (makedirs((s = dirname(mkbuf)), 0755) == -1) { + perror(s); + exit(1); + } + if (IsSymlink(src)) { + if ((rc = readlink(src, linkbuf, sizeof(linkbuf) - 1)) == -1) { + perror(src); + exit(1); + } + linkbuf[rc] = 0; + if (symlink(linkbuf, dst) == -1) { + perror(dst); + exit(1); + } + } else { + if (!MovePreservingDestinationInode(src, dst)) { + perror(src); + exit(1); + } } - return; -OnFail: - s = _strerdoc(errno); - fputs(prog, stderr); - fputs(": ", stderr); - fputs(src, stderr); - fputs(" ", stderr); - fputs(dst, stderr); - fputs(": ", stderr); - fputs(s, stderr); - fputs("\n", stderr); - exit(1); } int main(int argc, char *argv[]) { int i; - prog = argc > 0 ? argv[0] : "cp.com"; + + prog = argv[0]; + if (!prog) prog = "cp"; + GetOpts(argc, argv); - if (argc - optind < 2) PrintUsage(EX_USAGE, stderr); + + if (argc - optind < 2) { + tinyprint(2, prog, ": missing operand\n", NULL); + exit(1); + } + for (i = optind; i < argc - 1; ++i) { Cp(argv[i], argv[argc - 1]); } + return 0; } diff --git a/tool/build/fixupobj.c b/tool/build/fixupobj.c index c294dbbc7..5bc6db926 100644 --- a/tool/build/fixupobj.c +++ b/tool/build/fixupobj.c @@ -73,32 +73,20 @@ static const char *epath; static Elf64_Xword symcount; static const Elf64_Ehdr *elf; -nullterminated() static void Print(int fd, const char *s, ...) { - va_list va; - char buf[2048]; - va_start(va, s); - buf[0] = 0; - do { - strlcat(buf, s, sizeof(buf)); - } while ((s = va_arg(va, const char *))); - write(fd, buf, strlen(buf)); - va_end(va); -} - static wontreturn void Die(const char *reason) { - Print(2, epath, ": ", reason, "\n", NULL); + tinyprint(2, epath, ": ", reason, "\n", NULL); exit(1); } static wontreturn void SysExit(const char *func) { const char *errstr; if (!(errstr = _strerdoc(errno))) errstr = "EUNKNOWN"; - Print(2, epath, ": ", func, " failed with ", errstr, "\n", NULL); + tinyprint(2, epath, ": ", func, " failed with ", errstr, "\n", NULL); exit(1); } static wontreturn void PrintUsage(int fd, int exitcode) { - Print(fd, "\n\ + tinyprint(fd, "\n\ NAME\n\ \n\ Cosmopolitan Object Fixer\n\ @@ -106,7 +94,7 @@ NAME\n\ SYNOPSIS\n\ \n\ ", - program_invocation_name, " [FLAGS] OBJECT...\n\ + program_invocation_name, " [FLAGS] OBJECT...\n\ \n\ DESCRIPTION\n\ \n\ @@ -124,7 +112,7 @@ FLAGS\n\ -c checks only mode\n\ \n\ ", - NULL); + NULL); exit(exitcode); } @@ -143,10 +131,10 @@ static void GetOpts(int argc, char *argv[]) { } } if (optind == argc) { - Print(2, - "error: no elf object files specified\n" - "run ", - program_invocation_name, " -h for usage\n", NULL); + tinyprint(2, + "error: no elf object files specified\n" + "run ", + program_invocation_name, " -h for usage\n", NULL); exit(1); } } @@ -184,11 +172,11 @@ static void CheckPrivilegedCrossReferences(void) { if (~shdr->sh_flags & SHF_EXECINSTR) continue; // data reference if ((secname = GetElfString(elf, esize, secstrs, shdr->sh_name)) && strcmp(".privileged", secname)) { - Print(2, epath, - ": code in .privileged section " - "references symbol '", - GetElfString(elf, esize, symstrs, syms[x].st_name), - "' in unprivileged code section '", secname, "'\n", NULL); + tinyprint(2, epath, + ": code in .privileged section " + "references symbol '", + GetElfString(elf, esize, symstrs, syms[x].st_name), + "' in unprivileged code section '", secname, "'\n", NULL); exit(1); } } diff --git a/tool/build/gzip.c b/tool/build/gzip.c index 479e03d29..88aa0d78f 100644 --- a/tool/build/gzip.c +++ b/tool/build/gzip.c @@ -289,7 +289,8 @@ void Decompress(const char *inpath) { int main(int argc, char *argv[]) { int i; - prog = argc > 0 ? argv[0] : "cp.com"; + prog = argv[0]; + if (!prog) prog = "gzip"; GetOpts(argc, argv); if (opt_decompress) { if (optind == argc) { diff --git a/tool/build/helpop.c b/tool/build/helpop.c index 75af5c496..b3604eda5 100644 --- a/tool/build/helpop.c +++ b/tool/build/helpop.c @@ -52,7 +52,7 @@ void PrintUsage(int rc, FILE *f) { void GetOpts(int argc, char *argv[]) { int opt; bits_ = 64; - while ((opt = getopt(argc, argv, "?hbs")) != -1) { + while ((opt = getopt(argc, argv, "hbs")) != -1) { switch (opt) { case 's': succinct_ = true; @@ -60,7 +60,6 @@ void GetOpts(int argc, char *argv[]) { case 'b': bits_ = atoi(optarg); break; - case '?': case 'h': PrintUsage(EXIT_SUCCESS, stdout); default: diff --git a/tool/build/mkdir.c b/tool/build/mkdir.c index 57167db2e..28914e8e4 100644 --- a/tool/build/mkdir.c +++ b/tool/build/mkdir.c @@ -8,14 +8,9 @@ ╚─────────────────────────────────────────────────────────────────*/ #endif #include "libc/calls/calls.h" -#include "libc/errno.h" #include "libc/fmt/conv.h" -#include "libc/fmt/magnumstrs.internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/x/x.h" #include "third_party/getopt/getopt.internal.h" #define USAGE \ @@ -30,19 +25,19 @@ FLAGS\n\ const char *prog; -wontreturn void PrintUsage(int rc, FILE *f) { - fputs("Usage: ", f); - fputs(prog, f); - fputs(USAGE, f); +wontreturn void PrintUsage(int rc, int fd) { + tinyprint(fd, "USAGE\n\n ", prog, USAGE, NULL); exit(rc); } int main(int argc, char *argv[]) { int i, mode = 0755; int (*mkdirp)(const char *, unsigned) = mkdir; - prog = argc > 0 ? argv[0] : "mkdir.com"; - while ((i = getopt(argc, argv, "?hpm:")) != -1) { + prog = argv[0]; + if (!prog) prog = "mkdir"; + + while ((i = getopt(argc, argv, "hpm:")) != -1) { switch (i) { case 'p': mkdirp = makedirs; @@ -50,31 +45,21 @@ int main(int argc, char *argv[]) { case 'm': mode = strtol(optarg, 0, 8); break; - case '?': case 'h': - PrintUsage(0, stdout); + PrintUsage(0, 1); default: - PrintUsage(EX_USAGE, stderr); + PrintUsage(1, 2); } } if (optind == argc) { - fputs(prog, stderr); - fputs(": missing argument\n", stderr); - fputs("Try '", stderr); - fputs(prog, stderr); - fputs(" -h' for more information.\n", stderr); + tinyprint(2, prog, ": missing operand\n", NULL); exit(1); } for (i = optind; i < argc; ++i) { if (mkdirp(argv[i], mode) == -1) { - fputs(prog, stderr); - fputs(": cannot create directory '", stderr); - fputs(argv[i], stderr); - fputs("' ", stderr); - fputs(_strerdoc(errno), stderr); - fputc('\n', stderr); + perror(argv[i]); exit(1); } } diff --git a/tool/build/mv.c b/tool/build/mv.c index acf982b09..5cf3db7a3 100644 --- a/tool/build/mv.c +++ b/tool/build/mv.c @@ -62,27 +62,15 @@ char linkbuf[PATH_MAX]; void Mv(char *, char *); -nullterminated() void Print(int fd, const char *s, ...) { - va_list va; - char buf[2048]; - va_start(va, s); - buf[0] = 0; - do { - strlcat(buf, s, sizeof(buf)); - } while ((s = va_arg(va, const char *))); - write(fd, buf, strlen(buf)); - va_end(va); -} - wontreturn void Die(const char *path, const char *reason) { - Print(2, path, ": ", reason, "\n", NULL); + tinyprint(2, path, ": ", reason, "\n", NULL); exit(1); } -wontreturn void SysExit(const char *path, const char *func) { +wontreturn void SysDie(const char *path, const char *func) { const char *errstr; if (!(errstr = _strerdoc(errno))) errstr = "EUNKNOWN"; - Print(2, path, ": ", func, "() failed with ", errstr, "\n", NULL); + tinyprint(2, path, ": ", func, ": ", errstr, "\n", NULL); exit(1); } @@ -108,7 +96,7 @@ bool IsSymlink(const char *path) { } wontreturn void PrintUsage(int rc, int fd) { - Print(fd, "usage: ", prog, USAGE, NULL); + tinyprint(fd, "usage: ", prog, USAGE, NULL); exit(rc); } @@ -161,7 +149,7 @@ char *Join(const char *a, const char *b) { n = strlen(a); m = strlen(b); if (n + 1 + m + 1 > sizeof(dstfile)) { - Print(2, "error: mv: path too long\n", NULL); + tinyprint(2, "error: mv: path too long\n", NULL); exit(1); } stpcpy(stpcpy(stpcpy(dstfile, a), "/"), b); @@ -192,7 +180,7 @@ void Mv(char *src, char *dst) { strcpy(srcdir, ""); } if (nftw(src, Visit, 20, 0) == -1) { - SysExit(src, "nftw"); + SysDie(src, "nftw"); } return; } @@ -200,30 +188,31 @@ void Mv(char *src, char *dst) { dst = Join(dst, basename(src)); } if (!force && access(dst, W_OK) == -1 && errno != ENOENT) { - SysExit(dst, "access"); + SysDie(dst, "access"); } strcpy(mkbuf, dst); if (makedirs((d = dirname(mkbuf)), 0755) == -1) { - SysExit(d, "makedirs"); + SysDie(d, "makedirs"); } if (IsSymlink(src)) { if ((rc = readlink(src, linkbuf, sizeof(linkbuf) - 1)) == -1) { - SysExit(src, "readlink"); + SysDie(src, "readlink"); } linkbuf[rc] = 0; if (symlink(linkbuf, dst)) { - SysExit(dst, "symlink"); + SysDie(dst, "symlink"); } } else { if (rename(src, dst)) { - SysExit(src, "rename"); + SysDie(src, "rename"); } } } int main(int argc, char *argv[]) { int i; - prog = argc > 0 ? argv[0] : "mv.com"; + prog = argv[0]; + if (!prog) prog = "mv"; GetOpts(argc, argv); if (argc - optind < 2) PrintUsage(1, 2); for (i = optind; i < argc - 1; ++i) { diff --git a/tool/build/ocat.c b/tool/build/ocat.c deleted file mode 100644 index d60f6c3b9..000000000 --- a/tool/build/ocat.c +++ /dev/null @@ -1,79 +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/calls/calls.h" -#include "libc/errno.h" -#include "libc/fmt/itoa.h" -#include "libc/fmt/magnumstrs.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/o.h" -#include "third_party/getopt/getopt.internal.h" - -char buf[512]; - -static void Write(const char *s, ...) { - va_list va; - va_start(va, s); - do { - write(2, s, strlen(s)); - } while ((s = va_arg(va, const char *))); - va_end(va); -} - -wontreturn void SysExit(int rc, const char *call, const char *thing) { - int err; - char ibuf[12]; - const char *estr; - err = errno; - FormatInt32(ibuf, err); - estr = _strerdoc(err); - if (!estr) estr = "EUNKNOWN"; - Write(thing, ": ", call, "() failed: ", estr, " (", ibuf, ")\n", 0); - exit(rc); -} - -int main(int argc, char *argv[]) { - int i, opt; - const char *outpath = "/dev/stdout"; - while ((opt = getopt(argc, argv, "o:")) != -1) { - switch (opt) { - case 'o': - outpath = optarg; - break; - default: - return 1; - } - } - int out = open(outpath, O_WRONLY | O_CREAT | O_TRUNC, 0644); - if (out == -1) SysExit(2, "open", outpath); - for (i = optind; i < argc; ++i) { - int in = open(argv[i], O_RDONLY); - if (in == -1) SysExit(3, "open", argv[i]); - for (;;) { - ssize_t rc = read(in, buf, 512); - if (rc == -1) SysExit(3, "read", argv[i]); - if (!rc) break; - ssize_t rc2 = write(out, buf, rc); - if (rc2 != rc) SysExit(4, "write", outpath); - } - if (close(in) == -1) SysExit(5, "close", argv[i]); - } - if (close(out) == -1) SysExit(6, "close", outpath); -} diff --git a/tool/build/package.c b/tool/build/package.c index f6d0ba172..a1a570520 100644 --- a/tool/build/package.c +++ b/tool/build/package.c @@ -153,27 +153,15 @@ struct Relas { } * p; } prtu; -nullterminated() static void Print(int fd, const char *s, ...) { - va_list va; - char buf[2048]; - va_start(va, s); - buf[0] = 0; - do { - strlcat(buf, s, sizeof(buf)); - } while ((s = va_arg(va, const char *))); - write(fd, buf, strlen(buf)); - va_end(va); -} - static wontreturn void Die(const char *path, const char *reason) { - Print(2, path, ": ", reason, "\n", NULL); + tinyprint(2, path, ": ", reason, "\n", NULL); exit(1); } static wontreturn void SysExit(const char *path, const char *func) { const char *errstr; if (!(errstr = _strerrno(errno))) errstr = "EUNKNOWN"; - Print(2, path, ": ", func, " failed with ", errstr, "\n", NULL); + tinyprint(2, path, ": ", func, " failed with ", errstr, "\n", NULL); exit(1); } @@ -321,7 +309,7 @@ static void WritePackage(struct Package *pkg) { } static wontreturn void PrintUsage(int fd, int exitcode) { - Print(fd, "\n\ + tinyprint(fd, "\n\ NAME\n\ \n\ Cosmopolitan Monorepo Packager\n\ @@ -329,7 +317,7 @@ NAME\n\ SYNOPSIS\n\ \n\ ", - program_invocation_name, " [FLAGS] OBJECT...\n\ + program_invocation_name, " [FLAGS] OBJECT...\n\ \n\ DESCRIPTION\n\ \n\ @@ -345,7 +333,7 @@ FLAGS\n\ -d PATH package dependency path [repeatable]\n\ \n\ ", - NULL); + NULL); exit(exitcode); } @@ -370,14 +358,15 @@ static void GetOpts(struct Package *pkg, struct Packages *deps, int argc, } } if (pkg->path == -1) { - Print(2, "error: no packages passed to package.com\n", NULL); + tinyprint(2, "error: no packages passed to package.com\n", NULL); exit(1); } if (optind == argc) { - Print(2, - "no objects passed to package.com; is your foo.mk $(FOO_OBJS) glob " - "broken?\n", - NULL); + tinyprint( + 2, + "no objects passed to package.com; is your foo.mk $(FOO_OBJS) glob " + "broken?\n", + NULL); exit(1); } getargs_init(&ga, argv + optind); @@ -495,7 +484,7 @@ static void LoadPriviligedRefsToUndefs(struct Package *pkg, if (obj->syms[x].st_shndx) continue; // symbol is defined if (ELF64_ST_BIND(obj->syms[x].st_info) != STB_WEAK && ELF64_ST_BIND(obj->syms[x].st_info) != STB_GLOBAL) { - Print(2, "warning: undefined symbol not global\n", NULL); + tinyprint(2, "warning: undefined symbol not global\n", NULL); continue; } if (!(s = GetElfString(obj->elf, obj->size, obj->strs, @@ -602,13 +591,13 @@ static void CheckStrictDeps(struct Package *pkg, struct Packages *deps) { undef = &pkg->undefs.p[i]; if (undef->bind_ == STB_WEAK) continue; if (!FindSymbol(pkg->strings.p + undef->name, pkg, deps, NULL, NULL)) { - Print(2, pkg->strings.p + pkg->path, ": undefined symbol '", - pkg->strings.p + undef->name, "' (", - pkg->strings.p + pkg->objects.p[undef->object].path, - ") not defined by direct dependencies:\n", NULL); + tinyprint(2, pkg->strings.p + pkg->path, ": undefined symbol '", + pkg->strings.p + undef->name, "' (", + pkg->strings.p + pkg->objects.p[undef->object].path, + ") not defined by direct dependencies:\n", NULL); for (j = 0; j < deps->i; ++j) { dep = deps->p[j]; - Print(2, "\t", dep->strings.p + dep->path, "\n", NULL); + tinyprint(2, "\t", dep->strings.p + dep->path, "\n", NULL); } exit(1); } @@ -626,10 +615,11 @@ static void CheckYourPrivilege(struct Package *pkg, struct Packages *deps) { name = prtu.p[i].symbol_name; if (FindSymbol(name, pkg, deps, &dep, &sym) && dep->sections.p[sym->section].kind == kText) { - Print(2, prtu.p[i].object_path, - ": privileged code referenced unprivileged symbol '", name, - "' in section '", - dep->strings.p + dep->sections.p[sym->section].name, "'\n", NULL); + tinyprint(2, prtu.p[i].object_path, + ": privileged code referenced unprivileged symbol '", name, + "' in section '", + dep->strings.p + dep->sections.p[sym->section].name, "'\n", + NULL); ++f; } } diff --git a/tool/build/printf.c b/tool/build/printf.c index 2895c4951..d737abdda 100644 --- a/tool/build/printf.c +++ b/tool/build/printf.c @@ -119,9 +119,7 @@ int main(int argc, char *argv[]) { printf(U(argv[1]), argv[2], argv[3], argv[4], argv[5], argv[6], argv[7]); return 0; default: - if (argc > 0) { - fprintf(stderr, "%s: %s format [arguments]\n", argv[0], argv[0]); - } + fprintf(stderr, "%s: %s format [arguments]\n", argv[0], argv[0]); return 1; } } diff --git a/tool/build/pstrace.c b/tool/build/pstrace.c deleted file mode 100644 index d8a7c0cd3..000000000 --- a/tool/build/pstrace.c +++ /dev/null @@ -1,990 +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 2021 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/calls/calls.h" -#include "libc/calls/struct/sigaction.h" -#include "libc/calls/struct/sigset.h" -#include "libc/errno.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/bits.h" -#include "libc/log/check.h" -#include "libc/log/log.h" -#include "libc/mem/gc.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "libc/sysv/consts/nr.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/sa.h" -#include "libc/sysv/consts/sig.h" -#include "libc/x/xasprintf.h" -#include "libc/x/xgetline.h" -#include "third_party/dlmalloc/dlmalloc.h" -#include "third_party/getopt/getopt.internal.h" - -/** - * @fileoverview Pythonic System Call Trace - * - * This program invokes `strace` as a subprocess and turns its output - * into Python data structures. It is useful because strace output is - * this weird plaintext format that's so famously difficult to parse. - * - * For example, you can run this command: - * - * pstrace -o trace.pylog echo hello world - * - * After which you may parse the output with Python: - * - * for line in open('trace.pylog'): - * pid,time,elap,kind,x = eval(line) - * if kind == 1: - * name,ret,args = x - * print "%s%r -> %d" % (name, args, ret) - * - * This program traces the subset of system calls governing processes - * and files. To do that we must track file descriptor lifetimes too. - * We also track system calls that are problematic for build configs, - * such as sockets, since compiling code shouldn't need the Internet. - * - * @note this tool is linux only - * @note freebsd: truss PROC ARGS - * @note appleos: sudo dtruss PROC ARGS - * @note openbsd: ktrace PROC ARGS && kdump -f ktrace.out - * @note windows: https://github.com/rogerorr/NtTrace - */ - -#define DEBUG "%ld: %s", lineno, line -#define READ128BE(S) ((uint128_t)READ64BE(S) << 64 | READ64BE((S) + 8)) -#define APPEND(L) \ - do { \ - if (++L.n > L.c) { \ - L.c = MAX(11, L.c); \ - L.c += L.c >> 1; \ - L.p = realloc(L.p, L.c * sizeof(*L.p)); \ - } \ - bzero(L.p + L.n - 1, sizeof(*L.p)); \ - } while (0) - -struct Trace { - struct Slices { - long n, c; - struct Slice { - int n, c; - char *p; - } * p; - } slices; - struct HashTable { - long i, n; - struct HashEntry { - long h; - long i; - } * p; - } sliceindex; - struct Strlists { - long n, c; - struct Strlist { - long n, c; - long *p; // slices.p[p[i]] - } * p; - } strlists; - struct Events { - long n, c; - struct Event { - enum EventKind { - EK_NONE, - EK_CALL, - EK_EXIT, // ret is kernel code - EK_SIGNAL, // ret is signal code - EK_KILLED, // ret is signal code - } kind; - unsigned char arity; - unsigned char syscall_; - bool is_interrupted; - int us; - int elap; - int pid; - long sec; - long ret; - long lineno; - struct Arg { - enum ArgKind { - AK_LONG, // x - AK_STR, // slices.p[x] - AK_STRLIST, // strlists.p[x] - AK_INTPAIR, // (x&0xffffffff, x>>32) - } kind; - long name; - long x; - } arg[6]; - } * p; - } events; -}; - -static const struct Syscall { - char name[16]; -} kSyscalls[] = { - {"accept"}, // - {"accept4"}, // - {"access"}, // - {"bind"}, // - {"chdir"}, // - {"chmod"}, // - {"chown"}, // - {"chroot"}, // - {"clone"}, // - {"close"}, // - {"connect"}, // - {"creat"}, // - {"dup"}, // - {"dup2"}, // - {"dup3"}, // - {"epoll_create"}, // - {"epoll_create1"}, // - {"eventfd"}, // - {"eventfd2"}, // - {"execve"}, // - {"execveat"}, // - {"faccessat"}, // - {"fchmodat"}, // - {"fchownat"}, // - {"fdatasync"}, // - {"fcntl"}, // - {"flock"}, // - {"fork"}, // - {"fsync"}, // - {"lchown"}, // - {"link"}, // - {"linkat"}, // - {"listen"}, // - {"memfd_create"}, // - {"mkdir"}, // - {"mkdirat"}, // - {"mknod"}, // - {"mknodat"}, // - {"open"}, // - {"openat"}, // - {"pipe"}, // - {"pipe2"}, // - {"readlink"}, // - {"readlinkat"}, // - {"rename"}, // - {"renameat"}, // - {"renameat2"}, // - {"rmdir"}, // - {"signalfd"}, // - {"signalfd4"}, // - {"socket"}, // - {"socketpair"}, // - {"statfs"}, // - {"symlink"}, // - {"symlinkat"}, // - {"sync"}, // - {"syncfs"}, // - {"timerfd_create"}, // - {"truncate"}, // - {"unlink"}, // - {"unlinkat"}, // - {"utimensat"}, // - {"vfork"}, // -}; - -static const struct Signal { - char name[8]; - unsigned char number; -} kSignals[] = { - {"SIGABRT", 6}, // - {"SIGALRM", 14}, // - {"SIGBUS", 7}, // - {"SIGCHLD", 17}, // - {"SIGCONT", 18}, // - {"SIGFPE", 8}, // - {"SIGHUP", 1}, // - {"SIGILL", 4}, // - {"SIGINT", 2}, // - {"SIGIO", 29}, // - {"SIGIOT", 6}, // - {"SIGKILL", 9}, // - {"SIGPIPE", 13}, // - {"SIGPOLL", 29}, // - {"SIGPROF", 27}, // - {"SIGPWR", 30}, // - {"SIGQUIT", 3}, // - {"SIGSEGV", 11}, // - {"SIGSTOP", 19}, // - {"SIGSYS", 31}, // - {"SIGTERM", 15}, // - {"SIGTRAP", 5}, // - {"SIGTSTP", 20}, // - {"SIGTTIN", 21}, // - {"SIGTTOU", 22}, // - {"SIGURG", 23}, // - {"SIGUSR1", 10}, // - {"SIGUSR2", 12}, // - {"SIGWINCH", 28}, // - {"SIGXCPU", 24}, // - {"SIGXFSZ", 25}, // -}; - -static const struct Errno { - char name[16]; - unsigned char number; -} kErrnos[] = { - {"E2BIG", 7}, // - {"EACCES", 13}, // - {"EADDRINUSE", 98}, // - {"EADDRNOTAVAIL", 99}, // - {"EADV", 68}, // - {"EAFNOSUPPORT", 97}, // - {"EAGAIN", 11}, // - {"EALREADY", 114}, // - {"EBADE", 52}, // - {"EBADF", 9}, // - {"EBADFD", 77}, // - {"EBADMSG", 74}, // - {"EBADR", 53}, // - {"EBADRQC", 56}, // - {"EBADSLT", 57}, // - {"EBFONT", 59}, // - {"EBUSY", 16}, // - {"ECANCELED", 125}, // - {"ECHILD", 10}, // - {"ECHRNG", 44}, // - {"ECOMM", 70}, // - {"ECONNABORTED", 103}, // - {"ECONNREFUSED", 111}, // - {"ECONNRESET", 104}, // - {"EDEADLK", 35}, // - {"EDESTADDRREQ", 89}, // - {"EDOM", 33}, // - {"EDOTDOT", 73}, // - {"EDQUOT", 122}, // - {"EEXIST", 17}, // - {"EFAULT", 14}, // - {"EFBIG", 27}, // - {"EHOSTDOWN", 112}, // - {"EHOSTUNREACH", 113}, // - {"EHWPOISON", 133}, // - {"EIDRM", 43}, // - {"EILSEQ", 84}, // - {"EINPROGRESS", 115}, // - {"EINTR", 4}, // - {"EINVAL", 22}, // - {"EIO", 5}, // - {"EISCONN", 106}, // - {"EISDIR", 21}, // - {"EISNAM", 120}, // - {"EKEYEXPIRED", 127}, // - {"EKEYREJECTED", 129}, // - {"EKEYREVOKED", 128}, // - {"EL2HLT", 51}, // - {"EL2NSYNC", 45}, // - {"EL3HLT", 46}, // - {"EL3RST", 47}, // - {"ELIBACC", 79}, // - {"ELIBBAD", 80}, // - {"ELIBEXEC", 83}, // - {"ELIBMAX", 82}, // - {"ELIBSCN", 81}, // - {"ELNRNG", 48}, // - {"ELOOP", 40}, // - {"EMEDIUMTYPE", 124}, // - {"EMFILE", 24}, // - {"EMLINK", 31}, // - {"EMSGSIZE", 90}, // - {"EMULTIHOP", 72}, // - {"ENAMETOOLONG", 36}, // - {"ENAVAIL", 119}, // - {"ENETDOWN", 100}, // - {"ENETRESET", 102}, // - {"ENETUNREACH", 101}, // - {"ENFILE", 23}, // - {"ENOANO", 55}, // - {"ENOBUFS", 105}, // - {"ENOCSI", 50}, // - {"ENODATA", 61}, // - {"ENODEV", 19}, // - {"ENOENT", 2}, // - {"ENOEXEC", 8}, // - {"ENOKEY", 126}, // - {"ENOLCK", 37}, // - {"ENOLINK", 67}, // - {"ENOMEDIUM", 123}, // - {"ENOMEM", 12}, // - {"ENOMSG", 42}, // - {"ENONET", 64}, // - {"ENOPKG", 65}, // - {"ENOPROTOOPT", 92}, // - {"ENOSPC", 28}, // - {"ENOSR", 63}, // - {"ENOSTR", 60}, // - {"ENOSYS", 38}, // - {"ENOTBLK", 15}, // - {"ENOTCONN", 107}, // - {"ENOTDIR", 20}, // - {"ENOTEMPTY", 39}, // - {"ENOTNAM", 118}, // - {"ENOTRECOVERABLE", 131}, // - {"ENOTSOCK", 88}, // - {"ENOTSUP", 95}, // - {"ENOTTY", 25}, // - {"ENOTUNIQ", 76}, // - {"ENXIO", 6}, // - {"EOPNOTSUPP", 95}, // - {"EOVERFLOW", 75}, // - {"EOWNERDEAD", 130}, // - {"EPERM", 1}, // - {"EPFNOSUPPORT", 96}, // - {"EPIPE", 32}, // - {"EPROTO", 71}, // - {"EPROTONOSUPPORT", 93}, // - {"EPROTOTYPE", 91}, // - {"ERANGE", 34}, // - {"EREMCHG", 78}, // - {"EREMOTE", 66}, // - {"EREMOTEIO", 121}, // - {"ERESTART", 85}, // - {"ERFKILL", 132}, // - {"EROFS", 30}, // - {"ESHUTDOWN", 108}, // - {"ESOCKTNOSUPPORT", 94}, // - {"ESPIPE", 29}, // - {"ESRCH", 3}, // - {"ESRMNT", 69}, // - {"ESTALE", 116}, // - {"ESTRPIPE", 86}, // - {"ETIME", 62}, // - {"ETIMEDOUT", 110}, // - {"ETOOMANYREFS", 109}, // - {"ETXTBSY", 26}, // - {"EUCLEAN", 117}, // - {"EUNATCH", 49}, // - {"EUSERS", 87}, // - {"EWOULDBLOCK", 11}, // - {"EXDEV", 18}, // - {"EXFULL", 54}, // -}; - -static char **strace_args; -static size_t strace_args_len; -static volatile bool interrupted; - -static long Hash(const void *p, size_t n) { - unsigned h, i; - for (h = i = 0; i < n; i++) { - h += ((unsigned char *)p)[i]; - h *= 0x9e3779b1; - } - return MAX(1, h); -} - -static uint64_t MakeKey64(const char *p, size_t n) { - char k[8] = {0}; - memcpy(k, p, n); - return READ64BE(k); -} - -static uint128_t MakeKey128(const char *p, size_t n) { - char k[16] = {0}; - memcpy(k, p, n); - return READ128BE(k); -} - -static int GetSyscall(const char *name, size_t namelen) { - int m, l, r; - uint128_t x, y; - char *endofname; - if (namelen && namelen <= 16) { - x = MakeKey128(name, namelen); - l = 0; - r = ARRAYLEN(kSyscalls) - 1; - while (l <= r) { - m = (l + r) >> 1; - y = READ128BE(kSyscalls[m].name); - if (x < y) { - r = m - 1; - } else if (x > y) { - l = m + 1; - } else { - return m; - } - } - } - return -1; -} - -static int GetErrno(const char *name, size_t namelen) { - int m, l, r; - uint128_t x, y; - char *endofname; - if (namelen && namelen <= 16) { - x = MakeKey128(name, namelen); - l = 0; - r = ARRAYLEN(kErrnos) - 1; - while (l <= r) { - m = (l + r) >> 1; - y = READ128BE(kErrnos[m].name); - if (x < y) { - r = m - 1; - } else if (x > y) { - l = m + 1; - } else { - return kErrnos[m].number; - } - } - } - return -1; -} - -static int GetSignal(const char *name, size_t namelen) { - int m, l, r; - uint64_t x, y; - char *endofname; - if (namelen && namelen <= 8) { - x = MakeKey64(name, namelen); - l = 0; - r = ARRAYLEN(kSignals) - 1; - while (l <= r) { - m = (l + r) >> 1; - y = READ64BE(kSignals[m].name); - if (x < y) { - r = m - 1; - } else if (x > y) { - l = m + 1; - } else { - return kSignals[m].number; - } - } - } - return -1; -} - -static struct Trace *NewTrace(void) { - return calloc(1, sizeof(struct Trace)); -} - -static void FreeTrace(struct Trace *t) { - long i; - if (t) { - for (i = 0; i < t->slices.n; ++i) { - free(t->slices.p[i].p); - } - free(t->slices.p); - free(t->sliceindex.p); - for (i = 0; i < t->strlists.n; ++i) { - free(t->strlists.p[i].p); - } - free(t->strlists.p); - free(t->events.p); - free(t); - } -} - -static void AppendStrlists(struct Trace *t) { - APPEND(t->strlists); -} - -static void AppendStrlist(struct Strlist *l) { - APPEND((*l)); -} - -static void AppendEvent(struct Trace *t) { - APPEND(t->events); -} - -static void AppendSlices(struct Trace *t) { - APPEND(t->slices); -} - -static void AppendSlice(struct Slice *s, int c) { - APPEND((*s)); - s->p[s->n - 1] = c; -} - -static long Intern(struct Trace *t, char *data, long size) { - struct HashEntry *p; - long i, j, k, n, m, h, n2; - h = Hash(data, size); - n = t->sliceindex.n; - i = 0; - if (n) { - k = 0; - do { - i = (h + k + ((k + 1) >> 1)) & (n - 1); - if (t->sliceindex.p[i].h == h && - t->slices.p[t->sliceindex.p[i].i].n == size && - !memcmp(t->slices.p[t->sliceindex.p[i].i].p, data, size)) { - free(data); - return t->sliceindex.p[i].i; - } - ++k; - } while (t->sliceindex.p[i].h); - } - if (++t->sliceindex.i >= (n >> 1)) { - m = n ? n << 1 : 16; - p = calloc(m, sizeof(struct HashEntry)); - for (j = 0; j < n; ++j) { - if (t->sliceindex.p[j].h) { - k = 0; - do { - i = (t->sliceindex.p[j].h + k + ((k + 1) >> 1)) & (m - 1); - ++k; - } while (p[i].h); - p[i].h = t->sliceindex.p[j].h; - p[i].i = t->sliceindex.p[j].i; - } - } - k = 0; - do { - i = (h + k + ((k + 1) >> 1)) & (m - 1); - ++k; - } while (p[i].h); - free(t->sliceindex.p); - t->sliceindex.p = p; - t->sliceindex.n = m; - } - AppendSlices(t); - t->slices.p[t->slices.n - 1].p = data; - t->slices.p[t->slices.n - 1].n = size; - t->sliceindex.p[i].i = t->slices.n - 1; - t->sliceindex.p[i].h = h; - return t->slices.n - 1; -} - -static long ReadCharLiteral(struct Slice *buf, long c, char *p, long *i) { - if (c != '\\') return c; - switch ((c = p[(*i)++])) { - case 'a': - return '\a'; - case 'b': - return '\b'; - case 't': - return '\t'; - case 'n': - return '\n'; - case 'v': - return '\v'; - case 'f': - return '\f'; - case 'r': - return '\r'; - case 'e': - return 033; - case 'x': - if (isxdigit(p[*i])) { - c = hextoint(p[(*i)++]); - if (isxdigit(p[*i])) { - c = c * 16 + hextoint(p[(*i)++]); - } - } - return c; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - c -= '0'; - if ('0' <= p[*i] && p[*i] <= '7') { - c = c * 8 + (p[(*i)++] - '0'); - if ('0' <= p[*i] && p[*i] <= '7') { - c = c * 8 + (p[(*i)++] - '0'); - } - } - return c; - default: - return c; - } -} - -static long GetDuration(long sec1, long us1, long sec2, long us2) { - long elap; - if ((elap = (sec2 - sec1) * 1000000)) { - return elap + 1000000 - us1 + us2; - } else { - return elap + us2 - us1; - } -} - -static void Parse(struct Trace *t, const char *line, long lineno) { - char *p, *q; - struct Slice b; - long c, i, j, k, arg, pid, event, sec, us; - p = line; - pid = strtol(p, &p, 10); - while (*p == ' ') ++p; - sec = strtol(p, &p, 10); - CHECK_EQ('.', *p++, DEBUG); - us = strtol(p, &p, 10); - CHECK_EQ(' ', *p++, DEBUG); - if (_startswith(p, "<... ")) { - CHECK_NOTNULL((p = strchr(p, '>'))); - ++p; - for (event = t->events.n; event--;) { - if (t->events.p[event].pid == pid) { - CHECK(t->events.p[event].is_interrupted, DEBUG); - t->events.p[event].is_interrupted = false; - t->events.p[event].elap = - GetDuration(t->events.p[event].sec, t->events.p[event].us, sec, us); - break; - } - } - CHECK_GE(event, 0); - } else { - AppendEvent(t); - event = t->events.n - 1; - t->events.p[event].pid = pid; - t->events.p[event].sec = sec; - t->events.p[event].us = us; - t->events.p[event].lineno = lineno; - if (_startswith(p, "+++ exited with ")) { - p += strlen("+++ exited with "); - t->events.p[event].kind = EK_EXIT; - t->events.p[event].ret = atoi(p); - return; - } else if (_startswith(p, "+++ killed by ")) { - p += strlen("+++ killed by "); - CHECK((q = strchr(p, ' ')), DEBUG); - t->events.p[event].kind = EK_KILLED; - t->events.p[event].ret = GetSignal(p, q - p); - return; - } else if (_startswith(p, "--- ")) { - p += 4; - CHECK(isalpha(*p), DEBUG); - CHECK((q = strchr(p, ' ')), DEBUG); - t->events.p[event].kind = EK_SIGNAL; - t->events.p[event].ret = GetSignal(p, q - p); - return; - } else if (isalpha(*p) && (q = strchr(p, '('))) { - t->events.p[event].kind = EK_CALL; - CHECK_NE(-1, (t->events.p[event].syscall_ = GetSyscall(p, q - p)), DEBUG); - p = q + 1; - } - } - for (;;) { - if (*p == ',') ++p; - while (*p == ' ') ++p; - CHECK(*p, DEBUG); - if (_startswith(p, "")) { - t->events.p[event].is_interrupted = true; - break; - } else if (*p == ')') { - ++p; - while (isspace(*p)) ++p; - CHECK_EQ('=', *p++, DEBUG); - while (isspace(*p)) ++p; - CHECK(isdigit(*p) || *p == '-', DEBUG); - t->events.p[event].ret = strtol(p, &p, 0); - if (t->events.p[event].ret == -1) { - while (isspace(*p)) ++p; - CHECK((q = strchr(p, ' ')), DEBUG); - if ((t->events.p[event].ret = GetErrno(p, q - p)) != -1) { - t->events.p[event].ret = -t->events.p[event].ret; - } - } - break; - } - CHECK_LT((arg = t->events.p[event].arity++), 6); - if (isalpha(*p) && !_startswith(p, "NULL")) { - bzero(&b, sizeof(b)); - for (; isalpha(*p) || *p == '_'; ++p) { - AppendSlice(&b, *p); - } - t->events.p[event].arg[arg].name = Intern(t, b.p, b.n); - CHECK_EQ('=', *p++, DEBUG); - } else { - t->events.p[event].arg[arg].name = -1; - } - if (_startswith(p, "NULL")) { - p += 4; - t->events.p[event].arg[arg].kind = AK_LONG; - t->events.p[event].arg[arg].x = 0; - } else if (*p == '-' || isdigit(*p)) { - t->events.p[event].arg[arg].kind = AK_LONG; - for (;;) { - t->events.p[event].arg[arg].x |= strtol(p, &p, 0); - if (*p == '|') { - ++p; - } else { - break; - } - } - } else if (*p == '{') { - CHECK_NOTNULL((p = strchr(p, '}')), DEBUG); - ++p; - } else if (*p == '"') { - bzero(&b, sizeof(b)); - for (j = 0; (c = p[++j]);) { - if (c == '"') { - p += j + 1; - break; - } - c = ReadCharLiteral(&b, c, p, &j); - AppendSlice(&b, c); - } - t->events.p[event].arg[arg].kind = AK_STR; - t->events.p[event].arg[arg].x = Intern(t, b.p, b.n); - } else if (*p == '[') { - ++p; - if (isdigit(*p)) { - t->events.p[event].arg[arg].kind = AK_INTPAIR; - t->events.p[event].arg[arg].x = strtol(p, &p, 0) & 0xffffffff; - CHECK_EQ(',', *p++, DEBUG); - CHECK_EQ(' ', *p++, DEBUG); - t->events.p[event].arg[arg].x |= strtol(p, &p, 0) << 32; - CHECK_EQ(']', *p++, DEBUG); - } else { - AppendStrlists(t); - for (j = 0;; ++j) { - if (*p == ']') { - ++p; - break; - } - if (*p == ',') ++p; - if (*p == ' ') ++p; - CHECK_EQ('"', *p, DEBUG); - bzero(&b, sizeof(b)); - for (k = 0; (c = p[++k]);) { - if (c == '"') { - p += k + 1; - break; - } - c = ReadCharLiteral(&b, c, p, &k); - AppendSlice(&b, c); - } - AppendStrlist(&t->strlists.p[t->strlists.n - 1]); - t->strlists.p[t->strlists.n - 1] - .p[t->strlists.p[t->strlists.n - 1].n - 1] = Intern(t, b.p, b.n); - } - t->events.p[event].arg[arg].kind = AK_STRLIST; - t->events.p[event].arg[arg].x = t->strlists.n - 1; - } - } else { - CHECK(false, DEBUG); - } - } -} - -static void PrintArg(FILE *f, struct Trace *t, long ev, long arg) { - long i, x; - x = t->events.p[ev].arg[arg].name; - if (x != -1) { - fprintf(f, "b%`'.*s:", t->slices.p[x].n, t->slices.p[x].p); - } - x = t->events.p[ev].arg[arg].x; - switch (t->events.p[ev].arg[arg].kind) { - case AK_LONG: - fprintf(f, "%ld", x); - break; - case AK_STR: - fprintf(f, "b%`'.*s", t->slices.p[x].n, t->slices.p[x].p); - break; - case AK_INTPAIR: - fprintf(f, "(%d,%d)", x >> 32, x); - break; - case AK_STRLIST: - fprintf(f, "("); - for (i = 0; i < t->strlists.p[x].n; ++i) { - fprintf(f, "b%`'.*s,", t->slices.p[t->strlists.p[x].p[i]].n, - t->slices.p[t->strlists.p[x].p[i]].p); - } - fprintf(f, ")"); - break; - default: - abort(); - } -} - -static void PrintEvent(FILE *f, struct Trace *t, long ev) { - long arg; - fprintf(f, "(%d,%ld,%d,%d,", t->events.p[ev].pid, - t->events.p[ev].sec * 1000000 + t->events.p[ev].us, - t->events.p[ev].elap, t->events.p[ev].kind); - switch (t->events.p[ev].kind) { - case EK_EXIT: - case EK_SIGNAL: - case EK_KILLED: - fprintf(f, "%d", t->events.p[ev].ret); - break; - case EK_CALL: - CHECK_LT(t->events.p[ev].syscall_, ARRAYLEN(kSyscalls)); - fprintf(f, "(b%`'s,%ld,", kSyscalls[t->events.p[ev].syscall_].name, - t->events.p[ev].ret); - fprintf(f, "%c", - t->events.p[ev].arity && t->events.p[ev].arg[0].name != -1 ? '{' - : '('); - for (arg = 0; arg < t->events.p[ev].arity; ++arg) { - PrintArg(f, t, ev, arg); - fprintf(f, ","); - } - fprintf(f, "%c)", - t->events.p[ev].arity && t->events.p[ev].arg[0].name != -1 ? '}' - : ')'); - break; - default: - break; - } - fprintf(f, ")"); -} - -static void AppendArg(char *arg) { - strace_args = realloc(strace_args, ++strace_args_len * sizeof(*strace_args)); - strace_args[strace_args_len - 1] = arg; -} - -static wontreturn void PrintUsage(FILE *f, int rc) { - fprintf(f, "Usage: %s [-o OUT] PROG [ARGS...]\n", program_invocation_name); - exit(rc); -} - -int main(int argc, char *argv[]) { - int i; - int ws; - int opt; - int pid; - long ev; - FILE *fin; - FILE *fout; - char *line; - long lineno; - char *strace; - int pipefds[2]; - struct Trace *t; - sigset_t block, mask; - struct sigaction ignore, saveint, savequit; - - /* - * parse prefix arguments - */ - fout = stderr; - while ((opt = getopt(argc, argv, "?ho:")) != -1) { - switch (opt) { - case 'o': - fout = fopen(optarg, "w"); - break; - case 'h': - case '?': - PrintUsage(stdout, EXIT_SUCCESS); - default: - PrintUsage(stderr, EX_USAGE); - } - } - if (optind == argc) { - PrintUsage(stderr, EX_USAGE); - } - - /* - * resolve full paths of dependencies - */ - if ((strace = commandvenv("STRACE", "strace"))) { - strace = strdup(strace); - } else { - fprintf(stderr, "error: please install strace\n"); - exit(1); - } - - /* - * create strace argument list - */ - AppendArg("strace"); - AppendArg("-q"); // don't log attach/detach noise - AppendArg("-v"); // don't abbreviate arrays - AppendArg("-f"); // follow subprocesses - AppendArg("-ttt"); // print unixseconds.micros - AppendArg("-X"); // print numbers instead of symbols - AppendArg("raw"); // e.g. 2 vs. O_RDWR - AppendArg("-s"); // don't abbreviate data - AppendArg("805306368"); // strace won't let us go higher - AppendArg("-e"); // system calls that matter - AppendArg( - "open,close,access,pipe,dup,dup2,socket,connect,accept,bind,listen," - "socketpair,fork,vfork,execve,clone,flock,fsync,fdatasync,truncate,chdir," - "rename,mkdir,rmdir,creat,link,unlink,symlink,readlink,chmod,chown,fcntl," - "lchown,mknod,mknodat,statfs,chroot,sync,epoll_create,openat,mkdirat," - "fchownat,unlinkat,renameat,linkat,symlinkat,readlinkat,fchmodat,fchdir," - "faccessat,utimensat,accept4,dup3,pipe2,epoll_create1,signalfd,signalfd4," - "eventfd,eventfd2,timerfd_create,syncfs,renameat2,memfd_create,execveat"); - CHECK_NE(-1, pipe(pipefds)); - AppendArg("-o"); - AppendArg(xasprintf("/dev/fd/%d", pipefds[1])); - for (i = optind; i < argc; ++i) { - AppendArg(argv[i]); - } - AppendArg(NULL); - - /* - * spawn strace - */ - ignore.sa_flags = 0; - ignore.sa_handler = SIG_IGN; - sigemptyset(&ignore.sa_mask); - sigaction(SIGINT, &ignore, &saveint); - sigaction(SIGQUIT, &ignore, &savequit); - sigfillset(&block); - sigprocmask(SIG_BLOCK, &block, &mask); - CHECK_NE(-1, (pid = vfork())); - if (!pid) { - close(pipefds[0]); - sigaction(SIGINT, &saveint, NULL); - sigaction(SIGQUIT, &savequit, NULL); - sigprocmask(SIG_SETMASK, &mask, NULL); - execv(strace, strace_args); - _exit(127); - } - close(pipefds[1]); - sigaddset(&mask, SIGCHLD); - sigprocmask(SIG_SETMASK, &mask, NULL); - - /* - * read output of strace until eof - */ - fin = fdopen(pipefds[0], "r"); - t = NewTrace(); - for (ev = 0, lineno = 1; !interrupted && (line = xgetline(fin)); ++lineno) { - _chomp(line); - Parse(t, line, lineno); - free(line); - for (; ev < t->events.n && !t->events.p[ev].is_interrupted; ++ev) { - PrintEvent(fout, t, ev); - fprintf(fout, "\n"); - } - } - FreeTrace(t); - CHECK_NE(-1, fclose(fout)); - - /* - * wait for strace to exit - */ - while (waitpid(pid, &ws, 0) == -1) { - CHECK_EQ(EINTR, errno); - } - CHECK_NE(-1, fclose(fin)); - - /* - * propagate exit - */ - if (WIFEXITED(ws)) { - return WEXITSTATUS(ws); - } else { - return 128 + WTERMSIG(ws); - } -} diff --git a/tool/build/pwd.c b/tool/build/pwd.c index 2b7f59f01..0841ec29e 100644 --- a/tool/build/pwd.c +++ b/tool/build/pwd.c @@ -17,21 +17,27 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" +#include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" +#include "libc/str/str.h" /** * @fileoverview Tool for printing current directory. */ -char path[PATH_MAX]; - int main(int argc, char *argv[]) { - char *p; - if ((p = getcwd(path, sizeof(path)))) { - fputs(p, stdout); - fputc('\n', stdout); - return 0; - } else { - return 1; + char path[PATH_MAX + 2]; + + if (!getcwd(path, PATH_MAX)) { + perror(argv[0]); + exit(1); } + + strcat(path, "\n"); + if (write(1, path, strlen(path)) == -1) { + perror("write"); + exit(1); + } + + return 0; } diff --git a/tool/build/refactor.c b/tool/build/refactor.c deleted file mode 100644 index 5a7b5f12a..000000000 --- a/tool/build/refactor.c +++ /dev/null @@ -1,134 +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/calls/calls.h" -#include "libc/calls/struct/dirent.h" -#include "libc/calls/struct/stat.h" -#include "libc/fmt/fmt.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/log/check.h" -#include "libc/mem/alg.h" -#include "libc/mem/gc.internal.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/dt.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/prot.h" -#include "libc/x/x.h" - -/** - * @fileoverview Pretty fast substring refactor tool. - */ - -static const char kBefore[] = "\ -│ Copyright 2020 Justine Alexandra Roberts Tunney │\n\ -│ │\n\ -│ This program is free software; you can redistribute it and/or modify │\n\ -│ it under the terms of the GNU General Public License as published by │\n\ -│ the Free Software Foundation; version 2 of the License. │\n\ -│ │\n\ -│ This program is distributed in the hope that it will be useful, but │\n\ -│ WITHOUT ANY WARRANTY; without even the implied warranty of │\n\ -│ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU │\n\ -│ General Public License for more details. │\n\ -│ │\n\ -│ You should have received a copy of the GNU General Public License │\n\ -│ along with this program; if not, write to the Free Software │\n\ -│ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA │\n\ -│ 02110-1301 USA │\n\ -"; -const char kAfter[] = "\ -│ Copyright 2020 Justine Alexandra Roberts Tunney │\n\ -│ │\n\ -│ Permission to use, copy, modify, and/or distribute this software for │\n\ -│ any purpose with or without fee is hereby granted, provided that the │\n\ -│ above copyright notice and this permission notice appear in all copies. │\n\ -│ │\n\ -│ THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL │\n\ -│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │\n\ -│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │\n\ -│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │\n\ -│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │\n\ -│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │\n\ -│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │\n\ -│ PERFORMANCE OF THIS SOFTWARE. │\n\ -"; - -#if 0 -static const char kBefore[] = "\ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│"; -const char kAfter[] = "\ -/*-*- mode:unix-assembly; indent-tabs-mode:t; tab-width:8; coding:utf-8 -*-│"; -#endif - -void RefactorFile(const char *path) { - int fd; - struct stat st; - size_t len, partlen, len1, len2; - char *mem, *spot = NULL, *part1, *part2; - CHECK_NE(-1, (fd = open(path, O_RDONLY))); - CHECK_NE(-1, fstat(fd, &st)); - len2 = 0; - if ((len = st.st_size)) { - CHECK_NE(MAP_FAILED, - (mem = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0))); - partlen = sizeof(kBefore) - 1; - if ((spot = memmem(mem, len, kBefore, partlen))) { - part1 = gc(xmalloc((len1 = spot - mem))); - part2 = gc(xmalloc((len2 = len - partlen - (spot - mem)))); - memcpy(part1, mem, len1); - memcpy(part2, spot + partlen, len2); - } - CHECK_NE(-1, munmap(mem, len)); - } - CHECK_NE(-1, close(fd)); - if (spot) { - fprintf(stderr, "found! %s\n", path); - CHECK_NE(-1, (fd = open(path, O_RDWR | O_TRUNC))); - CHECK_EQ(len1, write(fd, part1, len1)); - CHECK_EQ(sizeof(kAfter) - 1, write(fd, kAfter, sizeof(kAfter) - 1)); - CHECK_EQ(len2, write(fd, part2, len2)); - CHECK_NE(-1, close(fd)); - } -} - -void RefactorDir(const char *dpath) { - DIR *dir; - struct dirent *ent; - char *path = gc(xmalloc(4096)); - CHECK_NOTNULL(dir = opendir(firstnonnull(dpath, "."))); - while ((ent = readdir(dir))) { - if (_startswith(ent->d_name, ".")) continue; - if (strcmp(ent->d_name, "o") == 0) continue; - snprintf(path, 4096, "%s%s%s", dpath ? dpath : "", dpath ? "/" : "", - ent->d_name); - if (isdirectory(path)) { - RefactorDir(path); - } else if (isregularfile(path)) { - RefactorFile(path); - } - } - CHECK_NE(-1, closedir(dir)); -} - -int main(int argc, char *argv[]) { - RefactorDir(NULL); - return 0; -} diff --git a/tool/build/rle.c b/tool/build/rle.c deleted file mode 100644 index 1d4afa547..000000000 --- a/tool/build/rle.c +++ /dev/null @@ -1,251 +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/calls/calls.h" -#include "libc/dce.h" -#include "libc/errno.h" -#include "libc/fmt/fmt.h" -#include "libc/log/check.h" -#include "libc/macros.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "libc/sysv/errfuns.h" -#include "third_party/getopt/getopt.internal.h" - -#define USAGE1 \ - "NAME\n\ -\n\ - rle - Run Length Encoder\n\ -\n\ -SYNOPSIS\n\ -\n\ - " - -#define USAGE2 \ - " [FLAGS] [FILE...]\n\ -\n\ -DESCRIPTION\n\ -\n\ - This is a primitive compression algorithm. Its advantage is that\n\ - the concomitant rldecode() library is seventeen bytes, and works\n\ - on IA-16, IA-32, and NexGen32e without needing to be recompiled.\n\ -\n\ - This CLI is consistent with gzip, bzip2, lzma, etc.\n\ -\n\ -FLAGS\n\ -\n\ - -1 .. -9 ignored\n\ - -a ignored\n\ - -c send to stdout\n\ - -d decompress\n\ - -f ignored\n\ - -t test integrity\n\ - -S SUFFIX overrides .rle extension\n\ - -h shows this information\n" - -FILE *fin_, *fout_; -bool decompress_, test_; -const char *suffix_, *hint_; - -void StartErrorMessage(void) { - fputs("error: ", stderr); - fputs(hint_, stderr); - fputs(": ", stderr); -} - -void PrintIoErrorMessage(void) { - int err; - err = errno; - StartErrorMessage(); - fputs(strerror(err), stderr); - fputc('\n', stderr); -} - -void PrintUsage(int rc, FILE *f) { - fputs(USAGE1, f); - fputs(program_invocation_name, f); - fputs(USAGE2, f); - exit(rc); -} - -void GetOpts(int argc, char *argv[]) { - int opt; - fin_ = stdin; - suffix_ = ".rle"; - while ((opt = getopt(argc, argv, "123456789S:acdfho:t")) != -1) { - switch (opt) { - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'a': - case 'f': - break; - case 'c': - fout_ = stdout; - break; - case 'd': - decompress_ = true; - break; - case 't': - test_ = true; - break; - case 'o': - fclose(fout_); - if (!(fout_ = fopen((hint_ = optarg), "w"))) { - PrintIoErrorMessage(); - exit(1); - } - break; - case 'S': - suffix_ = optarg; - break; - case 'h': - case '?': - PrintUsage(EXIT_SUCCESS, stdout); - default: - PrintUsage(EX_USAGE, stderr); - } - } -} - -int RunLengthEncode1(void) { - int byte1, byte2, runlength; - byte2 = -1; - runlength = 0; - if ((byte1 = fgetc(fin_)) == -1) return -1; - do { - while (++runlength < 255) { - if ((byte2 = fgetc(fin_)) != byte1) break; - } - if (fputc(runlength, fout_) == -1 || fputc(byte1, fout_) == -1) { - return -1; - } - runlength = 0; - } while ((byte1 = byte2) != -1); - return feof(fin_) ? 0 : -1; -} - -int RunLengthEncode2(void) { - return fputc(0, fout_) | fputc(0, fout_); -} - -int EmitRun(unsigned char count, unsigned char byte) { - do { - if (fputc(byte, fout_) == -1) return -1; - } while (--count); - return 0; -} - -int RunLengthDecode(void) { - int byte1, byte2; - if ((byte1 = fgetc(fin_)) == -1) return einval(); - if ((byte2 = fgetc(fin_)) == -1) return einval(); - while (byte1) { - if (!test_ && EmitRun(byte1, byte2) == -1) return -1; - if ((byte1 = fgetc(fin_)) == -1) break; - if ((byte2 = fgetc(fin_)) == -1) return einval(); - } - if (byte1 != 0 || byte2 != 0) return einval(); - fgetc(fin_); - return feof(fin_) ? 0 : -1; -} - -int RunLengthCode(void) { - if (test_ || decompress_) { - return RunLengthDecode(); - } else { - return RunLengthEncode1(); - } -} - -int Run(char **paths, size_t count) { - int rc; - char *p; - size_t i, suffixlen; - const char pathbuf[PATH_MAX]; - if (!count) { - hint_ = "/dev/stdin"; - if (!fout_) fout_ = stdout; - rc = RunLengthCode(); - rc |= fclose(fin_); - fin_ = 0; - } else { - rc = fclose(fin_); - fin_ = 0; - for (i = 0; i < count && rc != -1; ++i) { - rc = -1; - if ((fin_ = fopen((hint_ = paths[i]), "r"))) { - if (test_ || fout_) { - rc = RunLengthCode(); - } else { - suffixlen = strlen(suffix_); - if (!IsTrustworthy() && - strlen(paths[i]) + suffixlen >= ARRAYLEN(pathbuf)) { - return eoverflow(); - } - p = stpcpy(pathbuf, paths[i]); - if (!decompress_) { - strcpy(p, suffix_); - } else if (p - pathbuf > suffixlen && - memcmp(p - suffixlen, suffix_, suffixlen) == 0) { - p[-suffixlen] = '\0'; - } else { - return enotsup(); - } - if ((fout_ = fopen((hint_ = pathbuf), "w"))) { - rc = RunLengthCode(); - if (rc != -1 && !decompress_) { - rc = RunLengthEncode2(); - } - if ((rc |= fclose(fout_)) != -1) { - unlink(paths[i]); - } - fout_ = 0; - } - } - rc |= fclose(fin_); - fin_ = 0; - } - } - } - if (rc != -1 && fout_) { - rc = RunLengthEncode2(); - rc |= fclose(fout_); - fout_ = 0; - } - return rc; -} - -int main(int argc, char *argv[]) { - GetOpts(argc, argv); - if (Run(argv + optind, argc - optind) != -1) { - return EXIT_SUCCESS; - } else { - PrintIoErrorMessage(); - return EXIT_FAILURE; - } -} diff --git a/tool/build/rm.c b/tool/build/rm.c index 8c2e7aaa0..d374e277f 100644 --- a/tool/build/rm.c +++ b/tool/build/rm.c @@ -22,8 +22,6 @@ #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" #include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" #include "libc/sysv/consts/ok.h" #include "third_party/getopt/getopt.internal.h" @@ -36,63 +34,53 @@ SYNOPSIS\n\ \n\ FLAGS\n\ \n\ - -?\n\ -h help\n\ -f force\n\ \n" -bool force; -const char *prog; +static bool force; +static const char *prog; -wontreturn void PrintUsage(int rc, FILE *f) { - fputs("usage: ", f); - fputs(prog, f); - fputs(USAGE, f); +static wontreturn void PrintUsage(int rc, int fd) { + tinyprint(fd, "USAGE\n\n ", prog, USAGE, NULL); exit(rc); } -void GetOpts(int argc, char *argv[]) { +static void GetOpts(int argc, char *argv[]) { int opt; - while ((opt = getopt(argc, argv, "?hf")) != -1) { + while ((opt = getopt(argc, argv, "hf")) != -1) { switch (opt) { case 'f': force = true; break; case 'h': - case '?': - PrintUsage(EXIT_SUCCESS, stdout); + PrintUsage(0, 1); default: - PrintUsage(EX_USAGE, stderr); + PrintUsage(1, 2); } } } -void Remove(const char *path) { - const char *s; - if (!force && access(path, W_OK) == -1) goto OnFail; - if (unlink(path) == -1) goto OnFail; - return; -OnFail: - if (force && errno == ENOENT) return; - s = _strerdoc(errno); - fputs(prog, stderr); - fputs(": cannot remove '", stderr); - fputs(path, stderr); - fputs("': ", stderr); - fputs(s, stderr); - fputs("\n", stderr); - exit(1); +static void Remove(const char *path) { + if (!force && access(path, W_OK) == -1) { + perror(path); + exit(1); + } + if (unlink(path) == -1) { + if (force && errno == ENOENT) return; + perror(path); + exit(1); + } } int main(int argc, char *argv[]) { int i; - prog = argc > 0 ? argv[0] : "rm.com"; + + prog = argv[0]; + if (!prog) prog = "rm"; if (argc < 2) { - fputs(prog, stderr); - fputs(": missing operand\n" - "Try 'rm -h' for more information.\n", - stderr); + tinyprint(2, prog, ": missing operand\n", NULL); exit(1); } diff --git a/tool/build/sha256sum.c b/tool/build/sha256sum.c index 0ad9f5651..806b9221b 100644 --- a/tool/build/sha256sum.c +++ b/tool/build/sha256sum.c @@ -28,17 +28,15 @@ #include "third_party/getopt/getopt.internal.h" #include "third_party/mbedtls/sha256.h" -#define PROG "sha256sum" #define USAGE \ - "\ -Usage: " PROG " [-?hbctw] [PATH...]\n\ + "[-?hbctw] [PATH...]\n\ -h help\n\ -c check mode\n\ -b binary mode\n\ -t textual mode\n\ -w warning mode\n\ \n\ -cosmopolitan " PROG " v1.0\n\ +cosmopolitan sha256sum v1.1\n\ copyright 2022 justine alexandra roberts tunney\n\ notice licenses are embedded in the binary\n\ https://twitter.com/justinetunney\n\ @@ -56,11 +54,17 @@ static bool g_warn; static char g_mode; static bool g_check; static int g_mismatches; +static const char *prog; + +static wontreturn void PrintUsage(int rc, int fd) { + tinyprint(fd, "Usage: ", prog, USAGE, NULL); + exit(rc); +} static void GetOpts(int argc, char *argv[]) { int opt; g_mode = ' '; - while ((opt = getopt(argc, argv, "?hbctw")) != -1) { + while ((opt = getopt(argc, argv, "hbctw")) != -1) { switch (opt) { case 'w': g_warn = true; @@ -75,28 +79,13 @@ static void GetOpts(int argc, char *argv[]) { g_mode = '*'; break; case 'h': - case '?': - write(1, USAGE, sizeof(USAGE) - 1); - exit(0); + PrintUsage(0, 1); default: - write(2, USAGE, sizeof(USAGE) - 1); - exit(64); + PrintUsage(1, 2); } } } -static ssize_t Write(int fd, const char *s, ...) { - va_list va; - char buf[512]; - buf[0] = 0; - va_start(va, s); - do { - strlcat(buf, s, sizeof(buf)); - } while ((s = va_arg(va, const char *))); - va_end(va); - return write(fd, buf, strlen(buf)); -} - static bool IsModeCharacter(char c) { switch (c) { case ' ': @@ -117,7 +106,7 @@ static bool IsSupportedPath(const char *path) { case '\r': case '\n': case '\\': - Write(2, PROG, ": ", path, ": unsupported path\n", NULL); + tinyprint(2, prog, ": ", path, ": unsupported path\n", NULL); return false; default: break; @@ -135,7 +124,7 @@ static bool GetDigest(const char *path, FILE *f, unsigned char digest[32]) { _unassert(!mbedtls_sha256_update_ret(&ctx, buf, got)); } if (ferror(f)) { - Write(2, PROG, ": ", path, ": ", _strerdoc(errno), "\n", NULL); + tinyprint(2, prog, ": ", path, ": ", strerror(errno), "\n", NULL); return false; } _unassert(!mbedtls_sha256_finish_ret(&ctx, digest)); @@ -150,7 +139,7 @@ static bool ProduceDigest(const char *path, FILE *f) { if (!IsSupportedPath(path)) return false; if (!GetDigest(path, f, digest)) return false; hexpcpy(hexdigest, digest, 32); - Write(1, hexdigest, " ", mode, path, "\n", NULL); + tinyprint(1, hexdigest, " ", mode, path, "\n", NULL); return true; } @@ -182,13 +171,13 @@ static bool CheckDigests(const char *path, FILE *f) { ++g_mismatches; k = false; } - Write(1, path2, ": ", status, "\n", NULL); + tinyprint(1, path2, ": ", status, "\n", NULL); } else { k = false; } fclose(f2); } else { - Write(2, PROG, ": ", path2, ": ", _strerdoc(errno), "\n", NULL); + tinyprint(2, prog, ": ", path2, ": ", strerror(errno), "\n", NULL); k = false; } continue; @@ -196,12 +185,12 @@ static bool CheckDigests(const char *path, FILE *f) { if (g_warn) { char linestr[12]; FormatInt32(linestr, line + 1); - Write(2, PROG, ": ", path, ":", linestr, ": ", - "improperly formatted checksum line", "\n", NULL); + tinyprint(2, prog, ": ", path, ":", linestr, ": ", + "improperly formatted checksum line", "\n", NULL); } } if (ferror(f)) { - Write(2, PROG, ": ", path, ": ", _strerdoc(errno), "\n", NULL); + tinyprint(2, prog, ": ", path, ": ", strerror(errno), "\n", NULL); k = false; } return k; @@ -219,6 +208,8 @@ int main(int argc, char *argv[]) { int i; FILE *f; bool k = true; + prog = argv[0]; + if (!prog) prog = "sha256sum"; GetOpts(argc, argv); if (optind == argc) { f = stdin; @@ -229,7 +220,7 @@ int main(int argc, char *argv[]) { k &= Process(argv[i], f); fclose(f); } else { - Write(2, PROG, ": ", argv[i], ": ", _strerdoc(errno), "\n", NULL); + tinyprint(2, prog, ": ", argv[i], ": ", strerror(errno), "\n", NULL); k = false; } } @@ -237,8 +228,8 @@ int main(int argc, char *argv[]) { if (g_mismatches) { char ibuf[12]; FormatInt32(ibuf, g_mismatches); - Write(2, PROG, ": WARNING: ", ibuf, " computed checksum did NOT match\n", - NULL); + tinyprint(2, prog, ": WARNING: ", ibuf, + " computed checksum did NOT match\n", NULL); } return !k; } diff --git a/tool/build/touch.c b/tool/build/touch.c index 24967a5fb..75948dd04 100644 --- a/tool/build/touch.c +++ b/tool/build/touch.c @@ -17,31 +17,31 @@ │ PERFORMANCE OF THIS SOFTWARE. │ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/calls/calls.h" -#include "libc/errno.h" -#include "libc/fmt/magnumstrs.internal.h" #include "libc/runtime/runtime.h" #include "libc/stdio/stdio.h" -#include "libc/str/str.h" /** - * @fileoverview Command for updating timestamps on files. + * @fileoverview file timestamp update command */ int main(int argc, char *argv[]) { int i; - const char *s, *prog; - prog = argc > 0 ? argv[0] : "touch.com"; + const char *prog; + + prog = argv[0]; + if (!prog) prog = "touch"; + + if (argc < 2) { + tinyprint(2, prog, ": missing operand\n", NULL); + exit(1); + } + for (i = 1; i < argc; ++i) { if (touch(argv[i], 0666) == -1) { - s = _strerdoc(errno); - fputs(prog, stderr); - fputs(": cannot touch '", stderr); - fputs(argv[i], stderr); - fputs("': ", stderr); - fputs(s, stderr); - fputs("\n", stderr); + perror(argv[i]); exit(1); } } + return 0; } diff --git a/tool/build/unbundle.c b/tool/build/unbundle.c index 8b9c2800d..936e3eacc 100644 --- a/tool/build/unbundle.c +++ b/tool/build/unbundle.c @@ -74,7 +74,8 @@ int Visit(const char *fpath, const struct stat *sb, int tflag, int main(int argc, char *argv[]) { if (!IsLinux()) return 0; - prog = argc > 0 ? argv[0] : "unbundle.com"; + prog = argv[0]; + if (!prog) prog = "unbundle"; if (IsDirectory("o/third_party/gcc")) return 0; makedirs("o/third_party", 0755); FormatInt32(stpcpy(tmpdir, "o/third_party/gcc."), getpid()); diff --git a/tool/build/xlat.c b/tool/build/xlat.c deleted file mode 100644 index 9a6655886..000000000 --- a/tool/build/xlat.c +++ /dev/null @@ -1,330 +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/assert.h" -#include "libc/calls/calls.h" -#include "libc/fmt/conv.h" -#include "libc/log/check.h" -#include "libc/math.h" -#include "libc/mem/gc.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/str/tab.internal.h" -#include "libc/x/xasprintf.h" - -/** - * @fileoverview Tool for generating rldecode'd character sets, e.g. - * - * # generate http token table - * o//tool/build/xlat.com -TiC ' ()<>@,;:\"/[]?={}' -i - */ - -int dig; -int xlat[256]; -bool identity; -const char *symbol; - -static int Bing(int c) { - if (!c) return L'∅'; - if (c == ' ') return L'␠'; - if (c == '$') return L'§'; - if (c == '\\') return L'⭝'; - return kCp437[c & 255]; -} - -static void Fill(int f(int)) { - int i; - for (i = 0; i < 256; ++i) { - if (f(i)) { - xlat[i] = identity ? i : 1; - } - } -} - -static void Invert(void) { - int i; - for (i = 0; i < 256; ++i) { - xlat[i] = !xlat[i]; - } -} - -static void Negate(void) { - int i; - for (i = 0; i < 256; ++i) { - xlat[i] = ~xlat[i] & 255; - } -} - -static void Negative(void) { - int i; - for (i = 0; i < 256; ++i) { - xlat[i] = -xlat[i] & 255; - } -} - -static bool ArgNeedsShellQuotes(const char *s) { - if (*s) { - for (;;) { - switch (*s++ & 255) { - case 0: - return false; - case '-': - case '.': - case '/': - case '_': - case '=': - case ':': - case '0' ... '9': - case 'A' ... 'Z': - case 'a' ... 'z': - break; - default: - return true; - } - } - } else { - return true; - } -} - -static char *AddShellQuotes(const char *s) { - char *p, *q; - size_t i, j, n; - n = strlen(s); - p = malloc(1 + n * 5 + 1 + 1); - j = 0; - p[j++] = '\''; - for (i = 0; i < n; ++i) { - if (s[i] != '\'') { - p[j++] = s[i]; - } else { - p[j + 0] = '\''; - p[j + 1] = '"'; - p[j + 2] = '\''; - p[j + 3] = '"'; - p[j + 4] = '\''; - j += 5; - } - } - p[j++] = '\''; - p[j] = 0; - if ((q = realloc(p, j + 1))) p = q; - return p; -} - -static const char *GetArg(char *argv[], int i, int *k) { - if (argv[*k][i + 1]) { - return argv[*k] + i + 1; - } else { - return argv[++*k]; - } -} - -int main(int argc, char *argv[]) { - const char *arg; - int i, j, k, opt; - dig = 1; - symbol = "kXlatTab"; - - for (k = 1; k < argc; ++k) { - if (argv[k][0] != '-') { - for (i = 0; argv[k][i]; ++i) { - /* xlat[argv[k][i] & 255] = identity ? i : dig; */ - xlat[argv[k][i] & 255] = identity ? (argv[k][i] & 255) : dig; - } - } else { - i = 0; - moar: - ++i; - if ((opt = argv[k][i])) { - switch (opt) { - case 's': - symbol = GetArg(argv, i, &k); - break; - case 'x': - dig = atoi(GetArg(argv, i, &k)) & 255; - break; - case 'i': - Invert(); - goto moar; - case 'I': - identity = !identity; - goto moar; - case 'n': - Negative(); - goto moar; - case 'N': - Negate(); - goto moar; - case 'T': - Fill(isascii); - goto moar; - case 'C': - Fill(iscntrl); - goto moar; - case 'A': - Fill(isalpha); - goto moar; - case 'B': - Fill(isblank); - goto moar; - case 'G': - Fill(isgraph); - goto moar; - case 'P': - Fill(ispunct); - goto moar; - case 'D': - Fill(isdigit); - goto moar; - case 'U': - Fill(isupper); - goto moar; - case 'L': - Fill(islower); - goto moar; - default: - fprintf(stderr, "error: unrecognized option: %c\n", opt); - return 1; - } - } - } - } - - //////////////////////////////////////////////////////////// - printf("#include \"libc/macros.internal.h\"\n"); - printf("\n"); - - printf("//\tgenerated by:\n"); - printf("//\t"); - for (i = 0; i < argc; ++i) { - if (i) printf(" "); - printf("%s", !ArgNeedsShellQuotes(argv[i]) ? argv[i] - : _gc(AddShellQuotes(argv[i]))); - } - printf("\n"); - - //////////////////////////////////////////////////////////// - printf("//\n"); - printf("//\t present absent\n"); - printf("//\t ──────────────── ────────────────\n"); - for (i = 0; i < 16; ++i) { - char16_t absent[16]; - char16_t present[16]; - for (j = 0; j < 16; ++j) { - if (xlat[i * 16 + j]) { - absent[j] = L' '; - present[j] = Bing(i * 16 + j); - } else { - absent[j] = Bing(i * 16 + j); - present[j] = L' '; - } - } - printf("//\t %.16hs %.16hs 0x%02x\n", present, absent, i * 16); - } - - //////////////////////////////////////////////////////////// - printf("//\n"); - printf("//\tconst char %s[256] = {\n//\t", symbol); - for (i = 0; i < 16; ++i) { - printf(" "); - for (j = 0; j < 16; ++j) { - printf("%2d,", (char)xlat[i * 16 + j]); - } - printf(" // 0x%02x\n//\t", i * 16); - } - printf("};\n"); - printf("\n"); - - //////////////////////////////////////////////////////////// - printf("\t.initbss 300,_init_%s\n", symbol); - printf("%s:\n", symbol); - printf("\t.zero\t256\n"); - printf("\t.endobj\t%s,globl\n", symbol); - printf("\t.previous\n"); - printf("\n"); - - //////////////////////////////////////////////////////////// - printf("\t.initro 300,_init_%s\n", symbol); - printf("%s.rom:\n", symbol); - - int thebloat = 0; - int thetally = 0; - int thecount = 0; - int runstart = 0; - int runchar = -1; - int runcount = 0; - for (i = 0;; ++i) { - if (i < 256 && xlat[i] == runchar) { - ++runcount; - } else { - if (runcount) { - printf("\t.byte\t%-24s# %02x-%02x %hc-%hc\n", - _gc(xasprintf("%3d,%d", runcount, runchar)), runstart, - runstart + runcount - 1, Bing(runstart), - Bing(runstart + runcount - 1)); - thetally += 2; - thecount += runcount; - } - if (i < 256) { - runcount = 1; - runchar = xlat[i]; - runstart = i; - } - } - if (i == 256) { - break; - } - } - CHECK_EQ(256, thecount); - printf("\t.byte\t%-24s# terminator\n", "0,0"); - thetally += 2; - thebloat = thetally; - for (i = 0; (thetally + i) % 8; i += 2) { - printf("\t.byte\t%-24s# padding\n", "0,0"); - thebloat += 2; - } - - printf("\t.endobj\t%s.rom,globl\n", symbol); - printf("\n"); - - //////////////////////////////////////////////////////////// - printf("\t.init.start 300,_init_%s\n", symbol); - printf("\tcall\trldecode\n"); - thebloat += 5; - int padding = 8 - thetally % 8; - if (padding < 8) { - if (padding >= 4) { - thebloat += 1; - printf("\tlodsl\n"); - padding -= 4; - } - if (padding >= 2) { - thebloat += 2; - printf("\tlodsw\n"); - } - } - printf("\t.init.end 300,_init_%s\n", symbol); - - //////////////////////////////////////////////////////////// - printf("\n"); - printf("//\t%d bytes total (%d%% original size)\n", thebloat, - (int)round((double)thebloat / 256 * 100)); -} diff --git a/tool/build/zipcopy.c b/tool/build/zipcopy.c index d7c6c50c4..302215546 100644 --- a/tool/build/zipcopy.c +++ b/tool/build/zipcopy.c @@ -38,32 +38,20 @@ static const char *inpath; static const char *outpath; static unsigned char *inmap; -nullterminated() static void Print(int fd, const char *s, ...) { - va_list va; - char buf[2048]; - va_start(va, s); - buf[0] = 0; - do { - strlcat(buf, s, sizeof(buf)); - } while ((s = va_arg(va, const char *))); - write(fd, buf, strlen(buf)); - va_end(va); -} - static wontreturn void Die(const char *path, const char *reason) { - Print(2, path, ": ", reason, "\n", NULL); + tinyprint(2, path, ": ", reason, "\n", NULL); exit(1); } -static wontreturn void SysExit(const char *path, const char *func) { +static wontreturn void SysDie(const char *path, const char *func) { const char *errstr; if (!(errstr = _strerdoc(errno))) errstr = "EUNKNOWN"; - Print(2, path, ": ", func, " failed with ", errstr, "\n", NULL); + tinyprint(2, path, ": ", func, " failed with ", errstr, "\n", NULL); exit(1); } static wontreturn void PrintUsage(int fd, int exitcode) { - Print(fd, "\ + tinyprint(fd, "\ NAME\n\ \n\ Cosmopolitan Zip Copier\n\ @@ -71,7 +59,7 @@ NAME\n\ SYNOPSIS\n\ \n\ ", - program_invocation_name, " [FLAGS] SRC DST\n\ + program_invocation_name, " [FLAGS] SRC DST\n\ \n\ DESCRIPTION\n\ \n\ @@ -96,7 +84,7 @@ EXAMPLE\n\ \n\ \n\ ", - NULL); + NULL); exit(exitcode); } @@ -173,10 +161,10 @@ static void CopyZip(void) { // write output if ((outfd = open(outpath, O_WRONLY | O_CREAT, 0644)) == -1) { - SysExit(outpath, "open"); + SysDie(outpath, "open"); } if ((outsize = lseek(outfd, 0, SEEK_END)) == -1) { - SysExit(outpath, "lseek"); + SysDie(outpath, "lseek"); } ldest = outsize; cdest = outsize + ltotal; @@ -186,23 +174,23 @@ static void CopyZip(void) { // write local file length = ZIP_LFILE_SIZE(lfile); if (pwrite(outfd, lfile, length, ldest) != length) { - SysExit(outpath, "lfile pwrite"); + SysDie(outpath, "lfile pwrite"); } ldest += length; // write directory entry length = ZIP_CFILE_HDRSIZE(cfile); if (pwrite(outfd, cfile, length, cdest) != length) { - SysExit(outpath, "lfile pwrite"); + SysDie(outpath, "lfile pwrite"); } cdest += length; } WRITE32LE(eocd + kZipCdirOffsetOffset, outsize + ltotal); length = ZIP_CDIR_HDRSIZE(eocd); if (pwrite(outfd, eocd, length, cdest) != length) { - SysExit(outpath, "eocd pwrite"); + SysDie(outpath, "eocd pwrite"); } if (close(outfd)) { - SysExit(outpath, "close"); + SysDie(outpath, "close"); } } @@ -213,23 +201,23 @@ int main(int argc, char *argv[]) { } GetOpts(argc, argv); if ((infd = open(inpath, O_RDONLY)) == -1) { - SysExit(inpath, "open"); + SysDie(inpath, "open"); } if ((insize = lseek(infd, 0, SEEK_END)) == -1) { - SysExit(inpath, "lseek"); + SysDie(inpath, "lseek"); } if (!insize) { Die(inpath, "file is empty"); } if ((inmap = mmap(0, insize, PROT_READ | PROT_WRITE, MAP_PRIVATE, infd, 0)) == MAP_FAILED) { - SysExit(inpath, "mmap"); + SysDie(inpath, "mmap"); } CopyZip(); if (munmap(inmap, insize)) { - SysExit(inpath, "munmap"); + SysDie(inpath, "munmap"); } if (close(infd)) { - SysExit(inpath, "close"); + SysDie(inpath, "close"); } } diff --git a/tool/build/zipobj.c b/tool/build/zipobj.c index 9ff355e36..cb91014e5 100644 --- a/tool/build/zipobj.c +++ b/tool/build/zipobj.c @@ -21,7 +21,6 @@ #include "libc/elf/def.h" #include "libc/fmt/conv.h" #include "libc/fmt/libgen.h" -#include "libc/intrin/kprintf.h" #include "libc/limits.h" #include "libc/log/check.h" #include "libc/log/log.h" @@ -52,15 +51,16 @@ int strip_components_; const char *path_prefix_; struct timespec timestamp; -wontreturn void PrintUsage(int rc) { - kprintf("\n\ +wontreturn void PrintUsage(int fd, int rc) { + tinyprint(fd, "\n\ NAME\n\ \n\ Cosmpolitan Zip File Compiler\n\ \n\ SYNOPSIS\n\ \n\ - %s [FLAGS] FILE...\n\ + ", + program_invocation_name, " [FLAGS] FILE...\n\ \n\ DESCRIPTION\n\ \n\ @@ -80,7 +80,7 @@ FLAGS\n\ -y SYMBOL generate yoink for symbol (default __zip_eocd)\n\ \n\ ", - program_invocation_name); + NULL); exit(rc); } @@ -117,17 +117,18 @@ void GetOpts(int *argc, char ***argv) { break; case '?': case 'h': - PrintUsage(EXIT_SUCCESS); + PrintUsage(1, EXIT_SUCCESS); default: - PrintUsage(EX_USAGE); + PrintUsage(2, EX_USAGE); } } *argc -= optind; *argv += optind; if (!outpath_) { - kprintf("error: no output path specified\n" - "run %s -h for usage\n", - program_invocation_name); + tinyprint(2, + "error: no output path specified\n" + "run ", + program_invocation_name, " -h for usage\n", NULL); exit(1); } } diff --git a/tool/decode/peboff.c b/tool/decode/peboff.c deleted file mode 100644 index 94f28bae4..000000000 --- a/tool/decode/peboff.c +++ /dev/null @@ -1,101 +0,0 @@ -#include "libc/nt/struct/peb.h" -#include "libc/stdio/stdio.h" - -int main() { - printf("InheritedAddressSpace = 0x%x\n", - offsetof(struct NtPeb, InheritedAddressSpace)); - printf("ReadImageFileExecOptions = 0x%x\n", - offsetof(struct NtPeb, ReadImageFileExecOptions)); - printf("BeingDebugged = 0x%x\n", offsetof(struct NtPeb, BeingDebugged)); - printf("Mutant = 0x%x\n", offsetof(struct NtPeb, Mutant)); - printf("ImageBaseAddress = 0x%x\n", offsetof(struct NtPeb, ImageBaseAddress)); - printf("Ldr = 0x%x\n", offsetof(struct NtPeb, Ldr)); - printf("ProcessParameters = 0x%x\n", - offsetof(struct NtPeb, ProcessParameters)); - printf("SubSystemData = 0x%x\n", offsetof(struct NtPeb, SubSystemData)); - printf("ProcessHeap = 0x%x\n", offsetof(struct NtPeb, ProcessHeap)); - printf("FastPebLock = 0x%x\n", offsetof(struct NtPeb, FastPebLock)); - printf("KernelCallbackTable = 0x%x\n", - offsetof(struct NtPeb, KernelCallbackTable)); - printf("UserSharedInfoPtr = 0x%x\n", - offsetof(struct NtPeb, UserSharedInfoPtr)); - printf("SystemReserved = 0x%x\n", offsetof(struct NtPeb, SystemReserved)); - printf("__wut6 = 0x%x\n", offsetof(struct NtPeb, __wut6)); - printf("__wut7 = 0x%x\n", offsetof(struct NtPeb, __wut7)); - printf("TlsExpansionCounter = 0x%x\n", - offsetof(struct NtPeb, TlsExpansionCounter)); - printf("TlsBitmap = 0x%x\n", offsetof(struct NtPeb, TlsBitmap)); - printf("TlsBitmapBits = 0x%x\n", offsetof(struct NtPeb, TlsBitmapBits)); - printf("ReadOnlySharedMemoryBase = 0x%x\n", - offsetof(struct NtPeb, ReadOnlySharedMemoryBase)); - printf("ReadOnlyStaticServerData = 0x%x\n", - offsetof(struct NtPeb, ReadOnlyStaticServerData)); - printf("AnsiCodePageData = 0x%x\n", offsetof(struct NtPeb, AnsiCodePageData)); - printf("OemCodePageData = 0x%x\n", offsetof(struct NtPeb, OemCodePageData)); - printf("UnicodeCaseTableData = 0x%x\n", - offsetof(struct NtPeb, UnicodeCaseTableData)); - printf("NumberOfProcessors = 0x%x\n", - offsetof(struct NtPeb, NumberOfProcessors)); - printf("NtGlobalFlag = 0x%x\n", offsetof(struct NtPeb, NtGlobalFlag)); - printf("CriticalSectionTimeout = 0x%x\n", - offsetof(struct NtPeb, CriticalSectionTimeout)); - printf("HeapSegmentReserve = 0x%x\n", - offsetof(struct NtPeb, HeapSegmentReserve)); - printf("HeapSegmentCommit = 0x%x\n", - offsetof(struct NtPeb, HeapSegmentCommit)); - printf("HeapDeCommitTotalFreeThreshold = 0x%x\n", - offsetof(struct NtPeb, HeapDeCommitTotalFreeThreshold)); - printf("HeapDeCommitFreeBlockThreshold = 0x%x\n", - offsetof(struct NtPeb, HeapDeCommitFreeBlockThreshold)); - printf("NumberOfHeaps = 0x%x\n", offsetof(struct NtPeb, NumberOfHeaps)); - printf("MaximumNumberOfHeaps = 0x%x\n", - offsetof(struct NtPeb, MaximumNumberOfHeaps)); - printf("ProcessHeaps = 0x%x\n", offsetof(struct NtPeb, ProcessHeaps)); - printf("GdiSharedHandleTable = 0x%x\n", - offsetof(struct NtPeb, GdiSharedHandleTable)); - printf("ProcessStarterHelper = 0x%x\n", - offsetof(struct NtPeb, ProcessStarterHelper)); - printf("GdiDCAttributeList = 0x%x\n", - offsetof(struct NtPeb, GdiDCAttributeList)); - printf("LoaderLock = 0x%x\n", offsetof(struct NtPeb, LoaderLock)); - printf("OSMajorVersion = 0x%x\n", offsetof(struct NtPeb, OSMajorVersion)); - printf("OSMinorVersion = 0x%x\n", offsetof(struct NtPeb, OSMinorVersion)); - printf("OSVersion = 0x%x\n", offsetof(struct NtPeb, OSVersion)); - printf("OSBuildNumber = 0x%x\n", offsetof(struct NtPeb, OSBuildNumber)); - printf("OSCSDVersion = 0x%x\n", offsetof(struct NtPeb, OSCSDVersion)); - printf("OSPlatformId = 0x%x\n", offsetof(struct NtPeb, OSPlatformId)); - printf("ImageSubsystem = 0x%x\n", offsetof(struct NtPeb, ImageSubsystem)); - printf("ImageSubsystemMajorVersion = 0x%x\n", - offsetof(struct NtPeb, ImageSubsystemMajorVersion)); - printf("ImageSubsystemMinorVersion = 0x%x\n", - offsetof(struct NtPeb, ImageSubsystemMinorVersion)); - printf("ImageProcessAffinityMask = 0x%x\n", - offsetof(struct NtPeb, ImageProcessAffinityMask)); - printf("ActiveProcessAffinityMask = 0x%x\n", - offsetof(struct NtPeb, ActiveProcessAffinityMask)); - printf("GdiHandleBuffer = 0x%x\n", offsetof(struct NtPeb, GdiHandleBuffer)); - printf("PostProcessInitRoutine = 0x%x\n", - offsetof(struct NtPeb, PostProcessInitRoutine)); - printf("TlsExpansionBitmap = 0x%x\n", - offsetof(struct NtPeb, TlsExpansionBitmap)); - printf("TlsExpansionBitmapBits = 0x%x\n", - offsetof(struct NtPeb, TlsExpansionBitmapBits)); - printf("SessionId = 0x%x\n", offsetof(struct NtPeb, SessionId)); - printf("AppCompatFlags = 0x%x\n", offsetof(struct NtPeb, AppCompatFlags)); - printf("AppCompatFlagsUser = 0x%x\n", - offsetof(struct NtPeb, AppCompatFlagsUser)); - printf("pShimData = 0x%x\n", offsetof(struct NtPeb, pShimData)); - printf("AppCompatInfo = 0x%x\n", offsetof(struct NtPeb, AppCompatInfo)); - printf("CSDVersion = 0x%x\n", offsetof(struct NtPeb, CSDVersion)); - printf("ActivationContextData = 0x%x\n", - offsetof(struct NtPeb, ActivationContextData)); - printf("ProcessAssemblyStorageMap = 0x%x\n", - offsetof(struct NtPeb, ProcessAssemblyStorageMap)); - printf("SystemDefaultActivationContextData = 0x%x\n", - offsetof(struct NtPeb, SystemDefaultActivationContextData)); - printf("SystemAssemblyStorageMap = 0x%x\n", - offsetof(struct NtPeb, SystemAssemblyStorageMap)); - printf("MinimumStackCommit = 0x%x\n", - offsetof(struct NtPeb, MinimumStackCommit)); - return 0; -} diff --git a/tool/decode/scrubdox.c b/tool/decode/scrubdox.c deleted file mode 100644 index bb5256e2b..000000000 --- a/tool/decode/scrubdox.c +++ /dev/null @@ -1,202 +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 2021 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. │ -╚──────────────────────────────────────────────────────────────────────────────┘ - - THIS PROGRAM TURNS TEXT LIKE THIS - - +------------------------------------------------------------------------+ - | Button | Name | Go to | From 1.2.3 | - | | | | go to | - |------------+-------------+--------------------------------+------------| - | [ < ] | Back | previous section in reading | 1.2.2 | - | | | order | | - |------------+-------------+--------------------------------+------------| - | [ > ] | Forward | next section in reading order | 1.2.4 | - |------------+-------------+--------------------------------+------------| - | [ << ] | FastBack | previous or up-and-previous | 1.1 | - | | | section | | - |------------+-------------+--------------------------------+------------| - | [ Up ] | Up | up section | 1.2 | - |------------+-------------+--------------------------------+------------| - | [ >> ] | FastForward | next or up-and-next section | 1.3 | - |------------+-------------+--------------------------------+------------| - | [Top] | Top | cover (top) of document | | - |------------+-------------+--------------------------------+------------| - | [Contents] | Contents | table of contents | | - |------------+-------------+--------------------------------+------------| - | [Index] | Index | concept index | | - |------------+-------------+--------------------------------+------------| - | [ ? ] | About | this page | | - +------------------------------------------------------------------------+ - - INTO THIS - - ┌────────────┬─────────────┬────────────────────────────────┬────────────┐ - │ Button │ Name │ Go to │ From 1.2.3 │ - │ │ │ │ go to │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [ < ] │ Back │ previous section in reading │ 1.2.2 │ - │ │ │ order │ │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [ > ] │ Forward │ next section in reading order │ 1.2.4 │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [ << ] │ FastBack │ previous or up─and─previous │ 1.1 │ - │ │ │ section │ │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [ Up ] │ Up │ up section │ 1.2 │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [ >> ] │ FastForward │ next or up─and─next section │ 1.3 │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [Top] │ Top │ cover (top) of document │ │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [Contents] │ Contents │ table of contents │ │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [Index] │ Index │ concept index │ │ - ├────────────┼─────────────┼────────────────────────────────┼────────────┤ - │ [ ? ] │ About │ this page │ │ - └────────────┴─────────────┴────────────────────────────────┴────────────┘ */ -#include "libc/macros.internal.h" -#include "libc/mem/gc.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/str/strwidth.h" -#include "libc/x/x.h" -#include "libc/x/xasprintf.h" -#include "libc/x/xgetline.h" - -#define IsSpace(C) ((C) == ' ') -#define IsPipe(C) ((C) == '|' || (C) == u'│') -#define IsPlus(C) ((C) == '+' || (C) == u'┼') -#define IsHyphen(C) ((C) == '-' || (C) == u'─') -#define IsTick(C) ((C) == '`' || (C) == u'└') -#define IsPipe(C) ((C) == '|' || (C) == u'│') -#define IsEquals(C) ((C) == '=' || (C) == u'═') - -int n; -int yn; -int xn; - -FILE *f; -bool *V; -char **T; -char16_t **L; - -static void DoIt(int y, int x) { - if (V[y * (xn + 1) + x]) return; - V[y * (xn + 1) + x] = 1; - if (IsPipe(L[y - 1][x]) && IsHyphen(L[y][x - 1]) && IsPlus(L[y][x]) && - IsHyphen(L[y][x + 1]) && IsPipe(L[y + 1][x])) { - L[y][x] = u'┼'; - } else if (IsPipe(L[y - 1][x]) && IsEquals(L[y][x - 1]) && IsPlus(L[y][x]) && - IsEquals(L[y][x + 1]) && IsPipe(L[y + 1][x])) { - L[y][x] = u'╪'; - } else if (IsSpace(L[y - 1][x]) && IsHyphen(L[y][x - 1]) && - IsHyphen(L[y][x]) && IsHyphen(L[y][x + 1]) && - IsPipe(L[y + 1][x])) { - L[y][x] = u'┬'; - } else if (IsPipe(L[y - 1][x]) && IsHyphen(L[y][x - 1]) && - IsHyphen(L[y][x]) && IsHyphen(L[y][x + 1]) && - IsSpace(L[y + 1][x])) { - L[y][x] = u'┴'; - } else if (IsPipe(L[y - 1][x]) && IsSpace(L[y][x - 1]) && IsPipe(L[y][x]) && - IsHyphen(L[y][x + 1]) && IsPipe(L[y + 1][x])) { - L[y][x] = u'├'; - } else if (IsPipe(L[y - 1][x]) && IsHyphen(L[y][x - 1]) && IsPipe(L[y][x]) && - IsSpace(L[y][x + 1]) && IsPipe(L[y + 1][x])) { - L[y][x] = u'┤'; - } else if (IsSpace(L[y - 1][x]) && IsSpace(L[y][x - 1]) && IsPlus(L[y][x]) && - IsHyphen(L[y][x + 1]) && IsPipe(L[y + 1][x])) { - L[y][x] = u'┌'; - } else if (IsPipe(L[y - 1][x]) && IsHyphen(L[y][x - 1]) && IsPlus(L[y][x]) && - IsSpace(L[y][x + 1]) && IsSpace(L[y + 1][x])) { - L[y][x] = u'┘'; - } else if (IsSpace(L[y - 1][x]) && IsHyphen(L[y][x - 1]) && IsPlus(L[y][x]) && - IsSpace(L[y][x + 1]) && IsPipe(L[y + 1][x])) { - L[y][x] = u'┐'; - } else if (IsPipe(L[y - 1][x]) && IsSpace(L[y][x - 1]) && IsPlus(L[y][x]) && - IsHyphen(L[y][x + 1]) && IsSpace(L[y + 1][x])) { - L[y][x] = u'└'; - } else if (IsTick(L[y][x]) && IsPipe(L[y - 1][x]) && IsHyphen(L[y][x + 1]) && - IsSpace(L[y + 1][x]) && IsSpace(L[y][x - 1])) { - L[y][x] = u'└'; - } else if (IsHyphen(L[y][x])) { - L[y][x] = u'─'; - } else if (IsPipe(L[y][x])) { - L[y][x] = u'│'; - } else if (IsEquals(L[y][x])) { - L[y][x] = u'═'; - } else { - return; - } - DoIt(y - 1, x + 0); - DoIt(y + 1, x + 0); - DoIt(y + 0, x - 1); - DoIt(y + 0, x + 1); -} - -int main(int argc, char *argv[]) { - char *s; - int y, x; - ShowCrashReports(); - f = stdin; - while ((s = _chomp(xgetline(f)))) { - n = strwidth(s, 0); - xn = MAX(xn, n); - T = xrealloc(T, ++yn * sizeof(*T)); - T[yn - 1] = s; - } - xn += 1000; - L = xmalloc((yn + 2) * sizeof(*L)); - L[0] = utf8to16(_gc(xasprintf(" %*s ", xn, " ")), -1, 0); - for (y = 0; y < yn; ++y) { - s = xasprintf(" %s%*s ", T[y], xn - n, " "); - L[y + 1] = utf8to16(s, -1, 0); - free(T[y]); - free(s); - } - L[yn + 2 - 1] = utf8to16(_gc(xasprintf(" %*s ", xn, " ")), -1, 0); - free(T); - V = xcalloc((yn + 1) * (xn + 1), 1); - for (y = 1; y <= yn; ++y) { - for (x = 1; x <= xn; ++x) { - if (IsPipe(L[y - 1][x]) && IsHyphen(L[y][x - 1]) && IsPlus(L[y][x]) && - IsHyphen(L[y][x + 1]) && IsPipe(L[y + 1][x])) { - DoIt(y, x); - } - if (IsTick(L[y][x]) && IsPipe(L[y - 1][x]) && IsHyphen(L[y][x + 1]) && - IsSpace(L[y + 1][x]) && IsSpace(L[y][x - 1])) { - DoIt(y, x); - } - } - } - for (y = 1; y + 1 < yn; ++y) { - s = utf16to8(L[y], -1, 0); - n = strlen(s); - while (n && s[n - 1] == ' ') s[n - 1] = 0, --n; - puts(s + 1); - free(s); - } - for (y = 0; y < yn; ++y) { - free(L[y]); - } - free(L); - free(V); - return 0; -} diff --git a/tool/decode/zip2.c b/tool/decode/zip2.c deleted file mode 100644 index 7a247ced9..000000000 --- a/tool/decode/zip2.c +++ /dev/null @@ -1,284 +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 2021 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/calls/calls.h" -#include "libc/calls/struct/stat.h" -#include "libc/fmt/conv.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/log/check.h" -#include "libc/log/log.h" -#include "libc/mem/gc.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/sysv/consts/map.h" -#include "libc/sysv/consts/o.h" -#include "libc/sysv/consts/prot.h" -#include "libc/x/xasprintf.h" -#include "libc/x/xiso8601.h" -#include "libc/zip.internal.h" -#include "tool/decode/lib/asmcodegen.h" -#include "tool/decode/lib/disassemblehex.h" -#include "tool/decode/lib/zipnames.h" - -char *FormatDosDate(uint16_t dosdate) { - return xasprintf("%04u-%02u-%02u", ((dosdate >> 9) & 0b1111111) + 1980, - (dosdate >> 5) & 0b1111, dosdate & 0b11111); -} - -char *FormatDosTime(uint16_t dostime) { - return xasprintf("%02u:%02u:%02u", (dostime >> 11) & 0b11111, - (dostime >> 5) & 0b111111, (dostime << 1) & 0b111110); -} - -void ShowGeneralFlag(uint16_t generalflag) { - puts("\ -/ ┌─utf8\n\ -/ │ ┌─strong encryption\n\ -/ │ │┌─compressed patch data\n\ -/ │ ││ ┌─crc and size go after file content\n\ -/ │ ││ │┌─{normal,max,fast,superfast}\n\ -/ │ ││ ││ ┌─encrypted\n\ -/ rrrr│uuuu││r│├┐│"); - show(".short", format(b1, "0b%016b", generalflag), "generalflag"); -} - -void ShowCompressionMethod(uint16_t compressmethod) { - show(".short", - firstnonnull(findnamebyid(kZipCompressionNames, compressmethod), - format(b1, "%hu", compressmethod)), - "compressionmethod"); -} - -void ShowTimestamp(uint16_t time, uint16_t date) { - show(".short", format(b1, "%#04hx", time), - _gc(xasprintf("%s (%s)", "lastmodifiedtime", _gc(FormatDosTime(time))))); - show(".short", format(b1, "%#04hx", date), - _gc(xasprintf("%s (%s)", "lastmodifieddate", _gc(FormatDosDate(date))))); -} - -void ShowNtfs(uint8_t *ntfs, size_t n) { - struct timespec mtime, atime, ctime; - mtime = WindowsTimeToTimeSpec(READ64LE(ntfs + 8)); - atime = WindowsTimeToTimeSpec(READ64LE(ntfs + 16)); - ctime = WindowsTimeToTimeSpec(READ64LE(ntfs + 24)); - show(".long", _gc(xasprintf("%d", READ32LE(ntfs))), "ntfs reserved"); - show(".short", _gc(xasprintf("0x%04x", READ16LE(ntfs + 4))), - "ntfs attribute tag value #1"); - show(".short", _gc(xasprintf("%hu", READ16LE(ntfs + 6))), - "ntfs attribute tag size"); - show(".quad", _gc(xasprintf("%lu", READ64LE(ntfs + 8))), - _gc(xasprintf("%s (%s)", "ntfs last modified time", - _gc(xiso8601(&mtime))))); - show(".quad", _gc(xasprintf("%lu", READ64LE(ntfs + 16))), - _gc(xasprintf("%s (%s)", "ntfs last access time", - _gc(xiso8601(&atime))))); - show(".quad", _gc(xasprintf("%lu", READ64LE(ntfs + 24))), - _gc(xasprintf("%s (%s)", "ntfs creation time", _gc(xiso8601(&ctime))))); -} - -void ShowExtendedTimestamp(uint8_t *p, size_t n, bool islocal) { - int flag; - if (n) { - --n; - flag = *p++; - show(".byte", _gc(xasprintf("0b%03hhb", flag)), "fields present in local"); - if ((flag & 1) && n >= 4) { - show(".long", _gc(xasprintf("%u", READ32LE(p))), - _gc(xasprintf("%s (%s)", "last modified", - _gc(xiso8601(&(struct timespec){READ32LE(p)}))))); - p += 4; - n -= 4; - } - flag >>= 1; - if (islocal) { - if ((flag & 1) && n >= 4) { - show(".long", _gc(xasprintf("%u", READ32LE(p))), - _gc(xasprintf("%s (%s)", "access time", - _gc(xiso8601(&(struct timespec){READ32LE(p)}))))); - p += 4; - n -= 4; - } - flag >>= 1; - if ((flag & 1) && n >= 4) { - show(".long", _gc(xasprintf("%u", READ32LE(p))), - _gc(xasprintf("%s (%s)", "creation time", - _gc(xiso8601(&(struct timespec){READ32LE(p)}))))); - p += 4; - n -= 4; - } - } - } -} - -void ShowZip64(uint8_t *p, size_t n, bool islocal) { - if (n >= 8) { - show(".quad", _gc(xasprintf("%lu", READ64LE(p))), - _gc(xasprintf("uncompressed size (%,ld)", READ64LE(p)))); - } - if (n >= 16) { - show(".quad", _gc(xasprintf("%lu", READ64LE(p + 8))), - _gc(xasprintf("compressed size (%,ld)", READ64LE(p + 8)))); - } - if (n >= 24) { - show(".quad", _gc(xasprintf("%lu", READ64LE(p + 16))), - _gc(xasprintf("lfile hdr offset (%,ld)", READ64LE(p + 16)))); - } - if (n >= 28) { - show(".long", _gc(xasprintf("%u", READ32LE(p + 24))), "disk number"); - } -} - -void ShowInfoZipNewUnixExtra(uint8_t *p, size_t n, bool islocal) { - if (p[0] == 1 && p[1] == 4 && p[6] == 4) { - show(".byte", "1", "version"); - show(".byte", "4", "uid length"); - show(".long", _gc(xasprintf("%u", READ32LE(p + 2))), "uid"); - show(".byte", "4", "gid length"); - show(".long", _gc(xasprintf("%u", READ32LE(p + 7))), "gid"); - } else { - disassemblehex(p, n, stdout); - } -} - -void ShowExtra(uint8_t *extra, bool islocal) { - switch (ZIP_EXTRA_HEADERID(extra)) { - case kZipExtraNtfs: - ShowNtfs(ZIP_EXTRA_CONTENT(extra), ZIP_EXTRA_CONTENTSIZE(extra)); - break; - case kZipExtraExtendedTimestamp: - ShowExtendedTimestamp(ZIP_EXTRA_CONTENT(extra), - ZIP_EXTRA_CONTENTSIZE(extra), islocal); - break; - case kZipExtraZip64: - ShowZip64(ZIP_EXTRA_CONTENT(extra), ZIP_EXTRA_CONTENTSIZE(extra), - islocal); - break; - case kZipExtraInfoZipNewUnixExtra: - ShowInfoZipNewUnixExtra(ZIP_EXTRA_CONTENT(extra), - ZIP_EXTRA_CONTENTSIZE(extra), islocal); - break; - default: - disassemblehex(ZIP_EXTRA_CONTENT(extra), ZIP_EXTRA_CONTENTSIZE(extra), - stdout); - break; - } -} - -void ShowExtras(uint8_t *extras, uint16_t extrassize, bool islocal) { - int i; - bool first; - uint8_t *p, *pe; - if (extrassize) { - first = true; - for (p = extras, pe = extras + extrassize, i = 0; p < pe; - p += ZIP_EXTRA_SIZE(p), ++i) { - show(".short", - firstnonnull(findnamebyid(kZipExtraNames, ZIP_EXTRA_HEADERID(p)), - _gc(xasprintf("0x%04hx", ZIP_EXTRA_HEADERID(p)))), - _gc(xasprintf("%s[%d].%s", "extras", i, "headerid"))); - show(".short", _gc(xasprintf("%df-%df", (i + 2) * 10, (i + 1) * 10)), - _gc(xasprintf("%s[%d].%s (%hd %s)", "extras", i, "contentsize", - ZIP_EXTRA_CONTENTSIZE(p), "bytes"))); - if (first) { - first = false; - printf("%d:", (i + 1) * 10); - } - ShowExtra(p, islocal); - printf("%d:", (i + 2) * 10); - } - } - putchar('\n'); -} - -void ShowLocalFileHeader(uint8_t *lf, uint16_t idx) { - printf("\n/\t%s #%hu (%zu %s)\n", "local file", idx + 1, - ZIP_LFILE_HDRSIZE(lf), "bytes"); - show(".ascii", format(b1, "%`'.*s", 4, lf), "magic"); - show(".byte", - firstnonnull(findnamebyid(kZipEraNames, ZIP_LFILE_VERSIONNEED(lf)), - _gc(xasprintf("%d", ZIP_LFILE_VERSIONNEED(lf)))), - "pkzip version need"); - show(".byte", - firstnonnull(findnamebyid(kZipOsNames, ZIP_LFILE_OSNEED(lf)), - _gc(xasprintf("%d", ZIP_LFILE_OSNEED(lf)))), - "os need"); - ShowGeneralFlag(ZIP_LFILE_GENERALFLAG(lf)); - ShowCompressionMethod(ZIP_LFILE_COMPRESSIONMETHOD(lf)); - ShowTimestamp(ZIP_LFILE_LASTMODIFIEDTIME(lf), ZIP_LFILE_LASTMODIFIEDDATE(lf)); - show( - ".long", - format(b1, "%#x", ZIP_LFILE_CRC32(lf)), _gc(xasprintf("%s (%#x)", "crc32z", GetZipLfileCompressedSize(lf) /* crc32_z(0, ZIP_LFILE_CONTENT(lf), GetZipLfileCompressedSize(lf)) */))); - if (ZIP_LFILE_COMPRESSEDSIZE(lf) == 0xFFFFFFFF) { - show(".long", "0xFFFFFFFF", "compressedsize (zip64)"); - } else { - show(".long", "3f-2f", - format(b1, "%s (%u %s)", "compressedsize", - ZIP_LFILE_COMPRESSEDSIZE(lf), "bytes")); - } - show(".long", - ZIP_LFILE_UNCOMPRESSEDSIZE(lf) == 0xFFFFFFFF - ? "0xFFFFFFFF" - : format(b1, "%u", ZIP_LFILE_UNCOMPRESSEDSIZE(lf)), - "uncompressedsize"); - show(".short", "1f-0f", - format(b1, "%s (%hu %s)", "namesize", ZIP_LFILE_NAMESIZE(lf), "bytes")); - show( - ".short", "2f-1f", - format(b1, "%s (%hu %s)", "extrasize", ZIP_LFILE_EXTRASIZE(lf), "bytes")); - printf("0:"); - show(".ascii", - format(b1, "%`'s", - _gc(strndup(ZIP_LFILE_NAME(lf), ZIP_LFILE_NAMESIZE(lf)))), - "name"); - printf("1:"); - ShowExtras(ZIP_LFILE_EXTRA(lf), ZIP_LFILE_EXTRASIZE(lf), true); - printf("2:"); - disassemblehex(ZIP_LFILE_CONTENT(lf), ZIP_LFILE_COMPRESSEDSIZE(lf), stdout); - printf("3:\n"); -} - -void DisassembleZip(const char *path, uint8_t *p, size_t n) { - size_t i, records; - uint8_t *eocd, *cdir, *cf, *lf; - CHECK_NOTNULL((eocd = GetZipEocd(p, n, 0))); - records = GetZipCdirRecords(eocd); - cdir = p + GetZipCdirOffset(eocd); - for (i = 0, cf = cdir; i < records; ++i, cf += ZIP_CFILE_HDRSIZE(cf)) { - CHECK_EQ(kZipCfileHdrMagic, ZIP_CFILE_MAGIC(cf)); - lf = p + GetZipCfileOffset(cf); - CHECK_EQ(kZipLfileHdrMagic, ZIP_LFILE_MAGIC(lf)); - ShowLocalFileHeader(lf, i); - } -} - -int main(int argc, char *argv[]) { - int fd; - uint8_t *map; - struct stat st; - ShowCrashReports(); - CHECK_EQ(2, argc); - CHECK_NE(-1, (fd = open(argv[1], O_RDONLY))); - CHECK_NE(-1, fstat(fd, &st)); - CHECK_GE(st.st_size, kZipCdirHdrMinSize); - CHECK_NE(MAP_FAILED, - (map = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0))); - DisassembleZip(argv[1], map, st.st_size); - CHECK_NE(-1, munmap(map, st.st_size)); - CHECK_NE(-1, close(fd)); - return 0; -} diff --git a/tool/emacs/cosmo.el b/tool/emacs/cosmo.el index 0d4a8419e..88fb36d7f 100644 --- a/tool/emacs/cosmo.el +++ b/tool/emacs/cosmo.el @@ -1,4 +1,3 @@ -(require 'ctest-mode) (require 'ld-script) (require 'optinfo-mode) (require 'protobuf-mode) diff --git a/tool/emacs/ctest-mode.el b/tool/emacs/ctest-mode.el deleted file mode 100644 index e603daab1..000000000 --- a/tool/emacs/ctest-mode.el +++ /dev/null @@ -1,115 +0,0 @@ -(defconst ctest-operators - '("+" - "-" - "*" - "/" - "%" - "//" - "**" - "~" - "^" - "|" - "&" - ">>" - "<<" - "!" - "||" - "&&" - "=" - "!=" - "<" - ">" - "<=" - ">=")) - -(defconst ctest-consts - '("false" - "true" - "e" - "pi" - "epsilon" - "inf" - "nan" - "l2t" - "lg2" - "ln2" - "l2e")) - -(defconst ctest-builtins - '("emit" - "exit" - "meminfo" - "isnan" - "isinf" - "signbit" - "isfinite" - "isnormal" - "fpclassify")) - -(defconst ctest-functions - '("emit" - "cr" - "key" - "dup" - "swap" - "over" - "drop" - "expect" - "assert" - "abs" - "min" - "max")) - -(defconst ctest-functions-libm - '("mod" - "rem" - "gray" - "ungray" - "popcnt" - "sqrt" - "exp" - "exp2" - "exp10" - "ldexp" - "log" - "log2" - "log10" - "sin" - "cos" - "tan" - "asin" - "acos" - "atan" - "atan2" - "round" - "trunc" - "rint" - "nearbyint" - "ceil" - "floor" - "rand" - "rand64")) - -(defun ctest--make-regex (words) - (concat "\\_<" (regexp-opt words) "\\_>")) - -(defconst ctest-highlights - `(("\\(#.*\\)$" 1 font-lock-comment-face) - ("\\b0\\([xX]\\)[[:xdigit:]]+\\([ulUL]*\\)\\b" - (1 font-lock-constant-face) - (2 font-lock-constant-face)) - ("\\b0\\([bB]\\)[01]+\\([ulUL]*\\)\\b" - (1 font-lock-constant-face) - (2 font-lock-constant-face)) - (,(concat "\\_<" (regexp-opt ctest-consts) "\\_>") . - font-lock-constant-face) - (,(concat "\\_<" (regexp-opt ctest-builtins) "\\_>") . - font-lock-builtin-face))) - -(define-derived-mode ctest-mode fundamental-mode "CALCULATOR.COM" - "Major mode for editing CALCULATOR.COM smoke tests." - (setq font-lock-defaults '(ctest-highlights))) - -(add-to-list 'auto-mode-alist '("\\.ctest$" . ctest-mode)) - -(provide 'ctest-mode) diff --git a/tool/viz/generatematrix.c b/tool/viz/generatematrix.c deleted file mode 100644 index b485fbd60..000000000 --- a/tool/viz/generatematrix.c +++ /dev/null @@ -1,315 +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/fmt/conv.h" -#include "libc/fmt/fmt.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/limits.h" -#include "libc/log/check.h" -#include "libc/log/log.h" -#include "libc/macros.internal.h" -#include "libc/math.h" -#include "libc/mem/gc.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/lcg.internal.h" -#include "libc/stdio/rand.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "libc/x/x.h" -#include "third_party/gdtoa/gdtoa.h" -#include "third_party/getopt/getopt.internal.h" -#include "tool/viz/lib/formatstringtable.h" - -typedef double (*round_f)(double); -typedef unsigned long (*rand_f)(void); - -struct Range { - long double a; - long double b; -}; - -short xn_ = 8; -short yn_ = 8; -double digs_ = 6; -rand_f rand_; -round_f rounder_; -const char *path_ = "-"; -const char *name_ = "M"; -const char *type_ = "float"; -struct Range r1_ = {LONG_MIN, LONG_MAX}; -struct Range r2_ = {0, 1}; -StringTableFormatter *formatter_ = FormatStringTableAsCode; - -static wontreturn void PrintUsage(int rc, FILE *f) { - fprintf(f, "Usage: %s%s", program_invocation_name, "\ - [FLAGS] [FILE]\n\ -\n\ -Flags:\n\ - -u unsigned\n\ - -c char\n\ - -s short\n\ - -i int\n\ - -l long\n\ - -d double\n\ - -b bytes [-uc]\n\ - -g non-deterministic rng\n\ - -S output assembly\n\ - -W output whitespace\n\ - -o PATH output path\n\ - -x FLEX\n\ - -w FLEX width\n\ - -y FLEX\n\ - -h FLEX height\n\ - -N NAME name\n\ - -T NAME type name\n\ - -A FLEX min value\n\ - -B FLEX max value\n\ - -R FUNC round function for indexing\n\ - -D FLEX decimal digits to printout\n\ - -v increases verbosity\n\ - -? shows this information\n\ -\n"); - exit(rc); -} - -static bool StringEquals(const char *a, const char *b) { - return strcasecmp(a, b) == 0; -} - -static wontreturn void ShowInvalidArg(const char *name, const char *s, - const char *type) { - fprintf(stderr, "error: invalid %s %s: %s\n", type, name, s); - exit(EXIT_FAILURE); -} - -static double ParseFlexidecimalOrDie(const char *name, const char *s, - double min, double max) { - double x; - s = firstnonnull(s, "NULL"); - if (strchr(s, '.') || strchr(s, 'e')) { - x = strtod(s, NULL); - } else { - x = strtol(s, NULL, 0); - } - if (min <= x && x <= max) { - return x; - } else { - ShowInvalidArg(name, s, "flexidecimal"); - } -} - -static round_f ParseRoundingFunctionOrDie(const char *s) { - if (isempty(s) || StringEquals(s, "none") || StringEquals(s, "null")) { - return NULL; - } else if (StringEquals(s, "round")) { - return round; - } else if (StringEquals(s, "rint")) { - return rint; - } else if (StringEquals(s, "nearbyint")) { - return nearbyint; - } else if (StringEquals(s, "trunc")) { - return trunc; - } else if (StringEquals(s, "floor")) { - return floor; - } else if (StringEquals(s, "ceil")) { - return ceil; - } else { - ShowInvalidArg("round", s, "func"); - } -} - -static void ConfigureIntegralRange(const char *type, long min, long max) { - type_ = type; - r1_.a = min; - r1_.b = max; - r2_.a = min; - r2_.b = max; - if (!rounder_) rounder_ = round; -} - -void GetOpts(int argc, char *argv[]) { - int opt; - bool want_unsigned, want_char, want_short, want_int, want_long, want_double; - want_unsigned = false; - want_char = false; - want_short = false; - want_int = false; - want_long = false; - want_double = false; - if (argc == 2 && - (StringEquals(argv[1], "--help") || StringEquals(argv[1], "-help"))) { - PrintUsage(EXIT_SUCCESS, stdout); - } - while ((opt = getopt(argc, argv, "?vubcsildgSWo:x:w:y:h:N:A:B:C:E:T:R:D:")) != - -1) { - switch (opt) { - case 'b': - want_unsigned = true; - want_char = true; - break; - case 'u': - want_unsigned = true; - break; - case 'c': - want_char = true; - break; - case 's': - want_short = true; - break; - case 'i': - want_int = true; - break; - case 'l': - want_long = true; - break; - case 'd': - want_double = true; - break; - case 'g': - rand_ = _rand64; - break; - case 'N': - name_ = optarg; - break; - case 'o': - path_ = optarg; - break; - case 'S': - formatter_ = FormatStringTableAsAssembly; - break; - case 'W': - formatter_ = FormatStringTableBasic; - break; - case 't': - type_ = optarg; - break; - case 'x': - case 'w': - xn_ = ParseFlexidecimalOrDie("width", optarg, 1, SHRT_MAX); - break; - case 'y': - case 'h': - yn_ = ParseFlexidecimalOrDie("height", optarg, 1, SHRT_MAX); - break; - case 'D': - digs_ = ParseFlexidecimalOrDie("digs", optarg, 0, 15.95); - break; - case 'r': - rounder_ = ParseRoundingFunctionOrDie(optarg); - break; - case 'A': - r1_.a = ParseFlexidecimalOrDie("r1_.a", optarg, INT_MIN, INT_MAX); - break; - case 'B': - r1_.b = ParseFlexidecimalOrDie("r1_.b", optarg, INT_MIN, INT_MAX); - break; - case 'C': - r2_.a = ParseFlexidecimalOrDie("r2_.a", optarg, INT_MIN, INT_MAX); - break; - case 'E': - r2_.b = ParseFlexidecimalOrDie("r2_.b", optarg, INT_MIN, INT_MAX); - break; - case '?': - PrintUsage(EXIT_SUCCESS, stdout); - default: - PrintUsage(EX_USAGE, stderr); - } - } - if (want_unsigned && want_char) { - ConfigureIntegralRange("unsigned char", 0, 255); - } else if (want_char) { - ConfigureIntegralRange("signed char", -128, 127); - } else if (want_unsigned && want_short) { - ConfigureIntegralRange("unsigned short", USHRT_MIN, USHRT_MAX); - } else if (want_short) { - ConfigureIntegralRange("short", SHRT_MIN, SHRT_MAX); - } else if (want_unsigned && want_int) { - ConfigureIntegralRange("unsigned", UINT_MIN, UINT_MAX); - } else if (want_int) { - ConfigureIntegralRange("int", INT_MIN, INT_MAX); - } else if (want_unsigned && want_long) { - ConfigureIntegralRange("unsigned long", ULONG_MIN, ULONG_MAX); - } else if (want_long) { - ConfigureIntegralRange("long", LONG_MIN, LONG_MAX); - } else if (want_double) { - type_ = "double"; - r1_.a = LONG_MIN; - r1_.b = LONG_MAX; - digs_ = 19; - } -} - -static void *SetRandom(long n, long p[n]) { - long i; - uint64_t r; - if (rand_) { - for (r = 1, i = 0; i < n; ++i) { - p[i] = rand_(); - } - } else { - for (r = 1, i = 0; i < n; ++i) { - p[i] = KnuthLinearCongruentialGenerator(&r) >> 32 | - KnuthLinearCongruentialGenerator(&r) >> 32 << 32; - } - } - return p; -} - -static long double ConvertRange(long double x, long double a, long double b, - long double c, long double d) { - return (d - c) / (b - a) * (x - a) + c; -} - -static double Compand(long x, double a, double b, double c, double d) { - return ConvertRange(ConvertRange(x, LONG_MIN, LONG_MAX, a, b), a, b, c, d); -} - -static void GenerateMatrixImpl(long I[yn_][xn_], double M[yn_][xn_], FILE *f) { - long y, x; - for (y = 0; y < yn_; ++y) { - for (x = 0; x < xn_; ++x) { - M[y][x] = Compand(I[y][x], r1_.a, r1_.b, r2_.a, r2_.b); - } - if (rounder_) { - for (x = 0; x < xn_; ++x) { - M[y][x] = rounder_(M[y][x]); - } - } - } - FormatMatrixDouble(yn_, xn_, M, fputs, f, formatter_, type_, name_, NULL, - digs_, round); -} - -void GenerateMatrix(FILE *f) { - GenerateMatrixImpl(SetRandom(yn_ * xn_, gc(calloc(yn_ * xn_, sizeof(long)))), - gc(calloc(yn_ * xn_, sizeof(double))), f); -} - -int main(int argc, char *argv[]) { - int i; - FILE *f; - ShowCrashReports(); - GetOpts(argc, argv); - CHECK_NOTNULL((f = fopen(path_, "w"))); - if (optind < argc) FATALF("TODO(jart): support input files"); - GenerateMatrix(f); - return fclose(f); -} diff --git a/tool/viz/invertblocks.c b/tool/viz/invertblocks.c deleted file mode 100644 index 1830b8da5..000000000 --- a/tool/viz/invertblocks.c +++ /dev/null @@ -1,116 +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/log/check.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "third_party/getopt/getopt.internal.h" - -static FILE *fi_, *fo_; -static char *inpath_, *outpath_; - -wontreturn void usage(int rc, FILE *f) { - fprintf(f, "%s%s%s\n", "Usage: ", program_invocation_name, - " [-o FILE] [FILE...]\n"); - exit(rc); -} - -void getopts(int *argc, char *argv[]) { - int opt; - outpath_ = "-"; - while ((opt = getopt(*argc, argv, "?ho:")) != -1) { - switch (opt) { - case 'o': - outpath_ = optarg; - break; - case '?': - case 'h': - usage(EXIT_SUCCESS, stdout); - default: - usage(EX_USAGE, stderr); - } - } - if (optind == *argc) { - argv[(*argc)++] = "-"; - } -} - -void processfile(void) { - wint_t wc; - while ((wc = fgetwc(fi_)) != -1) { - switch (wc) { - case L'█': - wc = L' '; - break; - case L'▓': - wc = L'░'; - break; - case L'▒': - wc = L'▒'; - break; - case L'░': - wc = L'▓'; - break; - /* █ */ - case L'▐': - wc = L'▌'; - break; - case L'▌': - wc = L'▐'; - break; - case L'▀': - wc = L'▄'; - break; - case L'▄': - wc = L'▀'; - break; - case L'☺': - wc = L'☻'; - break; - case L'☻': - wc = L'☺'; - break; - case L'○': - wc = L'◙'; - break; - case L'◙': - wc = L'○'; - break; - default: - break; - } - fputwc(wc, fo_); - } -} - -int main(int argc, char *argv[]) { - size_t i; - getopts(&argc, argv); - CHECK_NOTNULL((fo_ = fopen(outpath_, "w"))); - for (i = optind; i < argc; ++i) { - CHECK_NOTNULL((fi_ = fopen((inpath_ = argv[i]), "r"))); - processfile(); - CHECK_NE(-1, fclose(fi_)); - fi_ = 0; - } - CHECK_NE(-1, fclose(fo_)); - fo_ = 0; - return 0; -} diff --git a/tool/viz/magikarp.c b/tool/viz/magikarp.c deleted file mode 100644 index c4fdb8768..000000000 --- a/tool/viz/magikarp.c +++ /dev/null @@ -1,642 +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 "dsp/core/c1331.h" -#include "dsp/core/c161.h" -#include "dsp/core/core.h" -#include "dsp/scale/scale.h" -#include "libc/assert.h" -#include "libc/calls/calls.h" -#include "libc/calls/struct/stat.h" -#include "libc/fmt/conv.h" -#include "libc/limits.h" -#include "libc/log/check.h" -#include "libc/log/log.h" -#include "libc/macros.internal.h" -#include "libc/math.h" -#include "libc/mem/gc.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/rand.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.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/testlib/testlib.h" -#include "libc/x/x.h" -#include "third_party/getopt/getopt.internal.h" -#include "third_party/stb/stb_image.h" -#include "tool/viz/lib/bilinearscale.h" -#include "tool/viz/lib/graphic.h" - -#define LONG long -#define CHAR char -#define CLAMP(X) MIN(255, MAX(0, X)) -#define C13(A, B) (((A) + 3 * (B) + 2) >> 2) -#define LERP(X, Y, P) ((X) + (((P) * ((Y) - (X))) >> 8)) - -static double r_; - -static unsigned char ChessBoard(unsigned y, unsigned x, unsigned char a, - unsigned char b) { - return !((y ^ x) & (1u << 2)) ? a : b; -} - -static unsigned char AlphaBackground(unsigned y, unsigned x) { - return ChessBoard(y, x, 255, 200); -} - -static unsigned char OutOfBoundsBackground(unsigned y, unsigned x) { - return ChessBoard(y, x, 40, 80); -} - -static unsigned char Opacify(CHAR w, const unsigned char P[1u << w][1u << w], - const unsigned char A[1u << w][1u << w], LONG yn, - LONG xn, long y, long x) { - if ((0 <= y && y < yn) && (0 <= x && x < xn)) { - return LERP(AlphaBackground(y, x), P[y][x], A[y][x]); - } else { - return OutOfBoundsBackground(y, x); - } -} - -static void PrintImage(CHAR w, unsigned char R[1u << w][1u << w], - unsigned char G[1u << w][1u << w], - unsigned char B[1u << w][1u << w], - unsigned char A[1u << w][1u << w], LONG yn, LONG xn) { - bool didhalfy; - long y, x; - didhalfy = false; - for (y = 0; y < yn; y += 2) { - if (y) printf("\e[0m\n"); - for (x = 0; x < xn; ++x) { - printf("\e[48;2;%d;%d;%d;38;2;%d;%d;%dm▄", - Opacify(w, R, A, yn, xn, y + 0, x), - Opacify(w, G, A, yn, xn, y + 0, x), - Opacify(w, B, A, yn, xn, y + 0, x), - Opacify(w, R, A, yn, xn, y + 1, x), - Opacify(w, G, A, yn, xn, y + 1, x), - Opacify(w, B, A, yn, xn, y + 1, x)); - } - if (y == 0) { - printf("\e[0m‾0"); - } else if (yn / 2 <= y && y <= yn / 2 + 1 && !didhalfy) { - printf("\e[0m‾%s%s", "yn/2", y % 2 ? "+1" : ""); - didhalfy = true; - } else if (y + 1 == yn / 2 && !didhalfy) { - printf("\e[0m⎯yn/2"); - didhalfy = true; - } else if (y + 1 == yn) { - printf("\e[0m⎯yn"); - } else if (y + 2 == yn) { - printf("\e[0m_yn"); - } else if (!(y % 10)) { - printf("\e[0m‾%,u", y); - } - } - printf("\e[0m\n"); -} - -static void DeblinterlaceRgba(CHAR w, unsigned char R[1u << w][1u << w], - unsigned char G[1u << w][1u << w], - unsigned char B[1u << w][1u << w], - unsigned char A[1u << w][1u << w], LONG yn, - LONG xn, const unsigned char src[yn][xn][4]) { - long y, x; - for (y = 0; y < yn; ++y) { - for (x = 0; x < xn; ++x) { - R[y][x] = src[y][x][0]; - G[y][x] = src[y][x][1]; - B[y][x] = src[y][x][2]; - A[y][x] = src[y][x][3]; - } - } -} - -static void SharpenX(CHAR w, unsigned char dst[1u << w][1u << w], - const unsigned char src[1u << w][1u << w], char yw, - char xw) { - int y, x; - for (y = 0; y < (1u << yw); ++y) { - for (x = 0; x < (1u << xw); ++x) { - dst[y][x] = C161(src[y][MAX(0, x - 1)], src[y][x], - src[y][MIN((1u << xw) - 1, x + 1)]); - } - } -} - -static void SharpenY(CHAR w, unsigned char dst[1u << w][1u << w], - const unsigned char src[1u << w][1u << w], char yw, - char xw) { - int y, x; - for (y = 0; y < (1u << yw); ++y) { - for (x = 0; x < (1u << xw); ++x) { - dst[y][x] = C161(src[MAX(0, y - 1)][x], src[y][x], - src[MIN((1u << yw) - 1, y + 1)][x]); - } - } -} - -static void UpscaleX(CHAR w, unsigned char img[1u << w][1u << w], char yw, - char xw) { - long y, x; - for (y = (1u << yw); y--;) { - for (x = (1u << xw); --x;) { - img[y][x] = - C13(img[y][MIN(((1u << xw) >> 1) - 1, (x >> 1) - 1 + (x & 1) * 2)], - img[y][x >> 1]); - } - } -} - -static void UpscaleY(CHAR w, unsigned char img[1u << w][1u << w], char yw, - char xw) { - long y, x; - for (y = (1u << yw); --y;) { - for (x = (1u << xw); x--;) { - img[y][x] = - C13(img[MIN(((1u << yw) >> 1) - 1, (y >> 1) - 1 + (y & 1) * 2)][x], - img[y >> 1][x]); - } - } -} - -static void Upscale(CHAR w, unsigned char img[1u << w][1u << w], - unsigned char tmp[1u << w][1u << w], char yw, char xw) { - UpscaleY(w, img, yw, xw - 1); - SharpenY(w, tmp, img, yw, xw - 1); - UpscaleX(w, tmp, yw, xw); - SharpenX(w, img, tmp, yw, xw); -} - -#if 0 -static void *MagikarpY(CHAR w, unsigned char p[1u << w][1u << w], char yw, - char xw) { - long y, x, yn, xn, ym; - unsigned char(*t)[(1u << w) + 2][1u << w]; - t = memalign(64, ((1u << w) + 2) * (1u << w)); - bzero(t, ((1u << w) + 2) * (1u << w)); - yn = 1u << yw; - xn = 1u << xw; - ym = yn >> 1; - for (y = 0; y < ym; ++y) { - for (x = 0; x < xn; ++x) { - (*t)[y + 1][x] = - C1331(y ? p[(y << 1) - 1][x] : 0, p[y << 1][x], p[(y << 1) + 1][x], - p[MIN(yn - 1, (y << 1) + 2)][x]); - } - } - for (y = 0; y < ym; ++y) { - for (x = 0; x < xn; ++x) { - p[y][x] = - C161((*t)[y + 1 - 1][x], (*t)[y + 1 + 0][x], (*t)[y + 1 + 1][x]); - } - } - free(t); - return p; -} -static void *MagikarpX(CHAR w, unsigned char p[1u << w][1u << w], char yw, - char xw) { - int y, x; - LONG yn, xn, xm; - yn = 1u << yw; - xn = 1u << xw; - xm = xn >> 1; - for (x = 0; x < xm; ++x) { - for (y = 0; y < yn; ++y) { - p[y][(xn - xm - 1) + (xm - x - 1)] = - C1331(p[y][MAX(00 + 0, xn - (x << 1) - 1 + (xn & 1) - 1)], - p[y][MIN(xn - 1, xn - (x << 1) - 1 + (xn & 1) + 0)], - p[y][MIN(xn - 1, xn - (x << 1) - 1 + (xn & 1) + 1)], - p[y][MIN(xn - 1, xn - (x << 1) - 1 + (xn & 1) + 2)]); - } - } - for (x = 0; x < xm; ++x) { - for (y = 0; y < yn; ++y) { - p[y][x] = C161(p[y][MAX(xn - 1 - xm, xn - xm - 1 + x - 1)], - p[y][MIN(xn - 1 - 00, xn - xm - 1 + x + 0)], - p[y][MIN(xn - 1 - 00, xn - xm - 1 + x + 1)]); - } - } - return p; -} -static void ProcessImageVerbatim(LONG yn, LONG xn, - unsigned char img[yn][xn][4]) { - CHAR w; - void *R, *G, *B, *A; - w = _roundup2log(MAX(yn, xn)); - R = xvalloc((1u << w) * (1u << w)); - G = xvalloc((1u << w) * (1u << w)); - B = xvalloc((1u << w) * (1u << w)); - A = xvalloc((1u << w) * (1u << w)); - DeblinterlaceRgba(w, R, G, B, A, yn, xn, img); - PrintImage(w, R, G, B, A, yn, xn); - free(R); - free(G); - free(B); - free(A); -} -static void ProcessImageDouble(LONG yn, LONG xn, unsigned char img[yn][xn][4]) { - CHAR w; - void *t, *R, *G, *B, *A; - w = _roundup2log(MAX(yn, xn)) + 1; - t = xvalloc((1u << w) * (1u << w)); - R = xvalloc((1u << w) * (1u << w)); - G = xvalloc((1u << w) * (1u << w)); - B = xvalloc((1u << w) * (1u << w)); - A = xvalloc((1u << w) * (1u << w)); - DeblinterlaceRgba(w, R, G, B, A, yn, xn, img); - Upscale(w, R, t, w, w); - Upscale(w, G, t, w, w); - Upscale(w, B, t, w, w); - Upscale(w, A, t, w, w); - free(t); - PrintImage(w, R, G, B, A, yn * 2, xn * 2); - free(R); - free(G); - free(B); - free(A); -} -static void ProcessImageHalf(LONG yn, LONG xn, unsigned char img[yn][xn][4]) { - CHAR w; - void *R, *G, *B, *A; - w = _roundup2log(MAX(yn, xn)); - R = xvalloc((1u << w) * (1u << w)); - G = xvalloc((1u << w) * (1u << w)); - B = xvalloc((1u << w) * (1u << w)); - A = xvalloc((1u << w) * (1u << w)); - DeblinterlaceRgba(w, R, G, B, A, yn, xn, img); - MagikarpY(w, R, w, w); - MagikarpY(w, G, w, w); - MagikarpY(w, B, w, w); - MagikarpY(w, A, w, w); - MagikarpX(w, R, w - 1, w); - MagikarpX(w, G, w - 1, w); - MagikarpX(w, B, w - 1, w); - MagikarpX(w, A, w - 1, w); - PrintImage(w, R, G, B, A, yn >> 1, xn >> 1); - free(R); - free(G); - free(B); - free(A); -} -static void ProcessImageHalfY(LONG yn, LONG xn, unsigned char img[yn][xn][4]) { - CHAR w; - void *R, *G, *B, *A; - w = _roundup2log(MAX(yn, xn)); - R = xvalloc((1u << w) * (1u << w)); - G = xvalloc((1u << w) * (1u << w)); - B = xvalloc((1u << w) * (1u << w)); - A = xvalloc((1u << w) * (1u << w)); - DeblinterlaceRgba(w, R, G, B, A, yn, xn, img); - MagikarpY(w, R, w, w); - MagikarpY(w, G, w, w); - MagikarpY(w, B, w, w); - MagikarpY(w, A, w, w); - PrintImage(w, R, G, B, A, yn >> 1, xn); - free(R); - free(G); - free(B); - free(A); -} -static void ProcessImageHalfLanczos(LONG yn, LONG xn, - unsigned char img[yn][xn][4]) { - CHAR w; - void *t, *R, *G, *B, *A; - t = xvalloc((yn >> 1) * (xn >> 1) * 4); - lanczos1b(yn >> 1, xn >> 1, t, yn, xn, &img[0][0][0]); - w = _roundup2log(MAX(yn >> 1, xn >> 1)); - R = xvalloc((1u << w) * (1u << w)); - G = xvalloc((1u << w) * (1u << w)); - B = xvalloc((1u << w) * (1u << w)); - A = xvalloc((1u << w) * (1u << w)); - DeblinterlaceRgba(w, R, G, B, A, yn >> 1, xn >> 1, img); - free(t); - PrintImage(w, R, G, B, A, yn >> 1, xn >> 1); - free(R); - free(G); - free(B); - free(A); -} -static void ProcessImageWash(LONG yn, LONG xn, unsigned char img[yn][xn][4]) { - long w; - void *R, *G, *B, *A, *t; - w = _roundup2log(MAX(yn, xn)) + 1; - t = xvalloc((1u << w) * (1u << w)); - R = xvalloc((1u << w) * (1u << w)); - G = xvalloc((1u << w) * (1u << w)); - B = xvalloc((1u << w) * (1u << w)); - A = xvalloc((1u << w) * (1u << w)); - DeblinterlaceRgba(w, R, G, B, A, yn, xn, img); - Upscale(w, R, t, w, w); - Upscale(w, G, t, w, w); - Upscale(w, B, t, w, w); - Upscale(w, A, t, w, w); - MagikarpY(w, R, w, w); - MagikarpY(w, G, w, w); - MagikarpY(w, B, w, w); - MagikarpY(w, A, w, w); - MagikarpX(w, R, w - 1, w); - MagikarpX(w, G, w - 1, w); - MagikarpX(w, B, w - 1, w); - MagikarpX(w, A, w - 1, w); - free(t); - PrintImage(w, R, G, B, A, yn, xn); - free(R); - free(G); - free(B); - free(A); -} -#endif - -#if 0 -static void *MagikarpY(size_t ys, size_t xs, unsigned char p[ys][xs], size_t yn, - size_t xn) { - int y, x, h, b; - b = yn % 2; - h = yn / 2; - if (b && yn < ys) yn++; - for (y = b; y < h + b; ++y) { - for (x = 0; x < xn; ++x) { - p[(yn - h - 1) + (h - y - 1)][x] = - C1331(p[MAX(00 + 0, yn - y * 2 - 1 - 1)][x], - p[MIN(yn - 1, yn - y * 2 - 1 + 0)][x], - p[MIN(yn - 1, yn - y * 2 - 1 + 1)][x], - p[MIN(yn - 1, yn - y * 2 - 1 + 2)][x]); - } - } - for (y = b; y < h + b; ++y) { - for (x = 0; x < xn; ++x) { - p[y][x] = C161(p[MAX(yn - 1 - h, yn - h - 1 + y - 1)][x], - p[MIN(yn - 1 - 0, yn - h - 1 + y + 0)][x], - p[MIN(yn - 1 - 0, yn - h - 1 + y + 1)][x]); - } - } - return p; -} -#endif - -#if 0 -static void *MagikarpX(size_t ys, size_t xs, unsigned char p[ys][xs], size_t yn, - size_t xn) { - int y, x, w, b; - b = xn % 2; - w = xn / 2; - if (b && xn < xs) xn++; - for (x = 0; x < w; ++x) { - for (y = b; y < yn + b; ++y) { - p[y][(xn - w - 1) + (w - x - 1)] = - C1331(p[y][MAX(00 + 0, xn - x * 2 - 1 - 1)], - p[y][MIN(xn - 1, xn - x * 2 - 1 + 0)], - p[y][MIN(xn - 1, xn - x * 2 - 1 + 1)], - p[y][MIN(xn - 1, xn - x * 2 - 1 + 2)]); - } - } - for (x = 0; x < w; ++x) { - for (y = b; y < yn + b; ++y) { - p[y][x] = C161(p[y][MAX(xn - 1 - w, xn - w - 1 + x - 1)], - p[y][MIN(xn - 1 - 0, xn - w - 1 + x + 0)], - p[y][MIN(xn - 1 - 0, xn - w - 1 + x + 1)]); - } - } - return p; -} -#endif - -#if 0 -static void ProcessImageMagikarpImpl(CHAR sw, - unsigned char src[5][1u << sw][1u << sw], - LONG syn, LONG sxn, - const unsigned char img[syn][sxn][4], - LONG dyn, LONG dxn) { - DeblinterlaceRgba2(sw, src, syn, sxn, img); - MagikarpY(sw, src[0], sw, sw); - MagikarpX(sw, src[0], sw - 1, sw); - MagikarpY(sw, src[1], sw, sw); - MagikarpX(sw, src[1], sw - 1, sw); - MagikarpY(sw, src[2], sw, sw); - MagikarpX(sw, src[2], sw - 1, sw); - BilinearScale(sw, src[4], sw, src[3], dyn, dxn, syn, sxn); - memcpy(src[3], src[4], syn * sxn); - PrintImage2(sw, src, dyn, dxn); -} -static void ProcessImageMagikarp(LONG syn, LONG sxn, - unsigned char img[syn][sxn][4]) { - CHAR sw; - LONG dyn, dxn; - dyn = syn >> 1; - dxn = sxn >> 1; - sw = _roundup2log(MAX(syn, sxn)); - ProcessImageMagikarpImpl(sw, gc(xvalloc((1u << sw) * (1u << sw) * 5)), syn, - sxn, img, dyn, dxn); -} -#endif - -/* -******************************************************************************** -*/ - -static unsigned char Opacify2(unsigned yw, unsigned xw, - const unsigned char P[yw][xw], - const unsigned char A[yw][xw], unsigned yn, - unsigned xn, unsigned y, unsigned x) { - if ((0 <= y && y < yn) && (0 <= x && x < xn)) { - return LERP(AlphaBackground(y, x), P[y][x], A[y][x]); - } else { - return OutOfBoundsBackground(y, x); - } -} - -static dontinline void PrintImage2(unsigned yw, unsigned xw, - unsigned char img[4][yw][xw], unsigned yn, - unsigned xn) { - bool didhalfy; - unsigned y, x; - didhalfy = false; - for (y = 0; y < yn; y += 2) { - if (y) printf("\e[0m\n"); - for (x = 0; x < xn; ++x) { - printf("\e[48;2;%d;%d;%d;38;2;%d;%d;%dm▄", - Opacify2(yw, xw, img[0], img[3], yn, xn, y + 0, x), - Opacify2(yw, xw, img[1], img[3], yn, xn, y + 0, x), - Opacify2(yw, xw, img[2], img[3], yn, xn, y + 0, x), - Opacify2(yw, xw, img[0], img[3], yn, xn, y + 1, x), - Opacify2(yw, xw, img[1], img[3], yn, xn, y + 1, x), - Opacify2(yw, xw, img[2], img[3], yn, xn, y + 1, x)); - } - if (y == 0) { - printf("\e[0m‾0"); - } else if (yn / 2 <= y && y <= yn / 2 + 1 && !didhalfy) { - printf("\e[0m‾%s%s", "yn/2", y % 2 ? "+1" : ""); - didhalfy = true; - } else if (y + 1 == yn / 2 && !didhalfy) { - printf("\e[0m⎯yn/2"); - didhalfy = true; - } else if (y + 1 == yn) { - printf("\e[0m⎯yn"); - } else if (y + 2 == yn) { - printf("\e[0m_yn"); - } else if (!(y % 10)) { - printf("\e[0m‾%,u", y); - } - } - printf("\e[0m\n"); -} - -static dontinline void *DeblinterlaceRgba2(unsigned yn, unsigned xn, - unsigned char D[4][yn][xn], - const unsigned char S[yn][xn][4]) { - unsigned y, x; - for (y = 0; y < yn; ++y) { - for (x = 0; x < xn; ++x) { - D[0][y][x] = S[y][x][0]; - D[1][y][x] = S[y][x][1]; - D[2][y][x] = S[y][x][2]; - D[3][y][x] = S[y][x][3]; - } - } - return D; -} - -void ProcessImageBilinearImpl(unsigned dyn, unsigned dxn, - unsigned char dst[4][dyn][dxn], unsigned syn, - unsigned sxn, unsigned char src[4][syn][sxn], - unsigned char img[syn][sxn][4]) { - DeblinterlaceRgba2(syn, sxn, src, img); - BilinearScale(4, dyn, dxn, dst, 4, syn, sxn, src, 0, 4, dyn, dxn, syn, sxn, - r_, r_, 0, 0); - PrintImage2(dyn, dxn, dst, dyn, dxn); -} - -void ProcessImageBilinear(unsigned yn, unsigned xn, - unsigned char img[yn][xn][4]) { - unsigned dyn, dxn; - dyn = lround(yn / r_); - dxn = lround(xn / r_); - ProcessImageBilinearImpl(dyn, dxn, gc(xmalloc(dyn * dxn * 4)), yn, xn, - gc(xmalloc(yn * xn * 4)), img); -} - -static void *b2f(long n, float dst[n], const unsigned char src[n]) { - long i; - float f; - for (i = 0; i < n; ++i) { - f = src[i]; - f *= 1 / 255.; - dst[i] = f; - } - return dst; -} - -static void *f2b(long n, unsigned char dst[n], const float src[n]) { - int x; - long i; - for (i = 0; i < n; ++i) { - x = lroundf(src[i] * 255); - dst[i] = MIN(255, MAX(0, x)); - } - return dst; -} - -void ProcessImageGyarados(unsigned yn, unsigned xn, - unsigned char img[yn][xn][4]) { - unsigned dyn, dxn; - dyn = lround(yn / r_); - dxn = lround(xn / r_); - PrintImage2( - dyn, dxn, - EzGyarados(4, dyn, dxn, gc(xmalloc(dyn * dxn * 4)), 4, yn, xn, - DeblinterlaceRgba2(yn, xn, gc(xmalloc(yn * xn * 4)), img), 0, - 4, dyn, dxn, yn, xn, r_, r_, 0, 0), - dyn, dxn); -} - -void MagikarpDecimate(int yw, int xw, unsigned char img[4][yw][xw], int yn, - int xn, int n) { - int c; - if (n <= 1) { - PrintImage2(yw, xw, img, yn, xn); - } else { - for (c = 0; c < 4; ++c) Magikarp2xY(yw, xw, img[c], yn, xn); - for (c = 0; c < 4; ++c) Magikarp2xX(yw, xw, img[c], (yn + 1) / 2, xn); - MagikarpDecimate(yw, xw, img, (yn + 1) / 2, (xn + 1) / 2, (n + 1) / 2); - } -} - -void ProcessImageMagikarp(unsigned yn, unsigned xn, - unsigned char img[yn][xn][4]) { - MagikarpDecimate(yn, xn, - DeblinterlaceRgba2(yn, xn, gc(xmalloc(yn * xn * 4)), img), - yn, xn, lround(r_)); -} - -dontinline void WithImageFile(const char *path, - void fn(unsigned yn, unsigned xn, - unsigned char img[yn][xn][4])) { - struct stat st; - int fd, yn, xn; - void *map, *data; - 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); - fadvise(fd, 0, 0, MADV_WILLNEED | MADV_SEQUENTIAL); - 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); -} - -int main(int argc, char *argv[]) { - int i, opt; - bool bilinear; - void (*scaler)(unsigned yn, unsigned xn, unsigned char[yn][xn][4]) = - ProcessImageMagikarp; - r_ = 2; - while ((opt = getopt(argc, argv, "mlsSybr:")) != -1) { - switch (opt) { - case 'r': - r_ = strtod(optarg, NULL); - break; - case 'm': - scaler = ProcessImageMagikarp; - break; - case 's': - case 'S': - scaler = ProcessImageGyarados; - break; - case 'b': - scaler = ProcessImageBilinear; - break; - default: - break; - } - } - ShowCrashReports(); - for (i = optind; i < argc; ++i) { - WithImageFile(argv[i], scaler); - } - return 0; -} diff --git a/tool/viz/memplan.c b/tool/viz/memplan.c deleted file mode 100644 index e31421bbe..000000000 --- a/tool/viz/memplan.c +++ /dev/null @@ -1,95 +0,0 @@ -#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/internal.h" -#include "libc/fmt/conv.h" -#include "libc/fmt/itoa.h" -#include "libc/intrin/bits.h" -#include "libc/macros.internal.h" -#include "libc/runtime/memtrack.internal.h" -#include "libc/stdio/stdio.h" -// clang-format off - -struct WinArgs { - char *argv[4096]; - char *envp[4092]; - intptr_t auxv[2][2]; - char argblock[ARG_MAX / 2]; - char envblock[ARG_MAX / 2]; -}; - -//#define INCREMENT _roundup2pow(kAutomapSize/16) -#define INCREMENT (64L*1024*1024*1024) - -uint64_t last; - -void plan2(uint64_t addr, uint64_t end, const char *name) { - char sz[32]; - sizefmt(sz, end-addr+1, 1024); - printf("%08x-%08x %-6s %s\n", addr>>16, end>>16, sz, name); -} - -void plan(uint64_t addr, uint64_t end, const char *name) { - uint64_t incr, next; - while (addr > last) { - if ((incr = last % INCREMENT)) { - incr = INCREMENT - incr; - } else { - incr = INCREMENT; - } - plan2(last,MIN(last+incr,addr)-1,"free"); - last = MIN(last+incr,addr); - } - while (addr <= end) { - if (end-addr+1 <= INCREMENT) { - plan2(addr,end,name); - last = end + 1; - break; - } - if (!(addr % INCREMENT)) { - plan2(addr, addr + INCREMENT - 1, name); - last = addr + INCREMENT; - addr += INCREMENT; - } else { - next = INCREMENT - addr % INCREMENT + addr; - plan2(addr, next - 1, name); - last = next; - addr = next; - } - } -} - -int main(int argc, char *argv[]) { - uint64_t x, y; - - plan(0x00000000, 0x00200000-1, "null"); - plan(0x00200000, 0x00400000-1, "loader"); - if (!IsWindows() || IsAtLeastWindows10()) { - plan(0x00400000, 0x50000000-1, "image"); - plan(0x50000000, 0x7ffdffff, "arena"); - plan(0x7fff0000, 0x10007fffffff, "asan"); - } else { - plan(0x00400000, 0x01000000-1, "image"); - } - plan(kAutomapStart, kAutomapStart + kAutomapSize - 1, "automap"); - plan(kMemtrackStart, kMemtrackStart + kMemtrackSize - 1, "memtrack"); - plan(kFixedmapStart, kFixedmapStart + kFixedmapSize - 1, "fixedmap"); - if (IsWindows() && !IsAtLeastWindows10()) { - plan(0x50000000, 0x7ffdffff, "arena"); - } - x = GetStaticStackAddr(0); - y = ROUNDUP(sizeof(struct WinArgs), FRAMESIZE); - plan(x - y, x - 1, "winargs"); - plan(x, x + GetStackSize() - 1, "stack"); - if (!IsWindows() || IsAtLeastWindows10()) { - plan(0x7f0000000000, 0x800000000000 - 1, "kernel"); - } - - return 0; -} diff --git a/tool/viz/ntmaster.c b/tool/viz/ntmaster.c deleted file mode 100644 index 2761448bf..000000000 --- a/tool/viz/ntmaster.c +++ /dev/null @@ -1,83 +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 2021 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/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/x/xgetline.h" - -#define DLL "iphlpapi" - -/** - * @fileoverview Tool for adding rnew libraries to libc/nt/master.sh - * - * If provided with a /tmp/syms.txt file containing one symbol name per - * line, this tool will output the correctly tab indented shell code. - */ - -int main(int argc, char *argv[]) { - FILE *f; - int i, n, t; - char *sym, tabs[64]; - ShowCrashReports(); - f = fopen("/tmp/syms.txt", "r"); - memset(tabs, '\t', 64); - while ((sym = _chomp(xgetline(f)))) { - if (strlen(sym)) { - printf("imp\t"); - - /* what we call the symbol */ - i = printf("'%s'", sym); - t = 0; - n = 56; - if (i % 8) ++t, i = ROUNDUP(i, 8); - t += (n - i) / 8; - printf("%.*s", t, tabs); - - /* what the kernel dll calls the symbol */ - i = printf("%s", sym); - t = 0; - n = 56; - if (i % 8) ++t, i = ROUNDUP(i, 8); - t += (n - i) / 8; - printf("%.*s", t, tabs); - - /* dll short name */ - i = printf("%s", DLL); - t = 0; - n = 16; - if (i % 8) ++t, i = ROUNDUP(i, 8); - t += (n - i) / 8; - printf("%.*s", t, tabs); - - /* hint */ - i = printf("0"); - t = 0; - n = 8; - if (i % 8) ++t, i = ROUNDUP(i, 8); - t += (n - i) / 8; - printf("%.*s", t, tabs); - - printf("\n"); - } - free(sym); - } - return 0; -} diff --git a/tool/viz/printpixel.c b/tool/viz/printpixel.c deleted file mode 100644 index de2ee784d..000000000 --- a/tool/viz/printpixel.c +++ /dev/null @@ -1,45 +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 "dsp/tty/quant.h" -#include "dsp/tty/xtermname.h" -#include "libc/fmt/conv.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" - -int main(int argc, char *argv[]) { - int i; - struct TtyRgb tty; - unsigned rgb, r, g, b; - if (argc < 2) { - fprintf(stderr, "Usage: %s RRGGBB...\n", program_invocation_name); - exit(EX_USAGE); - } - for (i = 1; i < argc; ++i) { - rgb = strtol(argv[i], NULL, 16); - b = (rgb & 0x0000ff) >> 000; - g = (rgb & 0x00ff00) >> 010; - r = (rgb & 0xff0000) >> 020; - tty = rgb2tty(r, g, b); - printf("\e[48;5;%dm \e[0m %d \\e[48;5;%dm %s #%02x%02x%02x\n", tty.xt, - tty.xt, tty.xt, IndexDoubleNulString(kXtermName, tty.xt), r, g, b); - } - return 0; -} diff --git a/tool/viz/rgbtoxterm.c b/tool/viz/rgbtoxterm.c deleted file mode 100644 index b569173a5..000000000 --- a/tool/viz/rgbtoxterm.c +++ /dev/null @@ -1,135 +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 "dsp/tty/quant.h" -#include "libc/calls/calls.h" -#include "libc/log/check.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "libc/sysv/consts/fileno.h" -#include "third_party/getopt/getopt.internal.h" - -#define kUsage \ - "Usage:\n\ -\n\ - %s [-cber] [-o FILE] [ARGS...]\n\ -\n\ -Flags:\n\ -\n\ - -e enable emphasis\n\ - -b emit as background color\n\ - -r print raw codes\n\ - -c emit cleanup (reset) codes when done\n\ - -o FILE redirects output [default: /dev/stdout]\n\ -\n\ -Arguments:\n\ -\n\ - - may be passed via ARGS or STDIN (one per line)\n\ - - may be #RRGGBB or RRGGBB\n\ - - may be #RGB or RGB (#123 → #112233)\n\ - - anything else is printed verbatim\n\ -\n" - -static FILE *fout_; -static size_t linecap_; -static char *outpath_, *line_; -static bool rawmode_, background_, emphasis_, cleanup_; - -wontreturn void usage(int rc, FILE *f) { - fprintf(f, kUsage, program_invocation_name); - exit(rc); -} - -void getopts(int *argc, char *argv[]) { - int opt; - outpath_ = "-"; - while ((opt = getopt(*argc, argv, "?hrecbo:")) != -1) { - switch (opt) { - case 'r': - rawmode_ = true; - break; - case 'b': - background_ = true; - break; - case 'c': - cleanup_ = true; - break; - case 'e': - emphasis_ = true; - break; - case 'o': - outpath_ = optarg; - break; - case '?': - case 'h': - usage(EXIT_SUCCESS, stdout); - default: - usage(EX_USAGE, stderr); - } - } -} - -void processarg(const char *arg) { - const char *p; - size_t r, g, b; - if (*(p = arg) == '#') p++; - if (strlen(p) == 3 && (isxdigit(p[0]) && isxdigit(p[1]) && isxdigit(p[2]))) { - r = hextoint(p[0]) << 4 | hextoint(p[0]); - g = hextoint(p[1]) << 4 | hextoint(p[1]); - b = hextoint(p[2]) << 4 | hextoint(p[2]); - } else if (strlen(p) == 6 && - (isxdigit(p[0]) && isxdigit(p[1]) && isxdigit(p[2]) && - isxdigit(p[3]) && isxdigit(p[4]) && isxdigit(p[5]))) { - r = hextoint(p[0]) << 4 | hextoint(p[1]); - g = hextoint(p[2]) << 4 | hextoint(p[3]); - b = hextoint(p[4]) << 4 | hextoint(p[5]); - } else { - fputs(arg, fout_); - return; - } - fprintf(fout_, "%s[%s%d;5;%hhum%s", rawmode_ ? "\e" : "\\e", - emphasis_ ? "1;" : "", background_ ? 48 : 38, rgb2tty(r, g, b).xt, - &"\n"[rawmode_]); -} - -int main(int argc, char *argv[]) { - size_t i; - getopts(&argc, argv); - CHECK_NOTNULL((fout_ = fopen(outpath_, "w"))); - if (optind < argc) { - for (i = optind; i < argc; ++i) { - processarg(argv[i]); - } - } else { - while ((getline(&line_, &linecap_, stdin)) != -1) { - processarg(_chomp(line_)); - } - free(line_); - line_ = 0; - } - if (cleanup_) { - fprintf(fout_, "%s[0m\n", rawmode_ ? "\e" : "\\e"); - } - CHECK_NE(-1, fclose(fout_)); - fout_ = 0; - return 0; -} diff --git a/tool/viz/tabalign.c b/tool/viz/tabalign.c deleted file mode 100644 index 51d88ce19..000000000 --- a/tool/viz/tabalign.c +++ /dev/null @@ -1,177 +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/fmt/conv.h" -#include "libc/intrin/safemacros.internal.h" -#include "libc/limits.h" -#include "libc/log/check.h" -#include "libc/log/log.h" -#include "libc/mem/arraylist.internal.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/str/strwidth.h" -#include "libc/str/unicode.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "third_party/getopt/getopt.internal.h" - -#define kOneTrueTabWidth 8 - -struct Pool { - size_t i, n; - char *p; -}; - -struct Lines { - size_t i, n; - struct Line { - uint16_t off; - uint16_t col; - int32_t line; - } * p; -}; - -static bool chunk_; -static FILE *fi_, *fo_; -static struct Pool pool_; -static struct Lines lines_; -static size_t mincol_, col_, maxcol_, linecap_; -static char *inpath_, *outpath_, *delim_, *line_; - -wontreturn void usage(int rc, FILE *f) { - fprintf(f, "%s%s%s\n", "Usage: ", program_invocation_name, - " [-c] [-m MINCOL] [-M MAXCOL] [-F DELIM] [-o FILE] [FILE...]\n" - "\n" - " This program aligns monospace text. It's aware of tabs,\n" - " color codes, wide characters, combining characters etc.\n"); - exit(rc); -} - -void getopts(int *argc, char *argv[]) { - int opt; - delim_ = "#"; - outpath_ = "-"; - while ((opt = getopt(*argc, argv, "?hco:m:M:F:")) != -1) { - switch (opt) { - case 'm': - mincol_ = strtol(optarg, NULL, 0); - break; - case 'M': - maxcol_ = strtol(optarg, NULL, 0); - break; - case 'c': - chunk_ = true; - break; - case 'o': - outpath_ = optarg; - break; - case 'F': - delim_ = optarg; - break; - case '?': - case 'h': - usage(EXIT_SUCCESS, stdout); - default: - usage(EX_USAGE, stderr); - } - } - if (optind == *argc) { - argv[(*argc)++] = "-"; - } -} - -void flush(void) { - size_t i, j; - const char *s; - struct Line l; - col_ = roundup(col_ + 1, kOneTrueTabWidth); - if (maxcol_) col_ = min(col_, maxcol_); - for (i = 0; i < lines_.i; ++i) { - l = lines_.p[i]; - s = &pool_.p[l.line]; - if (l.off < USHRT_MAX) { - fwrite(s, l.off, 1, fo_); - for (j = l.col; j < col_;) { - fputc('\t', fo_); - if (j % kOneTrueTabWidth == 0) { - j += 8; - } else { - j += kOneTrueTabWidth - (j & (kOneTrueTabWidth - 1)); - } - } - fwrite(s + l.off, strlen(s) - l.off, 1, fo_); - } else { - fwrite(s, strlen(s), 1, fo_); - } - fputc('\n', fo_); - } - col_ = mincol_; - pool_.i = 0; - lines_.i = 0; -} - -void processfile(void) { - char *p; - int col, s; - size_t off, len; - while ((getline(&line_, &linecap_, fi_)) != -1) { - _chomp(line_); - len = strlen(line_); - s = concat(&pool_, line_, len + 1); - if (len < USHRT_MAX) { - if ((p = strstr(line_, delim_))) { - off = p - line_; - col = strnwidth(line_, off, 0); - if (col < USHRT_MAX) { - col_ = max(col_, col); - append(&lines_, &((struct Line){.line = s, .off = off, .col = col})); - continue; - } - } else { - if (chunk_) { - flush(); - fputs(line_, fo_); - fputc('\n', fo_); - continue; - } - } - } - append(&lines_, &((struct Line){.line = s, .off = 0xffff, .col = 0xffff})); - } -} - -int main(int argc, char *argv[]) { - size_t i; - getopts(&argc, argv); - CHECK_NOTNULL((fo_ = fopen(outpath_, "w"))); - for (i = optind; i < argc; ++i) { - CHECK_NOTNULL((fi_ = fopen((inpath_ = argv[i]), "r"))); - processfile(); - CHECK_NE(-1, fclose(fi_)); - fi_ = 0; - } - flush(); - CHECK_NE(-1, fclose(fo_)); - fo_ = 0; - free(lines_.p); - free(pool_.p); - free(line_); - return 0; -} diff --git a/tool/viz/tcp.c b/tool/viz/tcp.c deleted file mode 100644 index 8a3c6559a..000000000 --- a/tool/viz/tcp.c +++ /dev/null @@ -1,156 +0,0 @@ -#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/intrin/bits.h" -#include "libc/stdio/stdio.h" -// clang-format off - -static char ip[] = "\ -\x45\x00\x00\x3c\xc8\xbc\x40\x00\x40\x06\x48\xf6\x7f\x0a\x0a\x7a\ -\x7f\x0a\x0a\x7c\xe2\x24\x1b\x58\xf6\xe9\xf2\x85\x00\x00\x00\x00\ -\xa0\x02\xfa\xf0\x5f\xac\x00\x00\x02\x04\x05\xb4\x04\x02\x08\x0a\ -\x4a\x43\x93\x29\x00\x00\x00\x00\x01\x03\x03\x07"; - -static const char *const kTcpOptionNames[] = { - [0] = "End of Option List", - [1] = "No-Operation", - [2] = "Maximum Segment Size", - [3] = "Window Scale", - [4] = "SACK Permitted", - [5] = "SACK", - [6] = "Echo (obsoleted by option 8)", - [7] = "Echo Reply (obsoleted by option 8)", - [8] = "Timestamps", - [9] = "Partial Order Connection Permitted (obsolete)", - [10] = "Partial Order Service Profile (obsolete)", - [11] = "CC (obsolete)", - [12] = "CC.NEW (obsolete)", - [13] = "CC.ECHO (obsolete)", - [14] = "TCP Alternate Checksum Request (obsolete)", - [15] = "TCP Alternate Checksum Data (obsolete)", - [16] = "Skeeter", - [17] = "Bubba", - [18] = "Trailer Checksum Option", - [19] = "MD5 Signature Option (obsoleted by option 29)", - [20] = "SCPS Capabilities", - [21] = "Selective Negative Acknowledgements", - [22] = "Record Boundaries", - [23] = "Corruption experienced", - [24] = "SNAP", - [25] = "Unassigned (released 2000-12-18)", - [26] = "TCP Compression Filter", - [27] = "Quick-Start Response", - [28] = "User Timeout Option", - [29] = "TCP Authentication Option (TCP-AO)", - [30] = "Multipath TCP (MPTCP)", - [31] = "Reserved (known unauthorized use without proper IANA assignm", - [32] = "Reserved (known unauthorized use without proper IANA assignm", - [33] = "Reserved (known unauthorized use without proper IANA assignm", - [34] = "variable TCP Fast Open Cookie", - [35] = "Reserved", - [69] = "Encryption Negotiation", - [253] = "RFC3692-1", - [254] = "RFC3692-2", -}; - -int main(int argc, char *argv[]) { - int version = (ip[0] & 0b11110000) >> 4; - int ihl = (ip[0] & 0b00001111) >> 0; - int dscp = (ip[1] & 0b11111100) >> 2; - int ecn = (ip[1] & 0b00000011) >> 0; - int lengthtotal = READ16BE(ip + 2); - int identification = READ16BE(ip + 4); - int flags = (ip[6] & 0b11100000) >> 5; - int fragmentoffset = (ip[6] & 0b00011111) << 8 | (ip[7] & 255); - int ttl = ip[8] & 255; - int protocol = ip[9] & 255; - int ipchecksum = (ip[10] & 255) << 8 | (ip[11] & 255); - int srcip = READ32BE(ip + 12); - int dstip = READ32BE(ip + 16); - - printf("\n"); - printf("// version = %u\n", version); - printf("// ihl = %u\n", ihl * 4); - printf("// dscp = %u\n", dscp); - printf("// ecn = %u\n", ecn); - printf("// lengthtotal = %u\n", lengthtotal); - printf("// identification = %u\n", identification); - printf("// flags = %u\n", flags); - printf("// fragmentoffset = %u\n", fragmentoffset); - printf("// ttl = %u\n", ttl); - printf("// protocol = %u\n", protocol); - printf("// ipchecksum = %u\n", ipchecksum); - printf("// srcip = %hhu.%hhu.%hhu.%hhu\n", srcip >> 24, srcip >> 16, srcip >> 8, srcip); - printf("// dstip = %hhu.%hhu.%hhu.%hhu\n", dstip >> 24, dstip >> 16, dstip >> 8, dstip); - printf("// \n"); - - char *tcp = ip + ihl * 4; - int srcport = READ16BE(tcp + 0); - int dstport = READ16BE(tcp + 2); - int sequence = READ32BE(tcp + 4); - int acknumber = READ32BE(tcp + 8); - int dataoffset = (tcp[12] & 0b11110000) >> 4; - bool ns = !!(tcp[12] & 0b00000001); - bool cwr = !!(tcp[13] & 0b10000000); - bool ece = !!(tcp[13] & 0b01000000); - bool urg = !!(tcp[13] & 0b00100000); - bool ack = !!(tcp[13] & 0b00010000); - bool psh = !!(tcp[13] & 0b00001000); - bool rst = !!(tcp[13] & 0b00000100); - bool syn = !!(tcp[13] & 0b00000010); - bool fin = !!(tcp[13] & 0b00000001); - int wsize = READ16BE(tcp + 14); - int tcpchecksum = READ16BE(tcp + 16); - int urgpointer = READ16BE(tcp + 18); - - printf("// srcport = %u\n", srcport); - printf("// dstport = %u\n", dstport); - printf("// sequence = %u\n", sequence); - printf("// acknumber = %u\n", acknumber); - printf("// dataoffset = %u\n", dataoffset); - printf("// ns = %u\n", ns); - printf("// cwr = %u\n", cwr); - printf("// ece = %u\n", ece); - printf("// urg = %u\n", urg); - printf("// ack = %u\n", ack); - printf("// psh = %u\n", psh); - printf("// rst = %u\n", rst); - printf("// syn = %u\n", syn); - printf("// fin = %u\n", fin); - printf("// wsize = %u\n", wsize); - printf("// tcpchecksum = %u\n", tcpchecksum); - printf("// urgpointer = %u\n", urgpointer); - printf("// \n"); - - int c, i, j, n; - for (i = 20; i + 1 < dataoffset * 4;) { - printf("// option"); - switch ((c = tcp[i] & 255)) { - case 0: - case 1: - printf(" %u", c); - ++i; - break; - default: - n = tcp[i + 1] & 255; - printf(" %u %u", c, n); - for (j = 2; j < n; ++j) { - printf(" %u", tcp[i + j] & 255); - } - i += n; - break; - } - if (kTcpOptionNames[c]) { - printf(" (%s)", kTcpOptionNames[c]); - } - printf("\n"); - } - - return 0; -} diff --git a/tool/viz/unicode.c b/tool/viz/unicode.c deleted file mode 100644 index 8c6d69ab7..000000000 --- a/tool/viz/unicode.c +++ /dev/null @@ -1,91 +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/str/unicode.h" -#include "libc/fmt/fmt.h" -#include "libc/mem/gc.h" -#include "libc/mem/mem.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/x/xasprintf.h" - -int a, b, w, i; -char name[512]; - -void DisplayUnicodeCharacter(void) { - int c, cw; - c = i; - cw = wcwidth(c); - if (cw < 1) { - c = '?'; - cw = 1; - } - if (w) { - if (w + 1 + cw > 80) { - printf("\n"); - w = 0; - } else { - fputc(' ', stdout); - w += 1 + cw; - } - } - if (!w) { - printf("%08x ", i); - w = 9 + cw; - } - fputwc(c, stdout); -} - -void DisplayUnicodeBlock(void) { - if (a == 0x10000) { - printf("\n\n\n\n\n\n\n " - "ASTRAL PLANES\n\n\n\n\n"); - } - if (a == 0x0590 /* hebrew */) return; - if (a == 0x0600 /* arabic */) return; - if (a == 0x08a0 /* arabic */) return; - if (a == 0x0750 /* arabic */) return; - if (a == 0x0700 /* syriac */) return; - if (a == 0x10800 /* cypriot */) return; - printf("\n\n%-60s%20s\n" - "──────────────────────────────────────────────" - "──────────────────────────────────\n", - name, _gc(xasprintf("%04x .. %04x", a, b))); - w = 0; - for (i = a; i <= b; ++i) { - DisplayUnicodeCharacter(); - } -} - -int main(int argc, char *argv[]) { - FILE *f; - char *line; - size_t linesize; - printf("\n\n\n\n\n UNICODE PLANES\n\n\n\n"); - f = fopen("libc/str/blocks.txt", "r"); - line = NULL; - linesize = 0; - while (!feof(f)) { - if (getline(&line, &linesize, f) == -1) break; - if (sscanf(line, "%x..%x; %s", &a, &b, name) != 3) continue; - DisplayUnicodeBlock(); - } - free(line); - fclose(f); - return 0; -} diff --git a/tool/viz/upscalefloat.c b/tool/viz/upscalefloat.c deleted file mode 100644 index 6bdd087f3..000000000 --- a/tool/viz/upscalefloat.c +++ /dev/null @@ -1,212 +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/calls/calls.h" -#include "libc/calls/struct/stat.h" -#include "libc/limits.h" -#include "libc/log/check.h" -#include "libc/macros.internal.h" -#include "libc/math.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.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/x/x.h" -#include "third_party/stb/stb_image.h" - -#define C13(A, B) (((A) + 3 * (B)) / 4) -#define S3T(A, B, C) MAX(0, ((24 * (B)) - (4 * ((A) + (C)))) / 16) -#define LERP(A, B, P) ((A) * (1 - (P)) + (B) * (P)) - -float ByteToFloat(int b) { - return 1 / 255.f * b; -} - -int FloatToByte(float f) { - return MAX(0, MIN(255, roundf(255 * f))); -} - -float ChessBoard(unsigned y, unsigned x, float a, float b) { - return !((y ^ x) & (1u << 2)) ? a : b; -} - -float AlphaBackground(unsigned y, unsigned x) { - return ChessBoard(y, x, 1.f, .7f); -} - -float OutOfBoundsBackground(unsigned y, unsigned x) { - return ChessBoard(y, x, .01f, .02f); -} - -float Opacify(size_t yn, size_t xn, const float P[yn][xn], - const float A[yn][xn], long y, long x) { - if ((0 <= y && y < yn) && (0 <= x && x < xn)) { - return LERP(AlphaBackground(y, x), P[y][x], A[y][x]); - } else { - return OutOfBoundsBackground(y, x); - } -} - -void PrintImage(size_t yn, size_t xn, float R[yn][xn], float G[yn][xn], - float B[yn][xn], float A[yn][xn]) { - unsigned y, x; - for (y = 0; y < yn; y += 2) { - if (y) printf("\e[0m\n"); - for (x = 0; x < xn; ++x) { - printf("\e[48;2;%d;%d;%d;38;2;%d;%d;%dm▄", - FloatToByte(Opacify(yn, xn, R, A, y + 0, x)), - FloatToByte(Opacify(yn, xn, G, A, y + 0, x)), - FloatToByte(Opacify(yn, xn, B, A, y + 0, x)), - FloatToByte(Opacify(yn, xn, R, A, y + 1, x)), - FloatToByte(Opacify(yn, xn, G, A, y + 1, x)), - FloatToByte(Opacify(yn, xn, B, A, y + 1, x))); - } - } - printf("\e[0m\n"); -} - -void DeblinterlaceRgba(size_t dyn, size_t dxn, float R[dyn][dxn], - float G[dyn][dxn], float B[dyn][dxn], float A[dyn][dxn], - size_t syn, size_t sxn, - const unsigned char src[syn][sxn][4]) { - unsigned y, x; - for (y = 0; y < syn; ++y) { - for (x = 0; x < sxn; ++x) { - R[y][x] = ByteToFloat(src[y][x][0]); - G[y][x] = ByteToFloat(src[y][x][1]); - B[y][x] = ByteToFloat(src[y][x][2]); - A[y][x] = ByteToFloat(src[y][x][3]); - } - } -} - -void SharpenX(size_t yw, size_t xw, float dst[yw][xw], const float src[yw][xw], - size_t yn, size_t xn) { - int y, x; - for (y = 0; y < yn; ++y) { - for (x = 0; x < xn; ++x) { - dst[y][x] = - S3T(src[y][MAX(0, x - 1)], src[y][x], src[y][MIN(xn - 1, x + 1)]); - } - } -} - -void SharpenY(size_t yw, size_t xw, float dst[yw][xw], const float src[yw][xw], - size_t yn, size_t xn) { - int y, x; - for (y = 0; y < yn; ++y) { - for (x = 0; x < xn; ++x) { - dst[y][x] = - S3T(src[MAX(0, y - 1)][x], src[y][x], src[MIN(yn - 1, y + 1)][x]); - } - } -} - -void UpscaleX(size_t yw, size_t xw, float img[yw][xw], size_t yn, size_t xn) { - unsigned y, x; - for (y = yn; y--;) { - for (x = xn; --x;) { - img[y][x] = - C13(img[y][MIN(xn / 2 - 1, x / 2 - 1 + x % 2 * 2)], img[y][x / 2]); - } - } -} - -void UpscaleY(size_t yw, size_t xw, float img[yw][xw], size_t yn, size_t xn) { - unsigned y, x; - for (y = yn; --y;) { - for (x = xn; x--;) { - img[y][x] = - C13(img[MIN(yn / 2 - 1, y / 2 - 1 + y % 2 * 2)][x], img[y / 2][x]); - } - } -} - -void Upscale(size_t yw, size_t xw, float img[yw][xw], float tmp[yw][xw], - size_t yn, size_t xn) { - UpscaleY(yw, xw, img, yn, xn / 2); - SharpenY(yw, xw, tmp, img, yn, xn / 2); - UpscaleX(yw, xw, tmp, yn, xn); - SharpenX(yw, xw, img, tmp, yn, xn); -} - -void ProcessImageDouble(size_t yn, size_t xn, unsigned char img[yn][xn][4]) { - void *t = xmemalign(32, sizeof(float) * yn * 2 * xn * 2); - void *R = xmemalign(32, sizeof(float) * yn * 2 * xn * 2); - void *G = xmemalign(32, sizeof(float) * yn * 2 * xn * 2); - void *B = xmemalign(32, sizeof(float) * yn * 2 * xn * 2); - void *A = xmemalign(32, sizeof(float) * yn * 2 * xn * 2); - DeblinterlaceRgba(yn * 2, xn * 2, R, G, B, A, yn, xn, img); - Upscale(yn * 2, xn * 2, R, t, yn * 2, xn * 2); - Upscale(yn * 2, xn * 2, G, t, yn * 2, xn * 2); - Upscale(yn * 2, xn * 2, B, t, yn * 2, xn * 2); - Upscale(yn * 2, xn * 2, A, t, yn * 2, xn * 2); - free(t); - PrintImage(yn * 2, xn * 2, R, G, B, A); - free(R); - free(G); - free(B); - free(A); -} - -void ProcessImage(size_t yn, size_t xn, unsigned char img[yn][xn][4]) { - void *R = xmemalign(32, sizeof(float) * yn * xn); - void *G = xmemalign(32, sizeof(float) * yn * xn); - void *B = xmemalign(32, sizeof(float) * yn * xn); - void *A = xmemalign(32, sizeof(float) * yn * xn); - DeblinterlaceRgba(yn, xn, R, G, B, A, yn, xn, img); - PrintImage(yn, xn, R, G, B, A); - free(R); - free(G); - free(B); - free(A); -} - -void WithImageFile(const char *path, void fn(size_t yn, size_t xn, - unsigned char img[yn][xn][4])) { - struct stat st; - int fd, yn, xn; - void *map, *data; - 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); - fadvise(fd, 0, 0, MADV_WILLNEED | MADV_SEQUENTIAL); - 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); -} - -int main(int argc, char *argv[]) { - int i; - for (i = 1; i < argc; ++i) { - WithImageFile(argv[i], ProcessImageDouble); - } - return 0; -} diff --git a/tool/viz/upscaleint.c b/tool/viz/upscaleint.c deleted file mode 100644 index c757b0704..000000000 --- a/tool/viz/upscaleint.c +++ /dev/null @@ -1,209 +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/calls/calls.h" -#include "libc/calls/struct/stat.h" -#include "libc/limits.h" -#include "libc/log/check.h" -#include "libc/macros.internal.h" -#include "libc/math.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.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/x/x.h" -#include "third_party/stb/stb_image.h" - -#define CLAMP(X) MAX(0, MIN(255, X)) -#define C13(A, B) (((A) + 3 * (B) + 2) >> 2) -#define S3T(A, B, C) CLAMP(-((A) >> 2) + ((B) + ((B) >> 1)) + -((C) >> 2)) -#define LERP(X, Y, P) ((X) + (((P) * ((Y) - (X))) >> 8)) - -static unsigned char ChessBoard(unsigned y, unsigned x, unsigned char a, - unsigned char b) { - return !((y ^ x) & (1u << 2)) ? a : b; -} - -static unsigned char AlphaBackground(unsigned y, unsigned x) { - return ChessBoard(y, x, 255, 200); -} - -static unsigned char OutOfBoundsBackground(unsigned y, unsigned x) { - return ChessBoard(y, x, 40, 80); -} - -static unsigned char Opacify(size_t yn, size_t xn, - const unsigned char P[yn][xn], - const unsigned char A[yn][xn], long y, long x) { - if ((0 <= y && y < yn) && (0 <= x && x < xn)) { - return LERP(AlphaBackground(y, x), P[y][x], A[y][x]); - } else { - return OutOfBoundsBackground(y, x); - } -} - -static void PrintImage(size_t yn, size_t xn, unsigned char R[yn][xn], - unsigned char G[yn][xn], unsigned char B[yn][xn], - unsigned char A[yn][xn]) { - unsigned y, x; - for (y = 0; y < yn; y += 2) { - if (y) printf("\e[0m\n"); - for (x = 0; x < xn; ++x) { - printf("\e[48;2;%d;%d;%d;38;2;%d;%d;%dm▄", - Opacify(yn, xn, R, A, y + 0, x), Opacify(yn, xn, G, A, y + 0, x), - Opacify(yn, xn, B, A, y + 0, x), Opacify(yn, xn, R, A, y + 1, x), - Opacify(yn, xn, G, A, y + 1, x), Opacify(yn, xn, B, A, y + 1, x)); - } - } - printf("\e[0m\n"); -} - -static void DeblinterlaceRgba(size_t dyn, size_t dxn, unsigned char R[dyn][dxn], - unsigned char G[dyn][dxn], - unsigned char B[dyn][dxn], - unsigned char A[dyn][dxn], size_t syn, size_t sxn, - const unsigned char src[syn][sxn][4]) { - unsigned y, x; - for (y = 0; y < syn; ++y) { - for (x = 0; x < sxn; ++x) { - R[y][x] = src[y][x][0]; - G[y][x] = src[y][x][1]; - B[y][x] = src[y][x][2]; - A[y][x] = src[y][x][3]; - } - } -} - -static void SharpenX(size_t yw, size_t xw, unsigned char dst[yw][xw], - const unsigned char src[yw][xw], size_t yn, size_t xn) { - int y, x; - for (y = 0; y < yn; ++y) { - for (x = 0; x < xn; ++x) { - dst[y][x] = - S3T(src[y][MAX(0, x - 1)], src[y][x], src[y][MIN(xn - 1, x + 1)]); - } - } -} - -static void SharpenY(size_t yw, size_t xw, unsigned char dst[yw][xw], - const unsigned char src[yw][xw], size_t yn, size_t xn) { - int y, x; - for (y = 0; y < yn; ++y) { - for (x = 0; x < xn; ++x) { - dst[y][x] = - S3T(src[MAX(0, y - 1)][x], src[y][x], src[MIN(yn - 1, y + 1)][x]); - } - } -} - -static void UpscaleX(size_t yw, size_t xw, unsigned char img[yw][xw], size_t yn, - size_t xn) { - unsigned y, x; - for (y = yn; y--;) { - for (x = xn; --x;) { - img[y][x] = - C13(img[y][MIN(xn / 2 - 1, x / 2 - 1 + x % 2 * 2)], img[y][x / 2]); - } - } -} - -static void UpscaleY(size_t yw, size_t xw, unsigned char img[yw][xw], size_t yn, - size_t xn) { - unsigned y, x; - for (y = yn; --y;) { - for (x = xn; x--;) { - img[y][x] = - C13(img[MIN(yn / 2 - 1, y / 2 - 1 + y % 2 * 2)][x], img[y / 2][x]); - } - } -} - -static void Upscale(size_t yw, size_t xw, unsigned char img[yw][xw], - unsigned char tmp[yw][xw], size_t yn, size_t xn) { - UpscaleY(yw, xw, img, yn, xn / 2); - SharpenY(yw, xw, tmp, img, yn, xn / 2); - UpscaleX(yw, xw, tmp, yn, xn); - SharpenX(yw, xw, img, tmp, yn, xn); -} - -static void ProcessImageDouble(size_t yn, size_t xn, - unsigned char img[yn][xn][4]) { - void *t = xmemalign(32, sizeof(unsigned char) * yn * 2 * xn * 2); - void *R = xmemalign(32, sizeof(unsigned char) * yn * 2 * xn * 2); - void *G = xmemalign(32, sizeof(unsigned char) * yn * 2 * xn * 2); - void *B = xmemalign(32, sizeof(unsigned char) * yn * 2 * xn * 2); - void *A = xmemalign(32, sizeof(unsigned char) * yn * 2 * xn * 2); - DeblinterlaceRgba(yn * 2, xn * 2, R, G, B, A, yn, xn, img); - Upscale(yn * 2, xn * 2, R, t, yn * 2, xn * 2); - Upscale(yn * 2, xn * 2, G, t, yn * 2, xn * 2); - Upscale(yn * 2, xn * 2, B, t, yn * 2, xn * 2); - Upscale(yn * 2, xn * 2, A, t, yn * 2, xn * 2); - free(t); - PrintImage(yn * 2, xn * 2, R, G, B, A); - free(R); - free(G); - free(B); - free(A); -} - -static void ProcessImage(size_t yn, size_t xn, unsigned char img[yn][xn][4]) { - void *R = xmemalign(32, sizeof(unsigned char) * yn * xn); - void *G = xmemalign(32, sizeof(unsigned char) * yn * xn); - void *B = xmemalign(32, sizeof(unsigned char) * yn * xn); - void *A = xmemalign(32, sizeof(unsigned char) * yn * xn); - DeblinterlaceRgba(yn, xn, R, G, B, A, yn, xn, img); - PrintImage(yn, xn, R, G, B, A); - free(R); - free(G); - free(B); - free(A); -} - -void WithImageFile(const char *path, void fn(size_t yn, size_t xn, - unsigned char img[yn][xn][4])) { - struct stat st; - int fd, yn, xn; - void *map, *data; - 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); - fadvise(fd, 0, 0, MADV_WILLNEED | MADV_SEQUENTIAL); - 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); -} - -int main(int argc, char *argv[]) { - int i; - for (i = 1; i < argc; ++i) { - WithImageFile(argv[i], ProcessImageDouble); - } - return 0; -} diff --git a/tool/viz/vdsodump.c b/tool/viz/vdsodump.c deleted file mode 100644 index fc50f0944..000000000 --- a/tool/viz/vdsodump.c +++ /dev/null @@ -1,85 +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/calls/struct/sigaction.h" -#include "libc/calls/struct/siginfo.h" -#include "libc/calls/ucontext.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/sysv/consts/auxv.h" -#include "libc/sysv/consts/sa.h" -#include "libc/sysv/consts/sig.h" -#include "third_party/xed/x86.h" -#ifdef __x86_64__ - -#define OUTPATH "vdso.elf" - -volatile bool finished; - -void OnSegmentationFault(int sig, siginfo_t *si, void *vctx) { - struct XedDecodedInst xedd; - ucontext_t *ctx = vctx; - xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64); - xed_instruction_length_decode(&xedd, (void *)ctx->uc_mcontext.rip, 15); - ctx->uc_mcontext.rip += xedd.length; - finished = true; -} - -int main(int argc, char *argv[]) { - FILE *f; - int byte; - volatile unsigned char *vdso, *p; - - vdso = (unsigned char *)getauxval(AT_SYSINFO_EHDR); - if (vdso) { - fprintf(stderr, "vdso found at address %p\n", vdso); - } else { - fprintf(stderr, "error: AT_SYSINFO_EHDR was not in auxiliary values\n"); - return 1; - } - - f = fopen(OUTPATH, "wb"); - if (!f) { - fprintf(stderr, "error: fopen(%`'s) failed\n", OUTPATH); - return 1; - } - - struct sigaction sa = { - .sa_sigaction = OnSegmentationFault, - .sa_flags = SA_SIGINFO, - }; - sigaction(SIGSEGV, &sa, 0); - sigaction(SIGBUS, &sa, 0); - - p = vdso; - for (;;) { - byte = *p++; - if (!finished) { - fputc(byte, f); - } else { - break; - } - } - - fclose(f); - fprintf(stderr, "%zu bytes dumped to %s\n", p - vdso, OUTPATH); - - return 0; -} - -#endif /* __x86_64__ */ diff --git a/tool/viz/vdsosyms.c b/tool/viz/vdsosyms.c deleted file mode 100644 index c97921d7e..000000000 --- a/tool/viz/vdsosyms.c +++ /dev/null @@ -1,166 +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/elf/def.h" -#include "libc/elf/scalar.h" -#include "libc/elf/struct/ehdr.h" -#include "libc/elf/struct/phdr.h" -#include "libc/elf/struct/sym.h" -#include "libc/elf/struct/verdaux.h" -#include "libc/elf/struct/verdef.h" -#include "libc/intrin/kprintf.h" -#include "libc/intrin/strace.internal.h" -#include "libc/runtime/runtime.h" -#include "libc/sysv/consts/auxv.h" - -static inline void PrintDsoSymbolVersions(Elf64_Verdef *vd, int sym, - char *strtab) { - Elf64_Verdaux *aux; - for (;; vd = (Elf64_Verdef *)((char *)vd + vd->vd_next)) { - if (!(vd->vd_flags & VER_FLG_BASE) && - (vd->vd_ndx & 0x7fff) == (sym & 0x7fff)) { - aux = (Elf64_Verdaux *)((char *)vd + vd->vd_aux); - kprintf(" %s", strtab + aux->vda_name); - } - if (!vd->vd_next) { - break; - } - } -} - -int PrintVdsoSymbols(void) { - void *p; - size_t i; - Elf64_Ehdr *ehdr; - Elf64_Phdr *phdr; - char *strtab = 0; - size_t *dyn, base; - unsigned long *ap; - Elf64_Sym *symtab = 0; - uint16_t *versym = 0; - Elf_Symndx *hashtab = 0; - Elf64_Verdef *verdef = 0; - const char *typename, *bindname; - - for (ehdr = 0, ap = __auxv; ap[0]; ap += 2) { - if (ap[0] == AT_SYSINFO_EHDR) { - ehdr = (void *)ap[1]; - break; - } - } - if (!ehdr) { - kprintf("error: AT_SYSINFO_EHDR not found\n"); - return 1; - } - - phdr = (void *)((char *)ehdr + ehdr->e_phoff); - for (base = -1, dyn = 0, i = 0; i < ehdr->e_phnum; - i++, phdr = (void *)((char *)phdr + ehdr->e_phentsize)) { - switch (phdr->p_type) { - case PT_LOAD: - // modern linux uses the base address zero, but elders - // e.g. rhel7 uses the base address 0xffffffffff700000 - base = (size_t)ehdr + phdr->p_offset - phdr->p_vaddr; - break; - case PT_DYNAMIC: - dyn = (void *)((char *)ehdr + phdr->p_offset); - break; - default: - break; - } - } - if (!dyn || base == -1) { - kprintf("error: missing program headers\n"); - return 2; - } - - for (i = 0; dyn[i]; i += 2) { - p = (void *)(base + dyn[i + 1]); - switch (dyn[i]) { - case DT_STRTAB: - strtab = p; - break; - case DT_SYMTAB: - symtab = p; - break; - case DT_HASH: - hashtab = p; - break; - case DT_VERSYM: - versym = p; - break; - case DT_VERDEF: - verdef = p; - break; - } - } - if (!verdef) { - versym = 0; - } - - if (!strtab || !symtab || !hashtab) { - kprintf("error: strtab/symtab/hashtab not found\n"); - return 3; - } - - for (i = 0; i < hashtab[1]; i++) { - if (!symtab[i].st_shndx) { - continue; - } - - switch (ELF64_ST_BIND(symtab[i].st_info)) { - case STB_LOCAL: - bindname = "locl"; - break; - case STB_GLOBAL: - bindname = "glob"; - break; - case STB_WEAK: - bindname = "weak"; - break; - default: - bindname = "????"; - break; - } - - switch (ELF64_ST_TYPE(symtab[i].st_info)) { - case STT_FUNC: - typename = "func"; - break; - case STT_OBJECT: - typename = " obj"; - break; - case STT_NOTYPE: - typename = "none"; - break; - default: - typename = "????"; - break; - } - - kprintf("%s %s %-40s", bindname, typename, strtab + symtab[i].st_name); - PrintDsoSymbolVersions(verdef, versym[i], strtab); - kprintf("\n"); - } - - return 0; -} - -int main(int argc, char *argv[]) { - return PrintVdsoSymbols(); -} diff --git a/tool/viz/xterm256cubes.c b/tool/viz/xterm256cubes.c deleted file mode 100644 index e9bb9f3e5..000000000 --- a/tool/viz/xterm256cubes.c +++ /dev/null @@ -1,97 +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/stdio/stdio.h" - -#define DIST(X, Y) ((X) - (Y)) -#define SQR(X) ((X) * (X)) -#define SUM(X, Y, Z) ((X) + (Y) + (Z)) - -static const uint8_t kXtermCube[] = {0, 0137, 0207, 0257, 0327, 0377}; - -static int uncube(int x) { - return x < 48 ? 0 : x < 115 ? 1 : (x - 35) / 40; -} - -static int rgb2xterm256(int r, int g, int b) { - unsigned av, ir, ig, ib, il, qr, qg, qb, ql; - av = (r + g + b) / 3; - ql = (il = av > 238 ? 23 : (av - 3) / 10) * 10 + 8; - qr = kXtermCube[(ir = uncube(r))]; - qg = kXtermCube[(ig = uncube(g))]; - qb = kXtermCube[(ib = uncube(b))]; - if (SUM(SQR(DIST(qr, r)), SQR(DIST(qg, g)), SQR(DIST(qb, b))) <= - SUM(SQR(DIST(ql, r)), SQR(DIST(ql, g)), SQR(DIST(ql, b)))) { - return ir * 36 + ig * 6 + ib + 020; - } else { - return il + 0350; - } -} - -bool IsUglyColorMixture(int rune, int y, int tone, bool toneisfg) { - assert(tone == 16 || (231 <= tone && tone <= 255)); - return false; -} - -int main(int argc, char *argv[]) { - unsigned y, z, x, k, w; - static const char16_t s[2][3] = {{u'▓', u'▒', u'░'}, {u'░', u'▒', u'▓'}}; - - printf("\npure\n"); - for (y = 0; y < 6; ++y) { - for (z = 0; z < 6; ++z) { - for (x = 0; x < 6; ++x) { - printf("\033[48;5;%hhum ", 16 + x + y * 6 + z * 6 * 6); - } - printf("\033[0m "); - } - printf("\n"); - } - -#define MIX(NAME, COLOR) \ - do { \ - printf("\n%s %d ▓░/▒▒/░▓\n", NAME, COLOR); \ - for (k = 0; k < 3; ++k) { \ - for (y = 0; y < 6; ++y) { \ - for (z = 0; z < 6; ++z) { \ - for (x = 0; x < 6; ++x) { \ - printf("\033[48;5;%hhu;38;5;%hhum%lc", COLOR, \ - 16 + x + y * 6 + z * 6 * 6, s[0][k]); \ - printf("\033[48;5;%hhu;38;5;%hhum%lc", 16 + x + y * 6 + z * 6 * 6, \ - COLOR, s[1][k]); \ - } \ - printf("\033[0m "); \ - } \ - printf("\n"); \ - } \ - } \ - } while (0) - - MIX("tint", 231); - MIX("tint", 255); - MIX("tint", 254); - MIX("tone", 240); - MIX("shade", 232); - - for (w = 233; w < 254; ++w) { - MIX("gray", w); - } - - return 0; -} diff --git a/tool/viz/xterm256effective.c b/tool/viz/xterm256effective.c deleted file mode 100644 index 639885654..000000000 --- a/tool/viz/xterm256effective.c +++ /dev/null @@ -1,183 +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 "dsp/tty/quant.h" -#include "libc/fmt/fmt.h" -#include "libc/intrin/bits.h" -#include "libc/intrin/xchg.internal.h" -#include "libc/math.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" - -/* #define ROUND(x) x */ -/* #define RT int */ -/* #define R1 1 */ -/* #define R2 2 */ -/* #define R3 3 */ - -#define RT float -#define MUL(x, y) ((x) * (y)) -#define RND(x) roundf(x) -#define R1 0.25f -#define R2 0.50f -#define R3 0.75f - -#define rgb_t struct TtyRgb - -forceinline RT lerp(RT x, RT y, RT d) { - return x * (1.0 - d) + y * d; -} -forceinline int lerp255(RT x, RT y, RT d) { - return lerp(x / 255.0, y / 255.0, d) * 255.0; -} -forceinline rgb_t rgblerp(rgb_t x, rgb_t y, RT d) { - return (rgb_t){lerp255(x.r, y.r, d), lerp255(x.g, y.g, d), - lerp255(x.b, y.b, d)}; -} - -forceinline rgb_t getquant(unsigned xt) { - return g_ansi2rgb_[xt]; -} -forceinline unsigned dist(int x, int y) { - return x - y; -} -forceinline unsigned sqr(int x) { - return x * x; -} -forceinline unsigned rgbdist(rgb_t x, rgb_t y) { - return sqrt(sqr(dist(x.r, y.r)) + sqr(dist(x.g, y.g)) + sqr(dist(x.b, y.b))); -} - -bool b; -rgb_t rgb, cc, c1, c2; -unsigned i, j, k, m, n, x, y; -char buf[128]; - -/* 0125 025 067-29 # '░' bg=0352 fg=0306 → ░░░ */ -/* 0125 025 067-29 # '▓' bg=0306 fg=0352 → ▓▓▓ */ -/* 0125 055 067-29 # '░' bg=0352 fg=0314 → ░░░ */ - -int main(int argc, char *argv[]) { - /* memcpy(g_ansi2rgb_, &kTangoPalette, sizeof(kTangoPalette)); */ - /* i = 21; */ - /* j = 22; */ - /* c1 = getquant(i); */ - /* c2 = getquant(j); */ - /* cc = rgblerp(c1, c2, R1); */ - /* printf("rgblerp((%3d,%3d,%3d), (%3d,%3d,%3d),4) → (%3d,%3d,%3d)\n", c1.r, - */ - /* c1.g, c1.b, c2.r, c2.g, c2.b, cc.r, cc.g, cc.b); */ - /* exit(0); */ - - for (m = 16; m < 256; m += 6) { - for (n = 16; n < 256; n += 6) { - printf("------------------------------------------------------------\n"); - i = m; - j = n; - b = false; - while (i < m + 6) { - printf("\n"); - - cc = getquant(i); - sprintf(buf, "\e[48;5;%dm ", i); - printf("0x%02x%02x%02x, %d,%d,0\t/* 0x%02x%02x%02x " - " + ' ' bg=%3d → %s \e[0m */\n", - cc.b, cc.g, cc.r, i, 0, getquant(i).r, getquant(i).g, - getquant(i).b, i, buf); - -#if 0 - sprintf(buf, "\e[38;5;%dm███", i); - printf("0x%08x 0x%02x%02x%02x\t" - " '█' fg=%3d → %s\e[0m\n", - cc.b, cc.g, cc.r, strlen(buf), i, buf); -#endif - - for (x = i; x < i + 1; ++x) { - for (y = j; y < j + 1; ++y) { - for (k = 0; k < 2; ++k) { - if (x > y /* && */ - /* rgbdist(getquant(x), getquant(y)) < 49744125 / 16 */ /* && - ((32 - <= x && x <= 232) && (32 <= y && y <= 232)) - && */ - /* (cc.r > 0137 && cc.g > 0137 && cc.b > 0137) */) { - sprintf(buf, "\e[48;5;%d;38;5;%dm░░░", x, y); - cc = rgblerp(getquant(x), getquant(y), R1); - printf("0x%02x%02x%02x, %d,%d,1\t/* 0x%02x%02x%02x + " - "0x%02x%02x%02x" - " + '░' bg=%3d fg=%3d → " - "\e[48;5;%dm \e[48;5;%dm " - "%s\e[48;2;%d;%d;%dm \e[0m */\n", - cc.b, cc.g, cc.r, x, y, getquant(x).r, getquant(x).g, - getquant(x).b, getquant(y).r, getquant(y).g, - getquant(y).b, x, y, x, y, buf, cc.r, cc.g, cc.b); - - sprintf(buf, "\e[48;5;%d;38;5;%dm▒▒▒", x, y); - cc = rgblerp(getquant(x), getquant(y), R2); - printf("0x%02x%02x%02x, %d,%d,2\t/* 0x%02x%02x%02x + " - "0x%02x%02x%02x" - " + '▒' bg=%3d fg=%3d → " - "\e[48;5;%dm \e[48;5;%dm " - "%s\e[48;2;%d;%d;%dm \e[0m */\n", - cc.b, cc.g, cc.r, x, y, getquant(x).r, getquant(x).g, - getquant(x).b, getquant(y).r, getquant(y).g, - getquant(y).b, x, y, x, y, buf, cc.r, cc.g, cc.b); - - sprintf(buf, "\e[48;5;%d;38;5;%dm▓▓▓", x, y); - cc = rgblerp(getquant(x), getquant(y), R3); - printf("0x%02x%02x%02x, %d,%d,3\t/* 0x%02x%02x%02x + " - "0x%02x%02x%02x" - " + '▓' bg=%3d fg=%3d → " - "\e[48;5;%dm \e[48;5;%dm " - "%s\e[48;2;%d;%d;%dm \e[0m */\n", - cc.b, cc.g, cc.r, x, y, getquant(x).r, getquant(x).g, - getquant(x).b, getquant(y).r, getquant(y).g, - getquant(y).b, x, y, x, y, buf, cc.r, cc.g, cc.b); - } - -#if 0 - sprintf(buf, "\e[48;5;%d;38;5;%dm▓▓▓", x, y); - cc = rgblerp((c1 = getquant(x)), (c2 = getquant(y)), R3); - printf("0%03o%03o%03o\t# '▓' bg=%3d fg=%3d → " - "%s\e[48;2;%d;%d;%dm \e[0m\n", - cc.b, cc.g, cc.r, strlen(buf), x, y, buf, - lerp255(c1.r, c2.r, R3), lerp255(c1.g, c2.g, R3), - lerp255(c1.b, c2.b, R3)); -#endif - - xchg(&x, &y); - } - } - } - - ++i; - ++j; - } - } - } - - /* for (i = 0; i < 255; ++i) { */ - /* for (j = 0; j < 255; ++j) { */ - /* for (k = 0; k < 255; ++k) { */ - /* printf("0%03o%03o%03o\n", i, j, k); */ - /* } */ - /* } */ - /* } */ - - return 0; -} diff --git a/tool/viz/xterm256effective2.c b/tool/viz/xterm256effective2.c deleted file mode 100644 index 8ac39914e..000000000 --- a/tool/viz/xterm256effective2.c +++ /dev/null @@ -1,186 +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 "dsp/tty/quant.h" -#include "libc/fmt/fmt.h" -#include "libc/log/check.h" -#include "libc/macros.internal.h" -#include "libc/math.h" -#include "libc/mem/mem.h" -#include "libc/runtime/runtime.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" -#include "libc/sysv/consts/ex.h" -#include "libc/sysv/consts/exit.h" -#include "third_party/getopt/getopt.internal.h" - -#define USAGE \ - " [FLAGS] [PATH...]\n\ -\n\ -Flags:\n\ - -o PATH output path\n\ - -h shows this information\n\ -\n" - -static size_t linecap_; -static FILE *in_, *out_; -static char *inpath_, *outpath_, *line_; - -void PrintUsage(int rc, FILE *f) { - fputs("Usage: ", f); - fputs(program_invocation_name, f); - fputs(USAGE, f); - exit(rc); -} - -void GetOpts(int *argc, char *argv[]) { - int opt; - outpath_ = "-"; - while ((opt = getopt(*argc, argv, "?ho:")) != -1) { - switch (opt) { - case 'o': - outpath_ = optarg; - break; - case '?': - case 'h': - PrintUsage(EXIT_SUCCESS, stdout); - default: - PrintUsage(EX_USAGE, stderr); - } - } - if (optind == *argc) { - argv[(*argc)++] = "-"; - } -} - -#define U256F1(X) ((float)((X)&0xffu) * 256.0f) -#define F1U256(X) MAX(MIN((int)rintl(roundl(256.0f * (X))), 255), 0) - -forceinline struct TtyRgb getquant(unsigned xt) { - return g_ansi2rgb_[xt]; -} - -forceinline unsigned dist(int x, int y) { - return x - y; -} - -forceinline unsigned sqr(int x) { - return x * x; -} - -static unsigned rgb2hsl(unsigned rgba) { - /* this is broken */ - unsigned h8, s8, l8; - float r, g, b, h, s, d, l, cmax, cmin; - r = U256F1(rgba); - g = U256F1(rgba >> 010); - b = U256F1(rgba >> 020); - cmax = MAX(MAX(r, g), b); - cmin = MIN(MIN(r, g), b); - h = 0.0f; - s = 0.0f; - d = cmax - cmin; - l = (cmax + cmin) / 2.0f; - if (cmax != cmin) { - s = l > 0.5L ? d / (2.0f - cmax - cmin) : d / (cmax + cmin); - if (cmax == r) { - h = (g - b) / d + (g < b ? 6.0f : 0.0f); - } else if (cmax == g) { - h = (b - r) / d + 2.0f; - } else if (cmax == b) { - h = (r - g) / d + 4.0f; - } - h /= 6.0f; - } - h8 = F1U256(h); - s8 = F1U256(s); - l8 = F1U256(l); - return ((rgba >> 030) & 255) << 030 | l8 << 020 | s8 << 010 | h8; -} -static struct TtyRgb rgb2hsl2(struct TtyRgb rgb) { - unsigned x = - (unsigned)rgb.b << 020 | (unsigned)rgb.g << 010 | (unsigned)rgb.r; - unsigned y = rgb2hsl(x); - return (struct TtyRgb){ - .r = y & 0xff, .g = (y >> 010) & 0xff, .b = (y >> 020) & 0xff}; -} -static unsigned rgbdist(struct TtyRgb x, struct TtyRgb y) { - x = rgb2hsl2(x); - y = rgb2hsl2(y); - return sqrt(sqr(dist(x.r, y.r)) + sqr(dist(x.g, y.g)) + sqr(dist(x.b, y.b))); -} - -static unsigned xtdist(unsigned x, unsigned y) { - return rgbdist(getquant(x), getquant(y)); -} - -void Show(unsigned color, unsigned bg, unsigned fg, unsigned glyph) { - uint8_t r, g, b; - b = (color >> 020) & 0xff; - g = (color >> 010) & 0xff; - r = color & 0xff; - printf("\tmix\t0x%04x,%3d,%3d,%3d,%3d,%3d,%3d\t# \e[48;2;%d;%d;%dm \e[0m\n", - rgbdist((struct TtyRgb){r, g, b, 0}, (struct TtyRgb){0, 0, 0, 0}), r, - g, b, bg, fg, glyph, r, g, b); -} - -void ProcessFile(void) { - char *p; - unsigned color1, bg1, fg1, glyph1; - unsigned color, bg, fg, glyph; - color1 = -1u; - bg1 = -1u; - fg1 = -1u; - glyph1 = -1u; - while ((getline(&line_, &linecap_, in_)) != -1) { - p = _chomp(line_); - sscanf(p, "%x, %u,%u,%u", &color, &bg, &fg, &glyph); - if (color != color1) { - if (color1 != -1u) { - Show(color1, bg1, fg1, glyph1); - } - color1 = color; - bg1 = bg; - fg1 = fg; - glyph1 = glyph; - } - if ((fg1 && !fg) || (fg && fg1 && xtdist(fg, bg) < xtdist(fg1, bg1))) { - color1 = color; - bg1 = bg; - fg1 = fg; - glyph1 = glyph; - } - } - Show(color1, bg1, fg1, glyph1); -} - -int main(int argc, char *argv[]) { - size_t i; - GetOpts(&argc, argv); - CHECK_NOTNULL((out_ = fopen(outpath_, "w"))); - for (i = optind; i < argc; ++i) { - CHECK_NOTNULL((in_ = fopen((inpath_ = argv[i]), "r"))); - ProcessFile(); - CHECK_NE(-1, fclose(in_)); - in_ = 0; - } - CHECK_NE(-1, fclose(out_)); - out_ = 0; - free(line_); - return 0; -} diff --git a/tool/viz/xterm256gradient.c b/tool/viz/xterm256gradient.c deleted file mode 100644 index 089e77cfa..000000000 --- a/tool/viz/xterm256gradient.c +++ /dev/null @@ -1,77 +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 2021 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/math.h" -#include "libc/stdio/stdio.h" - -#define N 8 - -#define SQR(X) ((X) * (X)) - -static const uint8_t kXtermCube[6] = {0, 0137, 0207, 0257, 0327, 0377}; - -static int rgb2xterm256(int r, int g, int b) { - int cerr, gerr, ir, ig, ib, gray, grai, cr, cg, cb, gv; - gray = round(r * .299 + g * .587 + b * .114); - grai = gray > 238 ? 23 : (gray - 3) / 10; - ir = r < 48 ? 0 : r < 115 ? 1 : (r - 35) / 40; - ig = g < 48 ? 0 : g < 115 ? 1 : (g - 35) / 40; - ib = b < 48 ? 0 : b < 115 ? 1 : (b - 35) / 40; - cr = kXtermCube[ir]; - cg = kXtermCube[ig]; - cb = kXtermCube[ib]; - gv = 8 + 10 * grai; - cerr = SQR(cr - r) + SQR(cg - g) + SQR(cb - b); - gerr = SQR(gv - r) + SQR(gv - g) + SQR(gv - b); - if (cerr <= gerr) { - return 16 + 36 * ir + 6 * ig + ib; - } else { - return 232 + grai; - } -} - -int main(int argc, char *argv[]) { - double d; - int i, j, x; - int r, g, b; - double G[N][3]; - double rgb[2][3] = { - {1, 0, 0}, - {0, 1, 0}, - }; - - for (i = 0; i < N; ++i) { - for (j = 0; j < 3; ++j) { - d = (rgb[1][j] - rgb[0][j]) / (N - 1); - G[i][j] = rgb[0][j] + d * i; - } - } - - for (i = 0; i < N; ++i) { - r = round(G[i][0] * 255); - g = round(G[i][1] * 255); - b = round(G[i][2] * 255); - x = rgb2xterm256(r, g, b); - printf("\e[38;5;232;48;5;%dmabcdefg \e[0m %3d " - "\e[38;5;232;48;2;%d;%d;%dmabcdgefg \e[0m " - "%3d %3d %3d %f %f %f\n", - x, x, r, g, b, r, g, b, G[i][0], G[i][1], G[i][2]); - } - - return 0; -} diff --git a/tool/viz/xterm256info.c b/tool/viz/xterm256info.c deleted file mode 100644 index a57a3d035..000000000 --- a/tool/viz/xterm256info.c +++ /dev/null @@ -1,706 +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 "dsp/tty/xtermname.h" -#include "libc/stdio/stdio.h" -#include "libc/str/str.h" - -struct Rgb { - uint8_t r, g, b; -}; - -const struct Rgb kTango[16] = { - {0x00, 0x00, 0x00}, {0x80, 0x00, 0x00}, {0x00, 0x80, 0x00}, - {0x80, 0x80, 0x00}, {0x00, 0x00, 0x80}, {0x80, 0x00, 0x80}, - {0x00, 0x80, 0x80}, {0xc0, 0xc0, 0xc0}, {0x80, 0x80, 0x80}, - {0xff, 0x00, 0x00}, {0x00, 0xff, 0x00}, {0xff, 0xff, 0x00}, - {0x00, 0x00, 0xff}, {0xff, 0x00, 0xff}, {0x00, 0xff, 0xff}, - {0xff, 0xff, 0xff}, -}; - -const struct Rgb kXtermRgb[] = { - /* 0..15: ansi 16-color palette */ - {0x00, 0x00, 0x00}, - {0x80, 0x00, 0x00}, - {0x00, 0x80, 0x00}, - {0x80, 0x80, 0x00}, - {0x00, 0x00, 0x80}, - {0x80, 0x00, 0x80}, - {0x00, 0x80, 0x80}, - {0xc0, 0xc0, 0xc0}, - {0x80, 0x80, 0x80}, - {0xff, 0x00, 0x00}, - {0x00, 0xff, 0x00}, - {0xff, 0xff, 0x00}, - {0x00, 0x00, 0xff}, - {0xff, 0x00, 0xff}, - {0x00, 0xff, 0xff}, - {0xff, 0xff, 0xff}, - - /* 16..231: xterm256 color cubes */ - {0x00, 0x00, 0x00}, - {0x00, 0x00, 0x5f}, - {0x00, 0x00, 0x87}, - {0x00, 0x00, 0xaf}, - {0x00, 0x00, 0xd7}, - {0x00, 0x00, 0xff}, - {0x00, 0x5f, 0x00}, - {0x00, 0x5f, 0x5f}, - {0x00, 0x5f, 0x87}, - {0x00, 0x5f, 0xaf}, - {0x00, 0x5f, 0xd7}, - {0x00, 0x5f, 0xff}, - {0x00, 0x87, 0x00}, - {0x00, 0x87, 0x5f}, - {0x00, 0x87, 0x87}, - {0x00, 0x87, 0xaf}, - {0x00, 0x87, 0xd7}, - {0x00, 0x87, 0xff}, - {0x00, 0xaf, 0x00}, - {0x00, 0xaf, 0x5f}, - {0x00, 0xaf, 0x87}, - {0x00, 0xaf, 0xaf}, - {0x00, 0xaf, 0xd7}, - {0x00, 0xaf, 0xff}, - {0x00, 0xd7, 0x00}, - {0x00, 0xd7, 0x5f}, - {0x00, 0xd7, 0x87}, - {0x00, 0xd7, 0xaf}, - {0x00, 0xd7, 0xd7}, - {0x00, 0xd7, 0xff}, - {0x00, 0xff, 0x00}, - {0x00, 0xff, 0x5f}, - {0x00, 0xff, 0x87}, - {0x00, 0xff, 0xaf}, - {0x00, 0xff, 0xd7}, - {0x00, 0xff, 0xff}, - {0x5f, 0x00, 0x00}, - {0x5f, 0x00, 0x5f}, - {0x5f, 0x00, 0x87}, - {0x5f, 0x00, 0xaf}, - {0x5f, 0x00, 0xd7}, - {0x5f, 0x00, 0xff}, - {0x5f, 0x5f, 0x00}, - {0x5f, 0x5f, 0x5f}, - {0x5f, 0x5f, 0x87}, - {0x5f, 0x5f, 0xaf}, - {0x5f, 0x5f, 0xd7}, - {0x5f, 0x5f, 0xff}, - {0x5f, 0x87, 0x00}, - {0x5f, 0x87, 0x5f}, - {0x5f, 0x87, 0x87}, - {0x5f, 0x87, 0xaf}, - {0x5f, 0x87, 0xd7}, - {0x5f, 0x87, 0xff}, - {0x5f, 0xaf, 0x00}, - {0x5f, 0xaf, 0x5f}, - {0x5f, 0xaf, 0x87}, - {0x5f, 0xaf, 0xaf}, - {0x5f, 0xaf, 0xd7}, - {0x5f, 0xaf, 0xff}, - {0x5f, 0xd7, 0x00}, - {0x5f, 0xd7, 0x5f}, - {0x5f, 0xd7, 0x87}, - {0x5f, 0xd7, 0xaf}, - {0x5f, 0xd7, 0xd7}, - {0x5f, 0xd7, 0xff}, - {0x5f, 0xff, 0x00}, - {0x5f, 0xff, 0x5f}, - {0x5f, 0xff, 0x87}, - {0x5f, 0xff, 0xaf}, - {0x5f, 0xff, 0xd7}, - {0x5f, 0xff, 0xff}, - {0x87, 0x00, 0x00}, - {0x87, 0x00, 0x5f}, - {0x87, 0x00, 0x87}, - {0x87, 0x00, 0xaf}, - {0x87, 0x00, 0xd7}, - {0x87, 0x00, 0xff}, - {0x87, 0x5f, 0x00}, - {0x87, 0x5f, 0x5f}, - {0x87, 0x5f, 0x87}, - {0x87, 0x5f, 0xaf}, - {0x87, 0x5f, 0xd7}, - {0x87, 0x5f, 0xff}, - {0x87, 0x87, 0x00}, - {0x87, 0x87, 0x5f}, - {0x87, 0x87, 0x87}, - {0x87, 0x87, 0xaf}, - {0x87, 0x87, 0xd7}, - {0x87, 0x87, 0xff}, - {0x87, 0xaf, 0x00}, - {0x87, 0xaf, 0x5f}, - {0x87, 0xaf, 0x87}, - {0x87, 0xaf, 0xaf}, - {0x87, 0xaf, 0xd7}, - {0x87, 0xaf, 0xff}, - {0x87, 0xd7, 0x00}, - {0x87, 0xd7, 0x5f}, - {0x87, 0xd7, 0x87}, - {0x87, 0xd7, 0xaf}, - {0x87, 0xd7, 0xd7}, - {0x87, 0xd7, 0xff}, - {0x87, 0xff, 0x00}, - {0x87, 0xff, 0x5f}, - {0x87, 0xff, 0x87}, - {0x87, 0xff, 0xaf}, - {0x87, 0xff, 0xd7}, - {0x87, 0xff, 0xff}, - {0xaf, 0x00, 0x00}, - {0xaf, 0x00, 0x5f}, - {0xaf, 0x00, 0x87}, - {0xaf, 0x00, 0xaf}, - {0xaf, 0x00, 0xd7}, - {0xaf, 0x00, 0xff}, - {0xaf, 0x5f, 0x00}, - {0xaf, 0x5f, 0x5f}, - {0xaf, 0x5f, 0x87}, - {0xaf, 0x5f, 0xaf}, - {0xaf, 0x5f, 0xd7}, - {0xaf, 0x5f, 0xff}, - {0xaf, 0x87, 0x00}, - {0xaf, 0x87, 0x5f}, - {0xaf, 0x87, 0x87}, - {0xaf, 0x87, 0xaf}, - {0xaf, 0x87, 0xd7}, - {0xaf, 0x87, 0xff}, - {0xaf, 0xaf, 0x00}, - {0xaf, 0xaf, 0x5f}, - {0xaf, 0xaf, 0x87}, - {0xaf, 0xaf, 0xaf}, - {0xaf, 0xaf, 0xd7}, - {0xaf, 0xaf, 0xff}, - {0xaf, 0xd7, 0x00}, - {0xaf, 0xd7, 0x5f}, - {0xaf, 0xd7, 0x87}, - {0xaf, 0xd7, 0xaf}, - {0xaf, 0xd7, 0xd7}, - {0xaf, 0xd7, 0xff}, - {0xaf, 0xff, 0x00}, - {0xaf, 0xff, 0x5f}, - {0xaf, 0xff, 0x87}, - {0xaf, 0xff, 0xaf}, - {0xaf, 0xff, 0xd7}, - {0xaf, 0xff, 0xff}, - {0xd7, 0x00, 0x00}, - {0xd7, 0x00, 0x5f}, - {0xd7, 0x00, 0x87}, - {0xd7, 0x00, 0xaf}, - {0xd7, 0x00, 0xd7}, - {0xd7, 0x00, 0xff}, - {0xd7, 0x5f, 0x00}, - {0xd7, 0x5f, 0x5f}, - {0xd7, 0x5f, 0x87}, - {0xd7, 0x5f, 0xaf}, - {0xd7, 0x5f, 0xd7}, - {0xd7, 0x5f, 0xff}, - {0xd7, 0x87, 0x00}, - {0xd7, 0x87, 0x5f}, - {0xd7, 0x87, 0x87}, - {0xd7, 0x87, 0xaf}, - {0xd7, 0x87, 0xd7}, - {0xd7, 0x87, 0xff}, - {0xd7, 0xaf, 0x00}, - {0xd7, 0xaf, 0x5f}, - {0xd7, 0xaf, 0x87}, - {0xd7, 0xaf, 0xaf}, - {0xd7, 0xaf, 0xd7}, - {0xd7, 0xaf, 0xff}, - {0xd7, 0xd7, 0x00}, - {0xd7, 0xd7, 0x5f}, - {0xd7, 0xd7, 0x87}, - {0xd7, 0xd7, 0xaf}, - {0xd7, 0xd7, 0xd7}, - {0xd7, 0xd7, 0xff}, - {0xd7, 0xff, 0x00}, - {0xd7, 0xff, 0x5f}, - {0xd7, 0xff, 0x87}, - {0xd7, 0xff, 0xaf}, - {0xd7, 0xff, 0xd7}, - {0xd7, 0xff, 0xff}, - {0xff, 0x00, 0x00}, - {0xff, 0x00, 0x5f}, - {0xff, 0x00, 0x87}, - {0xff, 0x00, 0xaf}, - {0xff, 0x00, 0xd7}, - {0xff, 0x00, 0xff}, - {0xff, 0x5f, 0x00}, - {0xff, 0x5f, 0x5f}, - {0xff, 0x5f, 0x87}, - {0xff, 0x5f, 0xaf}, - {0xff, 0x5f, 0xd7}, - {0xff, 0x5f, 0xff}, - {0xff, 0x87, 0x00}, - {0xff, 0x87, 0x5f}, - {0xff, 0x87, 0x87}, - {0xff, 0x87, 0xaf}, - {0xff, 0x87, 0xd7}, - {0xff, 0x87, 0xff}, - {0xff, 0xaf, 0x00}, - {0xff, 0xaf, 0x5f}, - {0xff, 0xaf, 0x87}, - {0xff, 0xaf, 0xaf}, - {0xff, 0xaf, 0xd7}, - {0xff, 0xaf, 0xff}, - {0xff, 0xd7, 0x00}, - {0xff, 0xd7, 0x5f}, - {0xff, 0xd7, 0x87}, - {0xff, 0xd7, 0xaf}, - {0xff, 0xd7, 0xd7}, - {0xff, 0xd7, 0xff}, - {0xff, 0xff, 0x00}, - {0xff, 0xff, 0x5f}, - {0xff, 0xff, 0x87}, - {0xff, 0xff, 0xaf}, - {0xff, 0xff, 0xd7}, - {0xff, 0xff, 0xff}, - - /* 232..255: xterm256 grayscale */ - {0x08, 0x08, 0x08}, /* 8 */ - {0x12, 0x12, 0x12}, /* 10 */ - {0x1c, 0x1c, 0x1c}, /* 10 */ - {0x26, 0x26, 0x26}, /* 10 */ - {0x30, 0x30, 0x30}, /* .. */ - {0x3a, 0x3a, 0x3a}, - {0x44, 0x44, 0x44}, - {0x4e, 0x4e, 0x4e}, - {0x58, 0x58, 0x58}, - {0x62, 0x62, 0x62}, - {0x6c, 0x6c, 0x6c}, - {0x76, 0x76, 0x76}, - {0x80, 0x80, 0x80}, - {0x8a, 0x8a, 0x8a}, - {0x94, 0x94, 0x94}, - {0x9e, 0x9e, 0x9e}, - {0xa8, 0xa8, 0xa8}, - {0xb2, 0xb2, 0xb2}, - {0xbc, 0xbc, 0xbc}, - {0xc6, 0xc6, 0xc6}, - {0xd0, 0xd0, 0xd0}, - {0xda, 0xda, 0xda}, - {0xe4, 0xe4, 0xe4}, - {0xee, 0xee, 0xee}, -}; - -const struct Rgb kXtermRgbAppleFg[] = { - {0, 0, 0}, {192, 55, 41}, {48, 187, 49}, {173, 172, 53}, - {73, 76, 224}, {209, 65, 209}, {60, 187, 199}, {203, 204, 205}, - {154, 155, 156}, {249, 59, 44}, {62, 229, 55}, {234, 234, 62}, - {89, 63, 251}, {247, 67, 245}, {48, 239, 239}, {233, 235, 235}, - {47, 49, 49}, {60, 46, 142}, {67, 51, 180}, {74, 56, 218}, - {82, 62, 248}, {89, 63, 251}, {46, 127, 43}, {46, 127, 127}, - {49, 127, 167}, {60, 127, 207}, {63, 127, 241}, {70, 126, 251}, - {57, 161, 50}, {47, 161, 122}, {50, 161, 161}, {60, 161, 200}, - {53, 161, 237}, {65, 160, 252}, {45, 194, 51}, {58, 194, 118}, - {51, 194, 156}, {59, 194, 194}, {48, 194, 233}, {63, 194, 252}, - {62, 227, 55}, {55, 227, 115}, {48, 227, 151}, {63, 227, 189}, - {52, 227, 227}, {66, 227, 253}, {51, 252, 57}, {53, 252, 111}, - {63, 252, 147}, {58, 252, 184}, {59, 252, 222}, {62, 253, 251}, - {138, 49, 43}, {134, 55, 134}, {134, 58, 174}, {133, 61, 213}, - {134, 67, 244}, {134, 65, 251}, {125, 124, 46}, {124, 125, 125}, - {122, 125, 165}, {123, 126, 205}, {124, 126, 243}, {125, 125, 251}, - {120, 159, 47}, {118, 159, 121}, {118, 159, 160}, {117, 160, 199}, - {118, 160, 238}, {119, 160, 252}, {115, 193, 53}, {113, 193, 117}, - {114, 193, 155}, {111, 193, 193}, {113, 194, 232}, {112, 193, 252}, - {110, 226, 53}, {108, 226, 114}, {110, 226, 151}, {106, 226, 189}, - {105, 227, 227}, {105, 226, 252}, {99, 251, 59}, {103, 251, 111}, - {104, 251, 146}, {97, 252, 184}, {102, 252, 221}, {98, 254, 250}, - {175, 54, 40}, {172, 58, 130}, {170, 61, 170}, {170, 66, 210}, - {169, 67, 245}, {168, 69, 251}, {164, 123, 47}, {162, 123, 124}, - {161, 124, 163}, {161, 124, 203}, {160, 125, 238}, {160, 125, 251}, - {158, 157, 47}, {157, 158, 120}, {157, 158, 159}, {155, 158, 198}, - {155, 159, 236}, {155, 158, 252}, {153, 192, 55}, {152, 192, 117}, - {151, 192, 154}, {151, 192, 193}, {150, 192, 231}, {150, 192, 251}, - {148, 225, 53}, {147, 225, 114}, {146, 225, 150}, {147, 226, 188}, - {145, 226, 226}, {145, 226, 250}, {142, 251, 61}, {141, 251, 111}, - {141, 252, 146}, {142, 253, 183}, {139, 254, 221}, {138, 255, 249}, - {211, 59, 40}, {209, 63, 126}, {207, 63, 166}, {206, 64, 206}, - {205, 69, 243}, {204, 72, 252}, {202, 121, 45}, {201, 122, 122}, - {200, 122, 161}, {199, 123, 200}, {199, 124, 238}, {197, 124, 252}, - {197, 156, 51}, {195, 156, 119}, {195, 157, 157}, {194, 157, 196}, - {193, 157, 234}, {193, 157, 252}, {191, 190, 54}, {190, 190, 116}, - {189, 191, 153}, {190, 191, 191}, {188, 191, 229}, {187, 191, 251}, - {186, 224, 55}, {185, 224, 113}, {184, 224, 150}, {184, 224, 187}, - {184, 225, 225}, {182, 224, 251}, {180, 253, 62}, {180, 253, 111}, - {179, 253, 146}, {179, 253, 183}, {179, 254, 220}, {177, 252, 249}, - {244, 59, 43}, {243, 62, 123}, {241, 65, 162}, {241, 69, 202}, - {240, 70, 238}, {238, 69, 252}, {239, 119, 50}, {238, 120, 120}, - {236, 121, 159}, {235, 121, 198}, {235, 123, 236}, {234, 123, 252}, - {234, 154, 53}, {233, 154, 118}, {232, 155, 156}, {231, 155, 194}, - {231, 156, 233}, {230, 156, 252}, {229, 188, 53}, {228, 189, 115}, - {227, 189, 152}, {227, 189, 190}, {226, 189, 228}, {225, 189, 253}, - {223, 222, 60}, {223, 223, 113}, {222, 223, 149}, {222, 223, 186}, - {222, 223, 224}, {220, 223, 252}, {218, 251, 61}, {217, 251, 109}, - {217, 251, 145}, {217, 251, 182}, {216, 251, 219}, {216, 251, 250}, - {252, 63, 43}, {252, 64, 120}, {252, 64, 159}, {252, 65, 198}, - {252, 67, 236}, {252, 72, 252}, {253, 117, 47}, {253, 118, 118}, - {253, 119, 156}, {253, 120, 194}, {253, 120, 233}, {252, 121, 252}, - {253, 152, 49}, {252, 152, 116}, {252, 153, 153}, {253, 153, 192}, - {252, 154, 229}, {251, 154, 251}, {253, 186, 56}, {251, 187, 114}, - {251, 187, 151}, {252, 187, 188}, {252, 188, 226}, {251, 188, 251}, - {251, 221, 61}, {250, 221, 112}, {250, 221, 148}, {250, 221, 185}, - {251, 222, 222}, {251, 222, 251}, {251, 250, 58}, {250, 250, 109}, - {249, 250, 144}, {247, 251, 181}, {247, 253, 218}, {254, 255, 255}, - {52, 53, 53}, {57, 58, 59}, {66, 67, 67}, {75, 76, 76}, - {84, 85, 85}, {92, 93, 94}, {101, 102, 102}, {109, 111, 111}, - {118, 119, 119}, {126, 127, 128}, {134, 136, 136}, {143, 144, 145}, - {151, 152, 153}, {159, 161, 161}, {167, 169, 169}, {176, 177, 177}, - {184, 185, 186}, {192, 193, 194}, {200, 201, 202}, {208, 209, 210}, - {216, 218, 218}, {224, 226, 226}, {232, 234, 234}, {240, 242, 242}, -}; - -const struct Rgb kXtermRgbAppleBg[] = { - {0, 0, 0}, {151, 4, 12}, {23, 164, 26}, {153, 152, 29}, - {8, 43, 181}, {177, 25, 176}, {26, 166, 177}, {191, 191, 191}, - {132, 132, 132}, {227, 10, 23}, {33, 215, 38}, {229, 228, 49}, - {11, 36, 251}, {227, 35, 227}, {39, 229, 228}, {230, 229, 230}, - {0, 0, 0}, {1, 7, 93}, {3, 14, 133}, {5, 21, 172}, - {7, 28, 211}, {11, 36, 251}, {8, 94, 11}, {10, 95, 95}, - {11, 96, 133}, {13, 97, 173}, {15, 99, 212}, {18, 101, 251}, - {17, 134, 20}, {18, 134, 96}, {18, 135, 134}, {20, 136, 173}, - {21, 137, 212}, {23, 138, 251}, {25, 173, 29}, {26, 174, 98}, - {26, 174, 136}, {27, 175, 174}, {28, 175, 213}, {30, 176, 252}, - {33, 213, 38}, {34, 213, 101}, {34, 214, 137}, {35, 214, 175}, - {36, 215, 214}, {37, 215, 253}, {41, 253, 47}, {42, 253, 104}, - {42, 253, 140}, {43, 253, 177}, {44, 254, 215}, {45, 255, 254}, - {94, 2, 4}, {94, 8, 94}, {94, 15, 133}, {94, 22, 172}, - {95, 29, 211}, {95, 36, 251}, {95, 94, 14}, {95, 95, 95}, - {95, 96, 134}, {95, 97, 173}, {96, 99, 212}, {96, 101, 251}, - {96, 134, 22}, {96, 134, 96}, {96, 135, 135}, {97, 136, 173}, - {97, 137, 212}, {97, 138, 252}, {98, 173, 30}, {98, 174, 98}, - {98, 174, 136}, {98, 175, 174}, {98, 176, 213}, {99, 177, 252}, - {100, 213, 39}, {100, 213, 101}, {100, 214, 138}, {100, 214, 176}, - {101, 215, 214}, {101, 215, 253}, {102, 253, 48}, {103, 253, 104}, - {103, 253, 140}, {103, 253, 177}, {103, 254, 215}, {104, 255, 254}, - {133, 3, 9}, {133, 10, 94}, {134, 16, 133}, {134, 23, 172}, - {134, 30, 212}, {134, 37, 251}, {134, 94, 18}, {134, 95, 96}, - {134, 96, 134}, {134, 97, 173}, {135, 99, 212}, {135, 101, 251}, - {135, 134, 25}, {135, 134, 97}, {135, 135, 135}, {135, 136, 174}, - {135, 137, 213}, {136, 138, 252}, {136, 173, 32}, {136, 174, 99}, - {136, 174, 136}, {136, 175, 175}, {136, 176, 213}, {137, 177, 252}, - {137, 213, 40}, {137, 213, 102}, {138, 214, 138}, {138, 214, 176}, - {138, 215, 214}, {138, 216, 253}, {139, 253, 49}, {139, 253, 105}, - {139, 253, 140}, {139, 254, 178}, {140, 254, 216}, {140, 255, 254}, - {173, 6, 15}, {173, 12, 95}, {173, 18, 134}, {173, 24, 173}, - {173, 31, 212}, {174, 38, 251}, {173, 95, 22}, {174, 95, 96}, - {174, 96, 135}, {174, 98, 173}, {174, 99, 212}, {174, 101, 252}, - {174, 134, 28}, {174, 135, 98}, {174, 135, 136}, {174, 136, 174}, - {174, 137, 213}, {175, 139, 252}, {175, 174, 35}, {175, 174, 100}, - {175, 174, 137}, {175, 175, 175}, {175, 176, 214}, {175, 177, 253}, - {176, 213, 43}, {176, 213, 102}, {176, 214, 139}, {176, 214, 176}, - {176, 215, 215}, {176, 216, 253}, {177, 253, 51}, {177, 253, 105}, - {177, 253, 141}, {177, 254, 178}, {178, 254, 216}, {178, 255, 254}, - {213, 9, 21}, {213, 15, 96}, {213, 20, 135}, {241, 69, 202}, - {213, 32, 212}, {213, 39, 251}, {213, 95, 27}, {213, 96, 97}, - {213, 97, 135}, {213, 98, 174}, {213, 100, 213}, {213, 102, 252}, - {213, 134, 32}, {213, 135, 99}, {213, 135, 136}, {214, 136, 175}, - {214, 137, 213}, {214, 139, 252}, {214, 174, 38}, {214, 174, 101}, - {214, 175, 138}, {214, 175, 176}, {214, 176, 214}, {214, 177, 253}, - {215, 213, 45}, {215, 214, 103}, {215, 214, 139}, {215, 214, 177}, - {215, 215, 215}, {215, 216, 254}, {216, 253, 53}, {216, 253, 106}, - {216, 253, 141}, {216, 254, 178}, {216, 254, 216}, {216, 255, 255}, - {252, 13, 27}, {252, 18, 98}, {252, 22, 135}, {252, 28, 174}, - {252, 34, 213}, {252, 40, 252}, {252, 96, 32}, {252, 96, 99}, - {252, 97, 136}, {253, 99, 175}, {253, 100, 213}, {253, 102, 252}, - {253, 135, 36}, {253, 135, 100}, {253, 136, 137}, {253, 137, 175}, - {253, 138, 214}, {253, 139, 253}, {253, 174, 42}, {253, 174, 102}, - {253, 175, 138}, {253, 175, 176}, {253, 176, 215}, {254, 177, 253}, - {254, 213, 48}, {254, 214, 105}, {254, 214, 140}, {254, 215, 177}, - {254, 215, 216}, {254, 216, 254}, {255, 253, 56}, {255, 253, 108}, - {255, 253, 142}, {255, 254, 179}, {255, 254, 217}, {255, 255, 255}, - {8, 8, 8}, {18, 18, 18}, {28, 28, 28}, {38, 38, 38}, - {48, 48, 48}, {58, 58, 58}, {68, 68, 68}, {78, 78, 78}, - {88, 88, 88}, {98, 98, 98}, {108, 108, 108}, {118, 118, 118}, - {128, 128, 128}, {138, 138, 138}, {148, 148, 148}, {158, 158, 158}, - {168, 168, 168}, {178, 178, 178}, {188, 188, 188}, {198, 198, 198}, - {208, 208, 208}, {218, 218, 218}, {228, 228, 228}, {238, 238, 238}, -}; - -const struct XtermDb { - struct Rgb rgb; - const char *text; -} kXtermDb[] = { - {{0x00, 0x00, 0x00}, "0 Black #000000"}, - {{0x80, 0x00, 0x00}, "1 Maroon #800000"}, - {{0x00, 0x80, 0x00}, "2 Green #008000"}, - {{0x80, 0x80, 0x00}, "3 Olive #808000"}, - {{0x00, 0x00, 0x80}, "4 Navy #000080"}, - {{0x80, 0x00, 0x80}, "5 Purple #800080"}, - {{0x00, 0x80, 0x80}, "6 Teal #008080"}, - {{0xc0, 0xc0, 0xc0}, "7 Silver #c0c0c0"}, - {{0x80, 0x80, 0x80}, "8 Grey #808080"}, - {{0xff, 0x00, 0x00}, "9 Red #ff0000"}, - {{0x00, 0xff, 0x00}, "10 Lime #00ff00"}, - {{0xff, 0xff, 0x00}, "11 Yellow #ffff00"}, - {{0x00, 0x00, 0xff}, "12 Blue #0000ff"}, - {{0xff, 0x00, 0xff}, "13 Fuchsia #ff00ff"}, - {{0x00, 0xff, 0xff}, "14 Aqua #00ffff"}, - {{0xff, 0xff, 0xff}, "15 White #ffffff"}, - {{0x00, 0x00, 0x00}, "16 Grey0 #000000"}, - {{0x00, 0x00, 0x5f}, "17 NavyBlue #00005f"}, - {{0x00, 0x00, 0x87}, "18 DarkBlue #000087"}, - {{0x00, 0x00, 0xaf}, "19 Blue3 #0000af"}, - {{0x00, 0x00, 0xd7}, "20 Blue3 #0000d7"}, - {{0x00, 0x00, 0xff}, "21 Blue1 #0000ff"}, - {{0x00, 0x5f, 0x00}, "22 DarkGreen #005f00"}, - {{0x00, 0x5f, 0x5f}, "23 DeepSkyBlue4 #005f5f"}, - {{0x00, 0x5f, 0x87}, "24 DeepSkyBlue4 #005f87"}, - {{0x00, 0x5f, 0xaf}, "25 DeepSkyBlue4 #005faf"}, - {{0x00, 0x5f, 0xd7}, "26 DodgerBlue3 #005fd7"}, - {{0x00, 0x5f, 0xff}, "27 DodgerBlue2 #005fff"}, - {{0x00, 0x87, 0x00}, "28 Green4 #008700"}, - {{0x00, 0x87, 0x5f}, "29 SpringGreen4 #00875f"}, - {{0x00, 0x87, 0x87}, "30 Turquoise4 #008787"}, - {{0x00, 0x87, 0xaf}, "31 DeepSkyBlue3 #0087af"}, - {{0x00, 0x87, 0xd7}, "32 DeepSkyBlue3 #0087d7"}, - {{0x00, 0x87, 0xff}, "33 DodgerBlue1 #0087ff"}, - {{0x00, 0xaf, 0x00}, "34 Green3 #00af00"}, - {{0x00, 0xaf, 0x5f}, "35 SpringGreen3 #00af5f"}, - {{0x00, 0xaf, 0x87}, "36 DarkCyan #00af87"}, - {{0x00, 0xaf, 0xaf}, "37 LightSeaGreen #00afaf"}, - {{0x00, 0xaf, 0xd7}, "38 DeepSkyBlue2 #00afd7"}, - {{0x00, 0xaf, 0xff}, "39 DeepSkyBlue1 #00afff"}, - {{0x00, 0xd7, 0x00}, "40 Green3 #00d700"}, - {{0x00, 0xd7, 0x5f}, "41 SpringGreen3 #00d75f"}, - {{0x00, 0xd7, 0x87}, "42 SpringGreen2 #00d787"}, - {{0x00, 0xd7, 0xaf}, "43 Cyan3 #00d7af"}, - {{0x00, 0xd7, 0xd7}, "44 DarkTurquoise #00d7d7"}, - {{0x00, 0xd7, 0xff}, "45 Turquoise2 #00d7ff"}, - {{0x00, 0xff, 0x00}, "46 Green1 #00ff00"}, - {{0x00, 0xff, 0x5f}, "47 SpringGreen2 #00ff5f"}, - {{0x00, 0xff, 0x87}, "48 SpringGreen1 #00ff87"}, - {{0x00, 0xff, 0xaf}, "49 MediumSpringGreen #00ffaf"}, - {{0x00, 0xff, 0xd7}, "50 Cyan2 #00ffd7"}, - {{0x00, 0xff, 0xff}, "51 Cyan1 #00ffff"}, - {{0x5f, 0x00, 0x00}, "52 DarkRed #5f0000"}, - {{0x5f, 0x00, 0x5f}, "53 DeepPink4 #5f005f"}, - {{0x5f, 0x00, 0x87}, "54 Purple4 #5f0087"}, - {{0x5f, 0x00, 0xaf}, "55 Purple4 #5f00af"}, - {{0x5f, 0x00, 0xd7}, "56 Purple3 #5f00d7"}, - {{0x5f, 0x00, 0xff}, "57 BlueViolet #5f00ff"}, - {{0x5f, 0x5f, 0x00}, "58 Orange4 #5f5f00"}, - {{0x5f, 0x5f, 0x5f}, "59 Grey37 #5f5f5f"}, - {{0x5f, 0x5f, 0x87}, "60 MediumPurple4 #5f5f87"}, - {{0x5f, 0x5f, 0xaf}, "61 SlateBlue3 #5f5faf"}, - {{0x5f, 0x5f, 0xd7}, "62 SlateBlue3 #5f5fd7"}, - {{0x5f, 0x5f, 0xff}, "63 RoyalBlue1 #5f5fff"}, - {{0x5f, 0x87, 0x00}, "64 Chartreuse4 #5f8700"}, - {{0x5f, 0x87, 0x5f}, "65 DarkSeaGreen4 #5f875f"}, - {{0x5f, 0x87, 0x87}, "66 PaleTurquoise4 #5f8787"}, - {{0x5f, 0x87, 0xaf}, "67 SteelBlue #5f87af"}, - {{0x5f, 0x87, 0xd7}, "68 SteelBlue3 #5f87d7"}, - {{0x5f, 0x87, 0xff}, "69 CornflowerBlue #5f87ff"}, - {{0x5f, 0xaf, 0x00}, "70 Chartreuse3 #5faf00"}, - {{0x5f, 0xaf, 0x5f}, "71 DarkSeaGreen4 #5faf5f"}, - {{0x5f, 0xaf, 0x87}, "72 CadetBlue #5faf87"}, - {{0x5f, 0xaf, 0xaf}, "73 CadetBlue #5fafaf"}, - {{0x5f, 0xaf, 0xd7}, "74 SkyBlue3 #5fafd7"}, - {{0x5f, 0xaf, 0xff}, "75 SteelBlue1 #5fafff"}, - {{0x5f, 0xd7, 0x00}, "76 Chartreuse3 #5fd700"}, - {{0x5f, 0xd7, 0x5f}, "77 PaleGreen3 #5fd75f"}, - {{0x5f, 0xd7, 0x87}, "78 SeaGreen3 #5fd787"}, - {{0x5f, 0xd7, 0xaf}, "79 Aquamarine3 #5fd7af"}, - {{0x5f, 0xd7, 0xd7}, "80 MediumTurquoise #5fd7d7"}, - {{0x5f, 0xd7, 0xff}, "81 SteelBlue1 #5fd7ff"}, - {{0x5f, 0xff, 0x00}, "82 Chartreuse2 #5fff00"}, - {{0x5f, 0xff, 0x5f}, "83 SeaGreen2 #5fff5f"}, - {{0x5f, 0xff, 0x87}, "84 SeaGreen1 #5fff87"}, - {{0x5f, 0xff, 0xaf}, "85 SeaGreen1 #5fffaf"}, - {{0x5f, 0xff, 0xd7}, "86 Aquamarine1 #5fffd7"}, - {{0x5f, 0xff, 0xff}, "87 DarkSlateGray2 #5fffff"}, - {{0x87, 0x00, 0x00}, "88 DarkRed #870000"}, - {{0x87, 0x00, 0x5f}, "89 DeepPink4 #87005f"}, - {{0x87, 0x00, 0x87}, "90 DarkMagenta #870087"}, - {{0x87, 0x00, 0xaf}, "91 DarkMagenta #8700af"}, - {{0x87, 0x00, 0xd7}, "92 DarkViolet #8700d7"}, - {{0x87, 0x00, 0xff}, "93 Purple #8700ff"}, - {{0x87, 0x5f, 0x00}, "94 Orange4 #875f00"}, - {{0x87, 0x5f, 0x5f}, "95 LightPink4 #875f5f"}, - {{0x87, 0x5f, 0x87}, "96 Plum4 #875f87"}, - {{0x87, 0x5f, 0xaf}, "97 MediumPurple3 #875faf"}, - {{0x87, 0x5f, 0xd7}, "98 MediumPurple3 #875fd7"}, - {{0x87, 0x5f, 0xff}, "99 SlateBlue1 #875fff"}, - {{0x87, 0x87, 0x00}, "100 Yellow4 #878700"}, - {{0x87, 0x87, 0x5f}, "101 Wheat4 #87875f"}, - {{0x87, 0x87, 0x87}, "102 Grey53 #878787"}, - {{0x87, 0x87, 0xaf}, "103 LightSlateGrey #8787af"}, - {{0x87, 0x87, 0xd7}, "104 MediumPurple #8787d7"}, - {{0x87, 0x87, 0xff}, "105 LightSlateBlue #8787ff"}, - {{0x87, 0xaf, 0x00}, "106 Yellow4 #87af00"}, - {{0x87, 0xaf, 0x5f}, "107 DarkOliveGreen3 #87af5f"}, - {{0x87, 0xaf, 0x87}, "108 DarkSeaGreen #87af87"}, - {{0x87, 0xaf, 0xaf}, "109 LightSkyBlue3 #87afaf"}, - {{0x87, 0xaf, 0xd7}, "110 LightSkyBlue3 #87afd7"}, - {{0x87, 0xaf, 0xff}, "111 SkyBlue2 #87afff"}, - {{0x87, 0xd7, 0x00}, "112 Chartreuse2 #87d700"}, - {{0x87, 0xd7, 0x5f}, "113 DarkOliveGreen3 #87d75f"}, - {{0x87, 0xd7, 0x87}, "114 PaleGreen3 #87d787"}, - {{0x87, 0xd7, 0xaf}, "115 DarkSeaGreen3 #87d7af"}, - {{0x87, 0xd7, 0xd7}, "116 DarkSlateGray3 #87d7d7"}, - {{0x87, 0xd7, 0xff}, "117 SkyBlue1 #87d7ff"}, - {{0x87, 0xff, 0x00}, "118 Chartreuse1 #87ff00"}, - {{0x87, 0xff, 0x5f}, "119 LightGreen #87ff5f"}, - {{0x87, 0xff, 0x87}, "120 LightGreen #87ff87"}, - {{0x87, 0xff, 0xaf}, "121 PaleGreen1 #87ffaf"}, - {{0x87, 0xff, 0xd7}, "122 Aquamarine1 #87ffd7"}, - {{0x87, 0xff, 0xff}, "123 DarkSlateGray1 #87ffff"}, - {{0xaf, 0x00, 0x00}, "124 Red3 #af0000"}, - {{0xaf, 0x00, 0x5f}, "125 DeepPink4 #af005f"}, - {{0xaf, 0x00, 0x87}, "126 MediumVioletRed #af0087"}, - {{0xaf, 0x00, 0xaf}, "127 Magenta3 #af00af"}, - {{0xaf, 0x00, 0xd7}, "128 DarkViolet #af00d7"}, - {{0xaf, 0x00, 0xff}, "129 Purple #af00ff"}, - {{0xaf, 0x5f, 0x00}, "130 DarkOrange3 #af5f00"}, - {{0xaf, 0x5f, 0x5f}, "131 IndianRed #af5f5f"}, - {{0xaf, 0x5f, 0x87}, "132 HotPink3 #af5f87"}, - {{0xaf, 0x5f, 0xaf}, "133 MediumOrchid3 #af5faf"}, - {{0xaf, 0x5f, 0xd7}, "134 MediumOrchid #af5fd7"}, - {{0xaf, 0x5f, 0xff}, "135 MediumPurple2 #af5fff"}, - {{0xaf, 0x87, 0x00}, "136 DarkGoldenrod #af8700"}, - {{0xaf, 0x87, 0x5f}, "137 LightSalmon3 #af875f"}, - {{0xaf, 0x87, 0x87}, "138 RosyBrown #af8787"}, - {{0xaf, 0x87, 0xaf}, "139 Grey63 #af87af"}, - {{0xaf, 0x87, 0xd7}, "140 MediumPurple2 #af87d7"}, - {{0xaf, 0x87, 0xff}, "141 MediumPurple1 #af87ff"}, - {{0xaf, 0xaf, 0x00}, "142 Gold3 #afaf00"}, - {{0xaf, 0xaf, 0x5f}, "143 DarkKhaki #afaf5f"}, - {{0xaf, 0xaf, 0x87}, "144 NavajoWhite3 #afaf87"}, - {{0xaf, 0xaf, 0xaf}, "145 Grey69 #afafaf"}, - {{0xaf, 0xaf, 0xd7}, "146 LightSteelBlue3 #afafd7"}, - {{0xaf, 0xaf, 0xff}, "147 LightSteelBlue #afafff"}, - {{0xaf, 0xd7, 0x00}, "148 Yellow3 #afd700"}, - {{0xaf, 0xd7, 0x5f}, "149 DarkOliveGreen3 #afd75f"}, - {{0xaf, 0xd7, 0x87}, "150 DarkSeaGreen3 #afd787"}, - {{0xaf, 0xd7, 0xaf}, "151 DarkSeaGreen2 #afd7af"}, - {{0xaf, 0xd7, 0xd7}, "152 LightCyan3 #afd7d7"}, - {{0xaf, 0xd7, 0xff}, "153 LightSkyBlue1 #afd7ff"}, - {{0xaf, 0xff, 0x00}, "154 GreenYellow #afff00"}, - {{0xaf, 0xff, 0x5f}, "155 DarkOliveGreen2 #afff5f"}, - {{0xaf, 0xff, 0x87}, "156 PaleGreen1 #afff87"}, - {{0xaf, 0xff, 0xaf}, "157 DarkSeaGreen2 #afffaf"}, - {{0xaf, 0xff, 0xd7}, "158 DarkSeaGreen1 #afffd7"}, - {{0xaf, 0xff, 0xff}, "159 PaleTurquoise1 #afffff"}, - {{0xd7, 0x00, 0x00}, "160 Red3 #d70000"}, - {{0xd7, 0x00, 0x5f}, "161 DeepPink3 #d7005f"}, - {{0xd7, 0x00, 0x87}, "162 DeepPink3 #d70087"}, - {{0xd7, 0x00, 0xaf}, "163 Magenta3 #d700af"}, - {{0xd7, 0x00, 0xd7}, "164 Magenta3 #d700d7"}, - {{0xd7, 0x00, 0xff}, "165 Magenta2 #d700ff"}, - {{0xd7, 0x5f, 0x00}, "166 DarkOrange3 #d75f00"}, - {{0xd7, 0x5f, 0x5f}, "167 IndianRed #d75f5f"}, - {{0xd7, 0x5f, 0x87}, "168 HotPink3 #d75f87"}, - {{0xd7, 0x5f, 0xaf}, "169 HotPink2 #d75faf"}, - {{0xd7, 0x5f, 0xd7}, "170 Orchid #d75fd7"}, - {{0xd7, 0x5f, 0xff}, "171 MediumOrchid1 #d75fff"}, - {{0xd7, 0x87, 0x00}, "172 Orange3 #d78700"}, - {{0xd7, 0x87, 0x5f}, "173 LightSalmon3 #d7875f"}, - {{0xd7, 0x87, 0x87}, "174 LightPink3 #d78787"}, - {{0xd7, 0x87, 0xaf}, "175 Pink3 #d787af"}, - {{0xd7, 0x87, 0xd7}, "176 Plum3 #d787d7"}, - {{0xd7, 0x87, 0xff}, "177 Violet #d787ff"}, - {{0xd7, 0xaf, 0x00}, "178 Gold3 #d7af00"}, - {{0xd7, 0xaf, 0x5f}, "179 LightGoldenrod3 #d7af5f"}, - {{0xd7, 0xaf, 0x87}, "180 Tan #d7af87"}, - {{0xd7, 0xaf, 0xaf}, "181 MistyRose3 #d7afaf"}, - {{0xd7, 0xaf, 0xd7}, "182 Thistle3 #d7afd7"}, - {{0xd7, 0xaf, 0xff}, "183 Plum2 #d7afff"}, - {{0xd7, 0xd7, 0x00}, "184 Yellow3 #d7d700"}, - {{0xd7, 0xd7, 0x5f}, "185 Khaki3 #d7d75f"}, - {{0xd7, 0xd7, 0x87}, "186 LightGoldenrod2 #d7d787"}, - {{0xd7, 0xd7, 0xaf}, "187 LightYellow3 #d7d7af"}, - {{0xd7, 0xd7, 0xd7}, "188 Grey84 #d7d7d7"}, - {{0xd7, 0xd7, 0xff}, "189 LightSteelBlue1 #d7d7ff"}, - {{0xd7, 0xff, 0x00}, "190 Yellow2 #d7ff00"}, - {{0xd7, 0xff, 0x5f}, "191 DarkOliveGreen1 #d7ff5f"}, - {{0xd7, 0xff, 0x87}, "192 DarkOliveGreen1 #d7ff87"}, - {{0xd7, 0xff, 0xaf}, "193 DarkSeaGreen1 #d7ffaf"}, - {{0xd7, 0xff, 0xd7}, "194 Honeydew2 #d7ffd7"}, - {{0xd7, 0xff, 0xff}, "195 LightCyan1 #d7ffff"}, - {{0xff, 0x00, 0x00}, "196 Red1 #ff0000"}, - {{0xff, 0x00, 0x5f}, "197 DeepPink2 #ff005f"}, - {{0xff, 0x00, 0x87}, "198 DeepPink1 #ff0087"}, - {{0xff, 0x00, 0xaf}, "199 DeepPink1 #ff00af"}, - {{0xff, 0x00, 0xd7}, "200 Magenta2 #ff00d7"}, - {{0xff, 0x00, 0xff}, "201 Magenta1 #ff00ff"}, - {{0xff, 0x5f, 0x00}, "202 OrangeRed1 #ff5f00"}, - {{0xff, 0x5f, 0x5f}, "203 IndianRed1 #ff5f5f"}, - {{0xff, 0x5f, 0x87}, "204 IndianRed1 #ff5f87"}, - {{0xff, 0x5f, 0xaf}, "205 HotPink #ff5faf"}, - {{0xff, 0x5f, 0xd7}, "206 HotPink #ff5fd7"}, - {{0xff, 0x5f, 0xff}, "207 MediumOrchid1 #ff5fff"}, - {{0xff, 0x87, 0x00}, "208 DarkOrange #ff8700"}, - {{0xff, 0x87, 0x5f}, "209 Salmon1 #ff875f"}, - {{0xff, 0x87, 0x87}, "210 LightCoral #ff8787"}, - {{0xff, 0x87, 0xaf}, "211 PaleVioletRed1 #ff87af"}, - {{0xff, 0x87, 0xd7}, "212 Orchid2 #ff87d7"}, - {{0xff, 0x87, 0xff}, "213 Orchid1 #ff87ff"}, - {{0xff, 0xaf, 0x00}, "214 Orange1 #ffaf00"}, - {{0xff, 0xaf, 0x5f}, "215 SandyBrown #ffaf5f"}, - {{0xff, 0xaf, 0x87}, "216 LightSalmon1 #ffaf87"}, - {{0xff, 0xaf, 0xaf}, "217 LightPink1 #ffafaf"}, - {{0xff, 0xaf, 0xd7}, "218 Pink1 #ffafd7"}, - {{0xff, 0xaf, 0xff}, "219 Plum1 #ffafff"}, - {{0xff, 0xd7, 0x00}, "220 Gold1 #ffd700"}, - {{0xff, 0xd7, 0x5f}, "221 LightGoldenrod2 #ffd75f"}, - {{0xff, 0xd7, 0x87}, "222 LightGoldenrod2 #ffd787"}, - {{0xff, 0xd7, 0xaf}, "223 NavajoWhite1 #ffd7af"}, - {{0xff, 0xd7, 0xd7}, "224 MistyRose1 #ffd7d7"}, - {{0xff, 0xd7, 0xff}, "225 Thistle1 #ffd7ff"}, - {{0xff, 0xff, 0x00}, "226 Yellow1 #ffff00"}, - {{0xff, 0xff, 0x5f}, "227 LightGoldenrod1 #ffff5f"}, - {{0xff, 0xff, 0x87}, "228 Khaki1 #ffff87"}, - {{0xff, 0xff, 0xaf}, "229 Wheat1 #ffffaf"}, - {{0xff, 0xff, 0xd7}, "230 Cornsilk1 #ffffd7"}, - {{0xff, 0xff, 0xff}, "231 Grey100 #ffffff"}, - {{0x08, 0x08, 0x08}, "232 Grey3 #080808"}, - {{0x12, 0x12, 0x12}, "233 Grey7 #121212"}, - {{0x1c, 0x1c, 0x1c}, "234 Grey11 #1c1c1c"}, - {{0x26, 0x26, 0x26}, "235 Grey15 #262626"}, - {{0x30, 0x30, 0x30}, "236 Grey19 #303030"}, - {{0x3a, 0x3a, 0x3a}, "237 Grey23 #3a3a3a"}, - {{0x44, 0x44, 0x44}, "238 Grey27 #444444"}, - {{0x4e, 0x4e, 0x4e}, "239 Grey30 #4e4e4e"}, - {{0x58, 0x58, 0x58}, "240 Grey35 #585858"}, - {{0x62, 0x62, 0x62}, "241 Grey39 #626262"}, - {{0x6c, 0x6c, 0x6c}, "242 Grey42 #6c6c6c"}, - {{0x76, 0x76, 0x76}, "243 Grey46 #767676"}, - {{0x80, 0x80, 0x80}, "244 Grey50 #808080"}, - {{0x8a, 0x8a, 0x8a}, "245 Grey54 #8a8a8a"}, - {{0x94, 0x94, 0x94}, "246 Grey58 #949494"}, - {{0x9e, 0x9e, 0x9e}, "247 Grey62 #9e9e9e"}, - {{0xa8, 0xa8, 0xa8}, "248 Grey66 #a8a8a8"}, - {{0xb2, 0xb2, 0xb2}, "249 Grey70 #b2b2b2"}, - {{0xbc, 0xbc, 0xbc}, "250 Grey74 #bcbcbc"}, - {{0xc6, 0xc6, 0xc6}, "251 Grey78 #c6c6c6"}, - {{0xd0, 0xd0, 0xd0}, "252 Grey82 #d0d0d0"}, - {{0xda, 0xda, 0xda}, "253 Grey85 #dadada"}, - {{0xe4, 0xe4, 0xe4}, "254 Grey89 #e4e4e4"}, - {{0xee, 0xee, 0xee}, "255 Grey93 #eeeeee"}, -}; - -int main(int argc, char *argv[]) { - size_t i; - printf("BG FG BB BF XTERM NAME HEX\n"); - for (i = 0; i < 256; ++i) { - printf("\e[48;5;%dm \e[0m \e[38;5;%dm██\e[0m \e[1;48;5;%dm " - "\e[0m \e[1;38;5;%dm██\e[0m %-6hhu%-18s#%02hhx%02hhx%02hhx\n", - i, i, i, i, i, IndexDoubleNulString(kXtermName, i), kXtermRgb[i].r, - kXtermRgb[i].g, kXtermRgb[i].b); - } - return 0; -}