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: |
269baab90a0d97cbfb1984d1590ea42b |
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 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 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 96 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 126 |
# kcli **kcli** is a module that implements common routines used by command-line utilities, such as option parsing, usage display, and more. ## functions ### kcli_usage(kcli_set, kiochan) kcli_usage() takes a `kcli_set` and prints a succinct usage summary to a [kiochan](../kio/kio.md). ## types ### struct kcli_set `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. * `const char* name` - program name (if null, will be determined from argv instead) * `size_t argc` - the number of arguments in the `argv` array. * `const char** argv` - the `argv` pointer passed to the `entry` function, representing the command-line arguments passed to the program. * `const char* desc` - program description * `const kcli_param* params` - a list of options expected by the program. * `size_t paramc` - the number of params in the list to process. * `const kcli_opt* opts` - a list of options expected by the program. * `size_t optc` - the number of options in the list to process. a kcli_set might be used like so: #include <k/core.h> #include <k/io.h> #include <k/cli.h> stat entry(kenv e) { kcli_flag aardvark; kcli_flag zebra; char* user; char* password; long age; kcli_param params[] = { { "user", kcli_param_string, kcli_class_required, &user, "the user to log in as" } // or Kcli_param(user,string,required,"the user to log in as"), { "age", kcli_param_dec, kcli_class_optional, &age, "the age of the user" } // or Kcli_param(age,dec,optional,"the age of the user"), }; kcli_opt options[] = { { 'a', "aardvark", kcli_opt_flag, &aardvark, "a nocturnal burrowing mammal" }, // or Kcli_opt(aardvark, 'a', flag, "a nocturnal burrowing mammal") { 'z', "zebra", kcli_opt_flag, &zebra, "a striped equine" }, { 'p', "password", kcli_opt_string, &password, "the password to log in with" } }; kcli_set argset = { "demo", e.argc, e.argv, "a demonstration of the kcli_set type", params, Kmsz(params), options, Kmsz(options) }, size_t args_parsed = kcli_parse(&argset); if (args_parsed == 0) { kcli_usage(&me, e.err); return 1; } return 0; } ### struct kcli_opt 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`. * `char id` - the short single-character form of the flag (or NUL for no short form) * `const char* name` - the long string form of the flag (or NULL for no long form) * `kcli_opt_kind kind` - enum that describes how the flag will function * `void* val` - a pointer to an appropriate type to store the return value in. * `const char* desc` - a description of the flag's purpose and function (or NULL for no description) #### enum kcli_opt_kind * `kcli_opt_none` - flag is disabled and will not be shown in usage * `kcli_opt_string` - flag tells kcli to add a string to the list of expected parameters; appropriate string will be returned * `kcli_opt_oct` - flag tells kcli to add an octal number to the list of expected parameters * `kcli_opt_dec` - flag tells kcli to add a decimal number to the list of expected parameters * `kcli_opt_hex` - flag tells kcli to add a hexdecimal number to the list of expected parameters * `kcli_opt_flag` - flag is an option: will return `kcli_flag_on` if entered at least once, `kcli_flag_off` otherwise. * `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. * `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`). * `kcli_opt_enum` - flag is one of a series of enumerated values, which will be matched against a table to yield the associated integer. ### struct kcli_param `kcli_param` describes a parameter that may be passed to the program whether or not any flags are passed. * `const char* name` - a short name for the parameter * `kcli_param_kind kind` - the kind of parameter passed * `kcli_class class` - whether or not the parameter is optional * `void* val` - a pointer to an appropriate type of variable to fill * `const char* desc` - a description of the parameter's function #### enum kcli_param_kind * `kcli_param_none` - parameter is disabled and will not be expected or accepted * `kcli_param_string` - parameter will not be parsed; a raw string will be returned * `kcli_param_oct` - parameter will be parsed as an octal number * `kcli_param_dec` - parameter will be parsed as a decimal number * `kcli_param_hex` - parameter will be parsed as a hexadecimal number ### enum kcli_class * `kcli_class_forbidden` - parameter may not be passed * `kcli_class_optional` - parameter may or may not be passed * `kcli_class_required` - parameter must be passed ### enum kcli_flag results that an option of kind `kcli_opt_flag` can return. * `kcli_flag_off = 0` - flag is off * `kcli_flag_on = 1` - flag is on ## macros ### Kcli_param(field, kind, class, description) a convenience macro for filling out parameter lists. `Kcli_param(field,a,b,"description")` is transformed into: { "field", kcli_param_a, kcli_class_b, &field, "description" } ### Kcli_opt(field, kind, class, description) a convenience macro for filling out option lists. `Kcli_opt(name,'n',string,"description")` is transformed into: { 'n', "name", kcli_opt_string, &name, "description" } |
Added mod/kcore/okay.fn.c version [4f27230207].
> > > > > > > |
1 2 3 4 5 6 7 |
#include <k/core.h> #include <k/type.h> #include <k/internal.egroup.h> bool kokay(kcond val) { return (val % kglobal_module_offset) == 0; } |
Added mod/kcore/syscall.fn.x86.lin.32.s version [78de383598].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 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 96 97 98 99 100 101 |
; kcore/syscall.fn.x86.lin.32.s ; ~ lexi hale <lexi@hale.su> ; ; this function performs a syscall and stores its ; results in the variables provided. this makes it ; possible to bypass the hideous errno mechanism ; altogether and access the error value of a ; syscall directly. invoke as: ; ; void k_platform_syscall_raw(s32* result, u32* errno, ; syscall, u8 valency, s32[] args) bits 32 %include "../arch/posix/x86.lin.32.s" %include "../arch/x86.cdecl.32.s" ; vim: ft=nasm %define result_ptr edi %define errno_ptr ebx %define valency ecx %define args esi %define opcode eax %macro handle_arg 1 push dword [args] sub args, 4 dec valency jz .perform_call %endmacro global k_platform_syscall_raw:function k_platform_syscall_raw: ; locals: rbx = s32* result ; r12 = u32* errno ; arg 0 = s32* result ; arg 1 = errno ptr ; arg 2 = syscall num ; arg 3 = valency ; arg 4 = args ptr ; store the locals in registers that ; are guaranteed not to be clobbered, ; saving us some cycles pushing to ; and popping back from the stack pop result_ptr pop errno_ptr pop edx ; opcode ; set up registers for the loop pop valency pop args ; ptr to args array mov eax, 4 mul valency add args, eax ; adjust args pointer to point ; at end of array, so it can be ; trivially pushed in backwards ; this needs to go before the loop ; or it'll get clobbered mov opcode, edx ; syscall number ; automatically generate the code ; needed to move the arguments into ; their correct registers. see above %assign i 0 %rep 6 handle_arg i %assign i i+1 %endrep ; valency >= 7. this is not valid, so ; we set our return value to 0 and the ; error number to its maximum value in ; order to indicate that the syscall ; was invalid mov dword [result_ptr], -1 mov dword [errno_ptr], -1 ret ; we have a valency match - perform the ; requested syscall already stored in eax .perform_call: sys.call ; check if an error has occurred, and ; jump to the error handling routine ; if necessary test sys.reg.ret, sys.reg.ret js .error ; move our return values into place and ; return to the caller (which should ; always be k_platform_syscall, btw) mov [result_ptr], sys.reg.ret mov dword [errno_ptr], 0 ret .error: neg sys.reg.ret mov dword [result_ptr], -1 mov [errno_ptr], sys.reg.ret ret |
Added mod/kmem/lina.fn.c version [0011a847e1].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
/* lina.fn.c - kmlina() - linear allocate * ~ lexi hale <lexi@hale.su> * kmlina() allocates the requested amount of space on * the heap and returns a pointer to it. it allocates * this memory simply by growing the heap the proper * length. */ #include <k/mem.h> #include <k/def.h> #ifdef KFenv_posix # include <posix/posix.h> #endif kmres kmlina(sz size) { k_platform_syscall_arg top = (sz)kmlini(), newbrk = top + size; struct k_platform_syscall_answer a = k_platform_syscall (k_platform_syscall_brk, 1, &newbrk); kmres reply; if (a.error != 0) reply.cond = kmcond_no_room, reply.raw = 0; else reply.cond = kmcond_ok, reply.raw = (void*)a.ret; return reply; } |
Added mod/kmem/lini.fn.c version [99be01eb40].
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
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 |
/* lini.fn.c - kmlini() - initiate a linear segment * ~ lexi hale <lexi@hale.su> * this function is the initiator function for the * linear memory store. it simply returns the current * heap position by invoking the brk syscall with the * value `0`. (note that the brk syscall and the libc * wrapper have different behavior.) */ #include <k/mem.h> #include <k/def.h> #ifdef KFenv_posix # include <posix/posix.h> #endif /* returns void* instead of kmres because kmlini has * no failure state */ void* kmlini(void) { k_platform_syscall_arg zero = 0; /* brk adjusts the heap break then returns the new * break. by passing zero, we can get retrieve the * current heap break. */ struct k_platform_syscall_answer a = k_platform_syscall (k_platform_syscall_brk, 1, &zero); /* no point in checking for errors, since none can * actually occur; just return the kernel's answer. */ return (void*)a.ret; } |