libk  Check-in [6479e060a3]

Overview
Comment:major update. fix ridiculous old type size determination mechanism. mmap is still broken and i'm not sure why; the syscall does not appear to be going through correctly - see posix_mmap, kmheapa, and kcore/testbin.exe.fn
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 6479e060a3558bd8c304bd0018448ebcad1ef74984ee467f972978f7aebb9a7a
User & Date: lexi on 2019-07-26 09:51:02
Other Links: manifest | tags
Context
2019-07-26
10:52
update kcore docs, fix bad type names and dumb logic check-in: 175dc46a91 user: lexi tags: trunk
09:51
major update. fix ridiculous old type size determination mechanism. mmap is still broken and i'm not sure why; the syscall does not appear to be going through correctly - see posix_mmap, kmheapa, and kcore/testbin.exe.fn check-in: 6479e060a3 user: lexi tags: trunk
2019-06-29
09:31
add a bunch of code, port the header mechanism to gpp; add a fuckton of definitions and compatibility header code; notably, add core function kstop and x86.lin.{32,64} impl. update docs accordingly check-in: e794c5edef user: lexi tags: trunk
Changes

Modified arch/makefile from [622e8ca4bc] to [3adea95421].

     3      3   
     4      4   ${TMP}/calls.x86.lin.32.s: ${lin-headers}/unistd_32.h ${TMP}
     5      5   	grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@
     6      6   ${TMP}/calls.x86.lin.64.s: ${lin-headers}/unistd_64.h ${TMP}
     7      7   	grep "#define __NR_" $< | sed 's;^#define __NR_;%define sys.;' > $@
     8      8   ${TMP}/calls.x86.fbsd.%.s: ${fbsd-headers}/syscall.h ${TMP}
     9      9   	grep "#define	SYS_" $< | sed 's;^#define	SYS_;%define sys.;' > $@
           10  +${TMP}/typesize: typesize.c
           11  +	$(CC) -std=c11 $< -o $@
           12  +${TMP}/typesize.def: ${TMP}/typesize
           13  +	$< > $@

