Full Code of r-lyeh/tinybits for AI

master 2a735d9717c9 cached
145 files
497.8 KB
168.3k tokens
558 symbols
1 requests
Download .txt
Showing preview only (531K chars total). Download the full file or copy to clipboard to get everything.
Repository: r-lyeh/tinybits
Branch: master
Commit: 2a735d9717c9
Files: 145
Total size: 497.8 KB

Directory structure:
gitextract_m65kpms5/

├── README.md
├── UNLICENSE.md
├── tinyarc4.hpp
├── tinyassert.c
├── tinyatoi.c
├── tinybenchmark.hpp
├── tinybsearch.c
├── tinybsearch.cc
├── tinybuild.h
├── tinydebug.h
├── tinydefer.cc
├── tinydir.cc
├── tinydixy.c
├── tinydual.sh.bat
├── tinyendian.c
├── tinyerror.c
├── tinyfsm.c
├── tinygc.cc
├── tinyhexbase.c
├── tinyhexdump.c
├── tinyhuman.hpp
├── tinyini.c
├── tinyjson5.c
├── tinylog.c
├── tinylog.h
├── tinylogger.h
├── tinylogger.hpp
├── tinymatch.c
├── tinymime.c
├── tinypipe.hpp
├── tinyprint.cc
├── tinypulse.c
├── tinyroman.cc
├── tinystring.c
├── tinystring.cc
├── tinytga.c
├── tinytime.cc
├── tinytodo.c
├── tinytty.c
├── tinyuniso.cc
├── tinyunit.c
├── tinyuntar.cc
├── tinyunzip.cc
├── tinyvariant.cc
├── tinyvbyte.h
├── tinywav.c
├── tinywtf.h
├── tinyzlib.cpp
└── vault/
    ├── ; ds
    ├── _test.c
    ├── all.c
    ├── bin.c
    ├── bin_dbkv.c
    ├── bin_json5.c
    ├── buf.c
    ├── buf_arc4.c
    ├── buf_base64.c
    ├── buf_base92.c
    ├── buf_cobs.c
    ├── buf_crc.c
    ├── buf_endian.c
    ├── buf_interleave.c
    ├── buf_netstring.c
    ├── buf_pack.c
    ├── buf_pack754.h
    ├── buf_packhalf.h
    ├── buf_packint.h
    ├── buf_packvli.h
    ├── buf_zigzag.c
    ├── c.c
    ├── c_alignas.c
    ├── c_benchmark.c
    ├── c_cc4.c
    ├── c_checkva.c
    ├── c_countof.c
    ├── c_ifdef.c
    ├── c_incbin.h
    ├── c_once.c
    ├── c_overload.c
    ├── c_plan.c
    ├── c_section.c
    ├── c_thread.c
    ├── c_unreachable.c
    ├── c_with.c
    ├── ds.c
    ├── ds_alloc.c
    ├── ds_array.c
    ├── ds_format.c
    ├── ds_hash.c
    ├── ds_map.c
    ├── ds_quark.c
    ├── ds_rope.c
    ├── ds_set.c
    ├── ds_sort.c
    ├── ds_stream.c
    ├── ds_string.c
    ├── net.c
    ├── net_ecdh.h
    ├── net_fragment.c
    ├── net_tunnel.c
    ├── net_webserver.c
    ├── os.c
    ├── os_ansi.c
    ├── os_assert.c
    ├── os_breakpoint.c
    ├── os_cpu.c
    ├── os_date.c
    ├── os_dialog.c
    ├── os_die.c
    ├── os_entropy.c
    ├── os_env.c
    ├── os_exec.c
    ├── os_exit.c
    ├── os_file.c
    ├── os_icon.c
    ├── os_ini.c
    ├── os_locale.c
    ├── os_logger.c
    ├── os_logger2.c
    ├── os_logger3.c
    ├── os_memory.c
    ├── os_mime.c
    ├── os_singleton.c
    ├── os_test.c
    ├── os_trap.c
    ├── os_tray.c
    ├── syn.c
    ├── syn_atomic.c
    ├── syn_channel.c
    ├── syn_condv.c
    ├── syn_coro.c
    ├── syn_fiber.c
    ├── syn_fiber_amd64.h
    ├── syn_fiber_arm.h
    ├── syn_fiber_ppc.h
    ├── syn_fiber_sjlj.h
    ├── syn_fiber_ucontext.h
    ├── syn_fiber_win32.h
    ├── syn_fiber_x86.h
    ├── syn_mcmp.c
    ├── syn_mutex.c
    ├── syn_semaphore.c
    ├── syn_sleep.c
    ├── syn_thread.c
    └── syn_tls.c

================================================
FILE CONTENTS
================================================

================================================
FILE: README.md
================================================
# tinybits
- [x] Tiny bits and useful snippets that I keep using everywhere.
- [x] Too simple to become libraries. Just cut & paste.
- [x] Cross-platform C/C++.
- [x] Public Domain.

|Snippet|Language|Domain|
|:------|:-------|:-----|
|[tinyarc4.hpp](tinyarc4.hpp)|C++|ARC4 stream cypher|
|[tinyassert.c](tinyassert.c)|C/C++|Old assert() macro with new tricks|
|[tinyatoi.c](tinyatoi.c)|C|atoi() implementation|
|[tinybenchmark.hpp](tinybenchmark.hpp)|C++|Benchmark code|
|[tinybsearch.c](tinybsearch.c)|C|Dichotomic binary search|
|[tinybsearch.cc](tinybsearch.cc)|C++|Dichotomic binary search|
|[tinybuild.h](tinybuild.h)|C|Build macros|
|[tinydebug.h](tinydebug.h)|C|Debug macros|
|[tinydefer.cc](tinydefer.cc)|C++|Defer macro, Go style|
|[tinydir.cc](tinydir.cc)|C++|Directory listing|
|[tinydixy.c](tinydixy.c)|C|Small YAML-subset config file parser|
|[tinydual.sh.bat](tinydual.sh.bat)|Bash|Dual bash/batch file|
|[tinyendian.c](tinyendian.c)|C|Endianness conversions|
|[tinyerror.c](tinyerror.c)|C|Error handling|
|[tinyfsm.c](tinyfsm.c)|C|Tight FSM|
|[tinygc.cc](tinygc.cc)|C++|Garbage collector (C++)|
|[tinyhexbase.c](tinyhexbase.c)|C|Simple binary to ascii encoder|
|[tinyhexdump.c](tinyhexdump.c)|C|Hexdump viewer|
|[tinyhuman.hpp](tinyhuman.hpp)|C++|De/humanized numbers|
|[tinyini.c](tinyini.c)|C|Config parser (ini+)|
|[tinyjson5.c](tinyjson5.c)|C|JSON5/SJSON/JSON parser/writer|
|[tinylog.h](tinylog.h)|C|Logging utilities|
|[tinylogger.h](tinylogger.h)|C|Simplest colorful logger|
|[tinylogger.hpp](tinylogger.hpp)|C++|Session logger|
|[tinymatch.c](tinymatch.c)|C|Wildcard/pattern matching|
|[tinymime.c](tinymime.c)|C|MIME/file-type detection|
|[tinypipe.hpp](tinypipe.hpp)|C++11|Chainable pipes|
|[tinyprint.cc](tinyprint.cc)|C++|Comma-based printer|
|[tinypulse.c](tinypulse.c)|C|Digital pulses|
|[tinyroman.cc](tinyroman.cc)|C++|Integer to roman literals|
|[tinystring.c](tinystring.c)|C|C string library|
|[tinystring.cc](tinystring.cc)|C++|C++ string utilities|
|[tinytga.c](tinytga.c)|C|TGA writer (fork)|
|[tinytime.cc](tinytime.cc)|C++|Timing utilities|
|[tinytodo.c](tinytodo.c)|C|TODO() macro|
|[tinytty.c](tinytty.c)|C|Terminal utilities|
|[tinyunit.c](tinyunit.c)|C|Unit-testing|
|[tinyuniso.cc](tinyuniso.cc)|C++|.iso/9960 unarchiver|
|[tinyuntar.cc](tinyuntar.cc)|C++|.tar unarchiver|
|[tinyunzip.cc](tinyunzip.cc)|C++|.zip unarchiver|
|[tinyvariant.cc](tinyvariant.cc)|C++|Variant class|
|[tinyvbyte.h](tinyvbyte.h)|C|vbyte encoder/decoder (VLE)|
|[tinywav.c](tinywav.c)|C|WAV writer (fork)|
|[tinywtf.h](tinywtf.h)|C/C++|Portable host macros|
|[tinyzlib.cpp](tinyzlib.cpp)|C++|zlib inflater|


================================================
FILE: UNLICENSE.md
================================================
This is free and unencumbered software released into the public domain.

Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.

In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

For more information, please refer to <http://unlicense.org>


================================================
FILE: tinyarc4.hpp
================================================
// tinyARC4, ARC4 stream cypher. based on code by Mike Shaffer.
// - rlyeh, public domain ~~ listening to Black Belt - Leeds | wtrmrkrlyeh

#pragma once
#include <string>

static
std::string tinyARC4( const std::string &text, const std::string &passkey ) {
    int sbox[256], key[256];
    std::string output;
    size_t plen = passkey.size(), tlen = text.size();
    if( plen ) {
        output.resize( text.size() );
        for( size_t a = 0; a < 256; a++ ) {
            key[ a ] = passkey[ a % plen ];
            sbox[ a ] = a;
        }
        for( size_t a = 0, b = 0; a < 256; a++ ) {
            b = (b + sbox[ a ] + key[ a ]) % 256;
            int swap = sbox[ a ]; sbox[ a ] = sbox[ b ]; sbox[ b ] = swap;
        }
        for( size_t a = 0, i = 0, j = 0, k; a < tlen; a++ ) {
            i = (i + 1) % 256;
            j = (j + sbox[ i ]) % 256;
            int swap = sbox[ i ]; sbox[ i ] = sbox[ j ]; sbox[ j ] = swap;
            k = sbox[(sbox[ i ] + sbox[j]) % 256];
            output[ a ] = text[ a ] ^ k;
        }
    } else output = text;
    return output;
}

/*
#include <cassert>
#include <iostream>
int main( int argc, const char **argv ) {
    // sample
    std::string encrypted = tinyARC4( "Hello world.", "my-password" );
    std::string decrypted = tinyARC4( encrypted, "my-password" );

    std::cout << "ARC4 Encrypted text: " << encrypted << std::endl;
    std::cout << "ARC4 Decrypted text: " << decrypted << std::endl;

    // tests
    assert( tinyARC4("hello world", "my key") != "hello world" );
    assert( tinyARC4(tinyARC4("hello world", "my key"), "my key") == "hello world" );
}
*/


================================================
FILE: tinyassert.c
================================================
// old assert() macro with new tricks.
// - rlyeh, public domain.
//
// - [x] log failures always. break debugger only once per failure.
// - [x] enabled always. even in optimized builds. unless ASSERT_LEVEL is 0.
// - [x] allow messages. ie, assert(my_var != 5, "failed my_var!=%d", my_var).
// - [x] break debugger only if present (hassle developers; dont hassle users).
// - [x] overridable logger & debugger break. tip: may define ASSERT_BREAK as abort(), or leave it blank as well.
// - [x] filter out by configurable range (to speed up things when having thousand of expensive asserts). see ASSERT_LEVEL.

// configuration: percentage of random checked asserts: [0%(none)..50%(half)..100%(all)]. default: 100%
#ifndef ASSERT_LEVEL
#define ASSERT_LEVEL 100 
#endif

// impl below ------------------------------------------------------------------
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include <assert.h>
#undef assert

// default logger: dump to stderr
#ifndef ASSERT_LOG
#define ASSERT_LOG(x) do { fprintf(stderr, "%s\n", (x)); } while(0)
#endif

// default break behavior: break if debugged.
#  if !defined ASSERT_BREAK && defined _WIN32
#define ASSERT_BREAK() do{ if(IsDebuggerPresent()) __debugbreak(); } while(0)
#include <winsock2.h> // needed for __cplusplus
#elif !defined ASSERT_BREAK // && defined __unix__
#define ASSERT_BREAK() do { signal(SIGTRAP, break_handler_); raise(SIGTRAP); } while(0)
#include <signal.h>
static void break_handler_(int signum) { signal(SIGTRAP, SIG_DFL); }
#endif

#if (ASSERT_LEVEL <= 0) || defined SHIPPING
#define assert(EXPR, ...) (void)0
#else
#define assert(EXPR, ...) do { \
    static int64_t maybe = -1; if(maybe < 0) { \
            /* original splitmix64 by Sebastiano Vigna (CC0)*/ \
            uint64_t z = (__LINE__ + __COUNTER__ + UINT64_C(0x9E3779B97F4A7C15)); \
            z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9); \
            maybe = (unsigned)((z ^ (z >> 31)) % 100) < ASSERT_LEVEL; } \
        if( maybe ) { \
            int msvc_trick[] = {0,}; \
            if( !(EXPR) ) { \
                char text[4096], *ptr = text; \
                ptr += sprintf( ptr, "!" __VA_ARGS__ ); \
                ptr += text[1] ? 0 : sprintf( ptr, "Assertion failed: %s", #EXPR ); \
                ptr += sprintf( ptr, " (unexpected) %s:%d", __FILE__, __LINE__); \
                ASSERT_LOG((1+text)); \
                msvc_trick[0]++; /* fool clang -Wunused-variable */ \
                static int once = 1; for(;once;once=0) ASSERT_BREAK(); \
            } \
        } \
    } while(0)
#endif

#if 0 // demo
int main() {
    for( int i = 0; i < 3; ++i ) {
        assert(i < 2);
        assert(i < 2, "Error! %d should be smaller than %d", i, 2);
    }
    puts("Program continues over here unless debugger is attached...");
}
#endif


================================================
FILE: tinyatoi.c
================================================
// Tiny atoi() replacement. rlyeh, public domain | wtrmrkrlyeh
#pragma once

static
int tinyatoi( const char *s ) {
    int v = 0, n = 1;
    if( s ) {
        while( *s == '-' ) n *= -1, s++;
        while( *s >= '0' && *s <= '9') v = (v * 10) + *s++ - '0';
    }
    return n * v;
}

/*
#include <assert.h>
int main() {
    assert( 1230 == tinyatoi("01230") );
    assert( -1230 == tinyatoi("-01230") );
    assert( 1230 == tinyatoi("--01230") );
    assert( -1230 == tinyatoi("---01230") );
}
*/


================================================
FILE: tinybenchmark.hpp
================================================
// tiny benchmarks. OpenMP required.
// - rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <omp.h>
#include <stdio.h>
struct bench {
    double line, time;
    operator bool() const { return true; }
    ~bench() { printf("L%d %gms\n", (int)line, (omp_get_wtime() - time) * 1000); }
};
#define bench if( const bench x = { __LINE__, omp_get_wtime() } ) 

/*
int main() {
   bench {
        for( int i = 0; i < 100000000; ++i );
        puts("hello stdio");
   }
}
*/


================================================
FILE: tinybsearch.c
================================================
// Tiny binary search (dichotomic): array must be sorted && supporting sequential access.
// - rlyeh, public domain | wtrmrkrlyeh

#include <string.h>

unsigned bsearchint( const int *array, int numelems, int key ) {
    int min = 0, max = numelems;
    while( min <= max ) {
        int mid = min + ( max - min ) / 2;
        /**/ if( key == array[mid] ) return mid;
        else if( key <  array[mid] ) max = mid - 1;
        else min = mid + 1;
    }
    return ~0u;
}
unsigned bsearchsz( const size_t *array, int numelems, size_t key ) {
    int min = 0, max = numelems;
    while( min <= max ) {
        int mid = min + ( max - min ) / 2;
        /**/ if( key == array[mid] ) return mid;
        else if( key <  array[mid] ) max = mid - 1;
        else min = mid + 1;
    }
    return ~0u;
}
unsigned bsearchstr( const char **array, int numelems, const char *key ) {
    int min = 0, max = numelems;
    while( min <= max ) {
        int mid = min + ( max - min ) / 2;
        int search = strcmp(key, array[mid]);
        /**/ if( 0 ==search ) return mid;
        else if( search < 0 ) max = mid - 1;
        else min = mid + 1;
    }
    return ~0u;
}

/*
#include <assert.h>
int main() {
                      // @ [0]    [1]            [2]        [3]
    const char *dict[] = { "abc", "abracadabra", "ale hop", "all your base"};

    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "abc") == 0 );           // @ [0]
    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "abracadabra") == 1 );   // @ [1]
    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "ale hop") ==   2 );     // @ [2]
    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "all your base") == 3 ); // @ [3]

    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "are belong to us") == ~0u ); // not found
    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "move") == ~0u ); // not found
    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "every") == ~0u ); // not found
    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "zig") == ~0u ); // not found
    assert( bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), "") == ~0u ); // not found

    for( int i = 0; i < sizeof(dict) / sizeof(dict[0]); ++i ) {
        assert( i == bsearchstr(dict, sizeof(dict) / sizeof(dict[0]), dict[i]) );
    }
}
*/


================================================
FILE: tinybsearch.cc
================================================
// Tiny binary search (dichotomic): container must be sorted && supporting sequential access.
// - rlyeh, public domain | wtrmrkrlyeh

template<typename container, typename T>
unsigned bsearch( const T &x, const container &v ) {
    int min = 0, max = int(v.size());
    while( min <= max ) {
        int mid = min + ( max - min ) / 2;
        /**/ if( x == v[mid] ) return mid;
        else if( x  < v[mid] ) max = mid - 1;
        else min = mid + 1;
    }
    return ~0u;
}

/*
#include <cassert>
#include <vector>
int main() {
                    // @ [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12]
    std::vector<int> v {  0,  1,  2,  3,  5,  6,  7, 10, 11, 12,  13,  15,  16 };

    assert( bsearch( 0, v) ==   0 ); // @ [ 0]
    assert( bsearch(10, v) ==   7 ); // @ [ 7]
    assert( bsearch(11, v) ==   8 ); // @ [ 8]
    assert( bsearch(15, v) ==  11 ); // @ [11]
    assert( bsearch(16, v) ==  12 ); // @ [12]
    assert( bsearch(-3, v) == ~0u ); // not found
    assert( bsearch(18, v) == ~0u ); // not found
    assert( bsearch( 8, v) == ~0u ); // not found
    assert( bsearch( 9, v) == ~0u ); // not found

    for( const auto &i : v ) {
        assert( v[bsearch(i,v)] == i );
    }
}
*/


================================================
FILE: tinybuild.h
================================================
// Tiny buildinfo macros
// - rlyeh, public domain | wtrmrkrlyeh

#pragma once

#ifndef BUILD_GIT_BRANCH
#define BUILD_GIT_BRANCH   "n/a"
#endif

#ifndef BUILD_GIT_REVISION
#define BUILD_GIT_REVISION "NaN"
#endif

#ifndef BUILD_BITS
#if _WIN64 || __x86_64__ || __ppc64__
#define BUILD_BITS 64
#elif _WIN32 || __GNUC__
#define BUILD_BITS 32
#else
#define BUILD_BITS 00
#endif
#endif

#ifndef BUILD_PROJECT
#define BUILD_PROJECT "UNNAMED"
#endif

#ifndef BUILD_VERSION
#define BUILD_VERSION "0.0.0"
#endif

#ifndef BUILD_URL
#define BUILD_URL     "https://"
#endif

#ifndef BUILD_STAMP
#define BUILD_STAMP   __DATE__ " " __TIME__
#endif

#ifndef BUILD_STR
#define BUILD_S7R(a)  #a
#define BUILD_STR(a)  BUILD_S7R(a)
#endif

#ifndef BUILD_ARCH
#define BUILD_ARCH    BUILD_STR(BUILD_BITS) "-bit"
#endif

#ifndef BUILD_TYPE
#define BUILD_TYPE    "DEBUG"
#endif

#ifndef BUILD_INFO
#define BUILD_INFO    BUILD_PROJECT " " BUILD_VERSION " (" BUILD_ARCH " " BUILD_TYPE ") (" BUILD_STAMP ") (git:" BUILD_GIT_BRANCH " rev:" BUILD_GIT_REVISION ")"
#endif

/*
#include <stdio.h>
int main() {
    puts( BUILD_INFO );
}
*/


================================================
FILE: tinydebug.h
================================================
// Tiny debug macros
// - rlyeh, public domain | wtrmrkrlyeh
//
// Build cube of 3 dimensions, 5 levels each:
//
//     . PUBLIC AXIS: 0 STUDIO/INTERNAL, 1 QA, 2 USER-TESTING, 3 SHOWCASE, 4 SHIPPING/MASTER
//    /
//   /
//  +--------> DEBUG AXIS: 0 FATAL, 1 ERROR, 2 WARN, 3 INFO, 4 VERBOSE
//  |
//  |
//  |
//  V OPTIMIZATION AXIS: 0 DEBUG, 1 DEBUGOPT, 2 OPTSYM, 3 OPTMAX, 4 STRIPPED
//
// Example: a RETAIL build might be PUB>=3 DBG<=1 OPT>=3

#pragma once

#if defined(DEBUG) && (defined(NDEBUG) || defined(_NDEBUG))
#undef DEBUG      // NDEBUG has precedence
#endif

#ifndef DBGLVL
#define DBGLVL (0)
#endif

#ifndef OPTLVL
#define OPTLVL (0)
#endif

#ifndef PUBLVL
#define PUBLVL (0)
#endif

#if DBGLVL
#define REL  if(0)
#define DBG  if(1)
#define DBG0 if(DBGLVL >= 0)
#define DBG1 if(DBGLVL >= 1)
#define DBG2 if(DBGLVL >= 2)
#define DBG3 if(DBGLVL >= 3)
#define DBG4 if(DBGLVL >= 4)
#else
#define REL  if(1)
#define DBG  if(0)
#define DBG0 if(0)
#define DBG1 if(0)
#define DBG2 if(0)
#define DBG3 if(0)
#define DBG4 if(0)
#endif

#if OPTLVL
#define OPT  if(1)
#define OPT0 if(OPTLVL == 0)
#define OPT1 if(OPTLVL >= 1)
#define OPT2 if(OPTLVL >= 2)
#define OPT3 if(OPTLVL >= 3)
#define OPT4 if(OPTLVL >= 4)
#else
#define OPT  if(0)
#define OPT0 if(1)
#define OPT1 if(0)
#define OPT2 if(0)
#define OPT3 if(0)
#define OPT4 if(0)
#endif

#if PUBLVL
#define DEV  if(0)
#define PUB  if(1)
#define PUB0 if(PUBLVL >= 0)
#define PUB1 if(PUBLVL >= 1)
#define PUB2 if(PUBLVL >= 2)
#define PUB3 if(PUBLVL >= 3)
#define PUB4 if(PUBLVL >= 4)
#else
#define DEV  if(1)
#define PUB  if(0)
#define PUB0 if(0)
#define PUB1 if(0)
#define PUB2 if(0)
#define PUB3 if(0)
#define PUB4 if(0)
#endif

// aliases
#define DEBUGSYM DEV DBG OPT0
#define DEBUGOPT DEV DBG OPT2
#define DEVELSYM DEV REL OPT0
#define DEVELOPT DEV REL OPT2
#define SHIPPING PUB REL OPT3

/*
#include <stdio.h>
#include <string.h>
int main() {
    DBG      puts("shown in debug builds");
    REL      puts("shown in release builds");
    DEV      puts("shown in internal development builds");
    DEV OPT0 puts("shown in internal development builds, with no optimization level");
    PUB OPT3 puts("shown in public builds with optimization level >= 3");
    SHIPPING puts("shown in final builds");

    char collected_flags[128] = {0};
    char *buf = collected_flags;

    DBG  strcat(buf, "DEBUG,");
    REL  strcat(buf, "RELEASE,");

    DBG0 strcat(buf, "DEBUG >= 0,");
    DBG1 strcat(buf, "DEBUG >= 1,");
    DBG2 strcat(buf, "DEBUG >= 2,");
    DBG3 strcat(buf, "DEBUG >= 3,");
    DBG4 strcat(buf, "DEBUG >= 4,");

    OPT0 strcat(buf, "OPTIM == 0,");
    OPT1 strcat(buf, "OPTIM == 1,");
    OPT2 strcat(buf, "OPTIM == 2,");
    OPT3 strcat(buf, "OPTIM == 3,");
    OPT4 strcat(buf, "OPTIM == 4,");

    OPT0 DBG strcat(buf, "DEVELDBG (OPT0 && DBG && DEV),");
    OPT2 DBG strcat(buf, "DEVELOPT (OPT2 && DBG && DEV),");
    OPT2 REL strcat(buf, "OPTIMSYM (OPT2 && REL && DEV),");
    SHIPPING strcat(buf, "SHIPPING (OPT3 && REL && PUB),");

    puts( collected_flags );
}
*/


================================================
FILE: tinydefer.cc
================================================
// tinydefer, Go style
// - rlyeh, public domain.

#include <functional>

struct defer {
    std::function<void()> fn;
    ~defer() { fn(); }
};

#define DEFER_MERGE_(a,b)  a##b
#define DEFER_LABEL_(a)    DEFER_MERGE_(unique_name_, a)
#define DEFER_UNIQUE_NAME  DEFER_LABEL_(__LINE__)
#define defer        defer DEFER_UNIQUE_NAME; DEFER_UNIQUE_NAME.fn = [&]

/*
#include <stdio.h>
int main() {
    puts("1");

    defer {
        puts("2");
        puts("3");
    };

    defer {
        puts("4");
        puts("5");
    };

    puts("6");
}
*/


================================================
FILE: tinydir.cc
================================================
// tiny directory listing
// - rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <string>

#ifdef _WIN32
#include <winsock2.h>
#else
#include <dirent.h>
#endif

template<typename FN>
bool tinydir( const char *directory, const FN &yield ) {
    std::string src( directory );
    while( !src.empty() && (src.back() == '/' || src.back() == '\\') ) src.pop_back();
#ifdef _WIN32
    WIN32_FIND_DATA fdata;
    for( HANDLE h = FindFirstFileA( (src + "/*").c_str(), &fdata ); h != INVALID_HANDLE_VALUE; ) {
        for( bool next = true; next; next = FindNextFileA( h, &fdata ) != 0 ) {
            if( fdata.cFileName[0] != '.' ) {
                yield( (src + "/" + fdata.cFileName).c_str(), (fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) > 0 );
            }
        }
        return FindClose( h ), true;
    }
#else
    for( DIR *dir = opendir( (src + "/").c_str() ); dir; ) {
        for( struct dirent *ep; ep = readdir( dir ); ) {
            if( ep->d_name[0] != '.' ) {
                DIR *tmp = opendir( ep->d_name );
                yield( (src + "/" + ep->d_name).c_str(), tmp ? (closedir( tmp ), 1) : 0 );
            }
        }
        return closedir( dir ), true;
    }
#endif
    return false;
}

/*
#include <stdio.h>
#include <functional>
int main() {
    std::function<void(const char *,bool)> callback = [&]( const char *name, bool is_dir ) {
        printf( "%5s %s\n", is_dir ? "<dir>" : "", name );
        //if( is_dir ) tinydir( name, callback ); // <-- uncomment for recursive listing
    };
    return tinydir( "./", callback );
}
*/


================================================
FILE: tinydixy.c
================================================
// tinydixy, small hierarchical config file format (subset of YAML, spec in https://github.com/kuyawa/Dixy)
// - rlyeh, public domain

// api, returns number of pairs found

int tinydixy( const char *buffer, int (*yield)(const char *key, const char *val) );

// implementation

#include <stdio.h>
#include <stdlib.h>

int tinydixy( const char *s, int (*yield)(const char *key, const char *val) ) {
    char *map = 0;
    int mapcap = 0, maplen = 0, num_pairs_found = 0;
    enum { DEL, REM, KEY, SUB, VAL } fsm = DEL;
    const char *cut[5] = {0}, *end[5] = {0};
    while( *s ) {
        while( *s && (*s == '\r' || *s == '\n') ) ++s;
        /**/ if( *s == '#' ) cut[fsm = REM] = ++s;
        else if( *s == ' ' || *s == '\t' ) cut[fsm = SUB] = ++s;
        else if( *s == ':' ) cut[fsm = VAL] = ++s;
        else if( *s > ' ' && *s <= 'z' ) cut[fsm = KEY] = cut[SUB] = end[SUB] = s, free(map), map = 0, mapcap = 0, maplen = 0;
        else { ++s; continue; }
        /**/ if( fsm == REM ) { while(*s && *s != '\r'&& *s != '\n') ++s; }
        else if( fsm == KEY ) { while(*s && *s >  ' ' && *s <= 'z' && *s != ':') ++s; end[fsm] = s; }
        else if( fsm == SUB ) { while(*s && *s >  ' ' && *s <= 'z' && *s != ':') ++s; end[fsm] = s; }
        else if( fsm == VAL ) { while(*s && *s >= ' ' && *s <= 'z' && *s != '\r' && *s != '\n') ++s; end[fsm] = s;
            while( end[fsm][-1] == ' ' ) --end[fsm];
            char buf[256] = {0}, *key = buf, *val = "";
            if( end[KEY] - cut[KEY] ) key += sprintf(key,  "%.*s", end[KEY] - cut[KEY], cut[KEY] );
            if( end[SUB] - cut[SUB] ) key += sprintf(key, ".%.*s", end[SUB] - cut[SUB], cut[SUB] );
            int reqlen = (key - buf) + 1 + (end[VAL] - cut[VAL]) + 1 + 1;
            if( (reqlen + maplen) >= mapcap ) map = realloc( map, mapcap += reqlen + 512 );
            sprintf( map + maplen, "%.*s%c%.*s%c%c", key - buf, buf, 0, end[VAL] - cut[VAL], cut[VAL], 0, 0 );
            val = map + maplen + (key - buf) + 2, key = map + maplen;
            if( val[0] ) { yield( key, val ); num_pairs_found++; }
            maplen += reqlen - 1;
        }
    }
    free( map );
    return num_pairs_found;
}

// sample
/*
int puts2( const char *key, const char *val ) {
    printf("%s:'%s'\n", key, val);
    return 0;
}

int main() {
    const char *sample = 
    "# Dixy 1.0\n"
    "\n"
    "name: Taylor Swift\n"
    "age: 27\n"
    "phones:\n"
    "    0: 555-SWIFT\n"
    "    1: 900-SWIFT\n"
    "    2: 800-TAYLOR\n"
    "body:\n"
    "    height: 6 ft\n"
    "    weight: 120 lbs\n"
    "pets:\n"
    "    0:\n"
    "        name: Fido\n"
    "        breed: chihuahua\n"
    "    1:\n"
    "        name: Tinkerbell\n"
    "        breed: bulldog\n";

    printf("%d keys found\n", tinydixy( sample, puts2 ));
}
*/


================================================
FILE: tinydual.sh.bat
================================================
#/bin/bash 2>nul || goto :windows

# bash
echo hello Bash
ls
exit

:windows
@echo off
echo hello Windows
ver
exit /b


================================================
FILE: tinyendian.c
================================================
// Tiny endianness. rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <stdint.h>

#define IS_BIG_ENDIAN (*(uint16_t *)"\0\1" == 1)
static uint16_t swap16( uint16_t x ) { return (x << 8) | (x >> 8); }
static uint32_t swap32( uint32_t x ) { return (x << 24) | (x >> 24) | ((x & 0xff00) << 8) | ((x >> 8) & 0xff00); }
static uint64_t swap64( uint64_t x ) { return (x << 56) | (x >> 56) | ((x & 0xff00) << 40) | ((x >> 40) & 0xff00) | ((x & 0xff0000) << 24) | ((x >> 24) & 0xff0000) | ((x & 0xff000000) << 8) | ((x >> 8) & 0xff000000); }
static uint16_t tobe16( uint16_t x ) { return IS_BIG_ENDIAN ? x : swap16(x); }
static uint32_t tobe32( uint32_t x ) { return IS_BIG_ENDIAN ? x : swap32(x); }
static uint64_t tobe64( uint64_t x ) { return IS_BIG_ENDIAN ? x : swap64(x); }
static uint16_t tole16( uint16_t x ) { return IS_BIG_ENDIAN ? swap16(x) : x; }
static uint32_t tole32( uint32_t x ) { return IS_BIG_ENDIAN ? swap32(x) : x; }
static uint64_t tole64( uint64_t x ) { return IS_BIG_ENDIAN ? swap64(x) : x; }

/*
#include <stdio.h>
int main() {
    printf("%x\n", swap32(0x12345678) );
}
*/


================================================
FILE: tinyerror.c
================================================
// simple error handling api. non-intrusive version.
// - rlyeh, public domain.
// 
// Errors automatically printed in debug builds.
// Usage: use return OK(retvalue) or return ERROR(retvalue, "error"...); as desired.
// Usage: to check for errors: if(ERROR) { /* do something here */ }
// Good habit: system errorcode first, then human explanation when reporting errors. Ie, ERROR(rc, "404 File not found %s\n", file);

#pragma once
#include <stdio.h>

#  if !defined ERROR_LOG && defined NDEBUG
#define ERROR_LOG(...)       (void)0
#elif !defined ERROR_LOG
#define ERROR_LOG(...)       (fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"))
#endif

#define OK(retval)         (ERROR = (char*)0, (retval))
#define ERROR(retval, ...) (ERROR_LOG("" __VA_ARGS__), ERROR = (char*)"Error: " #__VA_ARGS__ " (@" __FUNCTION__ " " __FILE__ ":" ERR0R(__LINE__) ") ", (retval))
#define ERR0R(rc)           ERRoR(rc)
#define ERRoR(rc)           #rc

#  ifdef __GNUC__
#define __FUNCTION__ ""
static __thread char* ERROR = 0;
#else // _MSC_VER
static __declspec(thread) char* ERROR = 0;
#endif

#if 0 // demo
int derefence(int *ptr) {
    if(ptr) return OK(*ptr);
    return ERROR(0, "404: Cannot deference pointer [%p]", ptr); // errorcode + variable message (ideal)
    return ERROR(0, "Cannot deference pointer [%p]", ptr);      // dynamic message (no errorcode)
    return ERROR(0, "Cannot deference pointer");                // fixed message (no errorcode)
    return ERROR(0);                                            // (no message) (no errorcode)
}
int main(int arg, char **argv) {
    int a = derefence(&arg); // pass
    int b = derefence(NULL); // fail
    if( ERROR ) { /* do something here */ }
}
#endif


================================================
FILE: tinyfsm.c
================================================
// Tiny FSM. rlyeh, public domain | wtrmrkrlyeh

#pragma once
#define with(st)        for(int i=1;i--;st[1]=st[0]) switch(((st[0])<<16)|(st[1]))
#define when(a)         break; case (((a)<<16)|(a))
#define transition(a,b) break; case (((b)<<16)|(a))
typedef int fsm[2];


/*
#include <stdio.h>

enum {
    IDLE,
    WALKING,
    RUNNING,
};

void update( fsm state ) {
    with(state) {
        when(IDLE):                  puts("idle");
        transition(IDLE,WALKING):    puts("idle --> walking");
        transition(IDLE,RUNNING):    puts("idle --> running");

        when(WALKING):               puts("walking");
        transition(WALKING,IDLE):    puts("walking --> idle");
        transition(WALKING,RUNNING): puts("walking --> running");

        when(RUNNING):               puts("running");
        transition(RUNNING,IDLE):    puts("running --> idle");
        transition(RUNNING,WALKING): puts("running --> walking");
    }
}

int main() {
    fsm state = {0};

    *state = IDLE;
    update(state);

    *state = WALKING;
    update(state);

    *state = WALKING;
    update(state);

    *state = RUNNING;
    update(state);

    *state = IDLE;
    update(state);
}
*/


================================================
FILE: tinygc.cc
================================================
// tiny garbage collector (<100 LOCs). Genius code tricks by @orangeduck (see: https://github.com/orangeduck/tgc README)
// - rlyeh, public domain.

void  gc_init(void *argc, int initial_mbytes_reserved); // pointer to argc (from main), and initial MiB reserved
void  gc_run(void);                                     // mark & sweep
void  gc_stop(void);                                    // sweep

void* gc_malloc(int sz);                                // allocator
char* gc_strdup(const char *str);                       // util

// macro that forbids pointer arithmetic (enables fixed pointer addresses)
#define GC(type) type const 

// ---

#include <setjmp.h> // setjmp, jmp_buf
#include <stdlib.h> // realloc
#include <string.h> // memcpy, strlen
#include <stdio.h>  // printf
#include <stdint.h> // uintptr_t, UINTPTR_MAX
#include <set>      // std::set<>
#include <vector>   // std::vector<>

#ifndef GC_REALLOC
#define GC_REALLOC realloc
#endif

static std::set<void*> gc_inuse;
static std::vector<void*> gc_spawned;
static void *gc_top = 0, *gc_min = 0, *gc_max = (void*)UINTPTR_MAX;

static void gc_mark_stack(void) {
    void *bot = gc_top, *top = &bot, *last = 0;

    for( void *p = bot<top?bot:top, *e = bot<top?top:bot; p < e; p = (char*)p + sizeof(void*) ) {
        void *ptr = *((void**)p);

        if( ptr == last  ) continue; // already checked
        if( ptr < gc_min ) continue; // out of gc_spawned bounds. also, nullptr check included here
        if( ptr > gc_max ) continue; // out of gc_spawned bounds.
        if( (uintptr_t)ptr & 0x7 ) continue; // 64-bit unaligned (not a pointer).

        gc_inuse.insert(last = ptr);
    }
}
static void gc_mark() { // mark reachable stack pointers
    jmp_buf env = {0};
    void (*volatile check)(void) = gc_mark_stack;
    setjmp(env);
    check();
}
static void gc_sweep() { // sweep unreachable stack pointers
    gc_min = (void*)UINTPTR_MAX, gc_max = 0;

    size_t back = gc_spawned.size();
    for( size_t i = 0; i < back; ++i) {
        void *ptr = gc_spawned[i];

        if( ptr > gc_max ) gc_max = ptr;
        if( ptr < gc_min ) gc_min = ptr;

        bool used = gc_inuse.find(ptr) != gc_inuse.end();
        if( !used ) {
            GC_REALLOC(gc_spawned[i], 0); //free

            void *swap = gc_spawned[--back]; // vector erase
            gc_spawned[back] = gc_spawned[i];
            gc_spawned[i--] = swap;
        }
    }

    size_t collected = gc_spawned.size() - back;
    if( collected ) printf("gc: %9d objects collected\n", (int)collected);

    gc_spawned.resize( back );
    gc_inuse.clear();
}

