libk  Check-in [269baab90a]

Overview
Comment:check in missing files
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 269baab90a0d97cbfb1984d1590ea42b227ee4fffc7fac55f3f507dda4472053
User & Date: lexi on 2019-08-22 08:45:23
Other Links: manifest | tags
Context
2019-08-22
08:52
add tests for linear allocators, fix dumb bug in kmheapf() that caused it to return an error on success check-in: f37ee769c9 user: lexi tags: trunk
08:45
check in missing files check-in: 269baab90a user: lexi tags: trunk
08:44
add kmlini() and kmlina() functions; restructure allocation functions to work more reasonably (returning a tuple struct instead of making a user pass in a void**); update docs accordingly check-in: acb4a9944e user: lexi tags: trunk
Changes

Added mod/kcli/kcli.md version [09b7990027].

            1  +# kcli
            2  +**kcli** is a module that implements common routines used by command-line utilities, such as option parsing, usage display, and more.
            3  +
            4  +## functions
            5  +
            6  +### kcli_usage(kcli_set, kiochan)
            7  +kcli_usage() takes a `kcli_set` and prints a succinct usage summary to a [kiochan](../kio/kio.md).
            8  +
            9  +## types
           10  +
           11  +### struct kcli_set
           12  +`kcli_set` is a struct containing information about your program, such as its name, a synopsis of its function, a pointer to `argv`, and a list of `kcli_opt`s.
           13  +
           14  + * `const char* name` - program name (if null, will be determined from argv instead)
           15  + * `size_t argc` - the number of arguments in the `argv` array.
           16  + * `const char** argv` - the `argv` pointer passed to the `entry` function, representing the command-line arguments passed to the program.
           17  + * `const char* desc` - program description
           18  + * `const kcli_param* params` - a list of options expected by the program.
           19  + * `size_t paramc` - the number of params in the list to process.
           20  + * `const kcli_opt* opts` - a list of options expected by the program.
           21  + * `size_t optc` - the number of options in the list to process.
           22  +
           23  +a kcli_set might be used like so:
           24  +
           25  +    #include <k/core.h>
           26  +    #include <k/io.h>
           27  +    #include <k/cli.h>
           28  +    stat entry(kenv e) {
           29  +    	kcli_flag aardvark;
           30  +    	kcli_flag zebra;
           31  +    	char* user;
           32  +    	char* password;
           33  +		long age;
           34  +		kcli_param params[] = {
           35  +    		{ "user", kcli_param_string, kcli_class_required,
           36  +    		  &user, "the user to log in as" }
           37  +			  // or Kcli_param(user,string,required,"the user to log in as"),
           38  +
           39  +			{ "age", kcli_param_dec, kcli_class_optional,
           40  +    		  &age, "the age of the user" }
           41  +			  // or Kcli_param(age,dec,optional,"the age of the user"),
           42  +		};
           43  +    	kcli_opt options[] = {
           44  +    		{ 'a', "aardvark", kcli_opt_flag, &aardvark,
           45  +    		  "a nocturnal burrowing mammal" },
           46  +			  // or Kcli_opt(aardvark, 'a', flag, "a nocturnal burrowing mammal")
           47  +    		{ 'z', "zebra", kcli_opt_flag, &zebra,
           48  +    		  "a striped equine" },
           49  +    		{ 'p', "password", kcli_opt_string, &password,
           50  +    		  "the password to log in with" }
           51  +    	};
           52  +    	kcli_set argset = {
           53  +    		"demo", e.argc, e.argv,
           54  +    		"a demonstration of the kcli_set type",
           55  +			params, Kmsz(params),
           56  +			options, Kmsz(options)
           57  +    	},
           58  +		size_t args_parsed = kcli_parse(&argset);
           59  +		if (args_parsed == 0) { kcli_usage(&me, e.err); return 1; }
           60  +
           61  +		return 0;
           62  +	}
           63  +
           64  +### struct kcli_opt
           65  +a `kcli_opt` is a representation of a command-line flag and its function. each option must have a unique `id` and/or a unique `name`.
           66  +
           67  + * `char id` - the short single-character form of the flag (or NUL for no short form)
           68  + * `const char* name` - the long string form of the flag (or NULL for no long form)
           69  + * `kcli_opt_kind kind` - enum that describes how the flag will function
           70  + * `void* val` - a pointer to an appropriate type to store the return value in.
           71  + * `const char* desc` - a description of the flag's purpose and function (or NULL for no description)
           72  +
           73  +#### enum kcli_opt_kind
           74  +
           75  + * `kcli_opt_none` - flag is disabled and will not be shown in usage
           76  + * `kcli_opt_string` - flag tells kcli to add a string to the list of expected parameters; appropriate string will be returned
           77  + * `kcli_opt_oct` - flag tells kcli to add an octal number to the list of expected parameters
           78  + * `kcli_opt_dec` - flag tells kcli to add a decimal number to the list of expected parameters
           79  + * `kcli_opt_hex` - flag tells kcli to add a hexdecimal number to the list of expected parameters
           80  + * `kcli_opt_flag` - flag is an option: will return `kcli_flag_on` if entered at least once, `kcli_flag_off` otherwise.
           81  + * `kcli_opt_toggle` - flag toggles value on and off: will return `kcli_flag_on` if entered an odd number of times, `kcli_flag_off` otherwise.
           82  + * `kcli_opt_accumulate` - flag increments a value every time it is entered; often used to implement `-v (--verbose)`-style options (e.g. `-vvvv` would return a value of `4`).
           83  + * `kcli_opt_enum` - flag is one of a series of enumerated values, which will be matched against a table to yield the associated integer.
           84  +
           85  +### struct kcli_param
           86  +`kcli_param` describes a parameter that may be passed to the program whether or not any flags are passed.
           87  +
           88  + * `const char* name` - a short name for the parameter
           89  + * `kcli_param_kind kind` - the kind of parameter passed
           90  + * `kcli_class class` - whether or not the parameter is optional
           91  + * `void* val` - a pointer to an appropriate type of variable to fill
           92  + * `const char* desc` - a description of the parameter's function
           93  +
           94  +#### enum kcli_param_kind
           95  + * `kcli_param_none` - parameter is disabled and will not be expected or accepted
           96  + * `kcli_param_string` - parameter will not be parsed; a raw string will be returned
           97  + * `kcli_param_oct` - parameter will be parsed as an octal number
           98  + * `kcli_param_dec` - parameter will be parsed as a decimal number
           99  + * `kcli_param_hex` - parameter will be parsed as a hexadecimal number
          100  +
          101  +### enum kcli_class
          102  + * `kcli_class_forbidden` - parameter may not be passed
          103  + * `kcli_class_optional` - parameter may or may not be passed
          104  + * `kcli_class_required` - parameter must be passed
          105  +
          106  +### enum kcli_flag
          107  +results that an option of kind `kcli_opt_flag` can return.
          108  +
          109  + * `kcli_flag_off = 0` - flag is off
          110  + * `kcli_flag_on = 1` - flag is on
          111  + 
          112  +## macros
          113  +
          114  +### Kcli_param(field, kind, class, description)
          115  +a convenience macro for filling out parameter lists.
          116  +
          117  +`Kcli_param(field,a,b,"description")` is transformed into:
          118  +
          119  +    { "field", kcli_param_a, kcli_class_b, &field, "description" }
          120  +
          121  +### Kcli_opt(field, kind, class, description)
          122  +a convenience macro for filling out option lists.
          123  +
          124  +`Kcli_opt(name,'n',string,"description")` is transformed into:
          125  +
          126  +    { 'n', "name", kcli_opt_string, &name, "description" }