Added arch/typesize.c version [9ee84449d7].

            1  +#include <stdio.h>
            2  +#include <limits.h>
            3  +#include <stddef.h>
            4  +
            5  +#define sflag(flag,val) printf("-D"#flag"=\"%s\" ", val)
            6  +#define mflag(flag,val) printf("-D"#flag"=-%llu ", val + 1)
            7  +#define iflag(flag,val) printf("-D"#flag"=%llu ", val)
            8  +#define fflag(flag,val) printf("-D"#flag"=%Lf ", val)
            9  +#define type_found(val) (found_type & (val / 8))
           10  +#define checkbits(type,x) \
           11  +	if(!type_found(x) && sizeof(type) == (x/CHAR_BIT)) \
           12  +		sflag(type_bit##x, #type), found_type |= (x / 8)
           13  +
           14  +#define describe_integral(type,label) { \
           15  +	unsigned type maxval = -1; \
           16  +	unsigned type smaxval = (maxval/2) - 1; \
           17  +	iflag(type_max_u_##label, maxval); \
           18  +	iflag(type_max_s_##label, smaxval); \
           19  +	mflag(type_min_s_##label, smaxval); \
           20  +	iflag(type_##label##_bits, (CHAR_BIT * sizeof(type))); \
           21  +	checkbits(type, 8); else checkbits(type,16); else \
           22  +	checkbits(type,32); else checkbits(type,64); else \
           23  +	checkbits(type,128); else \
           24  +	if (!found_sz && sizeof(type) == sizeof(size_t)) \
           25  +		found_sz = 1, sflag(type_sz, "unsigned " #type); \
           26  +	if (!found_ofs && sizeof(type) == sizeof(ptrdiff_t)) \
           27  +		found_ofs = 1, sflag(type_offset, "signed " #type); \
           28  +}
           29  +
           30  +int main() {
           31  +	int found_sz = 0, found_ofs = 0, found_type = 0;
           32  +	iflag(byte_bits,CHAR_BIT);
           33  +	describe_integral(char,char);
           34  +	describe_integral(short,short);
           35  +	describe_integral(int,int);
           36  +	describe_integral(long,long);
           37  +	describe_integral(long long,llong);
           38  +	printf("\n");
           39  +	return 0;
           40  +}

Added kconf/kconf.md version [b260f2842a].

            1  +# kconf
            2  +
            3  +while there are a number of existing configuration parser libraries out there, they all have their problems, and all depend on libc. since configuration string parsing is a fairly core functionality that would force many programs to either write their own code or drag libc back into their dependencies, supplying a basic parser with libk makes sense.
            4  +
            5  +## basic principles
            6  +
            7  +kconf is intended to be fast, lightweight, transparent, and low-overhead.
            8  +
            9  +to initialize a kconf structure, we begin by supplying a list of *atoms.* like in Xlib, an atom is a performant way to reference a known string of text from a compiled program. we can do this in two different ways, either by generating the values ourselves at compile time with an enum, or by generating them at runtime using the appropriate kconf interface. note that if you supply your own with an enum, because zero is used for in-band error signalling, the first atom should always be an error token. alternately, it may be explicitly set to a non-zero number and a return value of zero can be checked for implicitly or against a literal 0.
           10  +
           11  +note that, in a recurring libk pattern, if an element count of zero (or `null`) is passed to a function that takes an array of nullables, that function will treat its array argument as a null-terminated array to be counted at runtime.
           12  +
           13  +kconf is initialized by filling out the struct `kconf` with the parameters of operations and then passing it to the appropriate function.
           14  +
           15  +    enum atoms { parse_error, user, pw, email, atomct };
           16  +    kconf kc = {
           17  +    	.decl = { atomct, {
           18  +    		{ user,  {4, "user"    } },
           19  +    		{ pw,    {8, "password"} },
           20  +    		{ email, {5, "email"   } }
           21  +    	}}
           22  +    };
           23  +
           24  +	/* with runtime counts:
           25  +     * enum atoms { parse_error, user, pw, email };
           26  +     * kconf kc = {
           27  +     * 	.decl = { null, {
           28  +     * 		{ user,  {0, "user"    } },
           29  +     * 		{ pw,    {0, "password"} },
           30  +     * 		{ email, {0, "email"   } },
           31  +	 *		{ null }
           32  +     * 	}}
           33  +     * }; */
           34  +
           35  +	/* with macros:
           36  +     * enum atoms { parse_error, user, password, email };
           37  +     * kconf kc = {
           38  +     * 	.decl = {Kmpsa(kconf_decl, {
           39  +	 * 		Kconf_atom(user),
           40  +	 * 		Kconf_atom(password),
           41  +	 * 		Kconf_atom(email)
           42  +	 * 	})};
           43  +	 * }; */
           44  +
           45  +## types
           46  +
           47  +### struct kconf
           48  +	* `union { kconf_decl decl; kconf_gen gen; };`
           49  +
           50  +### struct kconf_atom
           51  +
           52  + * `sz key`
           53  + * `ksraw string`
           54  +
           55  +### struct kconf_pair
           56  +
           57  + * `kconf_atom atom`
           58  + * `ksraw* dest`
           59  +
           60  +
           61  +## macros
           62  +
           63  + * `Kconf_atom(atom)` - a convenience macro for definining an pre-defined atom structure (`kconf_atom`), under the assumption that the C enumerator name is the same as the string used to name the field in the configuration file. inserts the text `{atom, {sizeof(#atom), #atom}}`
           64  + * `Kconf_atom_pfx(pfx,atom)` - a convenience macro for definining an pre-defined atom structure (`kconf_atom`), under the assumption that the C enumerator name is the string used to name the field in the configuration file with a prefix attached. inserts the text `{pfx##atom, {sizeof(#atom), #atom}}`

Added kconf/makefile version [f0df06fe05].

            1  +include ../modmake

Modified kcore/core.h from [ded1289884] to [46cfa15699].

    85     85   #		define KVstd c++
    86     86   #		if (__cplusplus >= 201103L)
    87     87   #			define KFstd_cpp11
    88     88   #			define KVstd c++11
    89     89   #		endif /* TODO: add more */
    90     90   #	endif
    91     91   #endif
           92  +
           93  +#ifdef KFstd_c11
           94  +#	define Kassert _Static_assert
           95  +#else
           96  +#	define Kassert(x) { struct { int assertion_failed[(x) ? 1 : -1] }; }
           97  +#endif
    92     98   
    93     99   /* hooo boy. null. that one's got a storied
    94    100    * history across the versions and dialects.
    95    101    * below, we try to find the ideal way to
    96    102    * offer a "null" "keyword" depending on
    97    103    * dialect, version, and whether the user
    98    104    * has asked for macros to be suspended.
................................................................................
   117    123   #	define noreturn [[ noreturn ]]
   118    124   #elif __STDC_VERSION__ >= 201103L
   119    125   #	define noreturn _Noreturn
   120    126   #else
   121    127   #	define noreturn
   122    128   #endif
   123    129   
   124         -noreturn void kstop(longstat code);
          130  +noreturn void kstop(stat_long code);
   125    131   
   126    132   #ifdef KFclean
   127    133   #	undef noreturn
   128    134   #endif
   129    135   
   130    136   #endif

Modified kcore/def.h.m from [9abe158651] to [9c53671363].

     1      1   --- kcore/def.h.m → <k/def.h>
     2      2   --- ~ lexi hale <lexi@hale.su>
     3      3   --- this file gathers information on the environment it's
     4      4   --- being compiled in, setting macros that other headers
     5      5   --- need. it will be emitted as <k/def.h>.
     6      6   --- vim: ft=c
            7  +#ifndef KIdef
            8  +#define KIdef
     7      9   
     8     10   [ifdef atom_target_bits]
     9     11   	[define target: [atom_target_arch].[atom_target_os].[atom_target_bits]]
    10     12   	#define KVbits [atom_target_bits]
    11     13   [else]
    12     14   	[define target: [atom_target_arch].[atom_target_os]]
    13     15   [endif]
................................................................................
    26     28   #define Kpragma(p) _Pragma(#p)
    27     29   #if defined(__GNUC__) || defined(__clang__)
    28     30   #   define Kerror(msg) Kpragma(GCC error #msg) 
    29     31   #else
    30     32   #   define Kerror(msg) Kpragma(message #msg)
    31     33   #endif
    32     34   #define Knoimpl(fn) Kerror(no implementation of fn for platform [target])
           35  +
           36  +#endif

Modified kcore/magic.h from [1f7f63c3e2] to [a7232aabca].

     2      2    * ~ lexi hale <lexi@hale.su>
     3      3    * one of libk's biggest goals is standardization across
     4      4    * software. for this reason, we define here a variety
     5      5    * of "magical numbers" used to signal or describe
     6      6    * various states, messages, and errors. suggestions are
     7      7    * welcome.
     8      8    */
            9  +#ifndef KImagic
           10  +#define KImagic
           11  +
     9     12   #include <k/type.h>
    10     13   
    11     14   typedef enum kbad {
    12     15   	// values to be returned by an entry function
    13     16   	kbad_ok = 0,
    14     17   		/* the requested operation completed
    15     18   		 * successfully */
    16     19   
           20  +	kbad_mem = 1,
           21  +		/* the system does not have enough free
           22  +		 * memory to complete the requested operation */
           23  +
    17     24   	/* these are synchronized with freebsd's existing
    18     25   	 * sysexit.h conventions. */
    19     26   	kbad_usage = 64,
    20     27   		/* # fbsd EX_USAGE
    21     28   		 * a usage screen was displayed to the user
    22     29   		 * on request or due to improperly formed call */
    23     30   	kbad_data = 65,
................................................................................
    61     68   		/* # fbsd EX_NOPERM
    62     69   		 * you or the program do not have permissions
    63     70   		 * to do the thing requested */
    64     71   	kbad_conf = 78,
    65     72   		/* # fbsd EX_CONFIG
    66     73   		 * your configuration is fucked */
    67     74   } kbad;
           75  +
           76  +#endif

Modified kcore/makefile from [c01fcd380e] to [f9fefae3d1].

     3      3   # for stddef.h, and that can't be written in portable C.
     4      4   # so we're generating it at build time.
     5      5   
     6      6   # gen-headers = type.h
     7      7   
     8      8   include ../modmake
     9      9   
           10  +${OUT}/k/type.h: type.h.m ${TMP}/typesize.def
           11  +	$(m-comp) $< $(file < ${TMP}/typesize.def) > $@
           12  +
    10     13   ## the below code predates the introduction of gpp
    11     14   ## to generate these headers from templates instead
    12     15   ## of trying to write one for everypossible arch 
    13     16   ## tuple. it is left as a monument to a terrible
    14     17   ## and now blissfully forgotten past.
    15     18   #
    16     19   # look, imma just be straight with you. the mechanism we're

Modified kcore/stop.fn.c from [c4373dead4] to [5c15d4cc49].

     5      5   
     6      6   #include <k/core.h>
     7      7   #include <k/def.h> // so we know what system this is
     8      8   #include <k/type.h>
     9      9   
    10     10   #ifdef KFenv_posix
    11     11   #	define STOPFN kio_posix_exit
    12         -	extern void STOPFN(int);
           12  +	extern noreturn void STOPFN(int);
    13     13   #else
    14     14   	Knoimpl(kstop)
    15     15   #endif
    16     16   
    17         -noreturn void kstop (longstat code) { STOPFN(code); }
           17  +noreturn void kstop (stat_long code) { STOPFN(code); }

Modified kcore/testbin.exe.c from [f1bdb07ea2] to [5796abefa5].

     1      1   #include <k/core.h>
     2      2   #include <k/mem.h>
     3      3   #include <k/io.h>
     4      4   #include <k/magic.h>
            5  +
            6  +struct object {
            7  +	u8 a;
            8  +	s16 b;
            9  +	bool c;
           10  +};
     5     11   
     6     12   kbad entry(kenv e) {
     7     13   	const char msg[] = "hello from libk\n";
     8     14   	ksraw ptr = { Kmsz(msg), msg };
     9     15   
    10     16   	bool maybe = true;
    11     17   	maybe = no;
    12     18   
    13     19   	if (kiosend(e.std, ptr, null) == kiocond_ok) {
    14         -		return kbad_ok;
           20  +		/* great, continue */
    15     21   	} else {
    16     22   		return kbad_io;
    17     23   	}
           24  +
           25  +	struct object* block = kmheapa(sizeof (struct object) * 4);
           26  +	if (block == null) return kbad_mem; else return kbad_ok;
           27  +	
           28  +	block[1].a = 5;
           29  +
           30  +	return kbad_ok;
    18     31   }

Modified kcore/type.h.m from [8b1f2e0cb2] to [a9978dfd3a].

     1         ---- kcore/type.h.m → <k/def.h>
            1  +--- kcore/type.h.m → <k/type.h>
     2      2   --- ~ lexi hale <lexi@hale.su>
     3      3   --- this file gathers information on the environment it's
     4      4   --- being compiled in, defining types that our code
     5      5   --- needs. it will be emitted as <k/type.h>.
     6      6   --- vim: ft=c
            7  +#ifndef KItype
            8  +#define KItype
            9  +
           10  +typedef unsigned char      kc_uint_min;
           11  +typedef   signed char      kc_sint_min;
           12  +typedef unsigned long long kc_uint_max;
           13  +typedef   signed long long kc_sint_max;
           14  +
           15  +[ifdef type_bit8]
           16  +	typedef unsigned [type_bit8] u8;
           17  +	typedef   signed [type_bit8] s8;
           18  +[else]
           19  +	typedef kc_uint_min u8;
           20  +	typedef	kc_sint_min s8;
           21  +[endif]
           22  +
           23  +[ifdef type_bit16]
           24  +	typedef unsigned [type_bit16] u16;
           25  +	typedef   signed [type_bit16] s16;
           26  +[else]
           27  +	typedef kc_uint_max u16;
           28  +	typedef	kc_sint_max s16;
           29  +[endif]
           30  +
           31  +[ifdef type_bit32]
           32  +	typedef unsigned [type_bit32] u32;
           33  +	typedef   signed [type_bit32] s32;
           34  +[else]
           35  +	typedef kc_uint_max u32;
           36  +	typedef	kc_sint_max s32;
           37  +[endif]
           38  +
           39  +[ifdef type_bit64]
           40  +	typedef unsigned [type_bit64] u64;
           41  +	typedef   signed [type_bit64] s64;
           42  +	[ifndef type_bit128]
           43  +#		if defined(__GNUC__) || defined(__clang__)
           44  +			typedef unsigned __int128_t u128;
           45  +			typedef   signed __int128_t s128;
           46  +#		else
           47  +			typedef kc_uint_max u128;
           48  +			typedef kc_sint_max s128;
           49  +#		endif
           50  +	[endif]
           51  +[else]
           52  +	typedef kc_uint_max u64;
           53  +	typedef	kc_sint_max s64;
           54  +
           55  +	typedef kc_uint_max u128;
           56  +	typedef	kc_sint_max s128;
           57  +[endif]
           58  +
           59  +[ifdef type_bit128]
           60  +	typedef unsigned [type_bit128] u128;
           61  +	typedef   signed [type_bit128] s128;
           62  +[endif]
           63  +
           64  +enum /* max-min values of each type */ {
           65  +	/* assuming two's complement. TODO: check math */
           66  +	/* TODO: figure out how to calc min */
           67  +	kc_byte_bits = [byte_bits],
           68  +	  u8_min = 0,   u8_max = ((u8)-1),
           69  +	 u16_min = 0,  u16_max = ((u16)-1),
           70  +	 u32_min = 0,  u32_max = ((u32)-1),
           71  +	 u64_min = 0,  u32_max = ((u64)-1),
           72  +	u128_min = 0, u128_max = ((u128)-1),
           73  +
           74  +	[define merge: $1$2]
           75  +	[define [sspec type]:
           76  +		[merge [type],_min] = 0 - ((1 << sizeof([type]) * kc_byte_bits) / 2),
           77  +		[merge [type],_max] =      (1 << sizeof([type]) * kc_byte_bits) / 2 - 1]
           78  +
           79  +	[sspec s8], [sspec s16], [sspec s32],
           80  +	[sspec s64], [sspec s128],
           81  +
           82  +	kc_min_uchar  = 0, kc_max_uchar  = [type_max_u_char],
           83  +	kc_min_ushort = 0, kc_max_ushort = [type_max_u_short],
           84  +	kc_min_uint   = 0, kc_max_uint   = [type_max_u_int],
           85  +	kc_min_ulong  = 0, kc_max_ulong  = [type_max_u_long],
           86  +	kc_min_ullong = 0, kc_max_ullong = [type_max_u_llong],
           87  +
           88  +	kc_min_schar  = [type_min_s_char],  kc_max_schar  = [type_max_s_char],
           89  +	kc_min_sshort = [type_min_s_short], kc_max_sshort = [type_max_s_short],
           90  +	kc_min_sint   = [type_min_s_int],   kc_max_sint   = [type_max_s_int],
           91  +	kc_min_slong  = [type_min_s_long],  kc_max_slong  = [type_max_s_long],
           92  +	kc_min_sllong = [type_min_s_llong], kc_max_sllong = [type_max_s_llong],
           93  +};
     7     94   
     8         -// arch bit length [atom_target_bits]
     9         ---- make some gigantic fucking assumptions
    10         -[if [atom_target_bits] >= 8]
    11         -    typedef unsigned char  u8;
    12         -    typedef signed char    s8;
    13         -    [if [atom_target_bits] >= 16]
    14         -        typedef unsigned short u16;
    15         -        typedef signed short   s16;
    16         -        [if [atom_target_bits] >= 32]
    17         -            typedef unsigned long  u32;
    18         -            typedef signed long    s32;
    19         -            [if [atom_target_bits] >= 64]
    20         -                typedef unsigned long long u64;
    21         -                typedef signed long long s64;
    22         -                [if [atom_target_arch] == x86]
    23         -                    #if defined(__GNUC__) || defined(__clang__)
    24         -                        typedef __uint128_t u128;
    25         -                        typedef __int128_t  s128;
    26         -                    #endif
    27         -                [endif]
    28         -            [endif]
    29         -        [endif]
    30         -    [endif]
           95  +[ifdef type_sz]
           96  +	typedef [type_sz] sz;
           97  +[else]
           98  +#	ifdef __cplusplus
           99  + 	   /* C++ gives us a clean, standardized way to do this */
          100  + 	   typedef decltype (sizeof(char)) sz;
          101  +#	else
          102  +#		if defined(__GNUC__) || defined(__clang__)
          103  +			typedef __typeof__ (sizeof(char)) sz;
          104  +#		else
          105  +			/* we're stumped - set sz to the safest possible value under
          106  +			 * the circumstances, and warn the user. */
          107  +#			warning no authoritative sz (size_t) type definition \
          108  +			        available; defaulting to largest unsigned integer type
          109  +			typedef kc_uint_max sz;
          110  +#		endif
          111  +#	endif
    31    112   [endif]
    32    113   
    33         -typedef u[atom_target_bits]  sz;
    34         -typedef s[atom_target_bits] ssz;
    35         -
    36         ---- make sure something unlikely doesn't happen
    37         -[define [maxtype name, n]:
    38         -	[if [n] > [atom_target_bits]]
    39         -		typedef u[atom_target_bits] [name]
    40         -	[else]
    41         -		typedef u[n] [name]
    42         -	[endif]]
          114  +[ifdef type_offset]
          115  +	typedef [type_offset] offset;
          116  +[else]
          117  +#	ifdef __cplusplus
          118  + 	   /* C++ gives us a clean, standardized way to do this */
          119  +		typedef decltype (((void*)-1) - 1) offset;
          120  +#	else
          121  +#		if defined(__GNUC__) || defined(__clang__)
          122  +			typedef __typeof__ (((void*)10) - ((void*)5)) offset;
          123  +#		else
          124  +			/* no dice - set offset to the safest possible value under
          125  +			 * the circumstances, and warn the user. */
          126  +#			warning no authoritative offset (ptrdiff_t) type definition \
          127  +			        available; defaulting to largest unsigned integer type
          128  +			typedef kc_sint_max offset;
          129  +#		endif
          130  +#	endif
          131  +[endif]
    43    132   
    44    133   // exit status integer types - pls use kbad in <k/magic.h> instead
    45    134   [if [target_posix] == yes]
    46    135   	/* by convention, posix return values are 8-bit,
    47    136   	 * but note that many modern UNIXes do technically
    48    137   	 * support higher-bit values. for this reason,
    49    138   	 * longstat is defined differently under posix. */
    50    139   	typedef u8 stat;
    51         -	[maxtype longstat, 32];
          140  +	typedef u32 stat_long;
    52    141   [else]
    53    142   	[if ([atom_target_os] == win) ||
    54    143   		([atom_target_os] == vms)]
    55         -		[maxtype stat, 32]
          144  +		typedef u32 stat;
    56    145   	[else]
    57    146   		typedef u8 stat;
    58    147   		/* we don't know a specific exit status type
    59    148   		 * for your arch so we're going with a sane
    60    149   		 * default. if this is wrong, help us fix it! */
    61    150   	[endif]
    62         -	typedef stat longstat;
          151  +	typedef stat stat_long;
    63    152   [endif]
          153  +
          154  +#endif

Added kdb/kdb.md version [1c2867c8a9].

            1  +# kdb
            2  +
            3  +kdb is a module for storing and loading data from files.
            4  +
            5  +## model
            6  +
            7  +the first argument to all kdb functions is of type `struct kdb`, which describes the database to be accessed. the first field of that struct is a pointer to a struct of type `struct kdb_fmt` which describes the format of the database.
            8  +
            9  +kdb encodes records as a tuple of three fields: (kind, key, value). `kind` is a 16-bit integer, `key` is an integer of platform width, and `value` is a blob decoded according to the type of the record, which is not saved in the database itself. records are indexed by the tuple (kind, key); `key` may be null. `kind` denotes the structure of the record, and is user-defined.
           10  +
           11  +to use strings as the keys for database entries, either atoms should be stored in the database or a hash function may be used. kdb contains procedures to automate the use of atoms as keys.
           12  +
           13  +## types
           14  +
           15  +### struct kdb
           16  +
           17  + * `struct kdb_fmt* fmt`
           18  + * `enum kdb_conn conn`
           19  + * `union { kfile* file; const kdb_store* mem; kmptr ptr; } store;`
           20  +
           21  +### struct kdb_rec
           22  +
           23  + * `u16 kind`
           24  + * `word key`
           25  + * `ksraw value`
           26  +
           27  +### enum kdb_conn
           28  +
           29  + * `kdb_conn_none`: no database is connected; calls will fail
           30  + * `kdb_conn_file`: the database is stored in a file; calls to modify it will modify the file on-disk
           31  + * `kdb_conn_file_static`: the database is stored in a file; calls to modify it will fail. if the file is writable to the process, can be seamlessly changed to `kdb_conn_file` and vice-versa
           32  + * `kdb_conn_mem`: the database is stored in-memory, allocated by kmem and referenced by `ptr`. calls to modify it will re-allocate memory via the appropriate interfaces.
           33  + * `kdb_conn_mem_static`: the database is stored in-memory, referenced by `mem`; calls to modify it will fail
           34  +

Added kdb/makefile version [f0df06fe05].

            1  +include ../modmake

Modified kio/io.h from [aa4095c969] to [e3d3c3c357].

    39     39   	kiostream in;
    40     40   	  // text can be read from this stream
    41     41   	kiostream out;
    42     42   	  // text can be written to this stream
    43     43   } kiochan;
    44     44   
    45     45   typedef enum kiocond {
    46         -	kiocond_ok,
    47         -	  // success
    48         -    kiocond_fail,
    49         -	  // action failed
           46  +	/* to check if a call failed, perform (x >= kiocond_fail) where x
           47  +	 * is that call's return value. more typically however you should
           48  +	 * select explicitly against kiocond_ok or kiocond_partial, since
           49  +	 * those situations will usually need to be handled differently. */
           50  +
           51  +	kiocond_ok, // success
           52  +	kiocond_partial, // partial read or write
           53  +
           54  +    kiocond_fail, // action failed - unspecified reason
           55  +	kiocond_fail_closed_stream, // action failed because stream is closed
    50     56   } kiocond;
    51     57   
    52     58   kiocond kiosend(kiochan, ksraw, sz*); // send data to a channel
    53     59   kiocond kiorecv(kiochan, ksraw*); // receive data from a channel
    54     60   kmptr kiorecvall(kiochan, kmcell*, kmkind); // automatically allocate a bufer for a channel
    55     61     // kmkind is only used if kmcell* is NULL
    56     62   kiocond kiocon(kiochan, kiochan); // connect one channel to another
    57     63   
    58     64   #endif

Deleted kio/kio_posix_fd_write.fn.x86.lin.32.s version [7b77d86bab].

     1         -bits 32
     2         -global kio_posix_fd_write
     3         -
     4         -%include "../arch/x86.lin.32.s"
     5         -; vim: ft=nasm
     6         -
     7         -kio_posix_fd_write:
     8         -	mov sys.reg.0, sys.call.write
     9         -	mov sys.reg.1, [esp + 4] ; holy god but this took the most
    10         -	mov sys.reg.2, [esp + 8] ; stupidly long time to fucking
    11         -	mov sys.reg.3, [esp + 12]; figure out
    12         -	sys.call
    13         -	ret
    14         -

Deleted kio/kio_posix_fd_write.fn.x86.lin.64.s version [b72b3eff18].

     1         -bits 64
     2         -global kio_posix_fd_write
     3         -
     4         -%include "../arch/x86.lin.64.s"
     5         -; vim: ft=nasm
     6         -
     7         -kio_posix_fd_write:
     8         -	mov sys.reg.0, sys.write
     9         -	; mov sys.reg.1, ccall.reg.0 - nop
    10         -	; mov sys.reg.2, ccall.reg.1 - nop
    11         -	; mov sys.reg.3, ccall.reg.2 - nop
    12         -	sys.call
    13         -	ret
    14         -

Added kio/posix_fd_write.fn.x86.lin.32.s version [7b77d86bab].

            1  +bits 32
            2  +global kio_posix_fd_write
            3  +
            4  +%include "../arch/x86.lin.32.s"
            5  +; vim: ft=nasm
            6  +
            7  +kio_posix_fd_write:
            8  +	mov sys.reg.0, sys.call.write
            9  +	mov sys.reg.1, [esp + 4] ; holy god but this took the most
           10  +	mov sys.reg.2, [esp + 8] ; stupidly long time to fucking
           11  +	mov sys.reg.3, [esp + 12]; figure out
           12  +	sys.call
           13  +	ret
           14  +

Added kio/posix_fd_write.fn.x86.lin.64.s version [b72b3eff18].

            1  +bits 64
            2  +global kio_posix_fd_write
            3  +
            4  +%include "../arch/x86.lin.64.s"
            5  +; vim: ft=nasm
            6  +
            7  +kio_posix_fd_write:
            8  +	mov sys.reg.0, sys.write
            9  +	; mov sys.reg.1, ccall.reg.0 - nop
           10  +	; mov sys.reg.2, ccall.reg.1 - nop
           11  +	; mov sys.reg.3, ccall.reg.2 - nop
           12  +	sys.call
           13  +	ret
           14  +

Deleted kio/send.c version [d88d1642fe].

     1         -#include <k/io.h>
     2         -#include <k/core.h>
     3         -#include <k/def.h>
     4         -/* send.c - kiosend()
     5         - * ~ lexi hale <lexi@hale.su>
     6         - * kiosend() writes to a channel with an open out stream
     7         - */
     8         -
     9         -// we define all platform functions here,
    10         -// whether or not they're for the correct
    11         -// platform - only the ones actually called
    12         -// by the generated code will be linked
    13         -extern sz kio_posix_fd_write(int fd, const char* buf, sz len);
    14         -
    15         -kiocond kiosend(kiochan target, ksraw string, sz* len) {
    16         -#	ifdef KFenv_posix
    17         -		sz size = kio_posix_fd_write(target.out.platform_fd, string.ptr, string.size);
    18         -		if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors
    19         -#	else
    20         -#		if KVos == win
    21         -#			error windows IO send function not yet defined
    22         -#		else
    23         -			Knoimpl(kiosend,KVos);
    24         -#			error missing implementation // boring error for plebs
    25         -#		endif
    26         -#	endif
    27         -
    28         -	if (len != null) *len = size;
    29         -	return kiocond_ok;
    30         -}

Modified kio/send.fn.c from [430158e543] to [5cc5cc2649].

     1      1   #include <k/io.h>
     2      2   #include <k/core.h>
     3      3   #include <k/def.h>
     4         -/* send.c - kiosend()
            4  +/* send.c - kiosend() "send to channel"
     5      5    * ~ lexi hale <lexi@hale.su>
     6      6    * kiosend() writes to a channel with an open out stream
     7      7    */
     8      8   
     9         -// we define all platform functions here,
    10         -// whether or not they're for the correct
    11         -// platform - only the ones actually called
    12         -// by the generated code will be linked
            9  +/* we define all platform functions here,
           10  + * whether or not they're for the correct
           11  + * platform - only the ones actually called
           12  + * by the generated code will be linked */
    13     13   extern sz kio_posix_fd_write(int fd, const char* buf, sz len);
    14     14   
    15     15   kiocond kiosend(kiochan target, ksraw string, sz* len) {
           16  +	if (target.out.kind == kiostream_closed) return kiocond_fail_closed_stream;
           17  +
    16     18   #	ifdef KFenv_posix
    17     19   		sz size = kio_posix_fd_write(target.out.platform_fd, string.ptr, string.size);
    18     20   		if (size == -1) return kiocond_fail; //TODO: retrieve errno and offer more specific errors
    19     21   #	else
    20     22   #		if KVos == win
    21     23   #			error windows IO send function not yet defined
    22     24   #		else
    23         -			_Pragma("GCC diagnostic error \"" // fancy error for gcc
    24         -				"IO send fn for platform " #KVos " not defined"
    25         -			"\""))
    26         -#			error IO send fn not defined for platform
    27         -			   // boring error for plebs
           25  +			Knoimpl(kiosend,KVos);
           26  +#			error missing implementation // boring error for plebs
    28     27   #		endif
    29     28   #	endif
    30     29   
    31     30   	if (len != null) *len = size;
    32     31   	return kiocond_ok;
    33     32   }

Added kmem/heapa.fn.c version [f32eb209ee].

            1  +#include <k/core.h>
            2  +#include <k/def.h>
            3  +/* heapa.c - kmheapa() "heap alloc"
            4  + * ~ lexi hale <lexi@hale.su>
            5  + * kmheapa() allocates a pointer on the heap à la libc malloc()
            6  + * see also: kmheapf() "heap free"
            7  + */
            8  +
            9  +/* we define all platform functions here,
           10  + * whether or not they're for the correct
           11  + * platform - only the ones actually called
           12  + * by the generated code will be linked,
           13  + * linker errors are our friend here! */
           14  +extern void* kmem_posix_mmap(void* addr,
           15  +		unsigned long sz, unsigned long prot, unsigned long flags,
           16  +		unsigned long fd, unsigned long off);
           17  +
           18  +enum posix_prot {
           19  +	posix_prot_none  = 0,
           20  +	posix_prot_read  = 1 << 0,
           21  +	posix_prot_write = 1 << 1,
           22  +	posix_prot_exec  = 1 << 2
           23  +};
           24  +
           25  +enum posix_map {
           26  +	posix_map_shared  = 1,
           27  +	posix_map_private = 2
           28  +};
           29  +
           30  +enum posix_flag {
           31  +	posix_flag_fixed     = 0x10,
           32  +	posix_flag_anonymous = 0x20,
           33  +
           34  +	/* platform flags */
           35  +	posix_flag_linux_hugetlb = 0x40000
           36  +};
           37  +
           38  +void* kmheapa(sz len) {
           39  +	/* allocate an object on the heap and return
           40  +	 * a pointer, or NULL if the allocation failed. */
           41  +	void* val;
           42  +
           43  +#	ifdef KFenv_posix
           44  + 	   /* posix APIs - we've got it easy */
           45  +		val = kmem_posix_mmap(null, len, posix_prot_read | posix_prot_write,
           46  +				posix_flag_anonymous, -1, 0);
           47  +		/* impl note: while per manpage fd is "ignored"
           48  +		 * for MAP_ANONYMOUS, "some implementations" require
           49  +		 * a value of -1 */
           50  +
           51  +		if (val == (void*) -1) return null;
           52  +		/* worth retrieving errno? discuss */
           53  +
           54  +#	else
           55  + 	   Knoimpl(kmheapa,KVos);
           56  +#		error missing implementation
           57  +#	endif
           58  +
           59  +	return val;
           60  +}

Modified kmem/kmem.md from [9ed4178122] to [18509d6a57].

   155    155      * `kmtreef(void*) → kmptr` - frees a node and all its children
   156    156   
   157    157   ## macros
   158    158   
   159    159   kmem defines the following macros.
   160    160   
   161    161    * `Kmsz(array)` - a convenience macro to return the number of elements in a static array. inserts the text `( sizeof (array) / sizeof (array) [0] )`
          162  + * `Kmszs(type, struct)` - a convenience macro to return the size of a struct. requires compound literals.
          163  + * `Kmszsa(type, array)` - calculates the number of elements in an array of a given struct type. inserts the text `( sizeof ( (type) array ) / sizeof (type) )`
          164  + * `Kmpsa(type, struct)` - a convenience macro to insert a "pascal struct array" - that is, a struct array prefixed with a size value. this is equivalent to `Kmszsa(type, array), array`

Modified kmem/mem.h from [551899b415] to [ace4d63e01].

    31     31   typedef struct kmptr {
    32     32   	kmkind kind;
    33     33   	kmshred shred;
    34     34   	void* ref;
    35     35   	kmcell* cell;
    36     36   } kmptr;
    37     37   
           38  +/* heap functions */
           39  +
           40  +void* kmheapa(sz);
           41  +void  kmheapf(void*);
           42  +
    38     43   #endif

Added kmem/posix_mmap.fn.x86.lin.64.s version [0ee1179d8c].

            1  +bits 64
            2  +%include "../arch/x86.lin.64.s"
            3  +%include "../arch/x86.cdecl.64.s"
            4  +; vim: ft=nasm
            5  +
            6  +global kmem_posix_mmap
            7  +kmem_posix_mmap:
            8  +	; to call mmap, we need to translate the cdecl64
            9  +	; register arguments to their appropriate syscall64
           10  +	; registers. these are mostly the same, with one
           11  +	; obnoxious exception. the NOPs have been written
           12  +	; in as comments to aid in understanding.
           13  +
           14  +	  mov sys.reg.1, ccall.reg.0 ;nop - rdi → rdi
           15  +	  mov sys.reg.2, ccall.reg.1 ;nop - rsi → rsi
           16  +	  mov sys.reg.3, ccall.reg.2 ;nop - rdx → rdx
           17  +	  mov sys.reg.4, ccall.reg.3 ; OP - rcx → r10
           18  +	  mov sys.reg.5, ccall.reg.4 ;nop - r8 → r8
           19  +	  mov sys.reg.6, ccall.reg.5 ;nop - r9 → r9
           20  +
           21  +	mov sys.reg.0, sys.mmap
           22  +	sys.call
           23  +
           24  +	mov ccall.reg.ret, sys.reg.ret ; rax → rdi

Modified kstr/str.h from [f7e947c0d1] to [69d05c5e37].

     6      6   typedef struct kstr {
     7      7   	sz size;
     8      8   	kmptr ptr;
     9      9   } kstr;
    10     10   
    11     11   typedef struct ksraw {
    12     12   	sz size;
    13         -	char* ptr;
           13  +	const char* ptr;
    14     14   } ksraw;
           15  +
           16  +typedef struct ksmut {
           17  +	sz size;
           18  +	char* ptr;
           19  +} ksmut;
    15     20   #endif

Modified makefile from [d63468c69f] to [ce9c7792cb].

   100    100   
   101    101   %.tool: %/makefile $(TMP)/precomp.g $(OUT)
   102    102   	cd $* && $(MAKE) tool
   103    103   
   104    104   %.dbg: %/makefile $(OUT)
   105    105   	cd $* && $(MAKE) dbg
   106    106   
   107         -%.def: %/makefile $(TMP)/precomp.g $(OUT) $(OUT)/k
          107  +%.def: %/makefile $(TMP)/precomp.g $(TMP)/typesize.def $(OUT) $(OUT)/k
   108    108   	cd $* && $(MAKE) def
   109    109   
   110    110   %.calls: arch/makefile
   111    111   	cd arch && $(MAKE) $(TMP)/calls.$*.s
   112    112   
   113    113   $(TMP)/precomp.g: grammar/precomp.g.gpp $(TMP)
   114    114   	cd grammar && $(MAKE) $@
          115  +
          116  +$(TMP)/typesize.def: arch/makefile $(TMP)
          117  +	cd arch && $(MAKE) $@
   115    118   
   116    119   $(OUT)/libk.so: $(fnobjects) 
   117    120   	ld -shared $(COMPLIB) -o $@ $^
   118    121   	@# $(CC) -shared -fPIC -nostdlib $(COMPLIB) -o $@ $(OUT)/*.o
   119    122   
   120    123   $(OUT)/boot.o: $(rtobjects)
   121    124   	ld -r $^ -o $(OUT)/boot.o