void gc_init(void *argc, int MiB) {
    gc_top = argc;
    gc_spawned.reserve((MiB > 0) * MiB * 1024 * 1024 / sizeof(void*));
}
void gc_run() {
    gc_mark();
    gc_sweep();
}
void gc_stop() {
    gc_sweep();
}

void *gc_malloc( int sz ) {
    void *ptr = GC_REALLOC(0, sz); // malloc
    if( ptr ) gc_spawned.push_back(ptr);
    return ptr;
}
char *gc_strdup( const char *s ) {
    int bytes = (int)strlen(s)+1;
    return (char *)memcpy(gc_malloc(bytes), s, bytes);
}

/*
#include <time.h>
#define benchmark(t,...) for(clock_t beg=clock(), end=beg-beg; !end; printf("" __VA_ARGS__), printf(" %5.2fs\n", t=((end=clock()-beg) / (double)CLOCKS_PER_SEC)))

void bench() {
    enum { FRAMES = 30, COUNT = 1000000 };

    double baseline;
    benchmark(baseline, "%2.1fM allocs+frees (baseline; regular malloc)", FRAMES * COUNT * 2 / 1000000.0) {
        for( int frame = 0; frame < FRAMES; ++frame ) {
            for( int n = 0; n < COUNT; ++n ) {
                free( malloc(16) );
            }
        }
    }

    double gctime;
    benchmark(gctime, "%2.1fM allocs+frees (gc)", FRAMES * COUNT * 2 / 1000000.0) {
        for( int frame = 0; frame < FRAMES; ++frame ) {
            for( int n = 0; n < COUNT; ++n ) {
                (void)gc_malloc(16);
            }
        }
        gc_run();
    }

         if(baseline<=gctime) printf("gc is x%.2f times slower\n", gctime/baseline);
    else if(baseline >gctime) printf("gc is x%.2f times faster!\n", baseline/gctime);
}

void demo() {
    GC(void*) memory = gc_malloc(1024); (void)memory;     // will be collected
    GC(char*) string = gc_strdup("hello world");          // will be collected
    GC(char*) x = gc_strdup("Hi"); x[0] |= 32;            // will be collected. note: indexing is ok; pointer arithmetic is forbidden.
    gc_run();

    puts(string);
    gc_run();
}

int main(int argc, char **argv) {
    gc_init(&argc, 256); (void)argv;

    demo();
    bench();

    gc_stop();
}
*/


================================================
FILE: tinyhexbase.c
================================================
// hexBASE 
// Very simple binary to ascii encoding. 0 to 2+100% bytes overhead (worst case)
//
// Specification:
// if char in [32..126] range then print "%c", char ('~' escaped as "~~"),
// else print "~%02x[...]~", for all remaining bytes.
// 
// - rlyeh, public domain.

#pragma once
#include <stdio.h>

static inline
void hexbasenl( FILE *fp, const void *ptr, int len ) {
    const unsigned char *buf = (const unsigned char*)ptr;
    for( ; len-- > 0; buf++ ) {
        unsigned char chr = (unsigned char)*buf;
        /**/ if( chr >= 32 && chr < 126 ) fprintf(fp, "%c", chr);
        else if( chr == 126 )             fprintf(fp, "%s", "~~"); 
        else {
            fprintf(fp, "%c", '~');
            do fprintf(fp, "%02x", *buf++); while( len-- > 0 );
            fprintf(fp, "%c", '~');
        }
    }
}

static inline
void hexbase( FILE *fp, const void *ptr, int len ) {
    hexbasenl(fp, ptr, len);
    fprintf(fp, "%s\n", "");
}

/*
#include <string.h>
int main() {
    hexbase( stdout, "hello world", strlen("hello world") );                   // --> hello world
    hexbase( stdout, "hello world \x1\x2\x3\xff", strlen("hello world") + 5 ); // --> hello world ~010203ff~
    hexbase( stdout, "hello~world", strlen("hello~world") );                   // --> hello~~world
    hexbase( stdout, "\xa1\2\3", 3 );                                          // --> ~a10203~
    hexbase( stdout, "\1\2\3hello world", 3 + strlen("hello world") );         // --> ~01020368656c6c6f20776f726c64~
    hexbase( stdout, "\1\2\3hello world\xf0", 4 + strlen("hello world") );     // --> ~01020368656c6c6f20776f726c64f0~
}
*/


================================================
FILE: tinyhexdump.c
================================================
// Tiny hexdump viewer. rlyeh, public domain | wtrmrkrlyeh
#include <stdio.h>

void hexdump( FILE *fp, const void *ptr, unsigned len, int width ) {
    unsigned char *data = (unsigned char*)ptr;
    for( unsigned jt = 0; jt < len; jt += width ) {
        fprintf( fp, "; %05d ", jt );
        for( unsigned it = jt, next = it + width; it < len && it < next; ++it ) {
            fprintf( fp, "%02x %s", (unsigned char)data[it], &" \n\0...\n"[ (1+it) < len ? 2 * !!((1+it) % width) : 3 ] );
        }
        fprintf( fp, "; %05d ", jt );
        for( unsigned it = jt, next = it + width; it < len && it < next; ++it ) {
            fprintf( fp, " %c %s", (signed char)data[it] >= 32 ? (signed char)data[it] : (signed char)'.', &" \n\0...\n"[ (1+it) < len ? 2 * !!((1+it) % width) : 3 ] );
        }
    }
}

/*
#include <string.h>
int main() {
    const char *sample = __FILE__ "/" __TIME__ "/" __DATE__;
    hexdump( stdout, sample, strlen(sample), 16 );
}
*/


================================================
FILE: tinyhuman.hpp
================================================
// tiny de/humanized numbers. based on freebsd implementation.
// - rlyeh, public domain | wtrmrkrlyeh

#pragma once
#include <string>
#include <stdint.h>

inline std::string humanize( uint64_t num, const char *suffix = " " ) {
    const char prefixes[] = " KMGTPE";
    const char* prefixp = prefixes;
    uint64_t i = num, d = 0;
    while( (i > 1024) && *prefixp++ ) {
        d = (i % 1024) / 10, i /= 1024;
    }
    if (d > 0) return std::to_string(i) + '.' + std::to_string(d) + suffix + *prefixp;
    else       return std::to_string(i) + suffix + *prefixp;
}

inline uint64_t dehumanize( const std::string &str ) {
    size_t sz = 1, mul = 0;
    double num = std::stof(str, &sz);
    while( str[sz] && str[sz] == ' ' ) sz++;
    switch( str[sz] ) {
        default: case 'B': case 'b': mul = 0;
        break;   case 'K': case 'k': mul = 1;
        break;   case 'M': case 'm': mul = 2;
        break;   case 'G': case 'g': mul = 3;
        break;   case 'T': case 't': mul = 4;
        break;   case 'P': case 'p': mul = 5;
        break;   case 'E': case 'e': mul = 6; // may overflow
    }
    while( mul-- ) if( num * 1024 < num ) return 0; else num *= 1024;
    return num;
}

/*
#include <iostream>
int main() {
    std::cout << __LINE__ << " " << humanize(1238) << "m" << std::endl;
    std::cout << __LINE__ << " " << humanize(123823) << "l" << std::endl;
    std::cout << __LINE__ << " " << humanize(123828328) << "bytes" << std::endl;
    std::cout << "---" << std::endl;

    std::cout << __LINE__ << " " << dehumanize("118 km") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118.9M") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118M") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118b") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118k") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118mb") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118gb") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118tb") << std::endl;
    std::cout << __LINE__ << " " << dehumanize("118pb") << std::endl;
}
*/


================================================
FILE: tinyini.c
================================================
// ini+, extended ini format 
// - rlyeh, public domain
//
// # spec
//
//   ; line comment
//   [details]          ; map section name (optional)
//   user=john          ; key and value (mapped here as details.user=john)
//   +surname=doe jr.   ; sub-key and value (mapped here as details.user.surname=doe jr.)
//   color=240          ; key and value \
//   color=253          ; key and value |> array: color[0], color[1] and color[2]
//   color=255          ; key and value /
//   color=             ; remove key/value(s)
//   color=white        ; recreate key; color[1] and color[2] no longer exist
//   []                 ; unmap section
//   -note=keys may start with symbols (except plus and semicolon)
//   -note=linefeeds are either \r, \n or \r\n.
//   -note=utf8 everywhere.
//

#pragma once

// api

char *ini( const char *text );

// api, alternate callback version

void ini_cb( const char *text, void (*yield)( const char *key, const char *value, void *userdata ), void *userdata );

// impl

#include <stdio.h>
#include <stdlib.h>

static char *ini( const char *s ) {
    char *map = 0;
    int mapcap = 0, maplen = 0;
    enum { DEL, REM, TAG, KEY, SUB, VAL } fsm = DEL;
    const char *cut[6] = {0}, *end[6] = {0};
    while( *s ) {
        while( *s && (*s == ' ' || *s == '\t' || *s == '\r' || *s == '\n') ) ++s;
        /**/ if( *s == ';' ) cut[fsm = REM] = ++s;
        else if( *s == '[' ) cut[fsm = TAG] = ++s;
        else if( *s == '+' ) cut[fsm = SUB] = ++s;
        else if( *s == '=' ) cut[fsm = VAL] = ++s;
        else if( *s > ' ' && *s <= 'z' && *s != ']' ) cut[fsm = KEY] = cut[SUB] = end[SUB] = s;
        else { ++s; continue; }
        /**/ if( fsm == REM ) { while(*s && *s != '\r'&& *s != '\n') ++s; }
        else if( fsm == TAG ) { while(*s && *s != '\r'&& *s != '\n'&& *s != ']') ++s; end[fsm] = s; }
        else if( fsm == KEY ) { while(*s && *s >  ' ' && *s <= 'z' && *s != '=') ++s; end[fsm] = s; }
        else if( fsm == SUB ) { while(*s && *s >  ' ' && *s <= 'z' && *s != '=') ++s; end[fsm] = s; }
        else if( fsm == VAL ) { while(*s && *s >= ' ' && *s <= 'z' && *s != ';') ++s; end[fsm] = s;
            while( end[fsm][-1] == ' ' ) --end[fsm];
            char buf[256] = {0}, *key = buf;
            if( end[TAG] - cut[TAG] ) key += sprintf(key, "%.*s.", (int)(end[TAG] - cut[TAG]), cut[TAG] );
            if( end[KEY] - cut[KEY] ) key += sprintf(key,  "%.*s", (int)(end[KEY] - cut[KEY]), cut[KEY] );
            if( end[SUB] - cut[SUB] ) key += sprintf(key, ".%.*s", (int)(end[SUB] - cut[SUB]), cut[SUB] );
            int reqlen = (key - buf) + 1 + (end[VAL] - cut[VAL]) + 1 + 1;
            if( (reqlen + maplen) >= mapcap ) map = realloc( map, mapcap += reqlen + 512 );
            sprintf( map + maplen, "%.*s%c%.*s%c%c", (int)(key - buf), buf, 0, (int)(end[VAL] - cut[VAL]), cut[VAL], 0, 0 );
            maplen += reqlen - 1;
        }
    }
    return map;
}

static void ini_cb( const char *text, void (*yield)( const char *key, const char *value, void *userdata ), void *userdata ) {
    char *kv = ini( text );
    if( kv ) {
        for( char *iter = kv; iter[0]; ) {
            const char *key = iter; while( *iter++ );
            const char *val = iter; while( *iter++ );
            yield( key, val, userdata );
        }
        free( kv );
    }
}


/*
int main() {

    char *kv = ini(
        "; line comment\n"
        "[details]          ; map section name (optional)\n"
        "user=john          ; key and value (mapped here as details.user=john)\n"
        "+surname=doe jr.   ; sub-key and value (mapped here as details.user.surname=doe jr.)\n"
        "color=240          ; key and value \\\n"
        "color=253          ; key and value |> array: color[0], color[1] and color[2]\n"
        "color=255          ; key and value /\n"
        "color=             ; remove key/value(s)\n"
        "color=white        ; recreate key; color[1] and color[2] no longer exist\n"
        "[]                 ; unmap section\n"
        "-note=keys may start with symbols (except plus and semicolon)\n"
        "-note=linefeeds are either \\r, \\n or \\r\\n.\n"
        "-note=utf8 everywhere.\n"
    );

    if( kv ) {
        for( char *iter = kv; iter[0]; ) {
            printf("key: '%s', ", iter); while( *iter++ );
            printf("val: '%s'\n", iter); while( *iter++ );
        }
        free( kv );
    }
}
*/


================================================
FILE: tinyjson5.c
================================================
// JSON5 + SJSON parser module
//
// License:
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
// No warranty is implied, use at your own risk.
//
// Credits:
// Dominik Madarasz (original code) (GitHub: zaklaus)
// r-lyeh (fork)

#ifndef JSON5_H
#define JSON5_H

#ifndef JSON5_ASSERT
#define JSON5_ASSERT do { printf("JSON5: Error L%d while parsing '%c' in '%.16s'\n", __LINE__, p[0], p); assert(0); } while(0)
#endif

#ifndef JSON5_REALLOC
#define JSON5_REALLOC realloc
#endif

#include <stdint.h>
#include <stdio.h>

typedef enum json5_type {
    json5_undefined,
    json5_null,
    json5_bool,
    json5_object,
    json5_string,
    json5_array,
    json5_integer,
    json5_real,
} json5_type;

typedef struct json5 {
    char*      name;
    unsigned   type : 3;
    unsigned   count : 29;
    union {
        struct json5* array;
        struct json5* nodes;
        int64_t   integer;
        double    real;
        char*     string;
        int       boolean;
    };
} json5;

char* json5_parse(json5 *root, char *source, int flags);
void  json5_write(FILE *fp, const json5 *root);
void  json5_free(json5 *root);

#endif // JSON5_H


#ifdef JSON5_C
#pragma once
#include <assert.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

// vector library -------------------------------------------------------------
size_t vsize( void *p ) {
    return p ? 0[ (size_t*)p - 2 ] : 0;
}
void *vresize( void *p, size_t sz ) {
    size_t *ret = (size_t*)p - 2;
    if( !p ) {
        ret = (size_t*)JSON5_REALLOC( 0, sizeof(size_t) * 2 + sz );
        ret[0] = sz;
        ret[1] = 0;
    } else {
        size_t osz = ret[0];
        size_t ocp = ret[1];
        if( sz <= (osz + ocp) ) {
            ret[0] = sz;
            ret[1] = ocp - (sz - osz);
        } else {
            ret = (size_t*)JSON5_REALLOC( ret, sizeof(size_t) * 2 + sz * 1.75 );
            ret[0] = sz;
            ret[1] = (size_t)(sz * 1.75) - sz;
        }
    }
    return &ret[2];
}
void *vrealloc( void *p, size_t sz ) {
    if( sz ) {
        return vresize( p, sz );
    } else {
        if( p ) {
            size_t *ret = (size_t*)p - 2;
            ret[0] = 0;
            ret[1] = 0;
            JSON5_REALLOC( ret, 0 );
        }
        return 0;
    }
}

// array library --------------------------------------------------------------
#ifndef array_cast
#ifdef __cplusplus
#define array_cast(x) (decltype(x))
#else
#define array_cast(x) (void *)
#endif
#define array_push(t, ...) ( (t) = array_cast(t) vrealloc((t), (array_count(t) + 1) * sizeof(0[t]) ), (t)[ array_count(t) - 1 ] = (__VA_ARGS__) )
#define array_count(t) (int)( (t) ? vsize(t) / sizeof(0[t]) : 0u )
#define array_free(t) ( array_cast(t) vrealloc((t), 0), (t) = 0 )
#endif

// json5 ----------------------------------------------------------------------
char *json5__trim(char *p) {
    while (*p) {
        /**/ if( isspace(*p) ) ++p;
        else if( p[0] == '/' && p[1] == '*' ) { // skip C comment
            for( p += 2; *p && !(p[0] == '*' && p[1] == '/'); ++p) {}
            if( *p ) p += 2;
        }
        else if( p[0] == '/' && p[1] == '/' ) { // skip C++ comment
            for( p += 2; *p && p[0] != '\n'; ++p) {}
            if( *p ) ++p;
        }
        else break;
    }
    return p;
}

char *json5__parse_value(json5 *obj, char *p, char **err_code);

char *json5__parse_string(json5 *obj, char *p, char **err_code) {
    assert(obj && p);

    if( *p == '"' || *p == '\'' || *p == '`' ) {
        obj->type = json5_string;
        obj->string = p + 1;

        char eos_char = *p, *b = obj->string, *e = b;
        while (*e) {
            /**/ if( *e == '\\' && (e[1] == eos_char) ) ++e;
            else if( *e == '\\' && (e[1] == '\r' || e[1] == '\n') ) *e = ' ';
            else if( *e == eos_char ) break;
            ++e;
        }

        *e = '\0';
        return p = e + 1;
    }

    //JSON5_ASSERT; *err_code = "json5_error_invalid_value";
    return NULL;
}

char *json5__parse_object(json5 *obj, char *p, char **err_code) {
    assert(obj && p);

    if( 1 /* *p == '{' */ ) { /* <-- for SJSON */
        int skip = *p == '{'; /* <-- for SJSON */

        obj->type = json5_object;

        while (*p) {
            json5 node = { 0 };
            
            do { p = json5__trim(p + skip); skip = 1; } while( *p == ',' );

            if( *p == '}' ) {
                ++p;
                break;
            }
            // @todo: is_unicode() (s[0] == '\\' && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]))) {
            else if( isalpha(*p) || *p == '_' || *p == '$' ) { // also || is_unicode(p)
                node.name = p;

                do {
                    ++p;
                } while (*p && (*p == '_' || isalpha(*p) || isdigit(*p)) ); // also || is_unicode(p)

                char *e = p;
                p = json5__trim(p);
                *e = '\0';
            }
            else { //if( *p == '"' || *p == '\'' || *p == '`' ) {
                char *ps = json5__parse_string(&node, p, err_code);
                if( !ps ) {
                    return NULL;
                }
                p = ps;
                node.name = node.string;
                p = json5__trim(p);
            }

            // @todo: https://www.ecma-international.org/ecma-262/5.1/#sec-7.6
            if( !(node.name && node.name[0]) ) { // !json5__validate_name(node.name) ) {
                JSON5_ASSERT; *err_code = "json5_error_invalid_name";
                return NULL;
            }

            if( !p || (*p && (*p != ':' && *p != '=' /* <-- for SJSON */)) ) {
                JSON5_ASSERT; *err_code = "json5_error_invalid_name";
                return NULL;
            }
            p = json5__trim(p + 1);
            p = json5__parse_value(&node, p, err_code);

            if( *err_code[0] ) {
                return NULL;
            }

            if( node.type != json5_undefined ) {
                array_push(obj->nodes, node);
                ++obj->count;
            }

            if( *p == '}') { ++p; break; }
        }

        return p;
    }

    JSON5_ASSERT; *err_code = "json5_error_invalid_value";
    return NULL;
}

char *json5__parse_value(json5 *obj, char *p, char **err_code) {
    assert(obj && p);

    p = json5__trim(p);

    char *is_string = json5__parse_string(obj, p, err_code);

    if( is_string ) {
        p = is_string;
        if( *err_code[0] ) {
            return NULL;
        }
    }
    else if( *p == '{' ) {
        p = json5__parse_object( obj, p, err_code );
        if( *err_code[0] ) {
            return NULL;
        }
    }
    else if( *p == '[' ) {
        obj->type = json5_array;

        while (*p) {
            json5 elem = { 0 };

            do { p = json5__trim(p + 1); } while( *p == ',' );
            if( *p == ']') { ++p; break; }

            p = json5__parse_value(&elem, p, err_code);

            if( *err_code[0] ) {
                return NULL;
            }

            if( elem.type != json5_undefined ) {
                array_push(obj->array, elem);
                ++obj->count;
            }
            if (*p == ']') { ++p; break; }
        }
    }
    else if( isalpha(*p) || (*p == '-' && !isdigit(p[1])) ) {
        const char *labels[] = { "null", "on","true", "off","false", "nan","NaN", "-nan","-NaN", "inf","Infinity", "-inf","-Infinity" };
        const int lenghts[] = { 4, 2,4, 3,5, 3,3, 4,4, 3,8, 4,9 };
        for( int i = 0; labels[i]; ++i ) {
            if( !strncmp(p, labels[i], lenghts[i] ) ) {
                p += lenghts[i];
#ifdef _MSC_VER // somehow, NaN is apparently signed in MSC
                /**/ if( i >= 5 ) obj->type = json5_real, obj->real = i >= 11 ? -INFINITY : i >= 9 ? INFINITY : i >= 7 ?  NAN :-NAN;
#else
                /**/ if( i >= 5 ) obj->type = json5_real, obj->real = i >= 11 ? -INFINITY : i >= 9 ? INFINITY : i >= 7 ? -NAN : NAN;
#endif
                else if( i >= 1 ) obj->type = json5_bool, obj->boolean = i <= 2;
                else              obj->type = json5_null;
                break;
            }
        }
        if( obj->type == json5_undefined ) {
            JSON5_ASSERT; *err_code = "json5_error_invalid_value";
            return NULL;
        }
    }
    else if( isdigit(*p) || *p == '+' || *p == '-' || *p == '.' ) {
        char buffer[16] = {0}, *buf = buffer, is_hex = 0, is_dbl = 0;
        while( *p && strchr("+-.xX0123456789aAbBcCdDeEfF", *p)) {
            is_hex |= (*p | 32) == 'x';
            is_dbl |= *p == '.';
            *buf++ = *p++;
        }
        obj->type = is_dbl ? json5_real : json5_integer;
        /**/ if( is_dbl ) sscanf( buffer, "%lf", &obj->real );
        else if( is_hex ) sscanf( buffer, "%llx", &obj->integer ); // SCNx64 -> inttypes.h
        else              sscanf( buffer, "%lld", &obj->integer ); // SCNd64 -> inttypes.h
    }
    else {
        return NULL;
    }
    return p;
}

char *json5_parse(json5 *root, char *p, int flags) {
    assert(root && p);

    char *err_code = "";
    *root = (json5) {0};

    p = json5__trim(p);
    if( *p == '[' ) { /* <-- for SJSON */
        json5__parse_value(root, p, &err_code);
    } else {
        json5__parse_object(root, p, &err_code); /* <-- for SJSON */
    }

    return err_code[0] ? err_code : 0;
}

void json5_free(json5 *root) {
    if( root->type == json5_array && root->array ) {
        for( int i = 0, cnt = array_count(root->array); i < cnt; ++i ) {
            json5_free(root->array + i);
        }
        array_free(root->array);
    } 

    if( root->type == json5_object && root->nodes ) {
        for( int i = 0, cnt = array_count(root->nodes); i < cnt; ++i ) {
            json5_free(root->nodes + i);
        }
        array_free(root->nodes);
    }

    *root = (json5) {0}; // needed?
}