Added mod/kcore/okay.fn.c version [4f27230207].

            1  +#include <k/core.h>
            2  +#include <k/type.h>
            3  +#include <k/internal.egroup.h>
            4  +
            5  +bool kokay(kcond val) {
            6  +	return (val % kglobal_module_offset) == 0;
            7  +}

Added mod/kcore/syscall.fn.x86.lin.32.s version [78de383598].

            1  +; kcore/syscall.fn.x86.lin.32.s
            2  +; ~ lexi hale <lexi@hale.su>
            3  +;
            4  +; this function performs a syscall and stores its
            5  +; results in the variables provided. this makes it
            6  +; possible to bypass the hideous errno mechanism
            7  +; altogether and access the error value of a
            8  +; syscall directly. invoke as:
            9  +;
           10  +; 	void k_platform_syscall_raw(s32* result, u32* errno,
           11  +;		syscall, u8 valency, s32[] args)
           12  +
           13  +bits 32
           14  +%include "../arch/posix/x86.lin.32.s"
           15  +%include "../arch/x86.cdecl.32.s"
           16  +; vim: ft=nasm
           17  +
           18  +
           19  +%define result_ptr edi
           20  +%define errno_ptr ebx
           21  +%define valency ecx
           22  +%define args esi
           23  +%define opcode eax
           24  +
           25  +%macro handle_arg 1
           26  +	push dword [args]
           27  +	sub args, 4
           28  +	dec valency 
           29  +	jz .perform_call
           30  +%endmacro
           31  +
           32  +global k_platform_syscall_raw:function
           33  +k_platform_syscall_raw:
           34  +	; locals: rbx = s32* result
           35  +	;         r12 = u32* errno
           36  +	; arg 0 = s32* result
           37  +	; arg 1 = errno ptr
           38  +	; arg 2 = syscall num
           39  +	; arg 3 = valency
           40  +	; arg 4 = args ptr
           41  +
           42  +	; store the locals in registers that
           43  +	; are guaranteed not to be clobbered,
           44  +	; saving us some cycles pushing to
           45  +	; and popping back from the stack
           46  +	pop result_ptr 
           47  +	pop errno_ptr
           48  +	pop edx ; opcode
           49  +
           50  +	; set up registers for the loop
           51  +	pop valency
           52  +	pop args ; ptr to args array
           53  +	mov eax, 4
           54  +	mul valency
           55  +	add args, eax ; adjust args pointer to point
           56  +	              ; at end of array, so it can be
           57  +				  ; trivially pushed in backwards
           58  +
           59  +	; this needs to go before the loop
           60  +	; or it'll get clobbered
           61  +	mov opcode, edx ; syscall number
           62  +
           63  +	; automatically generate the code
           64  +	; needed to move the arguments into
           65  +	; their correct registers. see above
           66  +	%assign i 0
           67  +	%rep 6
           68  +		handle_arg i
           69  +		%assign i i+1
           70  +	%endrep
           71  +
           72  +	; valency >= 7. this is not valid, so
           73  +	; we set our return value to 0 and the
           74  +	; error number to its maximum value in
           75  +	; order to indicate that the syscall
           76  +	; was invalid
           77  +	mov dword [result_ptr], -1
           78  +	mov dword [errno_ptr], -1
           79  +	ret
           80  +
           81  +	; we have a valency match - perform the
           82  +	; requested syscall already stored in eax
           83  +	.perform_call: sys.call
           84  +
           85  +	; check if an error has occurred, and
           86  +	; jump to the error handling routine
           87  +	; if necessary
           88  +	test sys.reg.ret, sys.reg.ret
           89  +	js .error
           90  +	
           91  +	; move our return values into place and
           92  +	; return to the caller (which should
           93  +	; always be k_platform_syscall, btw)
           94  +	mov       [result_ptr], sys.reg.ret
           95  +	mov dword [errno_ptr], 0
           96  +	ret
           97  +
           98  +	.error: neg sys.reg.ret
           99  +	        mov dword [result_ptr], -1
          100  +			mov       [errno_ptr], sys.reg.ret
          101  +			ret