void json5_write(FILE *fp, const json5 *o) {
#ifdef _MSC_VER
    static __declspec(thread) int indent = 0;
#else
    static THREAD_LOCAL int indent = 0;
#endif
    static const char *tabs = 
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"
        "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
    if( o->name ) {
        fprintf(fp, "%.*s\"%s\": ", indent, tabs, o->name);
    }
    /**/ if( o->type == json5_null ) fprintf(fp, "%s", "null");
    else if( o->type == json5_bool ) fprintf(fp, "%s", o->boolean ? "true" : "false");
    else if( o->type == json5_integer ) fprintf(fp, "%lld", o->integer);
    else if( o->type == json5_real ) {
        /**/ if( isnan(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-nan" : "nan" );
        else if( isinf(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-inf" : "inf" );
        else fprintf(fp, "%.4llf", o->real);
    }
    else if( o->type == json5_string ) { // write (escaped) string
        char chars[] = "\\\"\n\r\b\f\v", remap[] = "\\\"nrbfv", esc[256];
        for( int i = 0; chars[i]; ++i ) esc[ chars[i] ] = remap[i];

        const char *b = o->string, *e = strpbrk(b, chars), *sep = "\"";
        while( e ) {
            fprintf(fp, "%s%.*s\\%c", sep, (int)(e - b), b, esc[(unsigned char)*e] );
            e = strpbrk( b = e + 1, chars);
            sep = "";
        }
        fprintf(fp, "%s%s\"", sep, b);
    }
    else if( o->type == json5_array ) {
        const char *sep = "";
        fprintf(fp, "%s", "[ ");
        for( int i = 0, cnt = o->count; i < cnt; ++i ) {
            fprintf(fp, "%s", sep); sep = ", ";
            json5_write(fp, o->array + i);
        }
        fprintf(fp, "%s", " ]");
    }
    else if( o->type == json5_object ) {
        const char *sep = "";
        fprintf(fp, "%.*s{\n", 0 * (++indent), tabs);
        for( int i = 0, cnt = o->count; i < cnt; ++i ) {
            fprintf(fp, "%s", sep); sep = ",\n";
            json5_write(fp, o->nodes + i);
        }
        fprintf(fp, "\n%.*s}", --indent, tabs);
    } else {
        char p[16] = {0};
        JSON5_ASSERT; /* "json5_error_invalid_value"; */
    }
}
#endif // JSON5_C

#ifdef JSON5_BENCH
#include <time.h>
int main() {
    // https://www.reddit.com/r/datasets/comments/1uyd0t/200000_jeopardy_questions_in_a_json_file/
    char *content = 0;
    for( FILE *fp = fopen("jeopardy.json", "rb"); fp; fclose(fp), fp = 0 ) {
        fseek(fp, 0L, SEEK_END);
        size_t pos = ftell(fp);
        fseek(fp, 0L, SEEK_SET);
        content = (char*)malloc( pos + 1 );
        fread(content, 1, pos, fp);
        content[pos] = 0;
    }

    if( content ) {
        clock_t start = clock();
        json5 root = {0};
        char *error = json5_parse(&root, content, 0);
        clock_t end = clock();
        double delta = ( end - start ) / (double)CLOCKS_PER_SEC;

        if( !error ) {
            printf("Parsing time: %.3fms\n", delta*1000);
            printf("Total nodes: %d\n", array_count(root.array));
            printf("Category: %s, air date: %s\nQuestion: %s\n", root.array[0].nodes[0].string,
                   root.array[0].nodes[1].string,
                   root.array[0].nodes[2].string);
        } else {
            printf("Error: %s\n", error);
        }

        json5_free(&root);
        free(content);
    }
}
#endif

#ifdef JSON5_DEMO
int main() {
    char source5[] = 
    "  // comments\n" /* json5 sample */
    "  unquoted: 'and you can quote me on that',\n"
    "  singleQuotes: 'I can use \"double quotes\" here',\n"
    "  lineBreaks : \"Look, Mom! \\\n"
    "No \\n's!\",\n"
    "  hexadecimal: 0x100,\n"
    "  leadingDecimalPoint: .8675309, andTrailing: 8675309.,\n"
    "  positiveSign: +1,\n"
    "  trailingComma: 'in objects', andIn: ['arrays', ],\n"
    "  \"backwardsCompatible\": \"with JSON\",\n"
    ""
    "  ip = \"127.0.0.1\"\n" /* sjson sample */
    "  port = 8888\n"
    ""
    "  /* comment //nested comment*/\n" /* tests */
    "  // comment /*nested comment*/\n"
    "  nil: null,"
    "  \"+lšctžýáíé=:\": true,,,,"
    "  huge: 2.2239333e5, "
    "  array: [+1,2,-3,4,5],    "
    "  hello: 'world /*comment in string*/ //again', "
    "  abc: 42.67, def: false, "
    "  children : { a: 1, b: 2, },"
    "  invalids : [ nan, NaN, -nan, -NaN, inf, Infinity, -inf, -Infinity ],"
    ""
    "}\n";

    json5 root = { 0 };
    char *error = json5_parse(&root, source5, 0);
    if( error ) {
        printf("Error: %s\n", error);
    } else {
        json5_write(stdout, &root);
    }
    json5_free(&root);
}
#endif


================================================
FILE: tinylog.c
================================================
// Tiny logging utilities. rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <stdio.h>
#include <time.h>

#ifdef _WIN32
#define TTY(ansi) ""
#else
#define TTY(ansi) ansi
#endif

#define TRACE(...) do { time_t t = time(0); printf("%s[TRACE %.8s]%s %s:%d ", TTY("\27[34m"), 11+ctime(&t), TTY("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define DEBUG(...) do { time_t t = time(0); printf("%s[DEBUG %.8s]%s %s:%d ", TTY("\27[36m"), 11+ctime(&t), TTY("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define INFO(...)  do { time_t t = time(0); printf("%s[INFO  %.8s]%s %s:%d ", TTY("\27[32m"), 11+ctime(&t), TTY("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define WARN(...)  do { time_t t = time(0); printf("%s[WARN  %.8s]%s %s:%d ", TTY("\27[33m"), 11+ctime(&t), TTY("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define ERROR(...) do { time_t t = time(0); printf("%s[ERROR %.8s]%s %s:%d ", TTY("\27[31m"), 11+ctime(&t), TTY("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define FATAL(...) do { time_t t = time(0); printf("%s[FATAL %.8s]%s %s:%d ", TTY("\27[35m"), 11+ctime(&t), TTY("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)

/*
int main() {
    FATAL("Hello %d\n", 123);
    ERROR("Hello %d\n", 123);
    WARN("Hello %d\n", 123);
    INFO("Hello %d\n", 123);
    DEBUG("Hello %d\n", 123);
    TRACE("Hello %d\n", 123);
}
*/


================================================
FILE: tinylog.h
================================================
// Tiny logging utilities. rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <stdio.h>
#include <time.h>

#ifdef _WIN32
#define ANSI(code) ""
#else
#define ANSI(code) code
#endif

#define TRACE(...) do { time_t t = time(0); printf("%s[TRACE %.8s]%s %s:%d ", ANSI("\27[34m"), 11+ctime(&t), ANSI("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define DEBUG(...) do { time_t t = time(0); printf("%s[DEBUG %.8s]%s %s:%d ", ANSI("\27[36m"), 11+ctime(&t), ANSI("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define INFO(...)  do { time_t t = time(0); printf("%s[INFO  %.8s]%s %s:%d ", ANSI("\27[32m"), 11+ctime(&t), ANSI("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define WARN(...)  do { time_t t = time(0); printf("%s[WARN  %.8s]%s %s:%d ", ANSI("\27[33m"), 11+ctime(&t), ANSI("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define ERROR(...) do { time_t t = time(0); printf("%s[ERROR %.8s]%s %s:%d ", ANSI("\27[31m"), 11+ctime(&t), ANSI("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)
#define FATAL(...) do { time_t t = time(0); printf("%s[FATAL %.8s]%s %s:%d ", ANSI("\27[35m"), 11+ctime(&t), ANSI("\27[0m"), __FILE__, __LINE__); printf(__VA_ARGS__); } while(0)

/*
int main() {
    FATAL("Hello %d\n", 123);
    ERROR("Hello %d\n", 123);
    WARN("Hello %d\n", 123);
    INFO("Hello %d\n", 123);
    DEBUG("Hello %d\n", 123);
    TRACE("Hello %d\n", 123);
}
*/


================================================
FILE: tinylogger.h
================================================
// simple logger. likely slow, though.
// - rlyeh, public domain.
//
// - [x] colors based on content.
// - [x] no logging categories. throughput flood configurable by percentage (see LOG_LEVEL var).
// - [x] print fatal errors always. with optional callstack (see LOG_PRINT_STACK macro).

#pragma once
#include <stdio.h>
#include <stdint.h>
#include <string.h>

#  if !defined LOG_LEVEL && (defined NDEBUG || defined SHIPPING)
#define LOG_LEVEL 0   //   0% - no messages logged (only fatal errors will)
#elif !defined LOG_LEVEL
#define LOG_LEVEL 100 // 100% - all messages logged
#endif

#ifndef LOG_TIMER
#define LOG_TIMER() 0.0 /* user-defined apptime clock here */
#endif

#ifndef LOG_PRINT_STACK
#define LOG_PRINT_STACK() /* user-defined callstack printer here */
#endif

#  if !defined LOG_ENABLE_ANSI && defined _WIN32
#include <winsock2.h>
#define LOG_ENABLE_ANSI() for(unsigned mode=0;!mode;mode=1) SetConsoleMode(GetStdHandle(-11), (GetConsoleMode(GetStdHandle(-11), &mode), mode|4))
#elif !defined LOG_ENABLE_ANSI
#define LOG_ENABLE_ANSI()
#endif

#define LOG(...) do { \
    static char must_log = -1; \
    static enum { undefined=-1, restore=0, r=31,g,y,b,p,t,w,inv=0x80 } color = undefined; \
    char buf[2048]; snprintf(buf, 2048, "" __VA_ARGS__); \
    if( color == undefined ) { \
        LOG_ENABLE_ANSI(); \
        char low[2048]; int i; for(i=0;buf[i];++i) low[i] = 32|buf[i]; low[i]='\0'; \
        /**/ if( strstr(low,"fatal")|| strstr(low,"panic") || strstr(low,"assert") ) color=r|inv,must_log=1; \
        else if( strstr(low,"fail") || strstr(low,"error") ) color=r; \
        else if( strstr(low,"warn") || strstr(low,"alert") ) color=y; /*beware,caution*/ \
        else if( strstr(low,"info") || strstr(low,"succe") ) color=g; /*ok, no error*/ \
        else if( strstr(low,"debug") ) color=t; \
        else if( strstr(low,"trace") ) color=p; else color=restore; \
        if( must_log < 0 ) { /* original splitmix64 by Sebastiano Vigna (CC0)*/ \
            uint64_t z = (__LINE__ + __COUNTER__ + UINT64_C(0x9E3779B97F4A7C15)); \
            z = (z ^ (z >> 30)) * UINT64_C(0xBF58476D1CE4E5B9); \
            must_log = (unsigned)((z ^ (z >> 31)) % 100) < LOG_LEVEL; } } \
    if( must_log ) { \
        double timer = LOG_TIMER(); \
        if(color&0x80) fprintf(stderr, "\033[7m"); \
        if(timer>0)fprintf(stderr, "\033[%dm%07.3fs %s (%s:%d)", color&0x7f, timer, buf, __FILE__, __LINE__); \
        else       fprintf(stderr, "\033[%dm%s (%s:%d)", color&0x7f, buf, __FILE__, __LINE__); \
        fprintf(stderr, "\033[%dm\n", restore); \
        if(color&0x7f == r) LOG_PRINT_STACK(); } \
} while(0)

#if 0 // demo
int main() {
    LOG("Test 1 - normal message: hello world %d", 123);
    LOG("Test 2 - trace message");
    LOG("Test 3 - debug message");
    LOG("Test 4 - info message");
    LOG("Test 5 - warning message");
    LOG("Test 6 - error message");
    LOG("Test 7 - fatal error message (fatal errors are always printed, despite LOG_LEVEL var)");
}
#endif


================================================
FILE: tinylogger.hpp
================================================
// Tiny session logger. rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <stdio.h>

#ifdef SHIPPING
struct logger {
    logger() {
        fclose(stdout);
    }
};
#else
struct logger {
    logger() {
#       if   defined(PSVITA)
        freopen("host0://log_vita.txt", "a+t", stdout);
#       elif defined(PS3)
        freopen("/app_home/log_ps3.txt", "a+t", stdout);
#       elif defined(PS4)
        freopen("/hostapp/log_ps4.txt", "a+t", stdout);
#       else
        freopen("log_desktop.txt", "a+t", stdout);
#       endif
        // Flush automatically every 16 KiB from now
        setvbuf(stdout, NULL, _IOFBF, 16 * 1024);
        // Header
        puts(";; New session");
        fflush(stdout);
    }
    ~logger() {
        fflush(stdout);
    }
};
#endif

/*
int main() {
    logger resident;
    puts("hello world");
}
*/


================================================
FILE: tinymatch.c
================================================
// tiny wildcard/pattern matching. Based on anonymous souce code (Rob Pike's ?).
// - rlyeh. public domain | wtrmrkrlyeh

static int match( const char *pattern, const char *str ) {
    if( *pattern=='\0' ) return !*str;
    if( *pattern=='*' )  return match(pattern+1, str) || (*str && match(pattern, str+1));
    if( *pattern=='?' )  return *str && (*str != '.') && match(pattern+1, str+1);
    return (*str == *pattern) && match(pattern+1, str+1);
}

/*
#include <stdio.h>
int main() {
    printf("%s\n", match("abc", "abc") ? "match!" : "not found" );
    printf("%s\n", match("abc*", "abc") ? "match!" : "not found" );
    printf("%s\n", match("*bc", "abc") ? "match!" : "not found" );
    printf("%s\n", match("*bc*", "abc") ? "match!" : "not found" );
    printf("%s\n", match("*b?d*", "abcdef") ? "match!" : "not found" );
}
*/


================================================
FILE: tinymime.c
================================================
// tinymime. ported from https://github.com/sindresorhus/file-type (source is mit licensed)
// - rlyeh, public domain

#pragma once

static const char *tinymime( const unsigned char *buf, size_t len ) {
    if( !(buf && len > 60) ) {
        return ""; // invalid
    }

    if (buf[0] == 0xFF && buf[1] == 0xD8 && buf[2] == 0xFF) {
        return "jpg";
    }

    if (buf[0] == 0x89 && buf[1] == 0x50 && buf[2] == 0x4E && buf[3] == 0x47) {
        return "png";
    }

    if (buf[0] == 0x47 && buf[1] == 0x49 && buf[2] == 0x46) {
        return "gif";
    }

    if (buf[8] == 0x57 && buf[9] == 0x45 && buf[10] == 0x42 && buf[11] == 0x50) {
        return "webp";
    }

    // needs to be before `tif` check
    if (((buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0x2A && buf[3] == 0x0) || (buf[0] == 0x4D && buf[1] == 0x4D && buf[2] == 0x0 && buf[3] == 0x2A)) && buf[8] == 0x43 && buf[9] == 0x52) {
        return "cr2";
    }

    if ((buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0x2A && buf[3] == 0x0) || (buf[0] == 0x4D && buf[1] == 0x4D && buf[2] == 0x0 && buf[3] == 0x2A)) {
        return "tif";
    }

    if (buf[0] == 0x42 && buf[1] == 0x4D) {
        return "bmp";
    }

    if (buf[0] == 0x49 && buf[1] == 0x49 && buf[2] == 0xBC) {
        return "jxr";
    }

    if (buf[0] == 0x38 && buf[1] == 0x42 && buf[2] == 0x50 && buf[3] == 0x53) {
        return "psd";
    }

    // needs to be before `zip` check
    if (buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x3 && buf[3] == 0x4 && buf[30] == 0x6D && buf[31] == 0x69 && buf[32] == 0x6D && buf[33] == 0x65 && buf[34] == 0x74 && buf[35] == 0x79 && buf[36] == 0x70 && buf[37] == 0x65 && buf[38] == 0x61 && buf[39] == 0x70 && buf[40] == 0x70 && buf[41] == 0x6C && buf[42] == 0x69 && buf[43] == 0x63 && buf[44] == 0x61 && buf[45] == 0x74 && buf[46] == 0x69 && buf[47] == 0x6F && buf[48] == 0x6E && buf[49] == 0x2F && buf[50] == 0x65 && buf[51] == 0x70 && buf[52] == 0x75 && buf[53] == 0x62 && buf[54] == 0x2B && buf[55] == 0x7A && buf[56] == 0x69 && buf[57] == 0x70) {
        return "epub";
    }

    // needs to be before `zip` check
    // assumes signed .xpi from addons.mozilla.org
    if (buf[0] == 0x50 && buf[1] == 0x4B && buf[2] == 0x3 && buf[3] == 0x4 && buf[30] == 0x4D && buf[31] == 0x45 && buf[32] == 0x54 && buf[33] == 0x41 && buf[34] == 0x2D && buf[35] == 0x49 && buf[36] == 0x4E && buf[37] == 0x46 && buf[38] == 0x2F && buf[39] == 0x6D && buf[40] == 0x6F && buf[41] == 0x7A && buf[42] == 0x69 && buf[43] == 0x6C && buf[44] == 0x6C && buf[45] == 0x61 && buf[46] == 0x2E && buf[47] == 0x72 && buf[48] == 0x73 && buf[49] == 0x61) {
        return "xpi";
    }

    if (buf[0] == 0x50 && buf[1] == 0x4B && (buf[2] == 0x3 || buf[2] == 0x5 || buf[2] == 0x7) && (buf[3] == 0x4 || buf[3] == 0x6 || buf[3] == 0x8)) {
        return "zip";
    }

    if( len > 261 ) 
    if (buf[257] == 0x75 && buf[258] == 0x73 && buf[259] == 0x74 && buf[260] == 0x61 && buf[261] == 0x72) {
        return "tar";
    }

    if (buf[0] == 0x52 && buf[1] == 0x61 && buf[2] == 0x72 && buf[3] == 0x21 && buf[4] == 0x1A && buf[5] == 0x7 && (buf[6] == 0x0 || buf[6] == 0x1)) {
        return "rar";
    }

    if (buf[0] == 0x1F && buf[1] == 0x8B && buf[2] == 0x8) {
        return "gz";
    }

    if (buf[0] == 0x42 && buf[1] == 0x5A && buf[2] == 0x68) {
        return "bz2";
    }

    if (buf[0] == 0x37 && buf[1] == 0x7A && buf[2] == 0xBC && buf[3] == 0xAF && buf[4] == 0x27 && buf[5] == 0x1C) {
        return "7z";
    }

    if (buf[0] == 0x78 && buf[1] == 0x01) {
        return "dmg";
    }

    if (
        (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && (buf[3] == 0x18 || buf[3] == 0x20) && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70) ||
        (buf[0] == 0x33 && buf[1] == 0x67 && buf[2] == 0x70 && buf[3] == 0x35) ||
        (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1C && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x6D && buf[9] == 0x70 && buf[10] == 0x34 && buf[11] == 0x32 && buf[16] == 0x6D && buf[17] == 0x70 && buf[18] == 0x34 && buf[19] == 0x31 && buf[20] == 0x6D && buf[21] == 0x70 && buf[22] == 0x34 && buf[23] == 0x32 && buf[24] == 0x69 && buf[25] == 0x73 && buf[26] == 0x6F && buf[27] == 0x6D) ||
        (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1C && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x69 && buf[9] == 0x73 && buf[10] == 0x6F && buf[11] == 0x6D) ||
        (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1c && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x6D && buf[9] == 0x70 && buf[10] == 0x34 && buf[11] == 0x32 && buf[12] == 0x0 && buf[13] == 0x0 && buf[14] == 0x0 && buf[15] == 0x0)
    ) {
        return "mp4";
    }

    if ((buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x1C && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x4D && buf[9] == 0x34 && buf[10] == 0x56)) {
        return "m4v";
    }

    if (buf[0] == 0x4D && buf[1] == 0x54 && buf[2] == 0x68 && buf[3] == 0x64) {
        return "mid";
    }

    // needs to be before the `webm` check
    if (buf[31] == 0x6D && buf[32] == 0x61 && buf[33] == 0x74 && buf[34] == 0x72 && buf[35] == 0x6f && buf[36] == 0x73 && buf[37] == 0x6B && buf[38] == 0x61) {
        return "mkv";
    }

    if (buf[0] == 0x1A && buf[1] == 0x45 && buf[2] == 0xDF && buf[3] == 0xA3) {
        return "webm";
    }

    if (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x0 && buf[3] == 0x14 && buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70) {
        return "mov";
    }

    if (buf[0] == 0x52 && buf[1] == 0x49 && buf[2] == 0x46 && buf[3] == 0x46 && buf[8] == 0x41 && buf[9] == 0x56 && buf[10] == 0x49) {
        return "avi";
    }

    if (buf[0] == 0x30 && buf[1] == 0x26 && buf[2] == 0xB2 && buf[3] == 0x75 && buf[4] == 0x8E && buf[5] == 0x66 && buf[6] == 0xCF && buf[7] == 0x11 && buf[8] == 0xA6 && buf[9] == 0xD9) {
        return "wmv";
    }

    if (buf[0] == 0x0 && buf[1] == 0x0 && buf[2] == 0x1 && (buf[3] >> 4) == 0xb ) { // buf[3].toString(16)[0] === 'b') {
        return "mpg";
    }

    if ((buf[0] == 0x49 && buf[1] == 0x44 && buf[2] == 0x33) || (buf[0] == 0xFF && buf[1] == 0xfb)) {
        return "mp3";
    }

    if ((buf[4] == 0x66 && buf[5] == 0x74 && buf[6] == 0x79 && buf[7] == 0x70 && buf[8] == 0x4D && buf[9] == 0x34 && buf[10] == 0x41) || (buf[0] == 0x4D && buf[1] == 0x34 && buf[2] == 0x41 && buf[3] == 0x20)) {
        return "m4a";
    }

    // needs to be before `ogg` check
    if (buf[28] == 0x4F && buf[29] == 0x70 && buf[30] == 0x75 && buf[31] == 0x73 && buf[32] == 0x48 && buf[33] == 0x65 && buf[34] == 0x61 && buf[35] == 0x64) {
        return "opus";
    }

    if (buf[0] == 0x4F && buf[1] == 0x67 && buf[2] == 0x67 && buf[3] == 0x53) {
        return "ogg";
    }

    if (buf[0] == 0x66 && buf[1] == 0x4C && buf[2] == 0x61 && buf[3] == 0x43) {
        return "flac";
    }

    if (buf[0] == 0x52 && buf[1] == 0x49 && buf[2] == 0x46 && buf[3] == 0x46 && buf[8] == 0x57 && buf[9] == 0x41 && buf[10] == 0x56 && buf[11] == 0x45) {
        return "wav";
    }

    if (buf[0] == 0x23 && buf[1] == 0x21 && buf[2] == 0x41 && buf[3] == 0x4D && buf[4] == 0x52 && buf[5] == 0x0A) {
        return "amr";
    }

    if (buf[0] == 0x25 && buf[1] == 0x50 && buf[2] == 0x44 && buf[3] == 0x46) {
        return "pdf";
    }

    if (buf[0] == 0x4D && buf[1] == 0x5A) {
        return "exe";
    }

    if ((buf[0] == 0x43 || buf[0] == 0x46) && buf[1] == 0x57 && buf[2] == 0x53) {
        return "swf";
    }

    if (buf[0] == 0x7B && buf[1] == 0x5C && buf[2] == 0x72 && buf[3] == 0x74 && buf[4] == 0x66) {
        return "rtf";
    }

    if (
        (buf[0] == 0x77 && buf[1] == 0x4F && buf[2] == 0x46 && buf[3] == 0x46) &&
        (
            (buf[4] == 0x00 && buf[5] == 0x01 && buf[6] == 0x00 && buf[7] == 0x00) ||
            (buf[4] == 0x4F && buf[5] == 0x54 && buf[6] == 0x54 && buf[7] == 0x4F)
        )
    ) {
        return "woff";
    }

    if (
        (buf[0] == 0x77 && buf[1] == 0x4F && buf[2] == 0x46 && buf[3] == 0x32) &&
        (
            (buf[4] == 0x00 && buf[5] == 0x01 && buf[6] == 0x00 && buf[7] == 0x00) ||
            (buf[4] == 0x4F && buf[5] == 0x54 && buf[6] == 0x54 && buf[7] == 0x4F)
        )
    ) {
        return "woff2";
    }

    if (
        (buf[34] == 0x4C && buf[35] == 0x50) &&
        (
            (buf[8] == 0x00 && buf[9] == 0x00 && buf[10] == 0x01) ||
            (buf[8] == 0x01 && buf[9] == 0x00 && buf[10] == 0x02) ||
            (buf[8] == 0x02 && buf[9] == 0x00 && buf[10] == 0x02)
        )
    ) {
        return "eot";
    }

    if (buf[0] == 0x00 && buf[1] == 0x01 && buf[2] == 0x00 && buf[3] == 0x00 && buf[4] == 0x00) {
        return "ttf";
    }

    if (buf[0] == 0x4F && buf[1] == 0x54 && buf[2] == 0x54 && buf[3] == 0x4F && buf[4] == 0x00) {
        return "otf";
    }

    if (buf[0] == 0x00 && buf[1] == 0x00 && buf[2] == 0x01 && buf[3] == 0x00) {
        return "ico";
    }

    if (buf[0] == 0x46 && buf[1] == 0x4C && buf[2] == 0x56 && buf[3] == 0x01) {
        return "flv";
    }

    if (buf[0] == 0x25 && buf[1] == 0x21) {
        return "ps";
    }

    if (buf[0] == 0xFD && buf[1] == 0x37 && buf[2] == 0x7A && buf[3] == 0x58 && buf[4] == 0x5A && buf[5] == 0x00) {
        return "xz";
    }

    if (buf[0] == 0x53 && buf[1] == 0x51 && buf[2] == 0x4C && buf[3] == 0x69) {
        return "sqlite";
    }

    if (buf[0] == 0x4E && buf[1] == 0x45 && buf[2] == 0x53 && buf[3] == 0x1A) {
        return "nes";
    }

    if (buf[0] == 0x43 && buf[1] == 0x72 && buf[2] == 0x32 && buf[3] == 0x34) {
        return "crx";
    }

    if (
        (buf[0] == 0x4D && buf[1] == 0x53 && buf[2] == 0x43 && buf[3] == 0x46) ||
        (buf[0] == 0x49 && buf[1] == 0x53 && buf[2] == 0x63 && buf[3] == 0x28)
    ) {
        return "cab";
    }

    // needs to be before `ar` check
    if (buf[0] == 0x21 && buf[1] == 0x3C && buf[2] == 0x61 && buf[3] == 0x72 && buf[4] == 0x63 && buf[5] == 0x68 && buf[6] == 0x3E && buf[7] == 0x0A && buf[8] == 0x64 && buf[9] == 0x65 && buf[10] == 0x62 && buf[11] == 0x69 && buf[12] == 0x61 && buf[13] == 0x6E && buf[14] == 0x2D && buf[15] == 0x62 && buf[16] == 0x69 && buf[17] == 0x6E && buf[18] == 0x61 && buf[19] == 0x72 && buf[20] == 0x79) {
        return "deb";
    }

    if (buf[0] == 0x21 && buf[1] == 0x3C && buf[2] == 0x61 && buf[3] == 0x72 && buf[4] == 0x63 && buf[5] == 0x68 && buf[6] == 0x3E) {
        return "ar";
    }

    if (buf[0] == 0xED && buf[1] == 0xAB && buf[2] == 0xEE && buf[3] == 0xDB) {
        return "rpm";
    }

    if (
        (buf[0] == 0x1F && buf[1] == 0xA0) ||
        (buf[0] == 0x1F && buf[1] == 0x9D)
    ) {
        return "z";
    }

    if (buf[0] == 0x4C && buf[1] == 0x5A && buf[2] == 0x49 && buf[3] == 0x50) {
        return "lz";
    }

    if (buf[0] == 0xD0 && buf[1] == 0xCF && buf[2] == 0x11 && buf[3] == 0xE0 && buf[4] == 0xA1 && buf[5] == 0xB1 && buf[6] == 0x1A && buf[7] == 0xE1) {
        return "msi";
    }

    return ""; // invalid
};

/*
#include <stdio.h>
int main( int argc, const char **argv ) {
    if( argc == 2 ) {
        FILE *fp = fopen( argv[1], "rb" );
        if( fp ) {
            char buf[512];
            int len = fread(buf, 1, 512, fp);
            puts( tinymime(buf, len) );
            fclose(fp);
        }
    }
}
*/


================================================
FILE: tinypipe.hpp
================================================
// tiny chainable pipes (C++11)
// - rlyeh, public domain | wtrmrkrlyeh

#pragma once
#include <vector>
#include <sstream>

template< typename T, typename istream >
void copy( T &s, const istream &is ) {
    std::stringstream ss;
    std::streamsize at = is.rdbuf()->pubseekoff(0,is.cur);
    ss << is.rdbuf();
    is.rdbuf()->pubseekpos(at);
    auto x = ss.str();
    s.assign( x.begin(), x.end() );
}

template< typename istream, typename ostream, typename container = std::vector<char> >
bool pipe( const istream &is, ostream &os, const std::vector< int (*)(const char *, int, char *, int) > &vec = std::vector< int (*)(const char *, int, char *, int) >() ) {
    container src, dst;
    container *A = &src, *B = &dst, *C;
    copy( src, is );
    if( !is.good() ) {
        return false;
    }
    for( auto &fn : vec ) {
        auto bounds = fn( (const char *)&(*A)[0],A->size(),0,B->size() );
        B->resize( bounds );
        int wlen = fn( (const char *)&(*A)[0], A->size(), &(*B)[0], B->size() );
        if( wlen >= 0 ) {
            B->resize( wlen );
            C = B, B = A, A = C;
        } else return false;
    }
    os.write( &(*A)[0], (*A).size() );
    return os.good();
}


/*
int rot13ish( const char *src, int slen, char *dst, int dlen ) {
    if( !dst ) return slen * 2; // bounds
    char *bak = dst;
    const char *p = src, *e = src + slen;
    while( p < e ) *dst++ = (*p & 0xf0) | (*p & 0x0f) ^ 0x7, ++p;
    return dst - bak;
}
int upper( const char *src, int slen, char *dst, int dlen ) {
    if( !dst ) return slen * 2; // bounds
    char *bak = dst;
    const char *p = src, *e = src + slen;
    size_t len = e - p;
    while( p < e ) *dst++ = (*p >= 'a' ? *p - 'a' + 'A' : *p), ++p;
    return dst - bak;
}
int lower( const char *src, int slen, char *dst, int dlen ) {
    if( !dst ) return slen * 2; // bounds
    char *bak = dst;
    const char *p = src, *e = src + slen;
    size_t len = e - p;
    while( p < e ) *dst++ = (*p >= 'A' ? *p - 'A' + 'a' : *p), ++p;
    return dst - bak;
}
int noparens( const char *src, int slen, char *dst, int dlen ) {
    if( !dst ) return slen * 2; // bounds
    char *bak = dst;
    const char *p = src, *e = src + slen;
    while( p < e ) {
        if( *p != '(' && *p != ')' ) *dst++ = *p++; else *p++;
    }
    return dst - bak;
}
int numberx2( const char *src, int slen, char *dst, int dlen ) {
    if( !dst ) return slen * 2; // bounds
    char *bak = dst;
    const char *p = src, *e = src + slen;
    while( p < e ) {
        bool n = *p >= '0' && *p <= '9';
        dst[0]=dst[n]=*p++, dst+=n+1;
    }
    return dst - bak;
}
int l33t( const char *src, int slen, char *dst, int dlen ) {
    if( !dst ) return slen * 2; // bounds
    char *bak = dst;
    const char *p = src, *e = src + slen;
    while(p < e)
    switch(*p++) {
        default: *dst++ = p[-1];
        break; case 'O': *dst++ = '0';
        break; case 'T': *dst++ = '7';
        break; case 'E': *dst++ = '3';
        break; case 'L': *dst++ = '1';
        break; case 'I': *dst++ = '1';
        break; case 'A': *dst++ = '4';
    }
    return dst - bak;
}
#include <fstream>
#include <iostream>
#include <sstream>
int main() {
    std::stringstream is; is << "hello";
    pipe( is, std::cout );

    std::ifstream ifs{__FILE__};
    pipe( ifs, std::cout, { rot13ish, rot13ish } );
    pipe( ifs, std::cout, { upper, l33t, lower, numberx2, noparens } );
}
*/

================================================
FILE: tinyprint.cc
================================================
// Tiny printer. Original code by Evan Wallace. rlyeh, public domain | wtrmrkrlyeh
#include <iostream>

struct print {
	const char *sep = "";
	~print() { std::cout << std::endl; }

	template<typename T> print& operator,( const T &t ) {
		return std::cout << sep << t, sep = " ", *this;
	}
};

#define print print(),

/*
int main() {
   print "hello", 123, "world";
   print "yeah";
}
*/


================================================
FILE: tinypulse.c
================================================
// Tiny digital pulses/signals. rlyeh, public domain | wtrmrkrlyeh
#include <stdio.h>

void pulse( int *state ) {
    switch( state[1] * 2 + state[0] ) {
        default:
        break; case 0: puts("pulse OFF");
        break; case 1: puts("pulse UP");
        break; case 2: puts("pulse DOWN");
        break; case 3: puts("pulse ON");
    }
    state[1] = state[0];
}

/*
int main() {
    int state[2] = {0};

    *state = 0;
    pulse(state);

    *state = 1;
    pulse(state);

    *state = 1;
    pulse(state);

    *state = 0;
    pulse(state);

    *state = 0;
    pulse(state);
}
*/


================================================
FILE: tinyroman.cc
================================================
// Tiny integer to roman numerals converter (roughly tested). rlyeh, public domain | wtrmrkrlyeh
#include <map>
#include <string>

std::string romanize( int i ) {
    static std::string table[] = {
        "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX",
        "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC",
        "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM",
        "M", "MM", "MMM", "MMMM",
    };
    std::string out;
    for( int base = 0; i > 0; base++, i /= 10 ) {
        int mod = i % 10;
        if( mod > 0 ) {
            out = table[(mod - 1) + base * 9] + out;
        }
    }
    return out;
}

/*
#include <cassert>
int main() {
    assert( romanize(0) == "" );
    assert( romanize(10) == "X" );
    assert( romanize(1990) == "MCMXC" );
    assert( romanize(2008) == "MMVIII" );
    assert( romanize(99) == "XCIX" );
    assert( romanize(47) == "XLVII" );
}
*/


================================================
FILE: tinystring.c
================================================
// C string library
// - rlyeh, public domain

// temporary strings api (stack)
char* strtmp(const char *fmt, ...);
int stristmp(const char *s);

// allocated strings api (heap)
#define strnew(fmt, ...) strdup(strtmp(fmt,__VA_ARGS__))
#define strdel(s)        ((stristmp(s) ? (void)0 : free(s)), (s)=0)

// implementation --------------------------------------------------------------

#if defined _MSC_VER && !defined __thread
#define __thread __declspec(thread)
#endif

#include <assert.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>

int stristmp(const char *s) { // is_va()
    return (1&(uintptr_t)s) && s[-1] == 0;
}
char* strtmp(const char *fmt, ...) { // va()
    va_list vl;
    va_start(vl, fmt);
    int sz = vsnprintf( 0, 0, fmt, vl ) + 1;
    va_end(vl);

    int reqlen = sz + 1; // 1 for even padding

    char* ptr;
    enum { STACK_ALLOC = 16384 };
    if( reqlen < STACK_ALLOC ) { // fit stack?
        static __thread char buf[STACK_ALLOC+1];
        static __thread int cur = 1, len = STACK_ALLOC;
        ptr = buf + ((cur+reqlen) > len ? cur = 1 : (cur += reqlen) - reqlen);
    } else { // else use heap (@fixme: single memleak per invoking thread)
        static __thread char *buf = 0;
        static __thread int cur = 1, len = -STACK_ALLOC;
        if( reqlen >= len ) buf = realloc(buf, len = abs(len) * 1.75 + reqlen);
        ptr = buf + ((cur+reqlen) > len ? cur = 1 : (cur += reqlen) - reqlen);
    }

    ptr += !(1&(uintptr_t)ptr); // align to even address only when already odd
    ptr[-1] = 0; // add header
    assert(stristmp(ptr));

    va_start(vl,fmt);
    vsnprintf( ptr, sz, fmt, vl );
    va_end(vl);

    return (char *)ptr;
}

/*
int main() {
    // creation
    char *x = strtmp("hello %d", 123); puts(x);
    char *y = strnew("hello %d", 123); puts(y);
    assert(strcmp(x,y)==0);

    // destruction
    // strdel(x); assert(x == 0); // optional free, since x is a temporary string (strtmp)
    strdel(y); assert(y == 0);    // required free, since y was explicitly allocated (with strnew)

    // test concat
    char *z = strtmp("%d",6); z = strtmp("%s%s%s",z,z,z); assert( 0 == strcmp(z,"666") );

    // test memory is never exhausted
    for(int i = 0; i < 10000; ++i) assert(strtmp("hello %d",123));

    // test asserts are enabled
    assert(~puts("Ok"));
}
*/


================================================
FILE: tinystring.cc
================================================
// tiny C++ string utilities
// - rlyeh, public domain | wtrmrkrlyeh

// @toadd: pad, left, right, center, triml, trimr, trim, [-1]

#include <deque>
#include <string>

std::deque< std::string > tokenize( const std::string &self, const char *delimiters ) {
    char map[256] = {};
    while( *delimiters++ ) map[ (unsigned char) delimiters[-1] ] = '\1';
    std::deque< std::string > tokens(1);
    for( auto &ch : self ) {
        /**/ if( !map[(unsigned char)ch] ) tokens.back().push_back( ch );
        else if( tokens.back().size() ) tokens.push_back( std::string() );
    }
    while( tokens.size() && !tokens.back().size() ) tokens.pop_back();
    return tokens;
}

std::deque< std::string > split( const std::string &self, const std::string &delimiters ) {
    std::string str;
    std::deque< std::string > tokens;
    for( auto &ch : self ) {
        if( delimiters.find_first_of( ch ) != std::string::npos ) {
            if( str.size() ) tokens.push_back( str ), str = "";
            tokens.push_back( std::string() + ch );
        } else str += ch;
    }
    return str.empty() ? tokens : ( tokens.push_back( str ), tokens );
}

std::string left_of( const std::string &substring, const std::string &self ) {
    std::string::size_type pos = self.find( substring );
    return pos == std::string::npos ? self : self.substr(0, pos);
}

std::string right_of( const std::string &substring, const std::string &self ) {
    std::string::size_type pos = self.find( substring );
    return pos == std::string::npos ? self : self.substr(pos + substring.size() );
}

std::string replace_one( const std::string &self, const std::string &target, const std::string &replacement ) {
    std::string str = self;
    auto found = str.find(target);
    return found == std::string::npos ? str : (str.replace(found, target.length(), replacement), str);
}

std::string replace_all( const std::string &self, const std::string &target, const std::string &replacement ) {
    size_t found = 0;
    std::string s = self;
    while( ( found = s.find( target, found ) ) != std::string::npos ) {
        s.replace( found, target.length(), replacement );
        found += replacement.length();
    }
    return s;
}

/*
#include <assert.h>
int main() {
    assert( tokenize("a/b/c/\\d\\e,f,g,", "/\\,") == (std::deque<std::string> { "a", "b", "c", "d", "e", "f", "g" }) );
    assert( split("a/b/c/\\d\\e,f,g,", "/\\,") == (std::deque<std::string> { "a", "/", "b", "/", "c", "/", "\\", "d", "\\", "e", ",", "f", ",", "g", "," }) );
    assert( left_of("beginning", "in the beginning") == "in the " );
    assert( right_of("in the ", "in the beginning") == "beginning" );
    assert( replace_all( "0cad0", "0", "abra" ) == "abracadabra" );
    assert( replace_one( "0cad0", "0", "abra" ) == "abracad0" );
}
*/


================================================
FILE: tinytga.c
================================================
// Tiny TGA writer: original code by jon olick, public domain
// Elder C version by rlyeh, public domain | wtrmrkrlyeh
#include <stdio.h>
static void tinytga(FILE *fp, void *rgba, int width, int height, int numChannels) {
    // Swap RGBA to BGRA if using 3 or more channels
    int x, i, y, j, bpc = numChannels * 8; // 8 bits per channel
    int remap[4] = {numChannels >= 3 ? 2 : 0, 1, numChannels >= 3 ? 0 : 2, 3};
    char *s = (char *)rgba;
    // Header
    fwrite("\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00", 12, 1, fp);
    fwrite(&width, 2, 1, fp);
    fwrite(&height, 2, 1, fp);
    fwrite(&bpc, 2, 1, fp);
    for(y = height-1; y >= 0; --y) {
        i = (y * width) * numChannels;
        for(x = i; x < i+width*numChannels; x += numChannels) {
            for(j = 0; j < numChannels; ++j) {
                fputc(s[x+remap[j]], fp);
            }
        }
    }
}


================================================
FILE: tinytime.cc
================================================
// Tiny timing utilities. rlyeh, public domain | wtrmrkrlyeh
#include <thread>
#include <chrono>
#if !defined(TIMING_USE_OMP) && ( defined(USE_OMP) || defined(_MSC_VER) /*|| defined(__ANDROID_API__)*/ )
#   define TIMING_USE_OMP
#   include <omp.h>
#endif
double now() {
#   ifdef TIMING_USE_OMP
    static auto const epoch = omp_get_wtime();
    return omp_get_wtime() - epoch;
#   else
    static auto const epoch = std::chrono::steady_clock::now(); // milli ms > micro us > nano ns
    return std::chrono::duration_cast< std::chrono::microseconds >( std::chrono::steady_clock::now() - epoch ).count() / 1000000.0;
#   endif
}
double bench( void (*fn)() ) {
    double took = -now();
    return ( fn(), took + now() );
}
void sleep( double secs ) {
    std::chrono::microseconds duration( (int)(secs * 1000000) );
    std::this_thread::sleep_for( duration );
}

/*
#include <stdio.h>
int main() {
    double t0 = now();
    printf("%g s.\n", bench( []{ sleep(0.1234); } ) );
    double t1 = now();
    printf("%g s.\n", t1 - t0 );
}
*/


================================================
FILE: tinytodo.c
================================================
// Tiny todo() static assert macro. based on code by https://github.com/andyw8/do_by
// - rlyeh, public domain | wtrmrkrlyeh

#pragma once
#include <stdio.h>

static inline int TODO(const char *DT) { return
       /*D*/ ( DT[4] == ' ' ? 0 : (DT[4] - '0') * 10 ) + (DT[5] - '0') +
       /*M*/ ( DT[2] == 'n' ? 1
             : DT[2] == 'b' ? 2
             : DT[2] == 'r' && DT[0] == 'M' ? 3
             : DT[2] == 'r' && DT[0] != 'M' ? 4
             : DT[2] == 'y' ? 5
             : DT[2] == 'n' ? 6
             : DT[2] == 'l' ? 7
             : DT[2] == 'g' ? 8
             : DT[2] == 'p' ? 9
             : DT[2] == 't' ? 10
             : DT[2] == 'v' ? 11 : 12 ) * 100 +
       /*Y*/ (DT[7] - '0') * 1e7 + (DT[8] - '0') * 1e6 + (DT[9] - '0') * 1e5 + (DT[10] - '0') * 1e4;
}

#define TODO(DT) do { static int ever = 0; if(!ever) { ever = 1; if( TODO(__DATE__) >= TODO(DT) ) fprintf(stderr, "TODO date expired! %s\n", DT); } } while(0)

/*
int main() {
    TODO( "Aug 11 2011: Finish prototype. Warn if current date >= Aug 11 2011" );
    TODO( "May 19 2014: Finish gameplay. Warn if current date >= May 19 2014" );
    TODO( "Sep 26 2015: Finish QA. Warn if current date >= Sep 26 2015" );
}
*/


================================================
FILE: tinytty.c
================================================
// Tiny terminal utilities. rlyeh, public domain | wtrmrkrlyeh
#include <stdio.h>

#ifdef _WIN32
#define ANSI(ansi, win) win
#else
#define ANSI(ansi, win) ansi
#endif

// A few unicode characters and ANSI colors
static const char *tick   = ANSI("\u2713", "[v]"), *cross   = ANSI("\u2717", "[x]"), *arrow = ANSI("\u2794", "[>]");
static const char *red    = ANSI("\27[31m",""),    *green   = ANSI("\27[32m",""),    *blue = ANSI("\27[34m","");
static const char *yellow = ANSI("\27[33m",""),    *magenta = ANSI("\27[35m",""),    *cyan = ANSI("\27[36m","");
static const char *end    = ANSI("\27[0m","");

// 256-color terminal
void tty256( unsigned char r, unsigned char g, unsigned char b ) {
    ANSI(printf("\033[38;5;%dm", (r/51)*36+(g/51)*6+(b/51)+16), (void)0);
}

// terminal writer w/ console width clamping
#ifdef _WIN32
#include <string.h>
#include <winsock2.h>
#endif
void tty( const char *txt ) {
#ifdef _WIN32
    CONSOLE_SCREEN_BUFFER_INFO c;
    if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &c) ) {
        int len = strlen(txt), w = c.srWindow.Right-c.srWindow.Left-c.dwCursorPosition.X;
        printf("%.*s%s\n", len > w ? w - 3 : w, txt, len > w ? "..." : "" );
        return;
    }
#endif
    puts( txt );
}

/*
int main() {
    // usage:
    printf("%s%s%s%s%s\n", green, tick, yellow, " passed", end);
    // or:
    tty256( 255, 192, 0 );
    printf("%s\n", "256 colors");
    // also:
    tty( "DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! " );
    // // more tests:
    // tty( "hey" );
    // printf("%s", "[test] ");
    // tty( "DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! DECREASE WINDOW WIDTH AND RUN THE APP AGAIN! " );
}
*/


================================================
FILE: tinyuniso.cc
================================================
// tiny iso/9660 unarchiver. [ref] http://wiki.osdev.org/ISO_9660
// - rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <functional>
#include <stdint.h>
#include <string>
#include <vector>

template<typename FN, typename istream>
bool tinyuniso( istream &is, const FN &yield ) {
    // directory record
    struct dir_t {
        uint8_t  flags;
        uint64_t offset;
        uint64_t length;
        uint16_t parent;
        union { uint8_t st[7]; struct { uint8_t Y,M,D,h,m,s,GMT; }; };
        std::string name;
    } root = {}; 

    // unpack data (raw)
    auto unpack_raw = [&]( int l, void *ptr ) {
        if( !ptr ) is.ignore( l ); else is.read( (char *)ptr, l );
    };

    // unpack directory record
    auto unpack_record = [&]( dir_t *out ) -> uint8_t {
        auto get_max_of = []( int a, int b ) { return a < b ? b : a; };
        auto unpack_16L = [&]( uint32_t *t ) { unpack_raw(4, t); if(t) *t &= (uint16_t)(-1); };
        auto unpack_32L = [&]( uint64_t *t ) { unpack_raw(8, t); if(t) *t &= (uint32_t)(-1); };
        auto unpack_str = [&]( int l, std::string *s ) {
            s->resize( l );
            unpack_raw( l, &(*s)[0] );
            while( !s->empty() && s->back() == ' ' ) s->pop_back();     // rstrip(' ')
            *s = s->substr( 0, s->find_first_of(';') );                 // left_of(';')
            for( auto &ch : *s ) ch -= 32 * ( ch >= 'a' && ch <= 'z' ); // upper()
        };
        uint8_t len0, len1;
        unpack_raw( 1, &len0 );
        if( len0 ) {
            unpack_raw( 1, 0 );
            unpack_32L( &(out->offset) );
            unpack_32L( &(out->length) );
            unpack_raw( 7, &(out->st) );
            unpack_raw( 1, &(out->flags) );
            unpack_raw( 1+1+4, 0 );
            unpack_raw( 1, &len1 );
            unpack_str( len1, &(out->name) );
            unpack_raw( !(len1 % 2), 0);
            unpack_raw( get_max_of(0, len0 - (34 + len1 - (len1 % 2))), 0 );
        } else len0 = 1, *out = dir_t();
        return len0;
    };

    // retrieve partial contents
    auto get_sector = [&]( int64_t sector, int64_t length ) {
        return is.seekg( sector*2048, is.beg ), is.good();
    };

    // retrieve whole file contents
    auto get_file = [&]( char *ptr, const dir_t &f ) {
        get_sector( f.offset, f.length );
        unpack_raw( f.length, ptr );
    };

    // parse volume descriptors
    int sector = 0x10;
    while( get_sector(sector++, 2048) ) {
        uint8_t typecode;
        unpack_raw(1, &typecode);

        /**/ if( typecode == 255 ) break;
        else if( typecode == 0x1 ) { // skip most of primary volume descriptor
            std::string id(5, '\0');
            unpack_raw(5, &id[0]); if(id != "CD001") return false;
            unpack_raw(1+1+32+32+8+8+32+4+4+4+8+4+4+4+4, 0);
            unpack_record( &root ); break;
        }
        else return false;
    }

    // recurse directory structure
    using fn = std::function<void (const dir_t &, const char *)>;
    fn tree = [&] ( const dir_t &node, const char *parent ) {
        std::vector<dir_t> list;
        // unpack dir
        auto sector = node.offset;
        auto read = 0;
        get_sector(sector, 2048);
        dir_t self; read += unpack_record( &self );
        dir_t prev; read += unpack_record( &prev );
        // iterate children
        while( read < self.length ) {
            if( read % 2048 == 0) {
                get_sector(++sector, 2048);
            }

            dir_t data;
            read += unpack_record( &data );

            if( data.name.empty() ) { // if end of directory
                auto skip = 2048 - (read % 2048);
                unpack_raw(skip, 0);
                read += skip;
            } else {
                list.push_back( data );
            }
        }
        // iterate listing: recurse if dir, else yield file
        for( auto &c : list ) {
            if( c.flags & 2 ) {
                tree( c, (node.name + "/").c_str() );
            } else {
                std::string fname = std::string("/") + parent + node.name + "/" + c.name;
                char buffer[128] = {};
                auto offset = (int)(c.GMT) * 15 * 60; // offset in seconds from GMT in 15min intervals
                sprintf(buffer, "%d/%02d/%02d %02d:%02d:%02d%c%d", 1900+c.Y, c.M, c.D, c.h, c.m, c.s, offset >= 0 ? '+':'-', offset );
                if( char *ptr = yield( fname, c.length, buffer, c.offset ) ) {
                    get_file( ptr, c );
                }
            }
        }
    };

    tree(root, "");
    return is.good();
}

/*
#include <iostream>
#include <fstream>
int main( int argc, const char **argv ) {
    if( argc <= 1 ) {
        return std::cout << "Usage: " << argv[0] << " file.iso [path]" << std::endl, -1;
    }
    std::string read;
    std::ifstream ifs( argv[1], std::ios::binary );
    bool ok = ifs.good() && tinyuniso( ifs, 
        [&]( const std::string &path, uint64_t size, const char *stamp, uint64_t offset ) { 
            // .csv list
            std::cout << "'" << path << "'," << size << ",'" << stamp  << "'" << std::endl;
            // read file (if provided)
            if( argc > 2 && path == argv[2] ) {
                read.resize( size );
                return &read[0];
            }
            return (char *)0;
        }
    );
    if( !read.empty() ) std::cout << read << std::endl;
    return ok;
}
*/


================================================
FILE: tinyunit.c
================================================
// Tiny unittest suite. rlyeh, public domain | wtrmrkrlyeh
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define suite(...) if(printf("------ " __VA_ARGS__),puts(""),1)
#define test(...)  (errno=0,++tst,err+=!(ok=!!(__VA_ARGS__))),printf("[%s] L%d %s (%s)\n",ok?" OK ":"FAIL",__LINE__,#__VA_ARGS__,strerror(errno))
static unsigned tst=0,err=0,ok=1; static void summary(void){ suite("summary"){ printf("[%s] %d tests = %d passed + %d errors\n",err?"FAIL":" OK ",tst,tst-err,err); }; }

/*
int main() {
    atexit( summary );
    // orphan test
    test(1<2);
    // grouped tests
    suite("grouped tests %d/%d", 1,1) {
        test(1<2);
        test(1<2);
    }
    suite("grouped tests %d/%d", 1,2) {
        test(1<2);
        test(1<2);
    }
}
*/

================================================
FILE: tinyuntar.cc
================================================
// portable gnu tar and ustar extraction
// - rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <string>
#include <stdint.h>

template<typename FN, typename istream>
bool tinyuntar( istream &is, const FN &yield ) {
    enum {
        name     =   0, // (null terminated)
        mode     = 100, // (octal)
        uid      = 108, // (octal)
        gid      = 116, // (octal)
        size     = 124, // (octal)
        modtime  = 136, // (octal)
        checksum = 148, // (octal)
        type     = 156, // \0|'0':file,1:hardlink,2:symlink,3:chardev,4:blockdev,5:dir,6:fifo,L:longnameblocknext
        linkname = 157, // if !ustar link indicator
        magic    = 257, // if ustar "ustar" -- 6th character may be space or null, else zero
        version  = 263, // if ustar "00", else zero
        uname    = 265, // if ustar owner username, else zero
        gname    = 297, // if ustar owner groupname, else zero
        devmajor = 329, // if ustar device major number, else zero
        devminor = 337, // if ustar device minor number , else zero
        path     = 345, // if ustar filename prefix, else zero
        padding  = 500, // if ustar relevant for checksum, else zero
        total    = 512
    };

    // equivalent to sscanf(buf, 8, "%.7o", &size); or (12, "%.11o", &modtime)
    // ignores everything after first null or space, including trailing bytes
    struct octal { 
        uint64_t operator()( const char *src, const char *eof ) const {
            uint64_t sum = 0, mul = 1;
            const char *ptr = eof;
            while( ptr-- >= src ) eof  = ( 0 != ptr[1] && 32 != ptr[1] ) ? eof : ptr;
            while( eof-- >= src ) sum += (uint8_t)(eof[1] - '0') * mul, mul *= 8;
            return sum;
    } };

    // handle both regular tar and ustar tar filenames until end of tar is found
    for( char header[512], blank[512] = {}; is.good(); ) {
        is.read( header, 512 );
        if( memcmp( header, blank, 512 ) ) {                                      // if not end of tar
            if( !memcmp( header+magic, "ustar", 5 ) ) {                           // if valid ustar
                int namelen = strlen(header+name), pathlen = strlen(header+path); // read filename
                std::string entry =
                std::string(header+path, pathlen < 155 ? pathlen : 155 ) + (pathlen ? "/" : "") +
                std::string(header+name, namelen < 100 ? namelen : 100 );

                switch( header[type] ) {
                    default:                                                      // unsupported file type
                    break; case '5': //yield(entry.back()!='/'?entry+'/':entry,0);// directory
                    break; case 'L': entry = header+name; is.read( header, 512 ); // gnu tar long filename
                    break; case '0': case 0: {                                    // regular file
                        uint64_t len = octal()(header+size, header+modtime);      // decode octal size
                        char *dst = (len ? yield(entry, len) : 0);                // read block if processed
                        if( dst ) is.read( dst, len ); else is.ignore( len );     // skip block if unprocessed
                        is.ignore( (512 - (len & 511)) & 511 );                   // skip padding
                    }
                }
            } else return false;
        } else return is.good();
    }

    return false;
}

/*
#include <iostream>
#include <fstream>
#include <map>
int main( int argc, const char **argv ) {
    if( argc != 2 ) return std::cerr << "Usage: " << argv[0] << " archive.tar" << std::endl, -1;
    std::map<std::string, char *> dir;
    std::ifstream in(argv[1], std::ios_base::binary);
    return tinyuntar( in, [&]( const std::string &filename, uint64_t size ) {
        std::cout << filename << " (" << size << " bytes)" << std::endl;
        return dir[ filename ] = (char *)malloc( size ); // processed if valid ptr, skipped if null
    } );
}
*/


================================================
FILE: tinyunzip.cc
================================================
// tiny zip unarchiver. based on junzip by Joonas Pihlajamaa
// - rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <stdint.h>
#include <vector>

#define STBI_NO_WRITE
#define STBI_NO_HDR
#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_STATIC
#include "stb_image.h"

template<typename FN, typename istream>
bool tinyunzip( istream &is, const FN &yield ) {
    bool swaple = 0;
    auto swap16 = [&]( uint16_t t ) { return !swaple ? t : (t >>  8) | (t <<  8); };
    auto swap32 = [&]( uint32_t t ) { return !swaple ? t : (t >> 24) | (t << 24) | ((t >> 8) & 0xff00) | ((t & 0xff00) << 8); };

#pragma pack( push, 1 )
    struct global_file_header {
        uint32_t magic; // <--
        uint16_t version;
        uint16_t versionreq;
        uint16_t flags;
        uint16_t zmethod; // <--
        uint16_t modftme;
        uint16_t modfdte;
        uint32_t crc32;
        uint32_t size;
        uint32_t unsize;
        uint16_t namelen; // <-- filename length
        uint16_t xtralen; // <-- extra field length
        uint16_t commlen; // <-- comment filed length
        uint16_t beginvol;
        uint16_t attrint;
        uint32_t attrext;
        uint32_t offsrel; // <--
    } gfh = {};

    struct file_header {
        uint16_t zmethod; // <--
        uint16_t modftme;
        uint16_t modfdte;
        uint32_t crc32;
        uint32_t size;   // <--
        uint32_t unsize; // <--
        union  { uint32_t offset;  // <--
        struct { uint16_t namelen; // <--
                 uint16_t xtralen; // <--
        }; };
    } fh = {};

    struct local_file_header {
        uint32_t magic; // <--
        uint16_t versionreq;
        uint16_t flags;
        file_header fh;
    } lfh;

    struct end_record {
        uint32_t magic; // <-- 0x06054b50
        uint16_t volno; // <--
        uint16_t volnodir; // <--
        uint16_t volentries; // <--
        uint16_t totentries; // <--
        uint32_t dirsize;
        uint32_t diroffs; // <--
        uint16_t commlen; // after this field, zip file comment follows (variable size)
    } er = {};
#pragma pack( pop )

    enum { BUFFER_SIZE = 65536 }; // max name len
    std::vector<char> buffer( BUFFER_SIZE ), cdata;

    auto read_end_record = [&] {
        is.seekg( 0, is.end );
        size_t total = is.tellg();
        if( total >= sizeof(end_record) ) {
            size_t to_read = (total < BUFFER_SIZE) ? total : BUFFER_SIZE;
            is.seekg( total - to_read, is.beg );
            is.read( &buffer[0], to_read );
            for( int at = to_read - sizeof(end_record); at >= 0; at-- ) {
                er = *(end_record *) &buffer[at];
                if( er.magic == 0x06054B50 || er.magic == 0x504B5460 ) {
                    swaple = er.magic != 0x06054B50;
                    return !swap16(er.volno) && !swap16(er.volnodir) && swap16(er.totentries) == swap16(er.volentries);
                }
            }
        }
        return false;
    };

    auto read_central_dir = [&] {
        is.seekg( swap32(er.diroffs), is.beg );
        if( is.good() ) for( int it = 0; it < swap16(er.totentries); it++ ) {
            is.read( (char *)&gfh, sizeof(global_file_header) );
            if( is.good() && gfh.magic == swap32(0x02014B50) && swap16(gfh.namelen) + 1 < BUFFER_SIZE ) {
                is.read( (char *)&buffer[0], swap16(gfh.namelen) );
                buffer[ swap16(gfh.namelen) ] = '\0';
                is.seekg( swap16(gfh.xtralen) + swap16(gfh.commlen), is.cur );
                fh = *(file_header *)&gfh.zmethod;
                fh.offset = gfh.offsrel;
                if( swap32(fh.size) != 0 || buffer[ swap16(gfh.namelen) - 1 ] != '/' )   // if not dir
                if( swap16(fh.zmethod) == 0 || swap16(fh.zmethod) == 8 ) {               // if supported
                    char *ptr = yield( &buffer[0], swap32(fh.unsize), swap32(fh.size) ); // reserve
                    if( ptr ) {
                        auto pos = is.tellg();
                        is.seekg( swap32(fh.offset), is.beg );
                        is.read( (char *)&lfh, sizeof(local_file_header) );
                        if( lfh.magic != swap32(0x04034B50) ) return false;
                        is.seekg(swap16(lfh.fh.namelen) + swap16(lfh.fh.xtralen), is.cur);
                        if( swap16(fh.zmethod) ) {
                            cdata.resize( swap32(fh.size) );
                            is.read( &cdata[0], cdata.size() );
                            if( stbi_zlib_decode_noheader_buffer( ptr, swap32(fh.unsize), &cdata[0], swap32(fh.size) ) < 0 ) {
                                return false;
                            }
                        } else {
                            is.read( ptr, swap32(fh.size) );
                        }
                        is.seekg( pos, is.beg );
                    }
                }
            } else return false;
        } else return false;
        return true;
    };

    return read_end_record() && read_central_dir() && is.good();
}

/*
#include <fstream>
#include <iostream>
#include <map>
int main( int argc, const char **argv ) {
    std::map<std::string, char *> toc;
    std::ifstream is( argc > 1 ? argv[1] : argv[0], std::ios::binary );
    return tinyunzip( is, [&]( const char *filename, int dlen, int zlen ) {
        std::cout << filename << " " << zlen << " -> " << dlen << std::endl;
        return toc[ filename ] = (char *)malloc(dlen);
    } );
}
*/


================================================
FILE: tinyvariant.cc
================================================
// Tiny variant class. rlyeh, public domain | wtrmrkrlyeh
#include <string>
#include <functional>

struct var {
    int type;
    union {
        int integer;
        double real;
        std::string *string;
        std::function<void()> *callback;
    };

    var() : type(0), integer(0)
    {}

    var( const int &i ) : type(0), integer(i)
    {}

    var( const double &r ) : type(1), real(r)
    {}

    var( const std::string &r ) : type(2), string( new std::string(r) )
    {}

    template<unsigned N>
    var( const char (&s)[N]) : type(2), string( new std::string(s) )
    {}

    template<typename T>
    var( const T &fn ) : type(3), callback( new std::function<void()>(fn) )
    {}

    var( const var &other ) {
        operator=( other );
    }

    ~var() {
        cleanup();
    }

    void cleanup() {
        /**/ if( type == 3 ) delete callback, callback = 0;
        else if( type == 2 ) delete string, string = 0;
        type = 0;
    }

    var &operator=( const var &other ) {
        if( &other != this ) {
            cleanup();
            type = other.type;
            /**/ if( type == 0 ) integer = other.integer;
            else if( type == 1 ) real = other.real;
            else if( type == 2 ) string = new std::string( *other.string );
            else if( type == 3 ) callback = new std::function<void()>( *other.callback );
        }
        return *this;
    }

    void operator()() const {
        if( type == 3 ) if( *callback ) (*callback)();
    }

    template<typename ostream>
    inline friend ostream &operator <<( ostream &os, const var &self ) {
        /**/ if( self.type == 0 ) return os << self.integer, os;
        else if( self.type == 1 ) return os << self.real, os;
        else if( self.type == 2 ) return os << *self.string, os;
        else if( self.type == 3 ) return os << '[' << self.callback << ']', os;
        return os;
    }
};

template<typename T> inline bool is(const var &v) { return false; }
template<>           inline bool is<int>(const var &v) { return v.type == 0; }
template<>           inline bool is<double>(const var &v) { return v.type == 1; }
template<>           inline bool is<std::string>(const var &v) { return v.type == 2; }
template<>           inline bool is<std::function<void()>>(const var &v) { return v.type == 3; }

template<typename T> inline const T& cast(const var &v) { static T t; return t = T(); }
template<>           inline const int& cast<int>(const var &v) { return v.integer; }
template<>           inline const double& cast<double>(const var &v) { return v.real; }
template<>           inline const std::string& cast<std::string>(const var &v) { return *v.string; }
template<>           inline const std::function<void()>& cast<std::function<void()>>(const var &v) { return *v.callback; }

/*
#include <iostream>
#include <assert.h>
int main() {
    std::cout << "sizeof(var)=" << sizeof(var) << std::endl;

    var digit = 42, other = "hello world";

    std::cout << digit << std::endl; assert( is<int>(digit) );
    std::cout << other << std::endl; assert( is<std::string>(other) );

    other = digit;
    std::cout << other << std::endl; assert( is<int>(other) );

    other = []{ std::cout << "callback!" << std::endl; };
    std::cout << other << std::endl;
    other();
}
*/


================================================
FILE: tinyvbyte.h
================================================
// tiny variable byte length encoder/decoder (vbyte)
// - rlyeh, public domain | wtrmrkrlyeh
#pragma once
#include <stdint.h>

enum { VBYTE_MIN_REQ_BYTES = 1, VBYTE_MAX_REQ_BYTES = 10 };

static uint64_t vbuencode( uint8_t *buffer, uint64_t value ) {
    /* 7-bit packing. MSB terminates stream */
    const uint8_t *buffer0 = buffer;
    do {
        *buffer++ = (uint8_t)( 0x80 | (value & 0x7f) );
        value >>= 7;
    } while( value > 0 );
    *(buffer-1) ^= 0x80;
    return buffer - buffer0;
}
static uint64_t vbudecode( uint64_t *value, const uint8_t *buffer ) {
    /* 7-bit unpacking. MSB terminates stream */
    const uint8_t *buffer0 = buffer;
    uint64_t out = 0, j = -7;
    do {
        out |= (( ((uint64_t)(*buffer)) & 0x7f) << (j += 7) );
    } while( ((uint64_t)(*buffer++)) & 0x80 );
    *value = out;
    return buffer - buffer0;
}

static uint64_t vbiencode( uint8_t *buffer, int64_t value ) {
    /* convert sign|magnitude to magnitude|sign */
    uint64_t nv = (uint64_t)((value >> 63) ^ (value << 1));
    /* encode unsigned */
    return vbuencode( buffer, nv );
}
static uint64_t vbidecode( int64_t *value, const uint8_t *buffer ) {
    /* decode unsigned */
    uint64_t nv, ret = vbudecode( &nv, buffer );
    /* convert magnitude|sign to sign|magnitude */
    *value = ((nv >> 1) ^ -(nv & 1));
    return ret;
}

/*
#include <stdio.h>
#define test(type, encfunc, decfunc, number) do { \
    type copy; \
    char buf[16]; \
    int written = encfunc( buf, number ), i = 0; \
    printf("[    ] %s: ", #type); \
    while( i < written ) printf("%02x,", (uint8_t)buf[i++] ); \
    decfunc( &copy, buf ); \
    printf("\r%s\n", copy == number ? "[ OK ]" : "[FAIL]"); \
} while(0)
int main() {
    test( int64_t, vbiencode, vbidecode,  0);
    test( int64_t, vbiencode, vbidecode, -1);
    test( int64_t, vbiencode, vbidecode, +1);
    test( int64_t, vbiencode, vbidecode, -2);
    test( int64_t, vbiencode, vbidecode, +2);
    test( int64_t, vbiencode, vbidecode, INT8_MIN);
    test( int64_t, vbiencode, vbidecode, INT8_MAX);
    test( int64_t, vbiencode, vbidecode, INT16_MIN);
    test( int64_t, vbiencode, vbidecode, INT16_MAX);
    test( int64_t, vbiencode, vbidecode, INT32_MIN);
    test( int64_t, vbiencode, vbidecode, INT32_MAX);
    test( int64_t, vbiencode, vbidecode, INT64_MIN);
    test( int64_t, vbiencode, vbidecode, INT64_MAX);

    test(uint64_t, vbuencode, vbudecode, 0);
    test(uint64_t, vbuencode, vbudecode, 1);
    test(uint64_t, vbuencode, vbudecode, 2);
    test(uint64_t, vbuencode, vbudecode, 3);
    test(uint64_t, vbuencode, vbudecode, 4);
    test(uint64_t, vbuencode, vbudecode, UINT8_MAX);
    test(uint64_t, vbuencode, vbudecode, UINT16_MAX);
    test(uint64_t, vbuencode, vbudecode, UINT32_MAX);
    test(uint64_t, vbuencode, vbudecode, UINT64_MAX);
}
*/


================================================
FILE: tinywav.c
================================================
// Tiny WAV writer: original code by jon olick, public domain
// Floating point support + pure C version by rlyeh, public domain | wtrmrkrlyeh
#include <stdio.h>
static void tinywav(FILE *fp, short numChannels, short bitsPerSample, int sampleRateHz, const void *data, int size, int is_floating) {
    short bpsamp;
    int length, bpsec;
    fwrite("RIFF", 1, 4, fp);
    length = size + 44 - 8;
    fwrite(&length, 1, 4, fp);
    fwrite(is_floating ? "WAVEfmt \x10\x00\x00\x00\x03\x00" : "WAVEfmt \x10\x00\x00\x00\x01\x00", 1, 14, fp);
    fwrite(&numChannels, 1, 2, fp);
    fwrite(&sampleRateHz, 1, 4, fp);
    bpsec = numChannels * sampleRateHz * bitsPerSample/8;
    fwrite(&bpsec, 1, 4, fp);
    bpsamp = numChannels * bitsPerSample/8;
    fwrite(&bpsamp, 1, 2, fp);
    fwrite(&bitsPerSample, 1, 2, fp);
    fwrite("data", 1, 4, fp);
    fwrite(&size, 1, 4, fp);
    fwrite(data, 1, size, fp);
}


================================================
FILE: tinywtf.h
================================================
// tiny portable host macros (C/C++ language features, compilers, os, arch, tls...)
// used to avoid #if/n/def hell.
// - rlyeh, public domain | wtrmrkrlyeh

#ifndef $no

// Core

#define $no(...)
#define $yes(...)        __VA_ARGS__

// Directive modifiers

#define $on(v)          (0 v(+1))  // usage: #if $on($cl)
#define $is             (0 v(+1))  // usage: #if $is($debug)
#define $has(...)       $clang(__has_feature(__VA_ARGS__)) $nclang(__VA_ARGS__) // usage: #if $has(cxx_exceptions)

// Text/code modifiers

#define $quote(...)     #__VA_ARGS__
#define $comment        $no
#define $uncomment      $yes

// Compiler utils

#include <stdint.h>
#if   INTPTR_MAX == INT64_MAX
#   define $bits64    $yes
#   define $bits32    $no
#elif INTPTR_MAX == INT32_MAX
#   define $bits64    $no
#   define $bits32    $yes
#else
#   define $bits64    $no
#   define $bits32    $no
#endif

#if defined(NDEBUG) || defined(_NDEBUG) || defined(RELEASE)
#   define $release   $yes
#   define $debug     $no
#else
#   define $release   $no
#   define $debug     $yes
#endif

#if defined(NDEVEL) || defined(_NDEVEL) || defined(PUBLIC)
#   define $public    $yes
#   define $devel     $no
#else
#   define $public    $no
#   define $devel     $yes
#endif

#if defined(__GNUC__) || defined(__MINGW32__)
#   define $gcc       $yes
#   define $ngcc      $no
#else
#   define $gcc       $no
#   define $ngcc      $yes
#endif

#ifdef _MSC_VER
#   define $cl        $yes
#   define $ncl       $no
#else
#   define $cl        $no
#   define $ncl       $yes
#endif

#ifdef __clang__
#   define $clang     $yes
#   define $nclang    $no
#else
#   define $clang     $no
#   define $nclang    $yes
#endif

#if $on($cl) || $on($gcc) || $on($clang)
#   define $supported_compiler   $yes
#   define $unsupported_compiler $no
#else
#   define $supported_compiler   $no
#   define $unsupported_compiler $yes
#endif

// usage: if $likely (expr) { ... }

#if $on($gcc) || $on($clang)
#   define $likely(expr)    (__builtin_expect(!!(expr), 1))
#   define $unlikely(expr)  (__builtin_expect(!!(expr), 0))
#else
#   define $likely(expr)    ((expr))
#   define $unlikely(expr)  ((expr))
#endif

// create a $warning(...) macro
// usage: $warning("this is shown at compile time")

#if   $on($gcc) || $on($clang)
#   define $w4rning(msg) _Pragma(#msg)
#   define $warning(msg) $w4rning( message( msg ) )
#elif $on($cl)
#   define $warning(msg) __pragma( message( msg ) )
#else
#   define $warning(msg)
#endif

// create a $todo(...) macro
// usage: $todo("this is shown at compile time")

#define $t0d0(X)   #X
#define $tod0(X)   $t0d0(X)
#define $todo(...) $warning( __FILE__ "(" $tod0(__LINE__)") : $todo - " #__VA_ARGS__ " - [ " $cl(__FUNCTION__) $ncl(__func__) " ]" )

// C++ detect and version

#ifdef __cplusplus
#   define $c              $no
#   define $cpp            $yes
#   if (__cplusplus < 201103L && !defined(_MSC_VER)) || (defined(_MSC_VER) && (_MSC_VER < 1700)) || (defined(__GLIBCXX__) && __GLIBCXX__ < 20130322L)
#      define $cpp11       $no
#      define $cpp03       $yes
#   else
#      define $cpp11       $yes
#      define $cpp03       $no
#   endif
#else
#   define $c              $yes
#   define $cpp            $no
#   define $cpp11          $no
#   define $cpp03          $no
#endif

// C++ exceptions

#if defined(__cplusplus) && ( \
    (defined(_HAS_EXCEPTIONS) && (_HAS_EXCEPTIONS > 0)) || \
    (defined(_STLP_USE_EXCEPTIONS) && (_STLP_USE_EXCEPTIONS > 0)) || \
    (defined(HAVE_EXCEPTIONS)) || \
    (defined(__EXCEPTIONS)) || \
    (defined(_CPPUNWIND)) || \
    ($has(cxx_exceptions)) ) /*(__has_feature(cxx_exceptions))*/
#   define $exceptions    $yes
#   define $nexceptions   $no
#else
#   define $exceptions    $no
#   define $nexceptions   $yes
#endif

// Thread Local Storage

#if defined(__MINGW32__) || defined(__SUNPRO_C) || defined(__xlc__) || defined(__GNUC__) || defined(__clang__) || defined(__GNUC__) // __INTEL_COMPILER on linux
//   MingW, Solaris Studio C/C++, IBM XL C/C++,[3] GNU C,[4] Clang[5] and Intel C++ Compiler (Linux systems)
#    define $tls(x) __thread x
#else
//   Visual C++,[7] Intel C/C++ (Windows systems),[8] C++Builder, and Digital Mars C++
#    define $tls(x) __declspec(thread) x
#endif

// OS utils

#if defined(_WIN32)
#   define $windows      $yes
#   define $nwindows     $no
#else
#   define $windows      $no
#   define $nwindows     $yes
#endif

#ifdef __linux__
#   define $linux        $yes
#   define $nlinux       $no
#else
#   define $linux        $no
#   define $nlinux       $yes
#endif

#ifdef __APPLE__
#   define $apple        $yes
#   define $napple       $no
#else
#   define $apple        $no
#   define $napple       $yes
#endif

#if defined(__APPLE__) && defined(TARGET_OS_MAC)
#   define $osx          $yes
#   define $nosx         $no
#else
#   define $osx          $no
#   define $nosx         $yes
#endif

#if defined(__APPLE__) && (defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR))
#   define $ios          $yes
#   define $nios         $no
#else
#   define $ios          $no
#   define $nios         $yes
#endif

#if defined(__ANDROID_API__)
#   define $android      $yes
#   define $nandroid     $no
#else
#   define $android      $no
#   define $nandroid     $yes
#endif

#if $on($windows) || $on($apple) || $on($linux) || $on($osx) || $on($ios) || $on($android)
#   define $supported_os         $yes
#   define $unsupported_os       $no
#else
#   define $supported_os         $no
#   define $unsupported_os       $yes
#endif

#endif

#ifdef UNDEFINE
#undef UNDEFINE
#undef $android
#undef $apple
#undef $bits32
#undef $bits64
#undef $c
#undef $cl
#undef $clang
#undef $comment
#undef $cpp
#undef $cpp03
#undef $cpp11
#undef $debug
#undef $devel
#undef $exceptions
#undef $gcc
#undef $has
#undef $ios
#undef $is
#undef $likely
#undef $linux
#undef $nandroid
#undef $napple
#undef $ncl
#undef $nclang
#undef $nexceptions
#undef $ngcc
#undef $nios
#undef $nlinux
#undef $no
#undef $nosx
#undef $nwindows
#undef $on
#undef $osx
#undef $public
#undef $quote
#undef $release
#undef $supported_compiler
#undef $supported_os
#undef $tls
#undef $todo
#undef $uncomment
#undef $unlikely
#undef $unsupported_compiler
#undef $unsupported_os
#undef $warning
#undef $windows
#undef $yes
#ifdef $tod0
#undef $tod0
#endif
#ifdef $t0d0
#undef $t0d0
#endif
#ifdef $w4rning
#undef $w4rning
#endif
#endif

/*
#include <stdio.h>
int main() {
    $c(
        puts("C");
    )
    $cpp(
        puts("C++");
        $cpp03(
            puts("C++03");
        )
        $cpp11(
            puts("C++11");
        )
        $exceptions(
            puts("exceptions enabled");
        )
        $nexceptions(
            puts("exceptions disabled");
        )
    )

    $bits32(
        puts("32-bit");
    )
    $bits64(
        puts("64-bit");
    )

    $debug(
        puts("unoptimized");
    )
    $release(
        puts("optimized");
    )

    $windows(
        puts("windows");
    )
    $ios(
        puts("ios");
    )
    $osx(
        puts("osx");
    )

    $warning("this line emits a warning");
    $todo("this line needs a better comment");

    const char *src = $quote(multi
    line);

    $comment(
        puts("never compiled");
    );

    static $tls(int) thread_local_integer = 1;

    // etc...
}
*/


================================================
FILE: tinyzlib.cpp
================================================
// tiny zlib inflater. extracted from tigr (credits to Richard Mitton). @todo: remove exceptions
// - rlyeh, public domain | wtrmrkrlyeh

static bool tinyzlib(void *out, unsigned outlen, const void *in, unsigned inlen) {
    struct State {
        unsigned bits, count;
        const unsigned char *in, *inend;
        unsigned char *out, *outend;
        unsigned litcodes[288], distcodes[32], lencodes[19];
        int tlit, tdist, tlen;
    };

    // Built-in DEFLATE standard tables.
    const char order[] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
    const char lenBits[29+2] = { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,  0,0 };
    const int lenBase[29+2] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,  0,0 };
    const char distBits[30+2] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,  0,0 };
    const int distBase[30+2] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577 };

    auto emit = [](State *s, int len) -> unsigned char * {
        s->out += len;
        if(!(s->out <= s->outend)) throw;
        return s->out-len;
    };

    auto bits = [](State *s, int n) {
        int v = s->bits & ((1 << n)-1);
        s->bits >>= n;
        s->count -= n;
        while (s->count < 16) {
            if(!(s->in != s->inend)) throw;
            s->bits |= (*s->in++) << s->count;
            s->count += 8;
        }
        return v;
    };

    auto copy = [&](State *s, const unsigned char *src, int len) {
        unsigned char *dest = emit(s, len);
        while (len--) *dest++ = *src++;
    };

    auto decode = [&](State *s, unsigned tree[], int max) {
        auto rev16_src = [](unsigned n) -> unsigned {
            // Table to .
            static const unsigned char reverseTable[256] = {
            #define R2(n)    n,     n + 128,     n + 64,     n + 192
            #define R4(n) R2(n), R2(n +  32), R2(n + 16), R2(n +  48)
            #define R6(n) R4(n), R4(n +   8), R4(n +  4), R4(n +  12)
                R6(0), R6(2), R6(1), R6(3)
            };
            return (reverseTable[n&0xff] << 8) | reverseTable[(n>>8)&0xff];
        };

        auto rev16 = [](unsigned n) -> unsigned { // bit-reverse two bytes
            return (((((n   )&0xff) * 0x0202020202ULL & 0x010884422010ULL) % 1023) << 8)
                 |  ((((n>>8)&0xff) * 0x0202020202ULL & 0x010884422010ULL) % 1023);
        };

        // Find the next prefix code.
        unsigned lo = 0, hi = max, key;
        unsigned search = (rev16(s->bits) << 16) | 0xffff;
        while (lo < hi) {
            unsigned guess = (lo + hi) / 2;
            if (search < tree[guess]) hi = guess;
            else lo = guess + 1;
        }

        // Pull out the key and check it.
        key = tree[lo-1];
        if(!(((search^key) >> (32-(key&0xf))) == 0)) throw;

        bits(s, key & 0xf);
        return (key >> 4) & 0xfff;
    };

    auto build = [&](State *s, unsigned *tree, unsigned char *lens, int symcount) -> int {
        int n, codes[16], first[16], counts[16]={0};

        // Frequency count.
        for (n=0;n<symcount;n++) counts[lens[n]]++;

        // Distribute codes.
        counts[0] = codes[0] = first[0] = 0;
        for (n=1;n<=15;n++) {
            codes[n] = (codes[n-1] + counts[n-1]) << 1;
            first[n] = first[n-1] + counts[n-1];
        }
        if(!(first[15]+counts[15] <= symcount)) throw;

        // Insert keys into the tree for each symbol.
        for (n=0;n<symcount;n++) {
            int len = lens[n];
            if (len != 0) {
                int code = codes[len]++, slot = first[len]++;
                tree[slot] = (code << (32-len)) | (n << 4) | len;
            }
        }

        return first[15];
    };

    auto block = [&](State *s) {
        auto run = [&](State *s, int sym) {
            int length = bits(s, lenBits[sym]) + lenBase[sym];
            int dsym = decode(s, s->distcodes, s->tdist);
            int offs = bits(s, distBits[dsym]) + distBase[dsym];
            copy(s, s->out - offs, length);
        };
        for (;;) {
            int sym = decode(s, s->litcodes, s->tlit);
                 if (sym < 256) *emit(s, 1) = (unsigned char)sym;
            else if (sym > 256) run(s, sym-257);
            else break;
        }
    };

    auto stored = [&](State *s) { // Uncompressed data block
        int len; 
        bits(s, s->count & 7);
        len = bits(s, 16);
        if(!(((len^s->bits)&0xffff) == 0xffff)) throw;
        if(!(s->in + len <= s->inend)) throw;

        copy(s, s->in, len);
        s->in += len;
        bits(s, 16);
    };

    auto fixed = [&](State *s) { // Fixed set of Huffman codes
        int n;
        unsigned char lens[288+32];
        for (n=  0;n<=143;n++) lens[n] = 8;
        for (n=144;n<=255;n++) lens[n] = 9;
        for (n=256;n<=279;n++) lens[n] = 7;
        for (n=280;n<=287;n++) lens[n] = 8;
        for (n=0;n<32;n++) lens[288+n] = 5;

        // Build lit/dist trees.
        s->tlit  = build(s, s->litcodes, lens, 288);
        s->tdist = build(s, s->distcodes, lens+288, 32);
    };

    auto dynamic = [&](State *s) {
        int n, i, nlit, ndist, nlen;
        unsigned char lenlens[19] = {0}, lens[288+32];
        nlit = 257 + bits(s, 5);
        ndist = 1 + bits(s, 5);
        nlen = 4 + bits(s, 4);
        for (n=0;n<nlen;n++) {
            lenlens[order[n]] = (unsigned char)bits(s, 3);
        }

        // Build the tree for decoding code lengths.
        s->tlen = build(s, s->lencodes, lenlens, 19);

        // Decode code lengths.
        for (n=0;n<nlit+ndist;) {
            int sym = decode(s, s->lencodes, s->tlen);
            switch (sym) {
            case 16: for (i =  3+bits(s,2); i; i--,n++) lens[n] = lens[n-1]; break;
            case 17: for (i =  3+bits(s,3); i; i--,n++) lens[n] = 0; break;
            case 18: for (i = 11+bits(s,7); i; i--,n++) lens[n] = 0; break;
            default: lens[n++] = (unsigned char)sym; break;
            }
        }

        // Build lit/dist trees.
        s->tlit  = build(s, s->litcodes, lens, nlit);
        s->tdist = build(s, s->distcodes, lens+nlit, ndist);
    };

    struct State s0 = {}, *s = &s0;

    // We assume we can buffer 2 extra bytes from off the end of 'in'.
    s->in  = (unsigned char *)in;  s->inend  = s->in  + inlen + 2;
    s->out = (unsigned char *)out; s->outend = s->out + outlen;
    s->bits = 0; s->count = 0; bits(s, 0);

    try {
        for( int last = 0; !last;  ) {
            last = bits(s, 1);
            switch (bits(s, 2)) {
            case 0: stored(s); break;
            case 1: fixed(s); block(s); break;
            case 2: dynamic(s); block(s); break;
            case 3: return 0;
            }
        }
        return true;
    }
    catch(...) 
    {}

    return false;
}



================================================
FILE: vault/; ds
================================================



================================================
FILE: vault/_test.c
================================================
// compilation test
// - rlyeh, public domain

#define ALL_C
#include "all.c"

int main() 
{}


================================================
FILE: vault/all.c
================================================
// - rlyeh, public domain

#ifdef ALL_C
#define C_C
#define OS_C
#define DS_C
#define SYN_C
#define BIN_C
#define BUF_C
#define NET_C
#endif

#include "c.c"
#include "os.c"
#include "ds.c"
#include "syn.c"
#include "bin.c"
#include "buf.c"
#include "net.c"


================================================
FILE: vault/bin.c
================================================
// - rlyeh, public domain

#ifdef BIN_C
#define DBKV_C
#define JSON5_C
#endif

#include "os.c"
#include "bin_dbkv.c"
#include "bin_json5.c"


================================================
FILE: vault/bin_dbkv.c
================================================
// KISSDB written by Adam Ierymenko <adam.ierymenko@zerotier.com>
// KISSDB is in the public domain and is distributed with NO WARRANTY.
// http://creativecommons.org/publicdomain/zero/1.0/

#ifndef DBKV_H
#define DBKV_H
#include <stdbool.h>

#if 0
#if !defined(DBKV_LEN_KEY) && !defined(DBKV_LEN_VALUE)
// UDP packet size  576 (IPv4) = UDP payload  508 + UDP header 8 + IP header 60
// UDP packet size 1280 (IPv6) = UDP payload 1212 + UDP header 8 + IP header 60
enum {
    DBKV_HASH_BUCKET = 508 /*1024*/,
    DBKV_LEN_KEY = 31+1, /*8*/
    DBKV_LEN_VALUE = 508 - DBKV_LEN_KEY /*64*/
};
#endif
#else
enum {
    DBKV_HASH_BUCKET = 1024,
    DBKV_LEN_KEY = 8,
    DBKV_LEN_VALUE = 64
};
#endif

typedef char dbkv_key[DBKV_LEN_KEY];
typedef char dbkv_val[DBKV_LEN_VALUE];

bool dbkv_read( const char *dbfile, const char *keystr, char *val );
bool dbkv_write( const char *dbfile, const char *keystr, const char *val );

#endif

#ifdef DBKV_C
#pragma once
#include <stdint.h>
//#include "detect/detect_memory.c" // realloc

#if 1 //ndef $
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
#endif
#include <stdio.h>
#  if !defined fseeko && defined _MSC_VER // _MSC_VER
#   define fseeko _fseeki64
#   define ftello _ftelli64
#  elif !defined fseeko
#   define fseeko fseek
#   define ftello ftell
#  endif
#  if !defined fopen_s && !defined _MSC_VER
#   define fopen_s(fp,path,mode) ( (*(fp) = fopen( path, mode ) ) )
#endif
#endif

/* (Keep It) Simple Stupid Database
 *
 * Written by Adam Ierymenko <adam.ierymenko@zerotier.com>
 * KISSDB is in the public domain and is distributed with NO WARRANTY.
 * http://creativecommons.org/publicdomain/zero/1.0/
 *
 * Note: big-endian systems will need changes to implement byte swapping
 * on hash table file I/O. Or you could just use it as-is if you don't care
 * that your database files will be unreadable on little-endian systems. 
 *
 * -----
 *
 * KISSDB file format (version 2)
 * Author: Adam Ierymenko <adam.ierymenko@zerotier.com>
 * http://creativecommons.org/publicdomain/zero/1.0/
 *
 * In keeping with the goal of minimalism the file format is very simple, the
 * sort of thing that would be given as an example in an introductory course in
 * data structures. It's a basic hash table that adds additional pages of hash
 * table entries on collision.
 *
 * It consists of a 28 byte header followed by a series of hash tables and data.
 * All integer values are stored in the native word order of the target
 * architecture (in the future the code might be fixed to make everything
 * little-endian if anyone cares about that).
 *
 * The header consists of the following fields:
 *
 * [0-3]   magic numbers: (ASCII) 'K', 'd', 'B', KISSDB_VERSION (currently 2)
 * [4-11]  64-bit hash table size in entries
 * [12-19] 64-bit key size in bytes
 * [20-27] 64-bit value size in bytes
 *
 * Hash tables are arrays of [hash table size + 1] 64-bit integers. The extra
 * entry, if nonzero, is the offset in the file of the next hash table, forming
 * a linked list of hash tables across the file.
 *
 * Immediately following the header, the first hash table will be written when
 * the first key/value is added. The algorithm for adding new entries is as
 * follows:
 *
 * (1) The key is hashed using a 64-bit variant of the DJB2 hash function, and
 *     this is taken modulo hash table size to get a bucket number.
 * (2) Hash tables are checked in order, starting with the first hash table,
 *     until a zero (empty) bucket is found. If one is found, skip to step (4).
 * (3) If no empty buckets are found in any hash table, a new table is appended
 *     to the file and the final pointer in the previous hash table is set to
 *     its offset. (In the code the update of the next hash table pointer in
 *     the previous hash table happens last, after the whole write is complete,
 *     to avoid corruption on power loss.)
 * (4) The key and value are appended, in order with no additional meta-data,
 *     to the database file. Before appending the offset in the file stream
 *     where they will be stored is saved. After appending, this offset is
 *     written to the empty hash table bucket we chose in steps 2/3. Hash table
 *     updates happen last to avoid corruption if the write does not complete.
 *
 * Lookup of a key/value pair occurs as follows:
 *
 * (1) The key is hashed and taken modulo hash table size to get a bucket
 *     number.
 * (2) If this bucket's entry in the hash table is nonzero, the key at the
 *     offset specified by this bucket is compared to the key being looked up.
 *     If they are equal, the value is read and returned.
 * (3) If the keys are not equal, the next hash table is checked and step (2)
 *     is repeated. If an empty bucket is encountered or if we run out of hash
 *     tables, the key was not found.
 *
 * To update an existing value, its location is looked up and the value portion
 * of the entry is rewritten.
 */