Added mod/kmem/lina.fn.c version [0011a847e1].

            1  +/* lina.fn.c - kmlina() - linear allocate
            2  + * ~ lexi hale <lexi@hale.su>
            3  + * kmlina() allocates the requested amount of space on
            4  + * the heap and returns a pointer to it. it allocates
            5  + * this memory simply by growing the heap the proper
            6  + * length. */
            7  +
            8  +#include <k/mem.h>
            9  +#include <k/def.h>
           10  +
           11  +#ifdef KFenv_posix
           12  +#	include <posix/posix.h>
           13  +#endif
           14  +
           15  +kmres kmlina(sz size) {
           16  +	k_platform_syscall_arg
           17  +		   top = (sz)kmlini(),
           18  +		newbrk = top + size;
           19  +
           20  +	struct k_platform_syscall_answer a = k_platform_syscall
           21  +		(k_platform_syscall_brk, 1, &newbrk);
           22  +
           23  +	kmres reply;
           24  +
           25  +	if (a.error != 0) reply.cond = kmcond_no_room,
           26  +	                  reply.raw = 0;
           27  +		else reply.cond = kmcond_ok,
           28  +			 reply.raw = (void*)a.ret;
           29  +
           30  +	return reply;
           31  +}

Added mod/kmem/lini.fn.c version [99be01eb40].

            1  +/* lini.fn.c - kmlini() - initiate a linear segment
            2  + * ~ lexi hale <lexi@hale.su>
            3  + * this function is the initiator function for the
            4  + * linear memory store. it simply returns the current
            5  + * heap position by invoking the brk syscall with the
            6  + * value `0`. (note that the brk syscall and the libc
            7  + * wrapper have different behavior.) */
            8  +
            9  +#include <k/mem.h>
           10  +#include <k/def.h>
           11  +
           12  +#ifdef KFenv_posix
           13  +#	include <posix/posix.h>
           14  +#endif
           15  +
           16  +/* returns void* instead of kmres because kmlini has
           17  + * no failure state */
           18  +void* kmlini(void) {
           19  +	k_platform_syscall_arg zero = 0;
           20  +	/* brk adjusts the heap break then returns the new
           21  +	 * break. by passing zero, we can get retrieve the
           22  +	 * current heap break. */
           23  +	struct k_platform_syscall_answer a = k_platform_syscall
           24  +		(k_platform_syscall_brk, 1, &zero);
           25  +
           26  +	/* no point in checking for errors, since none can
           27  +	 * actually occur; just return the kernel's answer. */
           28  +	return (void*)a.ret;
           29  +}