// --- kissdb.h ---

/* (Keep It) Simple Stupid Database
 *
 * Written by Adam Ierymenko <adam.ierymenko@zerotier.com>
 * KISSDB is in the public domain and is distributed with NO WARRANTY.
 *
 * http://creativecommons.org/publicdomain/zero/1.0/ */

/**
 * Version: 2
 *
 * This is the file format identifier, and changes any time the file
 * format changes. The code version will be this dot something, and can
 * be seen in tags in the git repository.
 */
#define KISSDB_VERSION 2

/**
 * KISSDB database state
 *
 * These fields can be read by a user, e.g. to look up key_size and
 * value_size, but should never be changed.
 */
typedef struct {
    unsigned long hash_table_size;
    unsigned long key_size;
    unsigned long value_size;
    unsigned long hash_table_size_bytes;
    unsigned long num_hash_tables;
    uint64_t *hash_tables;
    FILE *f;
} KISSDB;

enum { KISSDB_ERROR_IO = -1 };                   // I/O error or file not found
enum { KISSDB_ERROR_MALLOC = -2 };               // Out of memory
enum { KISSDB_ERROR_INVALID_PARAMETERS = -3 };   // Invalid paramters (e.g. missing _size paramters on init to create database)
enum { KISSDB_ERROR_CORRUPT_DBFILE = -4 };       // Database file appears corrupt
enum { KISSDB_OPEN_MODE_RDONLY = 1 };            // Open mode: read only
enum { KISSDB_OPEN_MODE_RDWR = 2 };              // Open mode: read/write
enum { KISSDB_OPEN_MODE_RWCREAT = 3 };           // Open mode: read/write, create if doesn't exist
enum { KISSDB_OPEN_MODE_RWREPLACE = 4 };         // Open mode: truncate database, open for reading and writing

/**
 * Open database
 *
 * The three _size parameters must be specified if the database could
 * be created or re-created. Otherwise an error will occur. If the
 * database already exists, these parameters are ignored and are read
 * from the database. You can check the struture afterwords to see what
 * they were.
 *
 * @param db Database struct
 * @param path Path to file
 * @param mode One of the KISSDB_OPEN_MODE constants
 * @param hash_table_size Size of hash table in 64-bit entries (must be >0)
 * @param key_size Size of keys in bytes
 * @param value_size Size of values in bytes
 * @return 0 on success, nonzero on error
 */
static int KISSDB_open(
    KISSDB *db,
    const char *path,
    int mode,
    unsigned long hash_table_size,
    unsigned long key_size,
    unsigned long value_size);

/**
 * Close database
 *
 * @param db Database struct
 */
static void KISSDB_close(KISSDB *db);

/**
 * Get an entry
 *
 * @param db Database struct
 * @param key Key (key_size bytes)
 * @param vbuf Value buffer (value_size bytes capacity)
 * @return -1 on I/O error, 0 on success, 1 on not found
 */
static int KISSDB_get(KISSDB *db,const void *key,void *vbuf);

/**
 * Put an entry (overwriting it if it already exists)
 *
 * In the already-exists case the size of the database file does not
 * change.
 *
 * @param db Database struct
 * @param key Key (key_size bytes)
 * @param value Value (value_size bytes)
 * @return -1 on I/O error, 0 on success
 */
static int KISSDB_put(KISSDB *db,const void *key,const void *value);

/**
 * Cursor used for iterating over all entries in database
 */
typedef struct {
    KISSDB *db;
    unsigned long h_no;
    unsigned long h_idx;
} KISSDB_Iterator;

/**
 * Initialize an iterator
 *
 * @param db Database struct
 * @param i Iterator to initialize
 */
static void KISSDB_Iterator_init(KISSDB *db,KISSDB_Iterator *dbi);

/**
 * Get the next entry
 *
 * The order of entries returned by iterator is undefined. It depends on
 * how keys hash.
 *
 * @param Database iterator
 * @param kbuf Buffer to fill with next key (key_size bytes)
 * @param vbuf Buffer to fill with next value (value_size bytes)
 * @return 0 if there are no more entries, negative on error, positive if an kbuf/vbuf have been filled
 */
static int KISSDB_Iterator_next(KISSDB_Iterator *dbi,void *kbuf,void *vbuf);

// --- kissdb.c ---

#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#define KISSDB_HEADER_SIZE ((sizeof(uint64_t) * 3) + 4)

/* djb2 hash function */
static uint64_t KISSDB_hash(const void *b,unsigned long len)
{
    unsigned long i;
    uint64_t hash = 5381;
    for(i=0;i<len;++i)
        hash = ((hash << 5) + hash) + (uint64_t)(((const uint8_t *)b)[i]);
    return hash;
}

static int KISSDB_open(
    KISSDB *db,
    const char *path,
    int mode,
    unsigned long hash_table_size,
    unsigned long key_size,
    unsigned long value_size)
{
    uint64_t tmp;
    uint8_t tmp2[4];
    uint64_t *httmp;
    uint64_t *hash_tables_rea;

    db->f = (FILE *)0;
    fopen_s(&db->f,path,((mode == KISSDB_OPEN_MODE_RWREPLACE) ? "w+b" : (((mode == KISSDB_OPEN_MODE_RDWR)||(mode == KISSDB_OPEN_MODE_RWCREAT)) ? "r+b" : "rb")));
    if (!db->f) {
        if (mode == KISSDB_OPEN_MODE_RWCREAT) {
            db->f = (FILE *)0;
            fopen_s(&db->f,path,"w+b");
        }
        if (!db->f)
            return KISSDB_ERROR_IO;
    }

    if (fseeko(db->f,0,SEEK_END)) {
        fclose(db->f);
        return KISSDB_ERROR_IO;
    }
    if (ftello(db->f) < KISSDB_HEADER_SIZE) {
        /* write header if not already present */
        if ((hash_table_size)&&(key_size)&&(value_size)) {
            if (fseeko(db->f,0,SEEK_SET)) { fclose(db->f); return KISSDB_ERROR_IO; }
            tmp2[0] = 'K'; tmp2[1] = 'd'; tmp2[2] = 'B'; tmp2[3] = KISSDB_VERSION;
            if (fwrite(tmp2,4,1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
            tmp = hash_table_size;
            if (fwrite(&tmp,sizeof(uint64_t),1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
            tmp = key_size;
            if (fwrite(&tmp,sizeof(uint64_t),1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
            tmp = value_size;
            if (fwrite(&tmp,sizeof(uint64_t),1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
            fflush(db->f);
        } else {
            fclose(db->f);
            return KISSDB_ERROR_INVALID_PARAMETERS;
        }
    } else {
        if (fseeko(db->f,0,SEEK_SET)) { fclose(db->f); return KISSDB_ERROR_IO; }
        if (fread(tmp2,4,1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
        if ((tmp2[0] != 'K')||(tmp2[1] != 'd')||(tmp2[2] != 'B')||(tmp2[3] != KISSDB_VERSION)) {
            fclose(db->f);
            return KISSDB_ERROR_CORRUPT_DBFILE;
        }
        if (fread(&tmp,sizeof(uint64_t),1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
        if (!tmp) {
            fclose(db->f);
            return KISSDB_ERROR_CORRUPT_DBFILE;
        }
        hash_table_size = (unsigned long)tmp;
        if (fread(&tmp,sizeof(uint64_t),1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
        if (!tmp) {
            fclose(db->f);
            return KISSDB_ERROR_CORRUPT_DBFILE;
        }
        key_size = (unsigned long)tmp;
        if (fread(&tmp,sizeof(uint64_t),1,db->f) != 1) { fclose(db->f); return KISSDB_ERROR_IO; }
        if (!tmp) {
            fclose(db->f);
            return KISSDB_ERROR_CORRUPT_DBFILE;
        }
        value_size = (unsigned long)tmp;
    }

    db->hash_table_size = hash_table_size;
    db->key_size = key_size;
    db->value_size = value_size;
    db->hash_table_size_bytes = sizeof(uint64_t) * (hash_table_size + 1); /* [hash_table_size] == next table */

    httmp = MALLOC(db->hash_table_size_bytes);
    if (!httmp) {
        fclose(db->f);
        return KISSDB_ERROR_MALLOC;
    }
    db->num_hash_tables = 0;
    db->hash_tables = (uint64_t *)0;
    while (fread(httmp,db->hash_table_size_bytes,1,db->f) == 1) {
        hash_tables_rea = REALLOC(db->hash_tables,db->hash_table_size_bytes * (db->num_hash_tables + 1));
        if (!hash_tables_rea) {
            KISSDB_close(db);
            FREE(httmp);
            return KISSDB_ERROR_MALLOC;
        }
        db->hash_tables = hash_tables_rea;

        memcpy(((uint8_t *)db->hash_tables) + (db->hash_table_size_bytes * db->num_hash_tables),httmp,db->hash_table_size_bytes);
        ++db->num_hash_tables;
        if (httmp[db->hash_table_size]) {
            if (fseeko(db->f,httmp[db->hash_table_size],SEEK_SET)) {
                KISSDB_close(db);
                FREE(httmp);
                return KISSDB_ERROR_IO;
            }
        } else break;
    }
    FREE(httmp);

    return 0;
}

static void KISSDB_close(KISSDB *db)
{
    if (db->hash_tables)
        FREE(db->hash_tables);
    if (db->f)
        fclose(db->f);
    memset(db,0,sizeof(KISSDB));
}

static int KISSDB_get(KISSDB *db,const void *key,void *vbuf)
{
    uint8_t tmp[4096];
    const uint8_t *kptr;
    unsigned long klen,i;
    uint64_t hash = KISSDB_hash(key,db->key_size) % (uint64_t)db->hash_table_size;
    uint64_t offset;
    uint64_t *cur_hash_table;
    long n;

    cur_hash_table = db->hash_tables;
    for(i=0;i<db->num_hash_tables;++i) {
        offset = cur_hash_table[hash];
        if (offset) {
            if (fseeko(db->f,offset,SEEK_SET))
                return KISSDB_ERROR_IO;

            kptr = (const uint8_t *)key;
            klen = db->key_size;
            while (klen) {
                n = (long)fread(tmp,1,(klen > sizeof(tmp)) ? sizeof(tmp) : klen,db->f);
                if (n > 0) {
                    if (memcmp(kptr,tmp,n))
                        goto get_no_match_next_hash_table;
                    kptr += n;
                    klen -= (unsigned long)n;
                } else return 1; /* not found */
            }

            if (fread(vbuf,db->value_size,1,db->f) == 1)
                return 0; /* success */
            else return KISSDB_ERROR_IO;
        } else return 1; /* not found */
get_no_match_next_hash_table:
        cur_hash_table += db->hash_table_size + 1;
    }

    return 1; /* not found */
}

static int KISSDB_put(KISSDB *db,const void *key,const void *value)
{
    uint8_t tmp[4096];
    const uint8_t *kptr;
    unsigned long klen,i;
    uint64_t hash = KISSDB_hash(key,db->key_size) % (uint64_t)db->hash_table_size;
    uint64_t offset;
    uint64_t htoffset,lasthtoffset;
    uint64_t endoffset;
    uint64_t *cur_hash_table;
    uint64_t *hash_tables_rea;
    long n;

    lasthtoffset = htoffset = KISSDB_HEADER_SIZE;
    cur_hash_table = db->hash_tables;
    for(i=0;i<db->num_hash_tables;++i) {
        offset = cur_hash_table[hash];
        if (offset) {
            /* rewrite if already exists */
            if (fseeko(db->f,offset,SEEK_SET))
                return KISSDB_ERROR_IO;

            kptr = (const uint8_t *)key;
            klen = db->key_size;
            while (klen) {
                n = (long)fread(tmp,1,(klen > sizeof(tmp)) ? sizeof(tmp) : klen,db->f);
                if (n > 0) {
                    if (memcmp(kptr,tmp,n))
                        goto put_no_match_next_hash_table;
                    kptr += n;
                    klen -= (unsigned long)n;
                }
            }

            /* C99 spec demands seek after fread(), required for Windows */
            fseeko(db->f,0,SEEK_CUR);
 
            if (fwrite(value,db->value_size,1,db->f) == 1) {
                fflush(db->f);
                return 0; /* success */
            } else return KISSDB_ERROR_IO;
        } else {
            /* add if an empty hash table slot is discovered */
            if (fseeko(db->f,0,SEEK_END))
                return KISSDB_ERROR_IO;
            endoffset = ftello(db->f);

            if (fwrite(key,db->key_size,1,db->f) != 1)
                return KISSDB_ERROR_IO;
            if (fwrite(value,db->value_size,1,db->f) != 1)
                return KISSDB_ERROR_IO;

            if (fseeko(db->f,htoffset + (sizeof(uint64_t) * hash),SEEK_SET))
                return KISSDB_ERROR_IO;
            if (fwrite(&endoffset,sizeof(uint64_t),1,db->f) != 1)
                return KISSDB_ERROR_IO;
            cur_hash_table[hash] = endoffset;

            fflush(db->f);

            return 0; /* success */
        }
put_no_match_next_hash_table:
        lasthtoffset = htoffset;
        htoffset = cur_hash_table[db->hash_table_size];
        cur_hash_table += (db->hash_table_size + 1);
    }

    /* if no existing slots, add a new page of hash table entries */
    if (fseeko(db->f,0,SEEK_END))
        return KISSDB_ERROR_IO;
    endoffset = ftello(db->f);

    hash_tables_rea = REALLOC(db->hash_tables,db->hash_table_size_bytes * (db->num_hash_tables + 1));
    if (!hash_tables_rea)
        return KISSDB_ERROR_MALLOC;
    db->hash_tables = hash_tables_rea;
    cur_hash_table = &(db->hash_tables[(db->hash_table_size + 1) * db->num_hash_tables]);
    memset(cur_hash_table,0,db->hash_table_size_bytes);

    cur_hash_table[hash] = endoffset + db->hash_table_size_bytes; /* where new entry will go */

    if (fwrite(cur_hash_table,db->hash_table_size_bytes,1,db->f) != 1)
        return KISSDB_ERROR_IO;

    if (fwrite(key,db->key_size,1,db->f) != 1)
        return KISSDB_ERROR_IO;
    if (fwrite(value,db->value_size,1,db->f) != 1)
        return KISSDB_ERROR_IO;

    if (db->num_hash_tables) {
        if (fseeko(db->f,lasthtoffset + (sizeof(uint64_t) * db->hash_table_size),SEEK_SET))
            return KISSDB_ERROR_IO;
        if (fwrite(&endoffset,sizeof(uint64_t),1,db->f) != 1)
            return KISSDB_ERROR_IO;
        db->hash_tables[((db->hash_table_size + 1) * (db->num_hash_tables - 1)) + db->hash_table_size] = endoffset;
    }

    ++db->num_hash_tables;

    fflush(db->f);

    return 0; /* success */
}

static void KISSDB_Iterator_init(KISSDB *db,KISSDB_Iterator *dbi)
{
    dbi->db = db;
    dbi->h_no = 0;
    dbi->h_idx = 0;
}

static int KISSDB_Iterator_next(KISSDB_Iterator *dbi,void *kbuf,void *vbuf)
{
    uint64_t offset;

    if ((dbi->h_no < dbi->db->num_hash_tables)&&(dbi->h_idx < dbi->db->hash_table_size)) {
        while (!(offset = dbi->db->hash_tables[((dbi->db->hash_table_size + 1) * dbi->h_no) + dbi->h_idx])) {
            if (++dbi->h_idx >= dbi->db->hash_table_size) {
                dbi->h_idx = 0;
                if (++dbi->h_no >= dbi->db->num_hash_tables)
                    return 0;
            }
        }
        if (fseeko(dbi->db->f,offset,SEEK_SET))
            return KISSDB_ERROR_IO;
        if (fread(kbuf,dbi->db->key_size,1,dbi->db->f) != 1)
            return KISSDB_ERROR_IO;
        if (fread(vbuf,dbi->db->value_size,1,dbi->db->f) != 1)
            return KISSDB_ERROR_IO;
        if (++dbi->h_idx >= dbi->db->hash_table_size) {
            dbi->h_idx = 0;
            ++dbi->h_no;
        }
        return 1;
    }

    return 0;
}

#endif

#ifdef DBKV_BENCH
#include <time.h>
#include <inttypes.h>

#ifdef _MSC_VER
#include <omp.h>
#define clock_t double
#define clock omp_get_wtime
#undef CLOCKS_PER_SEC
#define CLOCKS_PER_SEC 1.0
#endif

int main(int argc,char **argv)
{
    #ifndef N
    enum { N = 100000 };
    #endif
    uint64_t i,j;
    uint64_t v[8];
    KISSDB db;
    KISSDB_Iterator dbi;
    char *got_all_values = malloc(N);
    int q;

    clock_t begin, end;

    #ifdef STDIO2
    if( argc < 2 ) {
        printf("%s [file.db]\n", argv[0]);
        printf("%s [mem://file.db]\n", argv[0]);
        exit(0);
    }
    const char *dbfile = argv[1];
    #else
    const char *dbfile = "test.db";
    #endif

    begin = clock();

    printf("Opening new empty database %s...\n", dbfile);
    if (KISSDB_open(&db,dbfile,KISSDB_OPEN_MODE_RWREPLACE,1024,8,sizeof(v))) {
        printf("KISSDB_open failed\n");
        return 1;
    }

    end = clock();
    {
        double sec = (end - begin)/(double)CLOCKS_PER_SEC;
        printf("OK! %5.2fs\n", sec);
    }
    begin = clock();

    printf("Putting %d 64-byte values...\n", N);
    for(i=0;i<N;++i) {
        for(j=0;j<8;++j)
            v[j] = i;
        if (KISSDB_put(&db,&i,v)) {
            printf("KISSDB_put failed (%"PRIu64")\n",i);
            return 1;
        }
    }

    end = clock();
    {
        int ops = N;
        double sec = (end - begin)/(double)CLOCKS_PER_SEC;
        printf("OK! %d ops in %5.2fs, %5.2fops/s, %5.2fops/frame\n", ops, sec, ops/sec, ops/sec/60);
    }
    begin = clock();

    printf("Getting %d 64-byte values...\n", N);
    for(i=0;i<N;++i) {
        if ((q = KISSDB_get(&db,&i,v))) {
            printf("KISSDB_get (2) failed (%"PRIu64") (%d)\n",i,q);
            return 1;
        }
        for(j=0;j<8;++j) {
            if (v[j] != i) {
                printf("KISSDB_get (2) failed, bad data (%"PRIu64")\n",i);
                return 1;
            }
        }
    }

    end = clock();
    {
        int ops = N;
        double sec = (end - begin)/(double)CLOCKS_PER_SEC;
        printf("OK! %d ops in %5.2fs, %5.2fops/s, %5.2fops/frame\n", ops, sec, ops/sec, ops/sec/60);
    }
    begin = clock();

    printf("Closing and re-opening database in read-only mode...\n");
    KISSDB_close(&db);
    if (KISSDB_open(&db,dbfile,KISSDB_OPEN_MODE_RDONLY,1024,8,sizeof(v))) {
        printf("KISSDB_open failed\n");
        return 1;
    }

    end = clock();
    {
        double sec = (end - begin)/(double)CLOCKS_PER_SEC;
        printf("OK! %5.2fs\n", sec);
    }
    begin = clock();

    printf("Getting %d 64-byte values...\n", N);
    for(i=0;i<N;++i) {
        if ((q = KISSDB_get(&db,&i,v))) {
            printf("KISSDB_get (3) failed (%"PRIu64") (%d)\n",i,q);
            return 1;
        }
        for(j=0;j<8;++j) {
            if (v[j] != i) {
                printf("KISSDB_get (3) failed, bad data (%"PRIu64")\n",i);
                return 1;
            }
        }
    }

    end = clock();
    {
        int ops = N;
        double sec = (end - begin)/(double)CLOCKS_PER_SEC;
        printf("OK! %d ops in %5.2fs, %5.2fops/s, %5.2fops/frame\n", ops, sec, ops/sec, ops/sec/60);
    }
    begin = clock();

    printf("Iterating %d 64-byte values...\n", N);
    KISSDB_Iterator_init(&db,&dbi);
    i = 0xdeadbeef;
    memset(got_all_values,0,sizeof(N));
    while (KISSDB_Iterator_next(&dbi,&i,&v) > 0) {
        if (i < N)
            got_all_values[i] = 1;
        else {
            printf("KISSDB_Iterator_next failed, bad data (%"PRIu64")\n",i);
            return 1;
        }
    }
    for(i=0;i<N;++i) {
        if (!got_all_values[i]) {
            printf("KISSDB_Iterator failed, missing value index %"PRIu64"\n",i);
            return 1;
        }
    }

    KISSDB_close(&db);

    end = clock();
    {
        int ops = N;
        double sec = (end - begin)/(double)CLOCKS_PER_SEC;
        printf("OK! %d ops in %5.2fs, %5.2fops/s, %5.2fops/frame\n", ops, sec, ops/sec, ops/sec/60);
    }
    begin = clock();

    return 0;
}
#define main main__
#endif

#ifdef DBKV_C
#pragma once
bool dbkv_read( const char *dbfile, const char *keystr, char *val ) {
    KISSDB kdb = {0};
    int ok = 0 == KISSDB_open( &kdb, dbfile, KISSDB_OPEN_MODE_RWCREAT, DBKV_HASH_BUCKET, DBKV_LEN_KEY, DBKV_LEN_VALUE);
    if( ok ) {
        dbkv_key key = {0};
        strcpy( key, keystr ); //sprintf(key, "%.*s", strlen(keystr) > DBKV_LEN_KEY ? DBKV_LEN_KEY : strlen(keystr), keystr);

        int result = KISSDB_get( &kdb, key, val ), not_found = result > 0; // -1:I/O error, 0:ok, 1:not found
        ok = result >= 0; //printf("rd %s=%s (found: %d) (rc: %d)\n", key, val, !not_found, result);

        KISSDB_close( &kdb );
    }
    return !!ok;
}
bool dbkv_write( const char *dbfile, const char *keystr, const char *val ) {
    KISSDB kdb = {0};
    int ok = 0 == KISSDB_open( &kdb, dbfile, KISSDB_OPEN_MODE_RWCREAT, DBKV_HASH_BUCKET, DBKV_LEN_KEY, DBKV_LEN_VALUE);
    if( ok ) {
        dbkv_key key = {0};
        strcpy( key, keystr ); //sprintf(key, "%.*s", strlen(keystr) > DBKV_LEN_KEY ? DBKV_LEN_KEY : strlen(keystr), keystr);

        int result = KISSDB_put( &kdb, key, val ); // -1:I/O error, 0:ok
        ok = result >= 0; //printf("wr (rc: %d)\n", result);

        KISSDB_close( &kdb );
    }
    return !!ok;
}

#ifdef DBKV_DEMO
#include <stdio.h>
int main( int argc, char **argv ) {
    dbkv_val val = "0"; // default value, if not found
    dbkv_read( "db.kvs", "/hello", val );

    printf("/hello=%s\n", val);

    val[0] ++; if( val[0] > '9' ) val[0] = '0';
    dbkv_write( "db.kvs", "/hello", val );
}
#define main main__
#endif // KBDV_DEMO
#endif // KBDV_C



================================================
FILE: vault/bin_json5.c
================================================
// JSON5 + SJSON parser module
//
// License:
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
// No warranty is implied, use at your own risk.
//
// Credits:
// Dominik Madarasz (original code) (GitHub: zaklaus)
// r-lyeh (fork)

#ifndef JSON5_H
#define JSON5_H

#ifndef JSON5_ASSERT
#define JSON5_ASSERT do { printf("JSON5: Error L%d while parsing '%c' in '%.16s'\n", __LINE__, p[0], p); assert(0); } while(0)
#endif

#include <stdint.h>
#include <stdio.h>

typedef enum json5_type {
    json5_undefined, // 0
    json5_null,      // 1
    json5_bool,      // 2
    json5_object,    // 3
    json5_string,    // 4
    json5_array,     // 5
    json5_integer,   // 6
    json5_real,      // 7
} json5_type;

typedef struct json5 {
    char*      name;
#ifdef NDEBUG
    unsigned   type : 3;
#else
    json5_type type;
#endif
    unsigned   count : 29;
    union {
        struct json5* array;
        struct json5* nodes;
        int64_t   integer;
        double    real;
        char*     string;
        int       boolean;
    };
} json5;

char* json5_parse(json5 *root, char *source, int flags);
void  json5_write(FILE *fp, const json5 *root);
void  json5_free(json5 *root);

#endif // JSON5_H

// json5 ----------------------------------------------------------------------

#ifdef JSON5_C
#pragma once
#include <assert.h>
#include <ctype.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>

char *json5__trim(char *p) {
    while (*p) {
        /**/ if( isspace(*p) ) ++p;
        else if( p[0] == '/' && p[1] == '*' ) { // skip C comment
            for( p += 2; *p && !(p[0] == '*' && p[1] == '/'); ++p) {}
            if( *p ) p += 2;
        }
        else if( p[0] == '/' && p[1] == '/' ) { // skip C++ comment
            for( p += 2; *p && p[0] != '\n'; ++p) {}
            if( *p ) ++p;
        }
        else break;
    }
    return p;
}

char *json5__parse_value(json5 *obj, char *p, char **err_code);

char *json5__parse_string(json5 *obj, char *p, char **err_code) {
    assert(obj && p);

    if( *p == '"' || *p == '\'' || *p == '`' ) {
        obj->type = json5_string;
        obj->string = p + 1;

        char eos_char = *p, *b = obj->string, *e = b;
        while (*e) {
            /**/ if( *e == '\\' && (e[1] == eos_char) ) ++e;
            else if( *e == '\\' && (e[1] == '\r' || e[1] == '\n') ) *e = ' ';
            else if( *e == eos_char ) break;
            ++e;
        }

        *e = '\0';
        return p = e + 1;
    }

    //JSON5_ASSERT; *err_code = "json5_error_invalid_value";
    return NULL;
}

char *json5__parse_object(json5 *obj, char *p, char **err_code) {
    assert(obj && p);

    if( 1 /* *p == '{' */ ) { /* <-- for SJSON */
        int skip = *p == '{'; /* <-- for SJSON */

        obj->type = json5_object;
        obj->nodes = 0;
        obj->count = 0;

        while (*p) {
            json5 node = { 0 };
            
            do { p = json5__trim(p + skip); skip = 1; } while( *p == ',' );

            if( *p == '}' ) {
                ++p;
                break;
            }
            // @todo: is_unicode() (s[0] == '\\' && isxdigit(s[1]) && isxdigit(s[2]) && isxdigit(s[3]) && isxdigit(s[4]))) {
            else if( isalpha(*p) || *p == '_' || *p == '$' ) { // also || is_unicode(p)
                node.name = p;

                do {
                    ++p;
                } while (*p && (*p == '_' || isalpha(*p) || isdigit(*p)) ); // also || is_unicode(p)

                char *e = p;
                p = json5__trim(p);
                *e = '\0';
            }
            else { //if( *p == '"' || *p == '\'' || *p == '`' ) {
                char *ps = json5__parse_string(&node, p, err_code);
                if( !ps ) {
                    return NULL;
                }
                p = ps;
                node.name = node.string;
                p = json5__trim(p);
            }

            // @todo: https://www.ecma-international.org/ecma-262/5.1/#sec-7.6
            if( !(node.name && node.name[0]) ) { // !json5__validate_name(node.name) ) {
                JSON5_ASSERT; *err_code = "json5_error_invalid_name";
                return NULL;
            }

            if( !p || (*p && (*p != ':' && *p != '=' /* <-- for SJSON */)) ) {
                JSON5_ASSERT; *err_code = "json5_error_invalid_name";
                return NULL;
            }
            p = json5__trim(p + 1);
            p = json5__parse_value(&node, p, err_code);

            if( *err_code[0] ) {
                return NULL;
            }

            if( node.type != json5_undefined ) {
                array_push(obj->nodes, node);
                ++obj->count;
            }

            if( *p == '}') { ++p; break; }
        }

        return p;
    }

    JSON5_ASSERT; *err_code = "json5_error_invalid_value";
    return NULL;
}

char *json5__parse_value(json5 *obj, char *p, char **err_code) {
    assert(obj && p);

    p = json5__trim(p);

    char *is_string = json5__parse_string(obj, p, err_code);

    if( is_string ) {
        p = is_string;
        if( *err_code[0] ) {
            return NULL;
        }
    }
    else if( *p == '{' ) {
        p = json5__parse_object( obj, p, err_code );
        if( *err_code[0] ) {
            return NULL;
        }
    }
    else if( *p == '[' ) {
        obj->type = json5_array;
        obj->array = 0;
        obj->count = 0;

        while (*p) {
            json5 elem = { 0 };

            do { p = json5__trim(p + 1); } while( *p == ',' );
            if( *p == ']') { ++p; break; }

            p = json5__parse_value(&elem, p, err_code);

            if( *err_code[0] ) {
                return NULL;
            }

            if( elem.type != json5_undefined ) {
                array_push(obj->array, elem);
                ++obj->count;
            }
            if (*p == ']') { ++p; break; }
        }
    }
    else if( isalpha(*p) || (*p == '-' && !isdigit(p[1])) ) {
        const char *labels[] = { "null", "on","true", "off","false", "nan","NaN", "-nan","-NaN", "inf","Infinity", "-inf","-Infinity" };
        const int lenghts[] = { 4, 2,4, 3,5, 3,3, 4,4, 3,8, 4,9 };
        for( int i = 0; labels[i]; ++i ) {
            if( !strncmp(p, labels[i], lenghts[i] ) ) {
                p += lenghts[i];
#ifdef _MSC_VER // somehow, NaN is apparently signed in MSC
                /**/ if( i >= 5 ) obj->type = json5_real, obj->real = i >= 11 ? -INFINITY : i >= 9 ? INFINITY : i >= 7 ?  NAN :-NAN;
#else
                /**/ if( i >= 5 ) obj->type = json5_real, obj->real = i >= 11 ? -INFINITY : i >= 9 ? INFINITY : i >= 7 ? -NAN : NAN;
#endif
                else if( i >= 1 ) obj->type = json5_bool, obj->boolean = i <= 2;
                else              obj->type = json5_null;
                break;
            }
        }
        if( obj->type == json5_undefined ) {
            JSON5_ASSERT; *err_code = "json5_error_invalid_value";
            return NULL;
        }
    }
    else if( isdigit(*p) || *p == '+' || *p == '-' || *p == '.' ) {
        char buffer[32] = {0}, *buf = buffer, is_hex = 0, is_dbl = 0;
        while( *p && strchr("+-.xX0123456789aAbBcCdDeEfF", *p)) {
            is_hex |= (*p | 32) == 'x';
            is_dbl |= *p == '.';
            *buf++ = *p++;
        }
        obj->type = is_dbl ? json5_real : json5_integer;
        /**/ if( is_dbl ) sscanf( buffer, "%lf", &obj->real );
        else if( is_hex ) sscanf( buffer, "%llx", &obj->integer ); // SCNx64 -> inttypes.h
        else              sscanf( buffer, "%lld", &obj->integer ); // SCNd64 -> inttypes.h
    }
    else {
        return NULL;
    }
    return p;
}

char *json5_parse(json5 *root, char *p, int flags) {
    char *err_code = "";
    *root = (json5) {0};

    if( p && p[0] ) {
        p = json5__trim(p);
        if( *p == '[' ) { /* <-- for SJSON */
            json5__parse_value(root, p, &err_code);
        } else {
            json5__parse_object(root, p, &err_code); /* <-- for SJSON */
        }
    } else {
        root->type = json5_object;
    }

    return err_code[0] ? err_code : 0;
}

void json5_free(json5 *root) {
    if( root->type == json5_array && root->array ) {
        for( int i = 0, cnt = array_count(root->array); i < cnt; ++i ) {
            json5_free(root->array + i);
        }
        array_free(root->array);
    } 

    if( root->type == json5_object && root->nodes ) {
        for( int i = 0, cnt = array_count(root->nodes); i < cnt; ++i ) {
            json5_free(root->nodes + i);
        }
        array_free(root->nodes);
    }

    *root = (json5) {0}; // needed?
}

void json5_write(FILE *fp, const json5 *o) {
#ifdef _MSC_VER
    static __declspec(thread) int indent = 0;
#else
    static __thread int indent = 0;
#endif
    int tabs = 1; // 0,1,2,4,8
    if( o->name ) {
        fprintf(fp, "%*.s\"%s\"%s", indent * tabs, "", o->name, tabs ? ": " : ":");
    }
    /**/ if( o->type == json5_null ) fprintf(fp, "%s", "null");
    else if( o->type == json5_bool ) fprintf(fp, "%s", o->boolean ? "true" : "false");
    else if( o->type == json5_integer ) fprintf(fp, "%lld", o->integer);
    else if( o->type == json5_real ) {
        /**/ if( isnan(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-nan" : "nan" );
        else if( isinf(o->real) ) fprintf(fp, "%s", signbit(o->real) ? "-inf" : "inf" );
        else fprintf(fp, "%1.8e", o->real); // %1.8e from google:"randomascii 100 digits" ; %.4llf for compactness
    }
    #if 0
    else if( o->type == json5_string ) { // write (escaped) string
        char chars[] = "\\\"\n\r\b\f\v", remap[] = "\\\"nrbfv", esc[256];
        for( int i = 0; chars[i]; ++i ) esc[ chars[i] ] = remap[i];

        const char *b = o->string, *e = strpbrk(b, chars), *sep = "\"";
        while( e ) {
            fprintf(fp, "%s%.*s\\%c", sep, (int)(e - b), b, esc[(unsigned char)*e] );
            e = strpbrk( b = e + 1, chars);
            sep = "";
        }
        fprintf(fp, "%s%s\"", sep, b);
    }
    #else
    else if( o->type == json5_string ) { // write string
        fprintf(fp, "\"%s\"", o->string);
    }
    #endif
    else if( o->type == json5_array ) {
        const char *sep = "";
        fprintf(fp, "%s", tabs ? "[ " : "[");
        for( int i = 0, cnt = o->count; i < cnt; ++i ) {
            fprintf(fp, "%s", sep); sep = tabs ? ", " : ",";
            json5_write(fp, o->array + i);
        }
        fprintf(fp, "%s", tabs ? " ]" : "]");
    }
    else if( o->type == json5_object ) {
        const char *sep = "";
        fprintf(fp, "%*.s{%s", 0 * (++indent) * tabs, "", tabs ? "\n":"");
        for( int i = 0, cnt = o->count; i < cnt; ++i ) {
            fprintf(fp, "%s", sep); sep = tabs ? ",\n" : ",";
            json5_write(fp, o->nodes + i);
        }
        fprintf(fp, "%s%*.s}", tabs ? "\n":"", (--indent) * tabs, "");
    } else {
        char p[16] = {0};
        JSON5_ASSERT; /* "json5_error_invalid_value"; */
    }
}

#endif // JSON5_C

#ifdef JSON5_BENCH
#include <time.h>

int main() {
    // https://www.reddit.com/r/datasets/comments/1uyd0t/200000_jeopardy_questions_in_a_json_file/
    char *content = 0;
    for( FILE *fp = fopen("jeopardy.json", "rb"); fp; fclose(fp), fp = 0 ) {
        fseek(fp, 0L, SEEK_END);
        size_t pos = ftell(fp);
        fseek(fp, 0L, SEEK_SET);
        content = (char*)malloc( pos + 1 );
        fread(content, 1, pos, fp);
        content[pos] = 0;
    }

    if( content ) {
        clock_t start = clock();
        json5 root = {0};
        char *error = json5_parse(&root, content, 0);
        clock_t end = clock();
        double delta = ( end - start ) / (double)CLOCKS_PER_SEC;

        if( !error ) {
            printf("Parsing time: %.3fms\n", delta*1000);
            printf("Total nodes: %d\n", array_count(root.array));
            printf("Category: %s, air date: %s\nQuestion: %s\n", root.array[0].nodes[0].string,
                   root.array[0].nodes[1].string,
                   root.array[0].nodes[2].string);
        } else {
            printf("Error: %s\n", error);
        }

        json5_free(&root);
        free(content);
    }
}
#endif

#ifdef JSON5_DEMO
int main() {
    char source5[] = 
    "  // comments\n" /* json5 sample */
    "  unquoted: 'and you can quote me on that',\n"
    "  singleQuotes: 'I can use \"double quotes\" here',\n"
    "  lineBreaks : \"Look, Mom! \\\n"
    "No \\n's!\",\n"
    "  hexadecimal: 0x100,\n"
    "  leadingDecimalPoint: .8675309, andTrailing: 8675309.,\n"
    "  positiveSign: +1,\n"
    "  trailingComma: 'in objects', andIn: ['arrays', ],\n"
    "  \"backwardsCompatible\": \"with JSON\",\n"
    ""
    "  ip = \"127.0.0.1\"\n" /* sjson sample */
    "  port = 8888\n"
    ""
    "  /* comment //nested comment*/\n" /* tests */
    "  // comment /*nested comment*/\n"
    "  nil: null,"
    "  \"+lšctžýáíé=:\": true,,,,"
    "  huge: 2.2239333e5, "
    "  array: [+1,2,-3,4,5],    "
    "  hello: 'world /*comment in string*/ //again', "
    "  abc: 42.67, def: false, "
    "  children : { a: 1, b: 2, },"
    "  invalids : [ nan, NaN, -nan, -NaN, inf, Infinity, -inf, -Infinity ],"
    ""
    "  multiline: `this is\n"
    "a multiline string\n"
    "yeah`"
    "}\n";

    json5 root = { 0 };
    char *error = json5_parse(&root, source5, 0);
    if( error ) {
        printf("Error: %s\n", error);
    } else {
        json5_write(stdout, &root);
    }
    json5_free(&root);
}
#endif


================================================
FILE: vault/buf.c
================================================
// - rlyeh, public domain

#ifdef BUF_C
#define ARC4_C
#define BASE64_C
#define BASE92_C
#define COBS_C
#define CRC_C
#define ENDIAN_C
#define INTERLEAVE_C
#define NETSTRING_C
#define ZIGZAG_C
#define PACK_C
#define HALF_C
#endif

#include "os.c"
#include "buf_arc4.c"        // buffer_crypt_arc4
#include "buf_base64.c"      // buffer_rebase_base64
#include "buf_base92.c"      // buffer_rebase_base92
#include "buf_cobs.c"        // buffer_rebase_cobs
#include "buf_crc.c"         // buffer_checksum_crc
#include "buf_endian.c"      // buffer_utils_endianness
#include "buf_interleave.c"  // buffer_utils_interleave
#include "buf_netstring.c"   // buffer_escape_netstring
#include "buf_zigzag.c"      // buffer_utils_zigzag

#include "buf_packint.h"     // integer packing
#include "buf_packvli.h"     // variable int packing
#include "buf_pack754.h"     // float754 packing
#include "buf_packhalf.h"    // floathalf packing
#include "buf_pack.c"        // data packer


================================================
FILE: vault/buf_arc4.c
================================================
// ARC4 de/cryptor. Based on code by Mike Shaffer.
// - rlyeh, public domain.

void *arc4( void *buffer, unsigned buflen, const void *pass, unsigned passlen );

#ifdef ARC4_C
#pragma once
#include <assert.h>

void *arc4( void *buf_, unsigned buflen, const void *pass_, unsigned passlen ) {
    // [ref] http://www.4guysfromrolla.com/webtech/code/rc4.inc.html
    assert(passlen);
    int sbox[256], key[256];
    char *buf = (char*)buf_;
    const char *pass = (const char*)pass_;
    for( unsigned a = 0; a < 256; a++ ) {
        key[a] = pass[a % passlen];
        sbox[a] = a;
    }
    for( unsigned a = 0, b = 0; a < 256; a++ ) {
        b = (b + sbox[a] + key[a]) % 256;
        int swap = sbox[a]; sbox[a] = sbox[b]; sbox[b] = swap;
    }
    for( unsigned a = 0, b = 0, i = 0; i < buflen; ++i ) {
        a = (a + 1) % 256;
        b = (b + sbox[a]) % 256;
        int swap = sbox[a]; sbox[a] = sbox[b]; sbox[b] = swap;
        buf[i] ^= sbox[(sbox[a] + sbox[b]) % 256];
    }
    return buf_;
}

#ifdef ARC4_DEMO
#include <stdio.h>
#include <string.h>
int main( int argc, char **argv ) {
    char buffer[] = "Hello world."; int buflen = strlen(buffer);
    char *password = argc > 1 ? argv[1] : "abc123"; int passlen = strlen(password);

    printf("Original: %s\n", buffer);
    printf("Password: %s\n", password);

    char *encrypted = arc4( buffer, buflen, password, passlen );
    printf("ARC4 Encrypted text: '%s'\n", encrypted);

    char *decrypted = arc4( buffer, buflen, password, passlen );
    printf("ARC4 Decrypted text: '%s'\n", decrypted);
}
#endif // ARC4_DEMO
#endif // ARC4_C


================================================
FILE: vault/buf_base64.c
================================================
// base64 de/encoder. Based on code by Jon Mayo - November 13, 2003 (PUBLIC DOMAIN).
// - rlyeh, public domain
//
// note: functions return 0 on error
// note: base64("")==""

#ifndef BASE64_H
#define BASE64_H

unsigned base64_bounds(unsigned inlen);
unsigned base64_encode(const void *in, unsigned inlen, void *out, unsigned outlen);
unsigned base64_decode(const void *in, unsigned inlen, void *out, unsigned outlen);

#endif

#ifdef BASE64_C
#pragma once
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>
#include <ctype.h>

unsigned base64_bounds(unsigned size) {
    return 4 * ((size + 2) / 3);
}

unsigned base64_encode(const void *in_, unsigned inlen, void *out_, unsigned outlen) {
    uint_least32_t v;
    unsigned ii, io, rem;
    char *out = (char *)out_;
    const unsigned char *in = (const unsigned char *)in_;
    const uint8_t base64enc_tab[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";

    for(io = 0, ii = 0, v = 0, rem = 0; ii < inlen; ii ++) {
        unsigned char ch;
        ch = in[ii];
        v = (v << 8) | ch;
        rem += 8;
        while (rem >= 6) {
            rem -= 6;
            if (io >= outlen)
                return 0; /* truncation is failure */
            out[io ++] = base64enc_tab[(v >> rem) & 63];
        }
    }
    if (rem) {
        v <<= (6 - rem);
        if (io >= outlen)
            return 0; /* truncation is failure */
        out[io ++] = base64enc_tab[v & 63];
    }
    if (io < outlen)
        out[io] = 0;

    return io;
}

unsigned base64_decode(const void *in_, unsigned inlen, void *out_, unsigned outlen) {
    uint_least32_t v;
    unsigned ii, io, rem;
    char *out = (char *)out_;
    const unsigned char *in = (const unsigned char *)in_;
    const uint8_t base64dec_tab[256]= {
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255, 62,255,255,
         52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255,
        255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255, 63,
        255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
         41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
        255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
    };

    for (io = 0, ii = 0,v = 0, rem = 0; ii < inlen; ii ++) {
        unsigned char ch;
        if (isspace(in[ii]))
            continue;
        if ((in[ii]=='=') || (!in[ii]))
            break; /* stop at = or null character*/
        ch = base64dec_tab[(unsigned char)in[ii]];
        if (ch == 255)
            break; /* stop at a parse error */
        v = (v<<6) | ch;
        rem += 6;
        if (rem >= 8) {
            rem -= 8;
            if (io >= outlen)
                return 0; /* truncation is failure */
            out[io ++] = (v >> rem) & 255;
        }
    }
    if (rem >= 8) {
        rem -= 8;
        if (io >= outlen)
            return 0; /* truncation is failure */
        out[io ++] = (v >> rem) & 255;
    }
    return io;
}

#endif // BASE64_C


================================================
FILE: vault/buf_base92.c
================================================
// THE BEERWARE LICENSE (Revision 42):
// <thenoviceoof> wrote this file. As long as you retain this notice you
// can do whatever you want with this stuff. If we meet some day, and you
// think this stuff is worth it, you can buy me a beer in return
// - Nathan Hwang (thenoviceoof)

#ifndef BASE92_H
#define BASE92_H

unsigned base92_encode(const void *in, unsigned inlen, void* out, unsigned outlen);
unsigned base92_decode(const void *in, unsigned inlen, void* out, unsigned outlen);
unsigned base92_bounds(unsigned inlen);

#endif

#ifdef BASE92_C
#pragma once
#include <stdlib.h>
#include <string.h>

unsigned base92_bounds(unsigned inlen) {
    unsigned size = (inlen * 8) % 13, extra_null = 1;
    if(size == 0) return 2 * ((inlen * 8) / 13) + extra_null;
    if(size  < 7) return 2 * ((inlen * 8) / 13) + extra_null + 1;
                  return 2 * ((inlen * 8) / 13) + extra_null + 2;
}

unsigned base92_encode(const void* in, unsigned inlen, void *out, unsigned size) {
    char *res = (char *)out;
    const unsigned char *str = (const unsigned char *)in;
    unsigned int j = 0;          // j for encoded
    unsigned long workspace = 0; // bits holding bin
    unsigned short wssize = 0;   // number of good bits in workspace
    unsigned char c;
    const unsigned char ENCODE_MAPPING[256] = {
        33, 35, 36, 37, 38, 39, 40, 41, 42, 43,
        44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
        54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
        64, 65, 66, 67, 68, 69, 70, 71, 72, 73,
        74, 75, 76, 77, 78, 79, 80, 81, 82, 83,
        84, 85, 86, 87, 88, 89, 90, 91, 92, 93,
        94, 95, 97, 98, 99, 100, 101, 102, 103, 104,
        105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
        115, 116, 117, 118, 119, 120, 121, 122, 123, 124,
        125, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0
    };
    if (inlen) {
        for (unsigned i = 0; i < inlen; i++) {
            workspace = workspace << 8 | str[i];
            wssize += 8;
            if (wssize >= 13) {
                int tmp = (workspace >> (wssize - 13)) & 8191;
                c = ENCODE_MAPPING[(tmp / 91)];
                if (c == 0) return 0; // illegal char
                res[j++] = c;
                c = ENCODE_MAPPING[(tmp % 91)];
                if (c == 0) return 0; // illegal char
                res[j++] = c;
                wssize -= 13;
            }
        }
        // encode a last byte
        if (0 < wssize && wssize < 7) {
            int tmp = (workspace << (6 - wssize)) & 63;  // pad the right side
            c = ENCODE_MAPPING[(tmp)];
            if (c == 0) return 0; // illegal char
            res[j++] = c;
        } else if (7 <= wssize) {
            int tmp = (workspace << (13 - wssize)) & 8191; // pad the right side
            c = ENCODE_MAPPING[(tmp / 91)];
            if (c == 0) return 0; // illegal char
            res[j++] = c;
            c = ENCODE_MAPPING[(tmp % 91)];
            if (c == 0) return 0; // illegal char
            res[j++] = c;
        }
    } else {
        res[j++] = '~';
    }
    // add null byte
    res[j] = 0;
    return j;
}

// this guy expects a null-terminated string
// gives back a non-null terminated string, and properly filled len
unsigned base92_decode(const void* in, unsigned size, void *out, unsigned outlen_unused) {
    const char* str = (const char*)in;
    unsigned char *res = (unsigned char *)out;
    int i, j = 0, b1, b2;
    unsigned long workspace = 0;
    unsigned short wssize = 0;
    const unsigned char DECODE_MAPPING[256] = {
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 0, 255, 1, 2, 3, 4, 5,
        6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
        16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
        26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
        36, 37, 38, 39, 40, 41, 42, 43, 44, 45,
        46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
        56, 57, 58, 59, 60, 61, 255, 62, 63, 64,
        65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
        75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
        85, 86, 87, 88, 89, 90, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
        255, 255, 255, 255, 255, 255
    };

    // handle small cases first
    if (size == 0 || (str[0] == '~' && str[1] == '\0')) {
        res[0] = 0;
        return 1;
    }
    // calculate size
    int len = ((size/2 * 13) + (size%2 * 6)) / 8;
    // handle pairs of chars
    for (i = 0; i + 1 < size; i += 2) {
        b1 = DECODE_MAPPING[(str[i])];
        b2 = DECODE_MAPPING[(str[i+1])];
        workspace = (workspace << 13) | (b1 * 91 + b2);
        wssize += 13;
        while (wssize >= 8) {
            res[j++] = (workspace >> (wssize - 8)) & 255;
            wssize -= 8;
        }
    }
    // handle single char
    if (size % 2 == 1) {
        workspace = (workspace << 6) | DECODE_MAPPING[(str[size - 1])];
        wssize += 6;
        while (wssize >= 8) {
            res[j++] = (workspace >> (wssize - 8)) & 255;
            wssize -= 8;
        }
    }
    //assert(j == len);
    return j;
}

#endif


================================================
FILE: vault/buf_cobs.c
================================================
// Based on code by Jacques Fortier.
// "Redistribution and use in source and binary forms are permitted, with or without modification."
//
// Consistent Overhead Byte Stuffing is an encoding that removes all 0 bytes from arbitrary binary data.
// The encoded data consists only of bytes with values from 0x01 to 0xFF. This is useful for preparing data for
// transmission over a serial link (RS-232 or RS-485 for example), as the 0 byte can be used to unambiguously indicate
// packet boundaries. COBS also has the advantage of adding very little overhead (at least 1 byte, plus up to an
// additional byte per 254 bytes of data). For messages smaller than 254 bytes, the overhead is constant.
// 
// This implementation is designed to be both efficient and robust. 
// The decoder is designed to detect malformed input data and report an error upon detection.
//

#ifndef COBS_H
#define COBS_H

unsigned cobs_bounds(unsigned len);
unsigned cobs_encode(const void *in, unsigned inlen, void *out, unsigned outlen);
unsigned cobs_decode(const void *in, unsigned inlen, void *out, unsigned outlen);

#endif

#ifdef COBS_C
#pragma once
#include <stdint.h>
#include <stddef.h>
#include <math.h>

unsigned cobs_bounds( unsigned len ) {
    return ceil(len / 254.0) + 1;
}
unsigned cobs_encode(const void *in, unsigned inlen, void *out, unsigned outlen) {
    const uint8_t *src = (const uint8_t *)in;
    uint8_t *dst = (uint8_t*)out;
    size_t srclen = inlen;

    uint8_t code = 1;
    size_t read_index = 0, write_index = 1, code_index = 0;

    while( read_index < srclen ) {
        if( src[ read_index ] == 0) {
            dst[ code_index ] = code;
            code = 1;
            code_index = write_index++;
            read_index++;
        } else {
            dst[ write_index++ ] = src[ read_index++ ];
            code++;
            if( code == 0xFF ) {
                dst[ code_index ] = code;
                code = 1;
                code_index = write_index++;
            }
        }
    }

    dst[ code_index ] = code;
    return write_index;
}
unsigned cobs_decode(const void *in, unsigned inlen, void *out, unsigned outlen) {
    const uint8_t *src = (const uint8_t *)in;
    uint8_t *dst = (uint8_t*)out;
    size_t srclen = inlen;

    uint8_t code, i;
    size_t read_index = 0, write_index = 0;

    while( read_index < srclen ) {
        code = src[ read_index ];

        if( ((read_index + code) > srclen) && (code != 1) ) {
            return 0;
        }

        read_index++;

        for( i = 1; i < code; i++ ) {
            dst[ write_index++ ] = src[ read_index++ ];
        }
        if( (code != 0xFF) && (read_index != srclen) ) {
            dst[ write_index++ ] = '\0';
        }
    }

    return write_index;
}

#ifdef COBS_DEMO
#include <stdio.h>
#include <string.h>
#include <assert.h>
void test( const char *buffer, int buflen ) {
    char enc[4096];
    int enclen = cobs_encode( buffer, buflen, enc, 4096 );

    char dec[4096];
    int declen = cobs_decode( enc, enclen, dec, 4096 );

    assert( enclen >= buflen );
    assert( declen == buflen );
    assert( memcmp(dec, buffer, buflen) == 0 );

    printf("%d->%d->%d (+%d extra bytes)\n", declen, enclen, declen, enclen - declen);
}
int main() {
    const char *null = 0;
    test( null, 0 );

    const char empty[] = "";
    test( empty, sizeof(empty) );

    const char text[] = "hello world\n";
    test( text, sizeof(text) );

    const char bintext[] = "hello\0\0\0world\n";
    test( bintext, sizeof(bintext) );

    const char blank[512] = {0};
    test( blank, sizeof(blank) );

    char longbintext[1024];
    for( int i = 0; i < 1024; ++i ) longbintext[i] = (unsigned char)i;
    test( longbintext, sizeof(longbintext) );

    assert(~puts("Ok"));
}
#define main main__
#endif // COBS_DEMO
#endif // COBS_C


================================================
FILE: vault/buf_crc.c
================================================
// - rlyeh, public domain

unsigned crc32(unsigned h, const void *ptr, unsigned len);
uint64_t crc64(uint64_t h, const void *ptr, uint64_t len);

#ifdef CRC_C
#pragma once

unsigned crc32(unsigned h, const void *ptr_, unsigned len) {
    // based on public domain code by Karl Malbrain
    const uint8_t *ptr = (const uint8_t *)ptr_;
    if (!ptr) return 0;
    const unsigned tbl[16] = {
        0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac, 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
        0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c, 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c };
    for(h = ~h; len--; ) { uint8_t b = *ptr++; h = (h >> 4) ^ tbl[(h & 15) ^ (b & 15)]; h = (h >> 4) ^ tbl[(h & 15) ^ (b >> 4)]; }
    return ~h;
}

uint64_t crc64(uint64_t h, const void *ptr, uint64_t len) {
    // based on public domain code by Lasse Collin
    // also, use poly64 0xC96C5795D7870F42 for crc64-ecma
    static uint64_t crc64_table[256];
    static uint64_t poly64 = UINT64_C(0x95AC9329AC4BC9B5);
    if( poly64 ) {
        for( int b = 0; b < 256; ++b ) {
            uint64_t r = b;
            for( int i = 0; i < 8; ++i ) {
                r = r & 1 ? (r >> 1) ^ poly64 : r >> 1;
            }
            crc64_table[ b ] = r;
            //printf("%016llx\n", crc64_table[b]);
        }
        poly64 = 0;
    }
    const uint8_t *buf = (const uint8_t *)ptr;
    uint64_t crc = ~h; // ~crc;
    while( len != 0 ) {
        crc = crc64_table[(uint8_t)crc ^ *buf++] ^ (crc >> 8);
        --len;
    }
    return ~crc;
}
#endif


================================================
FILE: vault/buf_endian.c
================================================
// binary endianness ----------------------------------------------------------
// - rlyeh, public domain

#pragma once
#include <stdint.h>

static uint16_t bswap16( uint16_t x ) {
    return (x << 8) | (x >> 8);
}
static uint32_t bswap32( uint32_t x ) { 
    x = ((x << 8) & 0xff00ff00) | ((x >> 8) & 0x00ff00ff);
    return (x << 16) | (x >> 16);
}
static uint64_t bswap64( uint64_t x ) { 
    x = ((x <<  8) & 0xff00ff00ff00ff00ULL) | ((x >>  8) & 0x00ff00ff00ff00ffULL);
    x = ((x << 16) & 0xffff0000ffff0000ULL) | ((x >> 16) & 0x0000ffff0000ffffULL);
    return (x << 32) | (x >> 32);
}
static int is_big() {
    return (*(uint16_t *)"\0\1") == 1;
}
static int is_little() {
    return (*(uint16_t *)"\0\1") != 1;
}

#if defined(_MSC_VER)
#include <stdlib.h>
#define bswap16 _byteswap_ushort
#define bswap32 _byteswap_ulong
#define bswap64 _byteswap_uint64
#elif defined __GNUC__
#define bswap16 __builtin_bswap16
#define bswap32 __builtin_bswap32
#define bswap64 __builtin_bswap64
#endif


================================================
FILE: vault/buf_interleave.c
================================================
// array de/interleaving
// - rlyeh, public domain.
//
// results:
// R0G0B0   R1G1B1   R2G2B2...   -> R0R1R2... B0B1B2... G0G1G2...
// R0G0B0A0 R1G1B1A1 R2G2B2A2... -> R0R1R2... A0A1A2... B0B1B2... G0G1G2...

#ifndef INTERLEAVE_H
#define INTERLEAVE_H

void *interleave( void *out, const void *list, int list_count, int sizeof_item, unsigned columns );

#endif

// -----------------------------------------------------------------------------

#ifdef INTERLEAVE_C
#pragma once
#include <assert.h>
#include <string.h>

void *interleave( void *out, const void *list, int list_count, int sizeof_item, unsigned columns ) {
    void *bak = out;
    assert( columns < list_count ); // required
    int row_count = list_count / columns;
    for( int offset = 0; offset < columns; offset++ ) {
        for( int row = 0; row < row_count; row++ ) {
            memcpy( out, &((char*)list)[ (offset + row * columns) * sizeof_item ], sizeof_item );
            out = ((char*)out) + sizeof_item;
        }
    }
    return bak;
}

#ifdef INTERLEAVE_DEMO
#include <stdio.h>
void test( const char *name, int interleaving, int deinterleaving, const char *original ) {
    char interleaved[128] = {0};
    interleave( interleaved, original, strlen(original)/2, 2, interleaving );
    char deinterleaved[128] = {0};
    interleave( deinterleaved, interleaved, strlen(original)/2, 2, deinterleaving );

    printf( "\n%s\n", name );
    printf( "original:\t%s\n", original );
    printf( "interleaved:\t%s\n", interleaved );
    printf( "deinterleaved:\t%s\n", deinterleaved );

    assert( 0 == strcmp(original, deinterleaved) );
}
int main() {
    test("audio 2ch", 2, 3,
        "L0R0"
        "L1R1"
        "L2R2"
    );
    test("image 3ch", 3, 3,
        "R0G0B0"
        "R1G1B1"
        "R2G2B2"
    );
    test("image 4ch", 4, 3,
        "R0G0B0A0"
        "R1G1B1A1"
        "R2G2B2A2"
    );
    test("audio 5ch", 5, 3,
        "A0B0C0L0R0"
        "A1B1C1L1R1"
        "A2B2C2L2R2"
    );
    test("audio 5.1ch", 6, 3,
        "A0B0C0L0R0S0"
        "A1B1C1L1R1S1"
        "A2B2C2L2R2S2"
    );
    test("opengl material 9ch", 9, 3,
        "X0Y0Z0q0w0e0r0u0v0"
        "X1Y1Z1q1w1e1r1u1v1"
        "X2Y2Z2q2w2e2r2u2v2"
    );
    test("opengl material 10ch", 10, 3,
        "X0Y0Z0q0w0e0r0s0u0v0"
        "X1Y1Z1q1w1e1r1s1u1v1"
        "X2Y2Z2q2w2e2r2s2u2v2"
    );
    assert(~puts("Ok"));
}
#endif // INTERLEAVE_DEMO
#endif // INTERLEAVE_C


================================================
FILE: vault/buf_netstring.c
================================================
// netstring en/decoder
// - rlyeh, public domain.

unsigned netstring_bounds(unsigned inlen);
unsigned netstring_encode(const char *in, unsigned inlen, char *out, unsigned outlen);
unsigned netstring_decode(const char *in, unsigned inlen, char *out, unsigned outlen);

#ifdef NETSTRING_C
#pragma once
#include <stdio.h>
#include <string.h>

unsigned netstring_bounds(unsigned inlen) {
    return 5 + inlen + 3; // 3 for ;,\0 + 5 if inlen < 100k ; else (unsigned)ceil(log10(inlen + 1))
}
unsigned netstring_encode(const char *in, unsigned inlen, char *out, unsigned outlen) {
//  if(outlen < netstring_bounds(inlen)) return 0;
    sprintf(out, "%u:%.*s,", inlen, inlen, in);
    return strlen(out);
}
unsigned netstring_decode(const char *in, unsigned inlen, char *out, unsigned outlen) {
//  if(outlen < inlen) return 0;
    const char *bak = in;
    sscanf(in, "%u", &outlen);
    while( *++in != ':' );
    memcpy(out, in+1, outlen), out[outlen-1] = 0;
    // return outlen; // number of written bytes
    return (outlen + (in+2 - bak)); // number of read bytes
}

#ifdef NETSTRING_DEMO
#include <stdlib.h>
int main() {
    // encode
    const char text1[] = "hello world!", text2[] = "abc123";
    unsigned buflen = netstring_bounds(strlen(text1) + strlen(text2));
    char *buf = malloc(buflen), *ptr = buf;
    ptr += netstring_encode(text1, strlen(text1), ptr, buflen -= (ptr - buf));
    ptr += netstring_encode(text2, strlen(text2), ptr, buflen -= (ptr - buf));
    printf("%s -> ", buf);

    // decode
    char out[12];
    unsigned plen = strlen(ptr = buf);
    while(plen > 0) {
        int written = netstring_decode(ptr, plen, out, 12);
        ptr += written;
        plen -= written;
        printf("'%s'(%s)(%d), ", out, ptr, plen );
    }
    puts("");
}
#define main main__
#endif // NETSTRING_DEMO
#endif // NETSTRING_C


================================================
FILE: vault/buf_pack.c
================================================
// Based on code by Brian "Beej Jorgensen" Hall (public domain) [1].
// Based on code by Ginger Bill's half<->float (public domain) [2].
// - rlyeh, public domain.
//
// pack.c  -- perl/python-ish pack/unpack functions
// like printf and scanf, but for binary data.
//
// format flags:
//  (<) little endian       (>) big endian (! also)     (=) native endian
//  (c) 8-bit  char         (b) 8-bit  byte
//  (h) 16-bit half         (w) 16-bit word
//  (i) 32-bit integer      (u) 32-bit unsigned         (f) 32-bit float
//  (l) 64-bit long         (q) 64-bit quad             (d) 64-bit double
//  (v) varint
//  (s) string   (64-bit varint length prepended)
//  (S) string   (32-bit fixed  length prepended)
//  (m) memblock (64-bit varint length prepended)
//  (M) memblock (32-bit fixed  length prepended)
//  (z) memblock (zeroed)
//  (#) number of arguments processed (only when unpacking)
//
// @todo:
// - (x) document & test flag
// @totest:
// - (s) string   (64-bit variable length automatically prepended)
// - (S) string   (32-bit fixed    length automatically prepended)
// - (m) memblock (64-bit variable length automatically prepended)
// - (M) memblock (32-bit fixed    length automatically prepended)
// - (z) memblock (zeroed)
// - (#) number of arguments processed (only when unpacking)
//
// @refs:
// [1] http://beej.us/guide/bgnet/output/html/multipage/advanced.html#serialization (Modified to encode NaN and Infinity as well.)
// [2] https://github.com/gingerBill/gb
// [3] http://www.mrob.com/pub/math/floatformats.html#minifloat
// [4] microfloat: [0.002 to 240] range.
// [5] half float: can approximate any 16-bit unsigned integer or its reciprocal to 3 decimal places.

#ifndef PACK_H
#define PACK_H
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>

// - save data dictated by the format string from the buffer. return: number of bytes written, or 0 if error.
//   if first argument is zero, returns number of bytes required for packing.

int savef(FILE *file, const char *format, ...);
int saveb(unsigned char *buf, const char *format, ...);

// - load data dictated by the format string into the buffer. return: number of bytes read, or 0 if error.
//   if first argument is zero, returns number of bytes required for unpacking.

int loadf(FILE *file, const char *format, ...);
int loadb(const unsigned char *buf, const char *format, ...);

#endif


#ifdef PACK_C
#pragma once

// #include "packendian.c" // endianness
// #include "pack754.c" // float754 packing --------------------------------------
// #include "packint.c" // integer packing ---------------------------------------
// #include "packvli.c" // variable int packing ----------------------------------

// b/f packing -----------------------------------------------------------------

#include <ctype.h>
#include <inttypes.h>
#include <math.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

int loadb_(const uint8_t *buf, const char *fmt, va_list ap) {
    uint64_t args = 0;
    const uint8_t *buf0 = buf;
    char tmp[16+1];
    //uint64_t size = 0, len;
    int32_t len, count, maxstrlen=0;
    int le = 0;

    if(!buf) // buffer estimation
    for(; *fmt != '\0'; fmt++) {
        switch(*fmt) {
        default: if (!isdigit(*fmt)) return 0;
        break; case '!': case '>': case '<': case '=': case ' ':                                                      //  0-bit endianness
        break; case 'c': case 'b': { int8_t c = (int8_t)va_arg(ap, int); buf += 1; }                                  //  8-bit promoted
        break; case 'h': case 'w': { int16_t h = (int16_t)va_arg(ap, int); buf += 2; }                                // 16-bit promoted
        break; case 'i': case 'u': { int32_t l = va_arg(ap, int32_t); buf += 4; }                                     // 32-bit
        break; case 'l': case 'q': { int64_t L = va_arg(ap, int64_t); buf += 8; }                                     // 64-bit
        break; case 'f': { float f = (float)va_arg(ap, double); buf += 4; }                                           // 32-bit float promoted
        break; case 'd': { double F = (double)va_arg(ap, double); buf += 8; }   
Download .txt
gitextract_m65kpms5/

├── README.md
├── UNLICENSE.md
├── tinyarc4.hpp
├── tinyassert.c
├── tinyatoi.c
├── tinybenchmark.hpp
├── tinybsearch.c
├── tinybsearch.cc
├── tinybuild.h
├── tinydebug.h
├── tinydefer.cc
├── tinydir.cc
├── tinydixy.c
├── tinydual.sh.bat
├── tinyendian.c
├── tinyerror.c
├── tinyfsm.c
├── tinygc.cc
├── tinyhexbase.c
├── tinyhexdump.c
├── tinyhuman.hpp
├── tinyini.c
├── tinyjson5.c
├── tinylog.c
├── tinylog.h
├── tinylogger.h
├── tinylogger.hpp
├── tinymatch.c
├── tinymime.c
├── tinypipe.hpp
├── tinyprint.cc
├── tinypulse.c
├── tinyroman.cc
├── tinystring.c
├── tinystring.cc
├── tinytga.c
├── tinytime.cc
├── tinytodo.c
├── tinytty.c
├── tinyuniso.cc
├── tinyunit.c
├── tinyuntar.cc
├── tinyunzip.cc
├── tinyvariant.cc
├── tinyvbyte.h
├── tinywav.c
├── tinywtf.h
├── tinyzlib.cpp
└── vault/
    ├── ; ds
    ├── _test.c
    ├── all.c
    ├── bin.c
    ├── bin_dbkv.c
    ├── bin_json5.c
    ├── buf.c
    ├── buf_arc4.c
    ├── buf_base64.c
    ├── buf_base92.c
    ├── buf_cobs.c
    ├── buf_crc.c
    ├── buf_endian.c
    ├── buf_interleave.c
    ├── buf_netstring.c
    ├── buf_pack.c
    ├── buf_pack754.h
    ├── buf_packhalf.h
    ├── buf_packint.h
    ├── buf_packvli.h
    ├── buf_zigzag.c
    ├── c.c
    ├── c_alignas.c
    ├── c_benchmark.c
    ├── c_cc4.c
    ├── c_checkva.c
    ├── c_countof.c
    ├── c_ifdef.c
    ├── c_incbin.h
    ├── c_once.c
    ├── c_overload.c
    ├── c_plan.c
    ├── c_section.c
    ├── c_thread.c
    ├── c_unreachable.c
    ├── c_with.c
    ├── ds.c
    ├── ds_alloc.c
    ├── ds_array.c
    ├── ds_format.c
    ├── ds_hash.c
    ├── ds_map.c
    ├── ds_quark.c
    ├── ds_rope.c
    ├── ds_set.c
    ├── ds_sort.c
    ├── ds_stream.c
    ├── ds_string.c
    ├── net.c
    ├── net_ecdh.h
    ├── net_fragment.c
    ├── net_tunnel.c
    ├── net_webserver.c
    ├── os.c
    ├── os_ansi.c
    ├── os_assert.c
    ├── os_breakpoint.c
    ├── os_cpu.c
    ├── os_date.c
    ├── os_dialog.c
    ├── os_die.c
    ├── os_entropy.c
    ├── os_env.c
    ├── os_exec.c
    ├── os_exit.c
    ├── os_file.c
    ├── os_icon.c
    ├── os_ini.c
    ├── os_locale.c
    ├── os_logger.c
    ├── os_logger2.c
    ├── os_logger3.c
    ├── os_memory.c
    ├── os_mime.c
    ├── os_singleton.c
    ├── os_test.c
    ├── os_trap.c
    ├── os_tray.c
    ├── syn.c
    ├── syn_atomic.c
    ├── syn_channel.c
    ├── syn_condv.c
    ├── syn_coro.c
    ├── syn_fiber.c
    ├── syn_fiber_amd64.h
    ├── syn_fiber_arm.h
    ├── syn_fiber_ppc.h
    ├── syn_fiber_sjlj.h
    ├── syn_fiber_ucontext.h
    ├── syn_fiber_win32.h
    ├── syn_fiber_x86.h
    ├── syn_mcmp.c
    ├── syn_mutex.c
    ├── syn_semaphore.c
    ├── syn_sleep.c
    ├── syn_thread.c
    └── syn_tls.c
Download .txt
SYMBOL INDEX (558 symbols across 110 files)

FILE: tinyarc4.hpp
  function tinyARC4 (line 7) | static

FILE: tinyassert.c
  function break_handler_ (line 36) | static void break_handler_(int signum) { signal(SIGTRAP, SIG_DFL); }
  function main (line 64) | int main() {

FILE: tinyatoi.c
  function tinyatoi (line 4) | static

FILE: tinybenchmark.hpp
  type bench (line 6) | struct bench {

FILE: tinybsearch.c
  function bsearchint (line 6) | unsigned bsearchint( const int *array, int numelems, int key ) {
  function bsearchsz (line 16) | unsigned bsearchsz( const size_t *array, int numelems, size_t key ) {
  function bsearchstr (line 26) | unsigned bsearchstr( const char **array, int numelems, const char *key ) {

FILE: tinybsearch.cc
  function bsearch (line 5) | unsigned bsearch( const T &x, const container &v ) {

FILE: tinydefer.cc
  type defer (line 6) | struct defer {

FILE: tinydir.cc
  function tinydir (line 13) | bool tinydir( const char *directory, const FN &yield ) {

FILE: tinydixy.c
  function tinydixy (line 13) | int tinydixy( const char *s, int (*yield)(const char *key, const char *v...

FILE: tinyendian.c
  function swap16 (line 6) | static uint16_t swap16( uint16_t x ) { return (x << 8) | (x >> 8); }
  function swap32 (line 7) | static uint32_t swap32( uint32_t x ) { return (x << 24) | (x >> 24) | ((...
  function swap64 (line 8) | static uint64_t swap64( uint64_t x ) { return (x << 56) | (x >> 56) | ((...
  function tobe16 (line 9) | static uint16_t tobe16( uint16_t x ) { return IS_BIG_ENDIAN ? x : swap16...
  function tobe32 (line 10) | static uint32_t tobe32( uint32_t x ) { return IS_BIG_ENDIAN ? x : swap32...
  function tobe64 (line 11) | static uint64_t tobe64( uint64_t x ) { return IS_BIG_ENDIAN ? x : swap64...
  function tole16 (line 12) | static uint16_t tole16( uint16_t x ) { return IS_BIG_ENDIAN ? swap16(x) ...
  function tole32 (line 13) | static uint32_t tole32( uint32_t x ) { return IS_BIG_ENDIAN ? swap32(x) ...
  function tole64 (line 14) | static uint64_t tole64( uint64_t x ) { return IS_BIG_ENDIAN ? swap64(x) ...

FILE: tinyerror.c
  function derefence (line 31) | int derefence(int *ptr) {
  function main (line 38) | int main(int arg, char **argv) {

FILE: tinygc.cc
  function gc_mark_stack (line 32) | static void gc_mark_stack(void) {
  function gc_mark (line 46) | static void gc_mark() { // mark reachable stack pointers
  function gc_sweep (line 52) | static void gc_sweep() { // sweep unreachable stack pointers
  function gc_init (line 79) | void gc_init(void *argc, int MiB) {
  function gc_run (line 83) | void gc_run() {
  function gc_stop (line 87) | void gc_stop() {

FILE: tinyhexbase.c
  function hexbasenl (line 13) | static inline
  function hexbase (line 28) | static inline

FILE: tinyhexdump.c
  function hexdump (line 4) | void hexdump( FILE *fp, const void *ptr, unsigned len, int width ) {

FILE: tinyhuman.hpp
  function humanize (line 8) | inline std::string humanize( uint64_t num, const char *suffix = " " ) {
  function dehumanize (line 19) | inline uint64_t dehumanize( const std::string &str ) {

FILE: tinyini.c
  function ini_cb (line 68) | static void ini_cb( const char *text, void (*yield)( const char *key, co...

FILE: tinyjson5.c
  type json5_type (line 27) | typedef enum json5_type {
  type json5 (line 38) | typedef struct json5 {
  function vsize (line 68) | size_t vsize( void *p ) {
  function json5_free (line 326) | void json5_free(json5 *root) {
  function json5_write (line 344) | void json5_write(FILE *fp, const json5 *o) {
  function main (line 402) | int main() {
  function main (line 438) | int main() {

FILE: tinylogger.h
  function main (line 61) | int main() {

FILE: tinylogger.hpp
  type logger (line 6) | struct logger {
    method logger (line 7) | logger() {
    method logger (line 13) | logger() {
  type logger (line 12) | struct logger {
    method logger (line 7) | logger() {
    method logger (line 13) | logger() {

FILE: tinymatch.c
  function match (line 4) | static int match( const char *pattern, const char *str ) {

FILE: tinypipe.hpp
  function copy (line 9) | void copy( T &s, const istream &is ) {
  function pipe (line 19) | bool pipe( const istream &is, ostream &os, const std::vector< int (*)(co...

FILE: tinyprint.cc
  type print (line 4) | struct print {
    method print (line 8) | print& operator,( const T &t ) {

FILE: tinypulse.c
  function pulse (line 4) | void pulse( int *state ) {

FILE: tinyroman.cc
  function romanize (line 5) | std::string romanize( int i ) {

FILE: tinystring.c
  function stristmp (line 25) | int stristmp(const char *s) { // is_va()

FILE: tinystring.cc
  function tokenize (line 9) | std::deque< std::string > tokenize( const std::string &self, const char ...
  function split (line 21) | std::deque< std::string > split( const std::string &self, const std::str...
  function left_of (line 33) | std::string left_of( const std::string &substring, const std::string &se...
  function right_of (line 38) | std::string right_of( const std::string &substring, const std::string &s...
  function replace_one (line 43) | std::string replace_one( const std::string &self, const std::string &tar...
  function replace_all (line 49) | std::string replace_all( const std::string &self, const std::string &tar...

FILE: tinytga.c
  function tinytga (line 4) | static void tinytga(FILE *fp, void *rgba, int width, int height, int num...

FILE: tinytime.cc
  function now (line 8) | double now() {
  function bench (line 17) | double bench( void (*fn)() ) {
  function sleep (line 21) | void sleep( double secs ) {

FILE: tinytodo.c
  function TODO (line 7) | static inline int TODO(const char *DT) { return

FILE: tinytty.c
  function tty256 (line 17) | void tty256( unsigned char r, unsigned char g, unsigned char b ) {
  function tty (line 26) | void tty( const char *txt ) {

FILE: tinyuniso.cc
  function tinyuniso (line 10) | bool tinyuniso( istream &is, const FN &yield ) {

FILE: tinyunit.c
  function summary (line 7) | static void summary(void){ suite("summary"){ printf("[%s] %d tests = %d ...

FILE: tinyuntar.cc
  function tinyuntar (line 8) | bool tinyuntar( istream &is, const FN &yield ) {

FILE: tinyunzip.cc
  function tinyunzip (line 14) | bool tinyunzip( istream &is, const FN &yield ) {

FILE: tinyvariant.cc
  type var (line 5) | struct var {
    method var (line 14) | var() : type(0), integer(0)
    method var (line 17) | var( const int &i ) : type(0), integer(i)
    method var (line 20) | var( const double &r ) : type(1), real(r)
    method var (line 23) | var( const std::string &r ) : type(2), string( new std::string(r) )
    method var (line 27) | var( const char (&s)[N]) : type(2), string( new std::string(s) )
    method var (line 31) | var( const T &fn ) : type(3), callback( new std::function<void()>(fn) )
    method var (line 34) | var( const var &other ) {
    method cleanup (line 42) | void cleanup() {
    method var (line 48) | var &operator=( const var &other ) {
    method friend (line 65) | inline friend ostream &operator <<( ostream &os, const var &self ) {
  function is (line 74) | inline bool is(const var &v) { return false; }
  function T (line 80) | inline const T& cast(const var &v) { static T t; return t = T(); }

FILE: tinyvbyte.h
  function vbuencode (line 8) | static uint64_t vbuencode( uint8_t *buffer, uint64_t value ) {
  function vbudecode (line 18) | static uint64_t vbudecode( uint64_t *value, const uint8_t *buffer ) {
  function vbiencode (line 29) | static uint64_t vbiencode( uint8_t *buffer, int64_t value ) {
  function vbidecode (line 35) | static uint64_t vbidecode( int64_t *value, const uint8_t *buffer ) {

FILE: tinywav.c
  function tinywav (line 4) | static void tinywav(FILE *fp, short numChannels, short bitsPerSample, in...

FILE: tinyzlib.cpp
  function tinyzlib (line 4) | static bool tinyzlib(void *out, unsigned outlen, const void *in, unsigne...

FILE: vault/_test.c
  function main (line 7) | int main()

FILE: vault/bin_dbkv.c
  type KISSDB (line 152) | typedef struct {
  type KISSDB_Iterator (line 229) | typedef struct {
  function KISSDB_hash (line 265) | static uint64_t KISSDB_hash(const void *b,unsigned long len)
  function KISSDB_open (line 274) | static int KISSDB_open(
  function KISSDB_close (line 382) | static void KISSDB_close(KISSDB *db)
  function KISSDB_get (line 391) | static int KISSDB_get(KISSDB *db,const void *key,void *vbuf)
  function KISSDB_put (line 431) | static int KISSDB_put(KISSDB *db,const void *key,const void *value)
  function KISSDB_Iterator_init (line 536) | static void KISSDB_Iterator_init(KISSDB *db,KISSDB_Iterator *dbi)
  function KISSDB_Iterator_next (line 543) | static int KISSDB_Iterator_next(KISSDB_Iterator *dbi,void *kbuf,void *vbuf)
  function main (line 585) | int main(int argc,char **argv)
  function dbkv_read (line 737) | bool dbkv_read( const char *dbfile, const char *keystr, char *val ) {
  function dbkv_write (line 751) | bool dbkv_write( const char *dbfile, const char *keystr, const char *val...
  function main (line 768) | int main( int argc, char **argv ) {

FILE: vault/bin_json5.c
  type json5_type (line 23) | typedef enum json5_type {
  type json5 (line 34) | typedef struct json5 {
  function json5_free (line 282) | void json5_free(json5 *root) {
  function json5_write (line 300) | void json5_write(FILE *fp, const json5 *o) {
  function main (line 364) | int main() {
  function main (line 400) | int main() {

FILE: vault/buf_arc4.c
  function main (line 36) | int main( int argc, char **argv ) {

FILE: vault/buf_base64.c
  function base64_bounds (line 24) | unsigned base64_bounds(unsigned size) {
  function base64_encode (line 28) | unsigned base64_encode(const void *in_, unsigned inlen, void *out_, unsi...
  function base64_decode (line 59) | unsigned base64_decode(const void *in_, unsigned inlen, void *out_, unsi...

FILE: vault/buf_base92.c
  function base92_bounds (line 21) | unsigned base92_bounds(unsigned inlen) {
  function base92_encode (line 28) | unsigned base92_encode(const void* in, unsigned inlen, void *out, unsign...
  function base92_decode (line 103) | unsigned base92_decode(const void* in, unsigned size, void *out, unsigne...

FILE: vault/buf_cobs.c
  function cobs_bounds (line 29) | unsigned cobs_bounds( unsigned len ) {
  function cobs_encode (line 32) | unsigned cobs_encode(const void *in, unsigned inlen, void *out, unsigned...
  function cobs_decode (line 60) | unsigned cobs_decode(const void *in, unsigned inlen, void *out, unsigned...
  function test (line 92) | void test( const char *buffer, int buflen ) {
  function main (line 105) | int main() {

FILE: vault/buf_crc.c
  function crc32 (line 9) | unsigned crc32(unsigned h, const void *ptr_, unsigned len) {
  function crc64 (line 20) | uint64_t crc64(uint64_t h, const void *ptr, uint64_t len) {

FILE: vault/buf_endian.c
  function bswap16 (line 7) | static uint16_t bswap16( uint16_t x ) {
  function bswap32 (line 10) | static uint32_t bswap32( uint32_t x ) {
  function bswap64 (line 14) | static uint64_t bswap64( uint64_t x ) {
  function is_big (line 19) | static int is_big() {
  function is_little (line 22) | static int is_little() {

FILE: vault/buf_interleave.c
  function test (line 37) | void test( const char *name, int interleaving, int deinterleaving, const...
  function main (line 50) | int main() {

FILE: vault/buf_netstring.c
  function netstring_bounds (line 13) | unsigned netstring_bounds(unsigned inlen) {
  function netstring_encode (line 16) | unsigned netstring_encode(const char *in, unsigned inlen, char *out, uns...
  function netstring_decode (line 21) | unsigned netstring_decode(const char *in, unsigned inlen, char *out, uns...
  function main (line 33) | int main() {

FILE: vault/buf_pack.c
  function loadb_ (line 78) | int loadb_(const uint8_t *buf, const char *fmt, va_list ap) {
  function saveb_ (line 208) | int saveb_(uint8_t *buf, const char *fmt, va_list ap) {
  function saveb (line 314) | int saveb(uint8_t *buf, const char *fmt, ...) {
  function loadb (line 321) | int loadb(const uint8_t *buf, const char *fmt, ...) {
  function savef (line 329) | int savef(FILE *fp, const char *fmt, ...) {
  function loadf (line 345) | int loadf(FILE *fp, const char *fmt, ...) {
  type bootsector (line 364) | typedef struct bootsector {
  function main (line 380) | int main() {

FILE: vault/buf_pack754.h
  function pack754 (line 28) | static
  function unpack754 (line 63) | static
  function pack754 (line 95) | static uint64_t pack754(long double f, unsigned bits, unsigned expbits) {
  function unpack754 (line 132) | static long double unpack754(uint64_t i, unsigned bits, unsigned expbits) {

FILE: vault/buf_packhalf.h
  type half (line 6) | typedef uint16_t half;
  function half_to_float (line 15) | float half_to_float(half value) {
  function half (line 54) | half float_to_half(float value) {

FILE: vault/buf_packint.h
  function pack16i (line 11) | static void pack16i(uint8_t *buf, uint16_t i, int swap) {
  function pack32i (line 16) | static void pack32i(uint8_t *buf, uint32_t i, int swap) {
  function pack64i (line 21) | static void pack64i(uint8_t *buf, uint64_t i, int swap) {
  function unpack16i (line 31) | static int16_t unpack16i(const uint8_t *buf, int swap) {
  function unpack32i (line 38) | static int32_t unpack32i(const uint8_t *buf, int swap) {
  function unpack64i (line 45) | static int64_t unpack64i(const uint8_t *buf, int swap) {

FILE: vault/buf_packvli.h
  function pack64uv (line 44) | static uint64_t pack64uv( uint8_t *buffer, uint64_t value ) {
  function unpack64uv (line 58) | static uint64_t unpack64uv( const uint8_t *buffer, uint64_t *value ) {
  function pack64iv (line 84) | static uint64_t pack64iv( uint8_t *buffer, int64_t value_ ) {
  function unpack64iv (line 89) | static uint64_t unpack64iv( const uint8_t *buffer, int64_t *value ) {
  function pack_LEB128 (line 102) | static uint64_t pack_LEB128( uint8_t *buffer, int64_t value_ ) {
  function unpack_LEB128 (line 116) | static uint64_t unpack_LEB128( const uint8_t *buffer, int64_t *value ) {
  function main (line 134) | int main() {

FILE: vault/buf_zigzag.c
  function zig64 (line 18) | uint64_t zig64( int64_t value ) { // convert sign|magnitude to magnitude...
  function zag64 (line 21) | int64_t zag64( uint64_t value ) { // convert magnitude|sign to sign|magn...
  function main (line 27) | int main() {

FILE: vault/c_benchmark.c
  function main (line 23) | int main() {

FILE: vault/c_ifdef.c
  function main (line 258) | int main() {

FILE: vault/c_incbin.h
  function main (line 48) | int main(int argc, char **argv) {

FILE: vault/ds_alloc.c
  function vlen (line 59) | size_t vlen( void* p ) {
  function xlen (line 79) | size_t xlen(void* p) {

FILE: vault/ds_format.c
  function is_va (line 35) | int is_va(const char *s) {
  function main (line 78) | int main() {

FILE: vault/ds_hash.c
  function hash32 (line 37) | uint32_t hash32(uint32_t x) {
  function unhash32 (line 44) | uint32_t unhash32(uint32_t x) {
  function hash64 (line 51) | uint64_t hash64(uint64_t x) {
  function unhash64 (line 65) | uint64_t unhash64(uint64_t x) {
  function hash_triple32 (line 74) | uint64_t hash_triple32(uint32_t x) {
  function hash_untriple32 (line 86) | uint64_t hash_untriple32(uint32_t x) {
  function hash_mix64 (line 97) | uint64_t hash_mix64(uint64_t key) {
  function hash_int (line 110) | uint64_t hash_int(int key) {
  function hash_u64 (line 117) | uint64_t hash_u64(uint64_t key) {
  function hash_ptr (line 124) | uint64_t hash_ptr(const void *ptr) {
  function hash_flt (line 129) | uint64_t hash_flt(double dbl) {
  function hash_vec2 (line 134) | uint64_t hash_vec2(const float v2[2]) {
  function hash_vec3 (line 138) | uint64_t hash_vec3(const float v3[3]) {
  function hash_vec4 (line 142) | uint64_t hash_vec4(const float v4[4]) {
  function hash_str (line 146) | uint64_t hash_str(const char* str) {
  function main (line 157) | int main() {

FILE: vault/ds_map.c
  type pair (line 83) | typedef struct pair {
  type map (line 92) | typedef struct map {
  function map_get_index (line 124) | static int map_get_index(uint64_t hkey1) {
  function map_benchmark (line 241) | void map_benchmark() {
  function map_tests (line 325) | void map_tests() {
  function map_tests2 (line 378) | void map_tests2() {
  function map_benchmark2 (line 413) | void map_benchmark2() {
  function main (line 440) | int main() {

FILE: vault/ds_quark.c
  type quark (line 7) | typedef unsigned quark;
  type quark_dictionary (line 24) | typedef struct quark_dictionary {
  function quark (line 33) | quark (quark_intern)(char *s) {
  function quark_len (line 44) | int quark_len(quark q) {
  function quark_hash (line 47) | int quark_hash(quark q) {
  function quark_cmp (line 50) | int quark_cmp(quark q1, quark q2) {

FILE: vault/ds_rope.c
  type rope (line 4) | typedef struct rope rope;
  type rope (line 20) | struct rope {
  function rope_init (line 29) | void rope_init( rope *s, int reserve, float grow ) {
  function rope_append (line 35) | void rope_append( rope *s, const char *buf, int len ) {
  function rope_dump (line 53) | void rope_dump( rope *s ) {
  function rope_len (line 60) | int rope_len( rope *s ) {
  function main (line 69) | int main() {

FILE: vault/ds_set.c
  type set_item (line 83) | typedef struct set_item {
  type set (line 91) | typedef struct set {
  function set_get_index (line 123) | static int set_get_index(uint64_t hkey1) {
  function set_tests (line 235) | void set_tests() {
  function set_tests2 (line 288) | void set_tests2() {
  function set_benchmark (line 319) | void set_benchmark() {
  function main (line 346) | int main() {

FILE: vault/ds_sort.c
  function sort_int (line 49) | int sort_int(int a, int b) {
  function sort_u64 (line 52) | int sort_u64(uint64_t a, uint64_t b) {
  function sort_ptr (line 55) | int sort_ptr(void *a, void *b) {
  function sort_str (line 58) | int sort_str(const char *a, const char *b) {
  function sort_int_qs2 (line 70) | int sort_int_qs2(const void *a, const void *b) { return  sort_int_qs(*(c...
  function sort_uns_qs2 (line 71) | int sort_uns_qs2(const void *a, const void *b) { return  sort_uns_qs(*(c...
  function sort_i16_qs2 (line 72) | int sort_i16_qs2(const void *a, const void *b) { return  sort_i16_qs(*(c...
  function sort_u16_qs2 (line 73) | int sort_u16_qs2(const void *a, const void *b) { return  sort_u16_qs(*(c...
  function sort_i32_qs2 (line 74) | int sort_i32_qs2(const void *a, const void *b) { return  sort_i32_qs(*(c...
  function sort_u32_qs2 (line 75) | int sort_u32_qs2(const void *a, const void *b) { return  sort_u32_qs(*(c...
  function sort_f32_qs2 (line 76) | int sort_f32_qs2(const void *a, const void *b) { return  sort_f32_qs(*(c...
  function sort_i64_qs2 (line 77) | int sort_i64_qs2(const void *a, const void *b) { return  sort_i64_qs(*(c...
  function sort_u64_qs2 (line 78) | int sort_u64_qs2(const void *a, const void *b) { return  sort_u64_qs(*(c...
  function sort_f64_qs2 (line 79) | int sort_f64_qs2(const void *a, const void *b) { return  sort_f64_qs(*(c...
  function sort_ptr_qs2 (line 80) | int sort_ptr_qs2(const void *a, const void *b) { return  sort_ptr_qs(*(c...
  function sort_str_qs2 (line 81) | int sort_str_qs2(const void *a, const void *b) { return  sort_str_qs(*(c...
  function sort_stri_qs2 (line 82) | int sort_stri_qs2(const void *a,const void *b) { return sort_stri_qs(*(c...
  function sort_stra_qs2 (line 83) | int sort_stra_qs2(const void *a,const void *b) { return sort_stra_qs(*(c...
  function sort_int_qs (line 87) | int sort_int_qs(const void *a, const void *b) { return ( *((      int*)a...
  function sort_uns_qs (line 88) | int sort_uns_qs(const void *a, const void *b) { return ( *(( unsigned*)a...
  function sort_i16_qs (line 89) | int sort_i16_qs(const void *a, const void *b) { return ( *((  int16_t*)a...
  function sort_u16_qs (line 90) | int sort_u16_qs(const void *a, const void *b) { return ( *(( uint16_t*)a...
  function sort_i32_qs (line 91) | int sort_i32_qs(const void *a, const void *b) { return ( *((  int32_t*)a...
  function sort_u32_qs (line 92) | int sort_u32_qs(const void *a, const void *b) { return ( *(( uint32_t*)a...
  function sort_f32_qs (line 93) | int sort_f32_qs(const void *p, const void *q) { const     float*a = (con...
  function sort_i64_qs (line 94) | int sort_i64_qs(const void *p, const void *q) { const   int64_t*a = (con...
  function sort_u64_qs (line 95) | int sort_u64_qs(const void *p, const void *q) { const  uint64_t*a = (con...
  function sort_f64_qs (line 96) | int sort_f64_qs(const void *p, const void *q) { const    double*a = (con...
  function sort_ptr_qs (line 97) | int sort_ptr_qs(const void *p, const void *q) { const uintptr_t*a = (con...
  function sort_str_qs (line 99) | int sort_str_qs(const void *a, const void *b) { // str
  function sort_stri_qs (line 104) | int sort_stri_qs(const void *a, const void *b) { // str
  function sort_stra_qs (line 114) | int sort_stra_qs(const void *a, const void *b) { // str
  function sort__alphanum (line 122) | int sort__alphanum(const char *l, const char *r) {
  function main (line 202) | int main() {

FILE: vault/ds_stream.c
  type FILE (line 21) | typedef FILE STREAM_FILE;
  type STREAM (line 65) | typedef struct STREAM STREAM;
  function nil_open (line 102) | static int nil_open(STREAM *s, const char *spec, va_list vl) { return 0; }
  function nil_read (line 103) | static int nil_read(STREAM *s, void *ptr, int sz) { return sz; }
  function nil_write (line 104) | static int nil_write(STREAM *s, const void *ptr, int sz) { return sz; }
  function nil_seek (line 105) | static int nil_seek(STREAM *s, int offs, int mode) { return 0; }
  function nil_tell (line 106) | static int nil_tell(STREAM *s) { return 0; }
  function nil_sync (line 107) | static int nil_sync(STREAM *s) { return 0; }
  function nil_close (line 108) | static int nil_close(STREAM *s) { return 0; }
  type file (line 112) | typedef struct file {
  function file_open (line 122) | static int file_open(STREAM *s, const char *spec, va_list vl) {
  function file_read_ (line 126) | static int file_read_(STREAM *s, void *ptr, int sz) {
  function file_write_ (line 130) | static int file_write_(STREAM *s, const void *ptr, int sz) {
  function file_seek (line 134) | static int file_seek(STREAM *s, int offs, int mode) {
  function file_tell (line 138) | static int file_tell(STREAM *s) {
  function file_sync (line 142) | static int file_sync(STREAM *s) {
  function file_close (line 146) | static int file_close(STREAM *s) {
  function file_access (line 150) | static int file_access( const char *filename ) {
  type membuffer (line 164) | typedef struct membuffer {
  type ramdisk (line 171) | typedef struct ramdisk {
  function ramdisk (line 177) | ramdisk *ramnew(void) {
  function ramdisk (line 182) | ramdisk *ramfind(const char *filename) {
  function mem_open (line 189) | static int mem_open(STREAM *s, const char *spec, va_list vl) {
  function mem_read (line 221) | static int mem_read(STREAM *s, void *ptr, int sz) {
  function round_next_pow2 (line 232) | static unsigned round_next_pow2(unsigned v) {
  function mem_write (line 244) | static int mem_write(STREAM *s, const void *ptr, int sz) {
  function mem_seek (line 269) | static int mem_seek(STREAM *s, int offs, int mode) {
  function mem_tell (line 283) | static int mem_tell(STREAM *s) {
  function mem_sync (line 288) | static int mem_sync(STREAM *s) {
  function mem_close (line 293) | static int mem_close(STREAM *s) {
  type STREAM (line 315) | typedef struct STREAM {
  function stream_make (line 338) | int stream_make(
  function STREAM (line 362) | STREAM *stream_open(const char *spec, ...) {
  function stream_pipe (line 393) | int stream_pipe(STREAM *self, int(*pipe)(void*,int)) {
  function read_loop (line 399) | static
  function write_loop (line 419) | static
  function stream_read (line 439) | int stream_read(STREAM *self, void *ptr, int sz) {
  function stream_puts (line 451) | int stream_puts(STREAM *self, const void *ptr, int sz) {
  function stream_seek (line 463) | int stream_seek(STREAM *self, int offs, int mode) {
  function stream_tell (line 473) | int stream_tell(STREAM *self) {
  function stream_sync (line 484) | int stream_sync(STREAM *self) {
  function stream_shut (line 493) | int stream_shut(STREAM *self) {
  function stream_link (line 504) | int stream_link(STREAM *self, STREAM *other) {

FILE: vault/ds_string.c
  function strsplit (line 68) | array(char*) strsplit(const char *text_, const char *delimiters) {
  function strsplit2 (line 131) | array(char*) strsplit2(const char *str, const char *separator) { // @tod...
  function streq (line 165) | int streq( const char *string, const char *substr ) {
  function streqi (line 168) | int streqi( const char *string, const char *substr ) {
  function strhead (line 193) | int strhead( const char *str, const char *substr ) {
  function strtail (line 197) | int strtail( const char *s, const char *e ) {
  function strmatch (line 289) | int strmatch(const char *s, const char *wildcard) {
  function strhash (line 296) | uint64_t strhash( const char *s ) { // for convenience. wrapper over ori...
  function strutf8 (line 302) | array(uint32_t) strutf8( const char *utf8 ) {
  function strchop (line 336) | int strchop(const char *src, const char *substr, char **left, char **rig...
  function main (line 358) | int main() {

FILE: vault/net_ecdh.h
  type bitvec_t (line 231) | typedef bitvec_t gf2elem_t;
  type bitvec_t (line 232) | typedef bitvec_t scalar_t;
  function bitvec_get_bit (line 359) | static int bitvec_get_bit(const bitvec_t x, const uint32_t idx)
  function bitvec_clr_bit (line 364) | static void bitvec_clr_bit(bitvec_t x, const uint32_t idx)
  function bitvec_copy (line 369) | static void bitvec_copy(bitvec_t x, const bitvec_t y)
  function bitvec_swap (line 378) | static void bitvec_swap(bitvec_t x, bitvec_t y)
  function bitvec_equal (line 388) | static int bitvec_equal(const bitvec_t x, const bitvec_t y)
  function bitvec_equal (line 402) | static int bitvec_equal(const bitvec_t x, const bitvec_t y)
  function bitvec_set_zero (line 414) | static void bitvec_set_zero(bitvec_t x)
  function bitvec_is_zero (line 425) | static int bitvec_is_zero(const bitvec_t x)
  function bitvec_is_zero (line 440) | static int bitvec_is_zero(const bitvec_t x)
  function bitvec_degree (line 453) | static int bitvec_degree(const bitvec_t x)
  function bitvec_lshift (line 480) | static void bitvec_lshift(bitvec_t x, const bitvec_t y, int nbits)
  function gf2field_set_one (line 522) | static void gf2field_set_one(gf2elem_t x)
  function gf2field_is_one (line 536) | static int gf2field_is_one(const gf2elem_t x)
  function gf2field_is_one (line 556) | static int gf2field_is_one(const gf2elem_t x)
  function gf2field_add (line 576) | static void gf2field_add(gf2elem_t z, const gf2elem_t x, const gf2elem_t y)
  function gf2field_inc (line 586) | static void gf2field_inc(gf2elem_t x)
  function gf2field_mul (line 593) | static void gf2field_mul(gf2elem_t z, const gf2elem_t x, const gf2elem_t y)
  function gf2field_inv (line 648) | static void gf2field_inv(gf2elem_t z, const gf2elem_t x)
  function gf2point_copy (line 694) | static void gf2point_copy(gf2elem_t x1, gf2elem_t y1, const gf2elem_t x2...
  function gf2point_set_zero (line 700) | static void gf2point_set_zero(gf2elem_t x, gf2elem_t y)
  function gf2point_is_zero (line 706) | static int gf2point_is_zero(const gf2elem_t x, const gf2elem_t y)
  function gf2point_double (line 713) | static void gf2point_double(gf2elem_t x, gf2elem_t y)
  function gf2point_add (line 740) | static void gf2point_add(gf2elem_t x1, gf2elem_t y1, const gf2elem_t x2,...
  function gf2point_mul (line 790) | static void gf2point_mul(gf2elem_t x, gf2elem_t y, const scalar_t exp)
  function gf2point_mul (line 810) | static void gf2point_mul(gf2elem_t x, gf2elem_t y, const scalar_t exp)
  function gf2point_on_curve (line 842) | static int gf2point_on_curve(const gf2elem_t x, const gf2elem_t y)
  function ecdh_generate_keys (line 878) | int ecdh_generate_keys(uint8_t* public_key, const uint8_t* private_key)
  function ecdh_shared_secret (line 908) | int ecdh_shared_secret(const uint8_t* private_key, const uint8_t* others...
  function ecdsa_sign (line 944) | int ecdsa_sign(const uint8_t* private_key, uint8_t* hash, uint8_t* rando...
  function ecdsa_verify (line 1022) | int ecdsa_verify(const uint8_t* public_key, uint8_t* hash, const uint8_t...

FILE: vault/net_fragment.c
  type fragment_header (line 33) | typedef struct fragment_header {
  function fragment_num (line 41) | int fragment_num(int msglen) {
  function fragment_sizeof (line 44) | int fragment_sizeof(int fragment_seq, int msglen) {
  type fragment_header (line 60) | struct fragment_header
  function fragment_verify (line 70) | int fragment_verify(array(char*) fragments) {
  function main (line 108) | int main() {

FILE: vault/net_tunnel.c
  function handshake_server (line 7) | void handshake_server(const char *port) {
  function handshake_client (line 10) | void handshake_client(const char *address, const char *port) {

FILE: vault/net_webserver.c
  function nweb23 (line 82) | static
  function webserver (line 182) | int webserver(int port, const char *path) {
  function main (line 215) | int main() {

FILE: vault/os.c
  function main (line 131) | int main() {
  function my_quit (line 134) | void my_quit(void) {

FILE: vault/os_ansi.c
  function os_columns (line 20) | int os_columns(void) {
  function os_ansi (line 38) | void os_ansi(void) {
  function os_beep (line 51) | void os_beep(void) {
  function os_reset (line 55) | void os_reset(void) {
  function os_color (line 78) | void os_color(uint8_t r, uint8_t g, uint8_t b) {

FILE: vault/os_breakpoint.c
  function os_breakpoint (line 7) | void os_breakpoint() {
  function main (line 19) | int main() {

FILE: vault/os_cpu.c
  function ULONGLONG (line 10) | static ULONGLONG cpu_diff_time_(const FILETIME one, const FILETIME two) {
  function cpu_usage (line 30) | double cpu_usage(void) {
  function cpu_cores (line 65) | int cpu_cores(void) {
  function cpu_pid (line 105) | int cpu_pid(void) {
  function main (line 115) | int main() {

FILE: vault/os_date.c
  function date_base10 (line 27) | static uint64_t date_base10(int64_t unixstamp) {
  function today_ust (line 73) | uint64_t today_ust() {
  function today_gmt (line 77) | uint64_t today_gmt() {
  function date (line 88) | uint64_t date() {
  function main (line 116) | int main() {

FILE: vault/os_dialog.c
  function wchar_t (line 22) | wchar_t *dialog_widen(wchar_t *buf, int sz, const char *utf8) { // wide ...
  function os_dialog (line 32) | int os_dialog( int buttons, const char *title, const char *message ) {
  function main (line 70) | int main() {

FILE: vault/os_die.c
  function main (line 50) | int main() {

FILE: vault/os_entropy.c
  function os_entropy_ (line 14) | void os_entropy_( void *buf, unsigned n ) {
  function os_entropy_ (line 28) | void os_entropy_( void *buf, unsigned n ) {
  function prng_next (line 52) | static uint32_t prng_next(void) {
  function os_entropy_ (line 73) | void os_entropy_( void *buf, unsigned n ) {
  function os_entropy (line 87) | void os_entropy(void *buf, unsigned n) {
  function main (line 105) | int main() {

FILE: vault/os_env.c
  function env_free (line 127) | uint64_t env_free() {
  function main (line 169) | int main() {

FILE: vault/os_file.c
  function munmap (line 113) | static void munmap(void* addr, size_t length) {
  function wchar_t (line 125) | wchar_t *file_widen(const char *utf8) { // wide strings (windows only)
  function file_unmap (line 162) | void file_unmap( char *buf, size_t len ) {
  type maplen (line 167) | struct maplen { char *map; int len; }
  type maplen (line 170) | struct maplen
  function file_size (line 178) | int file_size( const char *pathfile ) {
  function file_stamp (line 193) | int file_stamp( const char *pathfile ) {
  function file_exist (line 199) | bool file_exist( const char *pathfile ) {
  function file_isdir (line 205) | bool file_isdir( const char *pathfile ) {
  function file_isfile (line 209) | bool file_isfile( const char *pathfile ) {
  function file_islink (line 213) | bool file_islink( const char *pathfile ) {
  function file_exact (line 223) | bool file_exact(const char *fname1, const char *fname2) {
  function file_write (line 267) | bool file_write(const char *pathfile, const void *data, int len) {
  function file_append (line 275) | bool file_append(const char *pathfile, const void *data, int len) {
  function file_touch (line 283) | bool file_touch( const char *pathfile, size_t modtime ) {
  function file_copy (line 295) | bool file_copy( const char *pathsrc, const char *pathdst ) {
  function file_delete (line 319) | bool file_delete( const char *path ) {
  function file_checksum (line 354) | uint64_t file_checksum( const char *pathfile ) {
  function file_stat (line 361) | bool file_stat( const char *uri, struct stat *out_info ) {
  function main (line 377) | int main() {

FILE: vault/os_icon.c
  function HICON (line 12) | static HICON os_load_ico( const char *ico_pathfile ) {
  function os_icon (line 25) | void os_icon(const char *pathfile_ico) {
  function os_icon (line 38) | void os_icon(const char *) {
  function main (line 44) | int main() {

FILE: vault/os_ini.c
  function main (line 63) | int main() {

FILE: vault/os_locale.c
  function os_locale (line 7) | void os_locale(void) {

FILE: vault/os_logger2.c
  type tm (line 27) | struct tm
  function log_create (line 38) | void log_create( FILE *fp, int bufsz ) {
  function log_puts (line 51) | int log_puts( const char *msg, ... ) {
  function main (line 65) | int main() {

FILE: vault/os_logger3.c
  function main (line 71) | int main() {

FILE: vault/os_mime.c
  type type (line 12) | struct type {
  function main (line 138) | int main( int argc, const char **argv ) {

FILE: vault/os_singleton.c
  function os_singleton__quit (line 18) | void os_singleton__quit(void) {
  function os_singleton (line 25) | bool os_singleton(const char *guid) {
  function os_singleton (line 40) | bool os_singleton(const char *guid) {
  function main (line 48) | int main() {

FILE: vault/os_test.c
  function unit (line 17) | int unit(const char *name) {
  function test (line 22) | int test(int expr) {
  function main (line 47) | int main() {

FILE: vault/os_trap.c
  function os_signal_ (line 11) | void os_signal_(int handler) {
  function os_trap (line 30) | void os_trap( void(*handler)(int) ) {
  function os_crash (line 43) | void os_crash(void) {
  function main (line 49) | int main() {
  function catch_signal (line 87) | static void catch_signal( int sig ) {
  function catch_se (line 102) | static void _cdecl catch_se( unsigned int ex, EXCEPTION_POINTERS *p ) {
  function os_trap_fpe (line 118) | void os_trap_fpe() {
  function os_trap (line 127) | void os_trap(void) { // @todo: TRAP_C, TRAP_CPP, TRAP_FPE flags?
  function os_crash (line 180) | void os_crash(void) {
  function main (line 187) | int main() {

FILE: vault/os_tray.c
  function LRESULT (line 19) | static LRESULT CALLBACK SystrayThreadProc(HWND hWnd, UINT Msg, WPARAM wP...
  function DWORD (line 56) | static DWORD CALLBACK SystrayThread(LPVOID arg) {
  function os_tray (line 73) | void os_tray( const char *tray_name, const char *tray_icon_pathfile ) {
  function os_tray (line 84) | void os_tray( const char *title, const char *icon )
  function main (line 89) | int main() {

FILE: vault/syn_atomic.c
  function atomic_set (line 33) | int64_t atomic_set( int64_t *ptr, const int value ) {
  function atomic_get (line 36) | int64_t atomic_get( int64_t *ptr ) {
  function atomic_inc (line 39) | int64_t atomic_inc( int64_t *ptr ) {
  function atomic_dec (line 42) | int64_t atomic_dec( int64_t *ptr ) {
  function main (line 49) | int main() {

FILE: vault/syn_channel.c
  type channel (line 23) | typedef struct channel channel;
  type channel (line 40) | struct channel {
  function channel (line 52) | channel* channel_init(int valuesize) {
  function channel_quit (line 70) | void channel_quit(channel *chan) {
  function channel_send (line 78) | void channel_send(channel *chan, void *value) {
  function channel_recv (line 116) | int channel_recv(channel *chan, void *output) {
  function channel_wait (line 137) | int channel_wait(channel *chan, void *output, int ms) {
  function async_send (line 172) | void async_send( void *args ) {
  function main (line 178) | int main() {
  function pstate (line 197) | void pstate(channel *chan) {
  function precv (line 215) | void precv(channel *chan) {
  function main (line 225) | int main() {

FILE: vault/syn_condv.c
  type condv (line 7) | typedef union condv {
  function condv_timedwait (line 68) | static int condv_timedwait( condv_t *c, mutex *m, int ms ) {
  function condv_init (line 92) | void condv_init( condv *c ) {
  function condv_quit (line 95) | void condv_quit( condv *c ) {
  function condv_emit (line 98) | void condv_emit( condv *c ) {
  function condv_wait (line 101) | void condv_wait( condv *c, void *m, int ms ) {
  function main (line 113) | int main() {

FILE: vault/syn_coro.c
  type coroutine_t (line 5) | typedef struct coroutine_t {

FILE: vault/syn_fiber.c
  function my_entry (line 145) | void my_entry(void) {
  function main (line 154) | int main() {

FILE: vault/syn_fiber_amd64.h
  function co_init (line 72) | static void co_init() {
  function co_init (line 102) | static void co_init() {
  function crash (line 112) | static void crash() {
  function cothread_t (line 116) | cothread_t co_active() {
  function cothread_t (line 121) | cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
  function co_delete (line 141) | void co_delete(cothread_t handle) {
  function co_switch (line 145) | void co_switch(cothread_t handle) {

FILE: vault/syn_fiber_arm.h
  function co_init (line 27) | static void co_init() {
  function cothread_t (line 36) | cothread_t co_active() {
  function cothread_t (line 41) | cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
  function co_delete (line 60) | void co_delete(cothread_t handle) {
  function co_switch (line 64) | __attribute__((target("arm"))) // @smibarber

FILE: vault/syn_fiber_ppc.h
  function cothread_t (line 278) | cothread_t co_create(unsigned int size, void (*entry_)(void)) {
  function co_delete (line 328) | void co_delete(cothread_t t) {
  function co_init_ (line 332) | static void co_init_(void) {
  function cothread_t (line 352) | cothread_t co_active() {
  function co_switch (line 358) | void co_switch(cothread_t t) {

FILE: vault/syn_fiber_sjlj.h
  type cothread_struct (line 16) | typedef struct {
  function springboard (line 26) | static void springboard(int ignored) {
  function cothread_t (line 32) | cothread_t co_active() {
  function cothread_t (line 37) | cothread_t co_create(unsigned int size, void (*coentry)(void)) {
  function co_delete (line 77) | void co_delete(cothread_t cothread) {
  function co_switch (line 86) | void co_switch(cothread_t cothread) {

FILE: vault/syn_fiber_ucontext.h
  function cothread_t (line 26) | cothread_t co_active() {
  function cothread_t (line 31) | cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
  function co_delete (line 47) | void co_delete(cothread_t cothread) {
  function co_switch (line 54) | void co_switch(cothread_t cothread) {

FILE: vault/syn_fiber_win32.h
  function co_thunk (line 17) | static void __stdcall co_thunk(void* coentry) {
  function cothread_t (line 21) | cothread_t co_active() {
  function cothread_t (line 29) | cothread_t co_create(unsigned int heapsize, void (*coentry)(void)) {
  function co_delete (line 37) | void co_delete(cothread_t cothread) {
  function co_switch (line 41) | void co_switch(cothread_t cothread) {

FILE: vault/syn_fiber_x86.h
  function co_init (line 46) | static void co_init() {
  function co_init (line 56) | static void co_init() {
  function crash (line 66) | static void crash() {
  function cothread_t (line 70) | cothread_t co_active() {
  function cothread_t (line 75) | cothread_t co_create(unsigned int size, void (*entrypoint)(void)) {
  function co_delete (line 95) | void co_delete(cothread_t handle) {
  function co_switch (line 99) | void co_switch(cothread_t handle) {

FILE: vault/syn_mcmp.c
  type mcmp (line 8) | struct mcmp
  type mcmp (line 10) | struct mcmp
  type mcmp (line 11) | struct mcmp
  type mcmp (line 12) | struct mcmp
  type mcmp (line 13) | struct mcmp
  type mcmp_node (line 25) | struct mcmp_node {
  type mcmp (line 30) | struct mcmp {
  function mcmp_new (line 36) | int mcmp_new(struct mcmp *ctx) {
  function mcmp_del (line 46) | int mcmp_del(struct mcmp *ctx){
  function mcmp_add (line 60) | int mcmp_add(struct mcmp *ctx, void * data) {
  type mcmp (line 78) | struct mcmp
  type mcmp_node (line 80) | struct mcmp_node
  function main (line 99) | int main() {

FILE: vault/syn_mutex.c
  type mutex (line 8) | typedef union mutex mutex;
  function mutex_initial_ (line 56) | static void mutex_initial_(pthread_mutex_t *mutex) {
  function mutex_new (line 69) | void mutex_new(mutex *m) {
  function mutex_del (line 73) | void mutex_del(mutex *m) {
  function mutex_trylock (line 76) | bool mutex_trylock(mutex *m) {
  function mutex_acquire (line 79) | void mutex_acquire(mutex *m) {
  function mutex_release (line 82) | void mutex_release(mutex *m) {
  function main (line 91) | int main() {
  function main (line 111) | int main() {

FILE: vault/syn_semaphore.c
  type semaphore (line 8) | typedef struct semaphore semaphore;
  type semaphore (line 22) | struct semaphore {
  function semaphore_init (line 28) | void semaphore_init( semaphore *s ) {
  function semaphore_wait (line 33) | void semaphore_wait( semaphore *s ) {
  function semaphore_emit (line 41) | void semaphore_emit( semaphore *s ) {
  function semaphore_quit (line 47) | void semaphore_quit( semaphore *s ) {
  function main (line 58) | int main() {

FILE: vault/syn_sleep.c
  function sleep_ns (line 22) | void sleep_ns( double ns ) {
  function sleep_us (line 39) | void sleep_us( double us ) {
  function sleep_ms (line 42) | void sleep_ms( double ms ) {
  function sleep_ss (line 45) | void sleep_ss( double ss ) {

FILE: vault/syn_thread.c
  function thread_self (line 57) | uint64_t thread_self() {
  function thread_yield (line 68) | void thread_yield() {
  function detach (line 78) | bool detach( void (*func)(void *), void *arg ) {
  function thread (line 81) | bool thread(int thread_id, void (*func)(void *), void *arg) {
  function join (line 84) | bool join(int thread_id) {
  type thread_args (line 89) | typedef struct thread_args {
  type thread_args (line 108) | struct thread_args
  type thread_args (line 108) | struct thread_args
  function detach (line 121) | bool detach( void (*func)(void *), void *arg ) {
  function thread (line 126) | bool thread(int thread_id, void (*func)(void *), void *arg) {
  function join (line 129) | bool join(int thread_id) {
  function write (line 153) | void write( void *arg ) {
  function main (line 156) | int main() {

FILE: vault/syn_tls.c
  type tls (line 17) | struct tls {
  function tls_add_init (line 23) | void tls_add_init( void (*func)(void *arg), void *arg ) {
  function tls_add_quit (line 28) | void tls_add_quit( void (*func)(void *arg), void *arg ) {
  function tls_init (line 33) | void tls_init() {
  function tls_quit (line 38) | void tls_quit() {
  function myinit1 (line 65) | void myinit1(void *arg) { puts("hi1!"); }
  function myinit2 (line 66) | void myinit2(void *arg) { puts("hi2!"); }
  function myquit2 (line 67) | void myquit2(void *arg) { puts("bye2!"); }
  function myquit1 (line 68) | void myquit1(void *arg) { puts("bye1!"); }
  function hello (line 70) | void hello(void *arg) { puts("hello"); }
  function main (line 72) | int main() {
Condensed preview — 145 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (538K chars).
[
  {
    "path": "README.md",
    "chars": 2627,
    "preview": "# tinybits\n- [x] Tiny bits and useful snippets that I keep using everywhere.\n- [x] Too simple to become libraries. Just "
  },
  {
    "path": "UNLICENSE.md",
    "chars": 1210,
    "preview": "This is free and unencumbered software released into the public domain.\n\nAnyone is free to copy, modify, publish, use, c"
  },
  {
    "path": "tinyarc4.hpp",
    "chars": 1630,
    "preview": "// tinyARC4, ARC4 stream cypher. based on code by Mike Shaffer.\n// - rlyeh, public domain ~~ listening to Black Belt - L"
  },
  {
    "path": "tinyassert.c",
    "chars": 2827,
    "preview": "// old assert() macro with new tricks.\n// - rlyeh, public domain.\n//\n// - [x] log failures always. break debugger only o"
  },
  {
    "path": "tinyatoi.c",
    "chars": 499,
    "preview": "// Tiny atoi() replacement. rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n\nstatic\nint tinyatoi( const char *s ) {\n    "
  },
  {
    "path": "tinybenchmark.hpp",
    "chars": 473,
    "preview": "// tiny benchmarks. OpenMP required.\n// - rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <omp.h>\n#include <std"
  },
  {
    "path": "tinybsearch.c",
    "chars": 2346,
    "preview": "// Tiny binary search (dichotomic): array must be sorted && supporting sequential access.\n// - rlyeh, public domain | wt"
  },
  {
    "path": "tinybsearch.cc",
    "chars": 1212,
    "preview": "// Tiny binary search (dichotomic): container must be sorted && supporting sequential access.\n// - rlyeh, public domain "
  },
  {
    "path": "tinybuild.h",
    "chars": 1109,
    "preview": "// Tiny buildinfo macros\n// - rlyeh, public domain | wtrmrkrlyeh\n\n#pragma once\n\n#ifndef BUILD_GIT_BRANCH\n#define BUILD_G"
  },
  {
    "path": "tinydebug.h",
    "chars": 3041,
    "preview": "// Tiny debug macros\n// - rlyeh, public domain | wtrmrkrlyeh\n//\n// Build cube of 3 dimensions, 5 levels each:\n//\n//     "
  },
  {
    "path": "tinydefer.cc",
    "chars": 546,
    "preview": "// tinydefer, Go style\n// - rlyeh, public domain.\n\n#include <functional>\n\nstruct defer {\n    std::function<void()> fn;\n "
  },
  {
    "path": "tinydir.cc",
    "chars": 1572,
    "preview": "// tiny directory listing\n// - rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <string>\n\n#ifdef _WIN32\n#include"
  },
  {
    "path": "tinydixy.c",
    "chars": 2793,
    "preview": "// tinydixy, small hierarchical config file format (subset of YAML, spec in https://github.com/kuyawa/Dixy)\n// - rlyeh, "
  },
  {
    "path": "tinydual.sh.bat",
    "chars": 117,
    "preview": "#/bin/bash 2>nul || goto :windows\n\n# bash\necho hello Bash\nls\nexit\n\n:windows\n@echo off\necho hello Windows\nver\nexit /b\n"
  },
  {
    "path": "tinyendian.c",
    "chars": 1097,
    "preview": "// Tiny endianness. rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <stdint.h>\n\n#define IS_BIG_ENDIAN (*(uint16"
  },
  {
    "path": "tinyerror.c",
    "chars": 1706,
    "preview": "// simple error handling api. non-intrusive version.\n// - rlyeh, public domain.\n// \n// Errors automatically printed in d"
  },
  {
    "path": "tinyfsm.c",
    "chars": 1183,
    "preview": "// Tiny FSM. rlyeh, public domain | wtrmrkrlyeh\n\n#pragma once\n#define with(st)        for(int i=1;i--;st[1]=st[0]) switc"
  },
  {
    "path": "tinygc.cc",
    "chars": 4554,
    "preview": "// tiny garbage collector (<100 LOCs). Genius code tricks by @orangeduck (see: https://github.com/orangeduck/tgc README)"
  },
  {
    "path": "tinyhexbase.c",
    "chars": 1626,
    "preview": "// hexBASE \n// Very simple binary to ascii encoding. 0 to 2+100% bytes overhead (worst case)\n//\n// Specification:\n// if "
  },
  {
    "path": "tinyhexdump.c",
    "chars": 961,
    "preview": "// Tiny hexdump viewer. rlyeh, public domain | wtrmrkrlyeh\n#include <stdio.h>\n\nvoid hexdump( FILE *fp, const void *ptr, "
  },
  {
    "path": "tinyhuman.hpp",
    "chars": 2127,
    "preview": "// tiny de/humanized numbers. based on freebsd implementation.\n// - rlyeh, public domain | wtrmrkrlyeh\n\n#pragma once\n#in"
  },
  {
    "path": "tinyini.c",
    "chars": 4395,
    "preview": "// ini+, extended ini format \n// - rlyeh, public domain\n//\n// # spec\n//\n//   ; line comment\n//   [details]          ; ma"
  },
  {
    "path": "tinyjson5.c",
    "chars": 14585,
    "preview": "// JSON5 + SJSON parser module\n//\n// License:\n// This software is dual-licensed to the public domain and under the follo"
  },
  {
    "path": "tinylog.c",
    "chars": 1441,
    "preview": "// Tiny logging utilities. rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <stdio.h>\n#include <time.h>\n\n#ifdef "
  },
  {
    "path": "tinylog.h",
    "chars": 1455,
    "preview": "// Tiny logging utilities. rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <stdio.h>\n#include <time.h>\n\n#ifdef "
  },
  {
    "path": "tinylogger.h",
    "chars": 3009,
    "preview": "// simple logger. likely slow, though.\n// - rlyeh, public domain.\n//\n// - [x] colors based on content.\n// - [x] no loggi"
  },
  {
    "path": "tinylogger.hpp",
    "chars": 844,
    "preview": "// Tiny session logger. rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <stdio.h>\n\n#ifdef SHIPPING\nstruct logge"
  },
  {
    "path": "tinymatch.c",
    "chars": 835,
    "preview": "// tiny wildcard/pattern matching. Based on anonymous souce code (Rob Pike's ?).\n// - rlyeh. public domain | wtrmrkrlyeh"
  },
  {
    "path": "tinymime.c",
    "chars": 11461,
    "preview": "// tinymime. ported from https://github.com/sindresorhus/file-type (source is mit licensed)\n// - rlyeh, public domain\n\n#"
  },
  {
    "path": "tinypipe.hpp",
    "chars": 3415,
    "preview": "// tiny chainable pipes (C++11)\n// - rlyeh, public domain | wtrmrkrlyeh\n\n#pragma once\n#include <vector>\n#include <sstrea"
  },
  {
    "path": "tinyprint.cc",
    "chars": 387,
    "preview": "// Tiny printer. Original code by Evan Wallace. rlyeh, public domain | wtrmrkrlyeh\n#include <iostream>\n\nstruct print {\n\t"
  },
  {
    "path": "tinypulse.c",
    "chars": 592,
    "preview": "// Tiny digital pulses/signals. rlyeh, public domain | wtrmrkrlyeh\n#include <stdio.h>\n\nvoid pulse( int *state ) {\n    sw"
  },
  {
    "path": "tinyroman.cc",
    "chars": 908,
    "preview": "// Tiny integer to roman numerals converter (roughly tested). rlyeh, public domain | wtrmrkrlyeh\n#include <map>\n#include"
  },
  {
    "path": "tinystring.c",
    "chars": 2373,
    "preview": "// C string library\n// - rlyeh, public domain\n\n// temporary strings api (stack)\nchar* strtmp(const char *fmt, ...);\nint "
  },
  {
    "path": "tinystring.cc",
    "chars": 2795,
    "preview": "// tiny C++ string utilities\n// - rlyeh, public domain | wtrmrkrlyeh\n\n// @toadd: pad, left, right, center, triml, trimr,"
  },
  {
    "path": "tinytga.c",
    "chars": 886,
    "preview": "// Tiny TGA writer: original code by jon olick, public domain\n// Elder C version by rlyeh, public domain | wtrmrkrlyeh\n#"
  },
  {
    "path": "tinytime.cc",
    "chars": 1038,
    "preview": "// Tiny timing utilities. rlyeh, public domain | wtrmrkrlyeh\n#include <thread>\n#include <chrono>\n#if !defined(TIMING_USE"
  },
  {
    "path": "tinytodo.c",
    "chars": 1204,
    "preview": "// Tiny todo() static assert macro. based on code by https://github.com/andyw8/do_by\n// - rlyeh, public domain | wtrmrkr"
  },
  {
    "path": "tinytty.c",
    "chars": 1900,
    "preview": "// Tiny terminal utilities. rlyeh, public domain | wtrmrkrlyeh\n#include <stdio.h>\n\n#ifdef _WIN32\n#define ANSI(ansi, win)"
  },
  {
    "path": "tinyuniso.cc",
    "chars": 5407,
    "preview": "// tiny iso/9660 unarchiver. [ref] http://wiki.osdev.org/ISO_9660\n// - rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#"
  },
  {
    "path": "tinyunit.c",
    "chars": 764,
    "preview": "// Tiny unittest suite. rlyeh, public domain | wtrmrkrlyeh\n#include <stdio.h>\n#include <string.h>\n#include <stdlib.h>\n#d"
  },
  {
    "path": "tinyuntar.cc",
    "chars": 3987,
    "preview": "// portable gnu tar and ustar extraction\n// - rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <string>\n#include"
  },
  {
    "path": "tinyunzip.cc",
    "chars": 5451,
    "preview": "// tiny zip unarchiver. based on junzip by Joonas Pihlajamaa\n// - rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#inclu"
  },
  {
    "path": "tinyvariant.cc",
    "chars": 3294,
    "preview": "// Tiny variant class. rlyeh, public domain | wtrmrkrlyeh\n#include <string>\n#include <functional>\n\nstruct var {\n    int "
  },
  {
    "path": "tinyvbyte.h",
    "chars": 2822,
    "preview": "// tiny variable byte length encoder/decoder (vbyte)\n// - rlyeh, public domain | wtrmrkrlyeh\n#pragma once\n#include <stdi"
  },
  {
    "path": "tinywav.c",
    "chars": 903,
    "preview": "// Tiny WAV writer: original code by jon olick, public domain\n// Floating point support + pure C version by rlyeh, publi"
  },
  {
    "path": "tinywtf.h",
    "chars": 7291,
    "preview": "// tiny portable host macros (C/C++ language features, compilers, os, arch, tls...)\n// used to avoid #if/n/def hell.\n// "
  },
  {
    "path": "tinyzlib.cpp",
    "chars": 6902,
    "preview": "// tiny zlib inflater. extracted from tigr (credits to Richard Mitton). @todo: remove exceptions\n// - rlyeh, public doma"
  },
  {
    "path": "vault/; ds",
    "chars": 1,
    "preview": "\n"
  },
  {
    "path": "vault/_test.c",
    "chars": 94,
    "preview": "// compilation test\n// - rlyeh, public domain\n\n#define ALL_C\n#include \"all.c\"\n\nint main() \n{}\n"
  },
  {
    "path": "vault/all.c",
    "chars": 257,
    "preview": "// - rlyeh, public domain\n\n#ifdef ALL_C\n#define C_C\n#define OS_C\n#define DS_C\n#define SYN_C\n#define BIN_C\n#define BUF_C\n"
  },
  {
    "path": "vault/bin.c",
    "chars": 140,
    "preview": "// - rlyeh, public domain\n\n#ifdef BIN_C\n#define DBKV_C\n#define JSON5_C\n#endif\n\n#include \"os.c\"\n#include \"bin_dbkv.c\"\n#in"
  },
  {
    "path": "vault/bin_dbkv.c",
    "chars": 25154,
    "preview": "// KISSDB written by Adam Ierymenko <adam.ierymenko@zerotier.com>\n// KISSDB is in the public domain and is distributed w"
  },
  {
    "path": "vault/bin_json5.c",
    "chars": 13560,
    "preview": "// JSON5 + SJSON parser module\n//\n// License:\n// This software is dual-licensed to the public domain and under the follo"
  },
  {
    "path": "vault/buf.c",
    "chars": 971,
    "preview": "// - rlyeh, public domain\n\n#ifdef BUF_C\n#define ARC4_C\n#define BASE64_C\n#define BASE92_C\n#define COBS_C\n#define CRC_C\n#d"
  },
  {
    "path": "vault/buf_arc4.c",
    "chars": 1604,
    "preview": "// ARC4 de/cryptor. Based on code by Mike Shaffer.\n// - rlyeh, public domain.\n\nvoid *arc4( void *buffer, unsigned buflen"
  },
  {
    "path": "vault/buf_base64.c",
    "chars": 3763,
    "preview": "// base64 de/encoder. Based on code by Jon Mayo - November 13, 2003 (PUBLIC DOMAIN).\n// - rlyeh, public domain\n//\n// not"
  },
  {
    "path": "vault/buf_base92.c",
    "chars": 6391,
    "preview": "// THE BEERWARE LICENSE (Revision 42):\n// <thenoviceoof> wrote this file. As long as you retain this notice you\n// can d"
  },
  {
    "path": "vault/buf_cobs.c",
    "chars": 3822,
    "preview": "// Based on code by Jacques Fortier.\n// \"Redistribution and use in source and binary forms are permitted, with or withou"
  },
  {
    "path": "vault/buf_crc.c",
    "chars": 1549,
    "preview": "// - rlyeh, public domain\n\nunsigned crc32(unsigned h, const void *ptr, unsigned len);\nuint64_t crc64(uint64_t h, const v"
  },
  {
    "path": "vault/buf_endian.c",
    "chars": 996,
    "preview": "// binary endianness ----------------------------------------------------------\n// - rlyeh, public domain\n\n#pragma once\n"
  },
  {
    "path": "vault/buf_interleave.c",
    "chars": 2437,
    "preview": "// array de/interleaving\n// - rlyeh, public domain.\n//\n// results:\n// R0G0B0   R1G1B1   R2G2B2...   -> R0R1R2... B0B1B2."
  },
  {
    "path": "vault/buf_netstring.c",
    "chars": 1841,
    "preview": "// netstring en/decoder\n// - rlyeh, public domain.\n\nunsigned netstring_bounds(unsigned inlen);\nunsigned netstring_encode"
  },
  {
    "path": "vault/buf_pack.c",
    "chars": 14316,
    "preview": "// Based on code by Brian \"Beej Jorgensen\" Hall (public domain) [1].\n// Based on code by Ginger Bill's half<->float (pub"
  },
  {
    "path": "vault/buf_pack754.h",
    "chars": 5621,
    "preview": "// float754.c packing ----------------------------------------------------------\n// [1] http://www.mrob.com/pub/math/flo"
  },
  {
    "path": "vault/buf_packhalf.h",
    "chars": 2408,
    "preview": "// from ginger bill's gbmath.h (public domain)\n\n#ifndef HALF_H\n#define HALF_H\n\ntypedef uint16_t half;\nfloat half_to_floa"
  },
  {
    "path": "vault/buf_packint.h",
    "chars": 1649,
    "preview": "// int packing -----------------------------------------------------------------\n// - rlyeh, public domain\n\n#pragma once"
  },
  {
    "path": "vault/buf_packvli.h",
    "chars": 7700,
    "preview": "// vli varint spec (licensed under public domain, unlicense, CC0 and MIT-0: pick one).\n// - rlyeh.\n// 7 [0 xxxx xxx]    "
  },
  {
    "path": "vault/buf_zigzag.c",
    "chars": 839,
    "preview": "// zigzag de/encoder\n// - rlyeh, public domain\n\n#ifndef ZIGZAG_H\n#define ZIGZAG_H\n#include <stdint.h>\n\nuint64_t zig64( i"
  },
  {
    "path": "vault/c.c",
    "chars": 410,
    "preview": "// - rlyeh, public domain\n\n#ifdef C_C\n#pragma once\n#define BENCHMARK_C\n#define IFDEF_C\n#define OVERLOAD_C\n#define WITH_C"
  },
  {
    "path": "vault/c_alignas.c",
    "chars": 208,
    "preview": "// - rlyeh, public domain\n\n#pragma once\n\n#if __STDC_VERSION__ >= 201112L\n#   ifndef _MSC_VER\n#   include <stdalign.h>\n# "
  },
  {
    "path": "vault/c_benchmark.c",
    "chars": 1010,
    "preview": "// - rlyeh, public domain\n\n#ifndef BENCHMARK_H\n#define BENCHMARK_H\n\n#include <stdio.h>\n#ifdef _MSC_VER\n#include <omp.h>\n"
  },
  {
    "path": "vault/c_cc4.c",
    "chars": 415,
    "preview": "#pragma once\n\n#define CC4(abcd)  ((0[#abcd \"\\0\\0\\0\\0\"] << 24) | (1[#abcd \"\\0\\0\\0\\0\"] << 16) | (2[#abcd \"\\0\\0\\0\\0\"] << 8)"
  },
  {
    "path": "vault/c_checkva.c",
    "chars": 258,
    "preview": "#pragma once\n\n// MSVC2015 trick by doynax (check+dead code elimination)\n// see: https://stackoverflow.com/a/42313782\n#de"
  },
  {
    "path": "vault/c_countof.c",
    "chars": 113,
    "preview": "// - rlyeh, public domain\n\n#pragma once\n\n#ifndef COUNTOF\n#define COUNTOF(x) (int)(sizeof(x)/sizeof(0[x]))\n#endif\n"
  },
  {
    "path": "vault/c_ifdef.c",
    "chars": 8083,
    "preview": "// - rlyeh, public domain\n\n#ifndef IFDEF_H\n#define IFDEF_H\n\n#define IF(x,T,...)           IF_(x)(T,__VA_ARGS__/*F*/)\n#de"
  },
  {
    "path": "vault/c_incbin.h",
    "chars": 13580,
    "preview": "/**\n * @file c_incbin.h\n * @author Dale Weiler\n * @brief Utility for including binary files\n *\n * Facilities for includi"
  },
  {
    "path": "vault/c_once.c",
    "chars": 428,
    "preview": "#pragma once\n#define ONCE static int once##__LINE__=1; for(;once##__LINE__;once##__LINE__=0)\n\n/*\n#define once_unique(a) "
  },
  {
    "path": "vault/c_overload.c",
    "chars": 796,
    "preview": "// msvc trick to expand vargs properly by Braden Steffaniak\n// - see https://stackoverflow.com/a/24028231\n\n#pragma once\n"
  },
  {
    "path": "vault/c_plan.c",
    "chars": 309,
    "preview": "// PLAN is usually a TODO taskfile, like: AUTORUN { puts(\"[x] task1\"); puts(\"[ ] task2\"); }\n// Usage: cl test.c -DPLAN=\""
  },
  {
    "path": "vault/c_section.c",
    "chars": 187,
    "preview": "// - rlyeh, public domain\n\n#pragma once\n\n#ifndef _MSC_VER\n#define SECTION(name) __attribute__((section(\".\" #name \"#\")))\n"
  },
  {
    "path": "vault/c_thread.c",
    "chars": 154,
    "preview": "// - rlyeh, public domain\n\n#pragma once\n\n#if defined _MSC_VER || defined __TINYC__\n#define THREAD __declspec(thread)\n#el"
  },
  {
    "path": "vault/c_unreachable.c",
    "chars": 352,
    "preview": "// - rlyeh, public domain\n\n#pragma once\n\n#ifdef DEBUG\n#define UNREACHABLE() assert(!\"This line was not meant to be reach"
  },
  {
    "path": "vault/c_with.c",
    "chars": 422,
    "preview": "// - rlyeh, public domain\n\n#pragma once\n#define ON  1\n#define OFF 0\n#define WITH(x) ((x)+0)\n\n/*\n// cl c_with.c\n// cl c_w"
  },
  {
    "path": "vault/ds.c",
    "chars": 531,
    "preview": "// [x] data structures: array, hash, map @todo: set, lfqueue, sort, comp,\n// - rlyeh, public domain\n\n#ifdef DS_C\n#define"
  },
  {
    "path": "vault/ds_alloc.c",
    "chars": 2854,
    "preview": "// [x] memory: realloc, vrealloc, stack\n// [ ] @todo: gc, pool, game mark/rewind+game stack |level|game|>---<stack|\n// -"
  },
  {
    "path": "vault/ds_array.c",
    "chars": 3819,
    "preview": "// array library --------------------------------------------------------------\n// - rlyeh, public domain\n\n#pragma once\n"
  },
  {
    "path": "vault/ds_format.c",
    "chars": 2211,
    "preview": "// format library\n// - rlyeh, public domain\n\n#ifndef FORMAT_H\n#define FORMAT_H\n#include <stdarg.h>\n\nchar*           vl(c"
  },
  {
    "path": "vault/ds_hash.c",
    "chars": 5142,
    "preview": "// hash ------------------------------------------------------------------------\n// - rlyeh, public domain\n\nuint64_t has"
  },
  {
    "path": "vault/ds_map.c",
    "chars": 11866,
    "preview": "// generic map<K,V> container.\n// ideas from: https://en.wikipedia.org/wiki/Hash_table\n// ideas from: https://probablyda"
  },
  {
    "path": "vault/ds_quark.c",
    "chars": 1281,
    "preview": "// quarks ----------------------------------------------------------------------\n// - rlyeh, public domain\n\n#ifndef QUAR"
  },
  {
    "path": "vault/ds_rope.c",
    "chars": 1948,
    "preview": "#ifndef ROPE_H\n#define ROPE_H\n\ntypedef struct rope rope;\n\nvoid rope_init( rope *s, int reserve, float grow );\nvoid rope_"
  },
  {
    "path": "vault/ds_set.c",
    "chars": 9108,
    "preview": "// generic set<K> container.\n// ideas from: https://en.wikipedia.org/wiki/Hash_table\n// ideas from: https://probablydanc"
  },
  {
    "path": "vault/ds_sort.c",
    "chars": 9961,
    "preview": "// compare (<0:less,0:equal,>0:greater) ----------------------------------------\n// - rlyeh, public domain\n\n// typed\nint"
  },
  {
    "path": "vault/ds_stream.c",
    "chars": 14939,
    "preview": "// stream: read/write/sync, stats, sim\n// implementations: mem/list(str), file/dir, tcp/udp, stdin/stdout, sql/kissdb\n//"
  },
  {
    "path": "vault/ds_string.c",
    "chars": 15529,
    "preview": "// string library\n// - rlyeh, public domain\n\n#ifndef STRING_H\n#define STRING_H\n\n// temporary strings api (stack)\n#define"
  },
  {
    "path": "vault/net.c",
    "chars": 300,
    "preview": "// - rlyeh, public domain\n\n#ifdef NET_C\n//#pragma once\n#define ECDH_C\n#define TCP_C\n#define FRAGMENT_C\n#define TUNNEL_C\n"
  },
  {
    "path": "vault/net_ecdh.h",
    "chars": 34155,
    "preview": "//#define ECC_CURVE NIST_K571 // 256bit, secure key is empty\n//#define ECC_CURVE NIST_B571 // 256bit, secure keys do not"
  },
  {
    "path": "vault/net_fragment.c",
    "chars": 4648,
    "preview": "// fragment data\n// - rlyeh, public domain\n//\n// ## fragment format\n// [fragnum:16][fraglen:16][crc:32][protocol-id(*):3"
  },
  {
    "path": "vault/net_tunnel.c",
    "chars": 263,
    "preview": "// crypted transport\n// 1. public handshake (ecdh) -> shared secret\n// 2. private tunnel (arc4 crypted)\n// - rlyeh, publ"
  },
  {
    "path": "vault/net_webserver.c",
    "chars": 8171,
    "preview": "// webserver, forked from nweb23.c by Nigel Griffiths (public domain).\n// - rlyeh, public domain.\n\n#ifndef WEBSERVER_H\n#"
  },
  {
    "path": "vault/os.c",
    "chars": 4456,
    "preview": "// [x] if/n/def hell + system headers: here, rather than in every header.\n// - rlyeh, public domain\n\n#ifndef OS_H\n#defin"
  },
  {
    "path": "vault/os_ansi.c",
    "chars": 3075,
    "preview": "// - rlyeh, public domain\n\nvoid os_ansi(void);\nvoid os_beep(void);\nvoid os_color(uint8_t r, uint8_t g, uint8_t b);\nvoid "
  },
  {
    "path": "vault/os_assert.c",
    "chars": 858,
    "preview": "// [x] assert: which works in release builds.\n// [x] test: test & autotest macros.\n// - rlyeh, public domain\n\n// -------"
  },
  {
    "path": "vault/os_breakpoint.c",
    "chars": 421,
    "preview": "void os_breakpoint();\n\n#ifdef BREAKPOINT_C\n#pragma once\n#include <signal.h>\n\nvoid os_breakpoint() {\n#if _MSC_VER\n    __d"
  },
  {
    "path": "vault/os_cpu.c",
    "chars": 3497,
    "preview": "   int cpu_pid(void);\n   int cpu_cores(void);\ndouble cpu_usage(void);\n\n\n#ifdef CPU_DEMO\n#pragma once\n#ifdef _WIN32\n#incl"
  },
  {
    "path": "vault/os_date.c",
    "chars": 3893,
    "preview": "// base10 clock format\n// -------------------\n// Every base10 calendar is a 64-bit number, where:\n//\n// 1844674407370955"
  },
  {
    "path": "vault/os_dialog.c",
    "chars": 2973,
    "preview": "// # dialog ###################################################################\n\nint os_dialog( int buttons, const char "
  },
  {
    "path": "vault/os_die.c",
    "chars": 1249,
    "preview": "#ifndef DIE_H\n#define DIE_H\n\n#define os_die(...) os_die(-__LINE__, __VA_ARGS__)\nvoid (os_die)(int rc, const char *fmt, ."
  },
  {
    "path": "vault/os_entropy.c",
    "chars": 2747,
    "preview": "// - rlyeh, public domain\n\nvoid os_entropy( void *buf, unsigned n );\n\n\n#ifdef ENTROPY_C\n#pragma once\n\n#ifdef _WIN32\n#inc"
  },
  {
    "path": "vault/os_env.c",
    "chars": 4634,
    "preview": "#ifndef ENV_H\n#define ENV_H\n\n// environment folders\n\nchar*    env_user(); // user name\nchar*    env_home(); // user home"
  },
  {
    "path": "vault/os_exec.c",
    "chars": 584,
    "preview": "// cmd system invokation\n// - rlyeh, public domain.\n\nchar *os_exec( const char *cmd );\n\n#ifdef EXEC_C\n#pragma once\n#ifde"
  },
  {
    "path": "vault/os_exit.c",
    "chars": 432,
    "preview": "// - rlyeh, public domain\n\n#ifndef EXIT_H\n#define EXIT_H\n\nvoid os_exit(int rc, const char *msg);\n#define os_exit(rc, ..."
  },
  {
    "path": "vault/os_file.c",
    "chars": 13056,
    "preview": "// file functions\n// - rlyeh, public domain.\n//\n// @todo: file_lock, file_unlock\n\n#ifndef FILE_H\n#define FILE_H\n#include"
  },
  {
    "path": "vault/os_icon.c",
    "chars": 1833,
    "preview": "// change window icon.\n// - rlyeh, public domain.\n\nvoid os_icon(const char *pathfile_ico);  // \"\" to restore (win32 only"
  },
  {
    "path": "vault/os_ini.c",
    "chars": 4062,
    "preview": "// ini+, extended ini format\n// - rlyeh, public domain\n//\n// # spec\n//\n//   ; line comment\n//   [user]             ; map"
  },
  {
    "path": "vault/os_locale.c",
    "chars": 197,
    "preview": "void os_locale(void);\n\n#ifdef LOCALE_C\n#pragma once\n#include <locale.h>\n\nvoid os_locale(void) {\n    // @graphitemaster r"
  },
  {
    "path": "vault/os_logger.c",
    "chars": 1373,
    "preview": "// [x] logger: info, warn, fail, quit. also todo() and fixme()\n// - rlyeh, public domain\n\n// ---------------------------"
  },
  {
    "path": "vault/os_logger2.c",
    "chars": 1943,
    "preview": "#ifndef LOGGER2_H\n#define LOGGER2_H\n#include <stdio.h>\n\n// create logger with given buffer size\nvoid log_create( FILE *f"
  },
  {
    "path": "vault/os_logger3.c",
    "chars": 3470,
    "preview": "// simple logger. likely slow, though.\n// - rlyeh, public domain.\n//\n// - [x] colors based on content.\n// - [x] no loggi"
  },
  {
    "path": "vault/os_memory.c",
    "chars": 628,
    "preview": "// - rlyeh, public domain\n\n#ifndef MEMORY_H\n#define MEMORY_H\n\n#include <string.h>\n#include <stdlib.h>\n\n#ifndef REALLOC\n#"
  },
  {
    "path": "vault/os_mime.c",
    "chars": 5929,
    "preview": "// detect file/mime types\n// - rlyeh, public domain.\n\nconst char *os_mime(const char *filename);\nconst char *os_mime_buf"
  },
  {
    "path": "vault/os_singleton.c",
    "chars": 1343,
    "preview": "// - rlyeh, public domain\n\nbool os_singleton(const char *guid);\n\n#ifdef SINGLETON_C\n#pragma once\n#include <stdbool.h>\n\n#"
  },
  {
    "path": "vault/os_test.c",
    "chars": 1351,
    "preview": "// # tst ######################################################################\n// @todo: measure time with overrides as"
  },
  {
    "path": "vault/os_trap.c",
    "chars": 6297,
    "preview": "void os_trap( void(*handler)(int) );\nvoid os_crash(void);\n\n\n#ifdef TRAP_C\n#pragma once\n#include <float.h> // _control87\n"
  },
  {
    "path": "vault/os_tray.c",
    "chars": 3616,
    "preview": "// Based on code from MinimalSystray project (unlicensed)\n// - rlyeh, public domain.\n\nvoid os_tray( const char *tray_nam"
  },
  {
    "path": "vault/syn.c",
    "chars": 582,
    "preview": "// - rlyeh, public domain\n\n#ifdef SYN_C\n#pragma once\n#define ATOMIC_C\n#define CHANNEL_C\n#define CONDV_C\n#define MCMP_C\n#"
  },
  {
    "path": "vault/syn_atomic.c",
    "chars": 2168,
    "preview": "// # atomics ##################################################################\n// - rlyeh, public domain\n//\n// looking "
  },
  {
    "path": "vault/syn_channel.c",
    "chars": 6484,
    "preview": "// # channels #################################################################\n// - rlyeh, public domain\n//\n// [src] ba"
  },
  {
    "path": "vault/syn_condv.c",
    "chars": 4620,
    "preview": "// # condition variables ######################################################\n// - rlyeh, public domain\n\n#ifndef CONDV"
  },
  {
    "path": "vault/syn_coro.c",
    "chars": 1769,
    "preview": "// from randypgaul https://github.com/RandyGaul/kk_slides (likely public domain)\n\n#pragma once\n\ntypedef struct coroutine"
  },
  {
    "path": "vault/syn_fiber.c",
    "chars": 3705,
    "preview": "/*\n  libco v18 (2016-09-14)\n  author: byuu\n  license: public domain\n  libco is released to the public domain by John Mac"
  },
  {
    "path": "vault/syn_fiber_amd64.h",
    "chars": 5900,
    "preview": "/*\n  libco.amd64 (2016-09-14)\n  author: byuu\n  license: public domain\n*/\n\n#include <assert.h>\n#include <stdlib.h>\n\nstati"
  },
  {
    "path": "vault/syn_fiber_arm.h",
    "chars": 1744,
    "preview": "/*\n  libco.arm (2016-09-14)\n  author: byuu\n  license: public domain\n*/\n\n#include <assert.h>\n#include <stdlib.h>\n#include"
  },
  {
    "path": "vault/syn_fiber_ppc.h",
    "chars": 11736,
    "preview": "/*\n  libco.ppc (2016-09-14)\n  author: blargg\n  license: public domain\n*/\n\n#include <stdlib.h>\n#include <stdint.h>\n#inclu"
  },
  {
    "path": "vault/syn_fiber_sjlj.h",
    "chars": 2167,
    "preview": "/*\n  libco.sjlj (2008-01-28)\n  author: Nach\n  license: public domain\n*/\n\n/*\n  note this was designed for UNIX systems. B"
  },
  {
    "path": "vault/syn_fiber_ucontext.h",
    "chars": 1633,
    "preview": "/*\n  libco.ucontext (2008-01-28)\n  author: Nach\n  license: public domain\n*/\n\n/*\n  WARNING: the overhead of POSIX ucontex"
  },
  {
    "path": "vault/syn_fiber_win32.h",
    "chars": 852,
    "preview": "/*\n  libco.win (2008-01-28)\n  authors: Nach, byuu\n  license: public domain\n*/\n\n#ifndef WINVER\n#define WINVER 0x0400\n#end"
  },
  {
    "path": "vault/syn_fiber_x86.h",
    "chars": 2900,
    "preview": "/*\n  libco.x86 (2016-09-14)\n  author: byuu\n  license: public domain\n*/\n\n#include <assert.h>\n#include <stdlib.h>\n\n#if def"
  },
  {
    "path": "vault/syn_mcmp.c",
    "chars": 2765,
    "preview": "// # lockfree queues (multiple consumer-multiple producer) #####################\n// License: WTFPL. https://github.com/d"
  },
  {
    "path": "vault/syn_mutex.c",
    "chars": 3422,
    "preview": "// # mutexes ###################################################################\n// - rlyeh, public domain\n\n#ifndef MUTE"
  },
  {
    "path": "vault/syn_semaphore.c",
    "chars": 1365,
    "preview": "// # semaphores ################################################################\n// combination of mutex+condvar. used t"
  },
  {
    "path": "vault/syn_sleep.c",
    "chars": 1104,
    "preview": "// # sleep functions ###########################################################\n// - rlyeh, public domain\n\n#ifndef SLEE"
  },
  {
    "path": "vault/syn_thread.c",
    "chars": 5006,
    "preview": "// # threads ###################################################################\n// - rlyeh, public domain\n//\n// [ref] h"
  },
  {
    "path": "vault/syn_tls.c",
    "chars": 1710,
    "preview": "// # thread-local storage ######################################################\n// - rlyeh, public domain.\n\n#ifndef TLS"
  }
]

About this extraction

This page contains the full source code of the r-lyeh/tinybits GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 145 files (497.8 KB), approximately 168.3k tokens, and a symbol index with 558 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!