libk  Diff

Differences From Artifact [09e6f94502]:

To Artifact [51bd833f89]:


            1  +#include <k/core.h>
     1      2   #include <k/cli.h>
     2      3   #include <k/io.h>
     3      4   #include <k/str.h>
            5  +
            6  +extern char* _k_internal_binary_name;
            7  +
            8  +static const struct { const char* front, * back; } param_styles [] = {
            9  +	[kcli_rule_required] = { "<",">" },
           10  +	[kcli_rule_optional] = { "[","]" },
           11  +	[kcli_rule_overflow] = { "","..." },
           12  +};
     4     13   
     5     14   kcond
     6     15   kcli_usage(kcli_set prg, kiochan ch) {
           16  +	enum { max_name_len = 32 };
           17  +
           18  +	kcond c;
     7     19   	ubyte buf_space [sizeof(ksbuf) + 256];
     8     20   	ksbuf* out = ksbufmk(buf_space, ch, 256);
     9     21   
           22  +	const char* name = prg.name != null ?
           23  +		prg.name : _k_internal_binary_name;
           24  +
    10     25   	const char* msg [] = {
    11         -		prg.name, " v", prg.version, "\n\n",
           26  +		name, " v", prg.version, "\n\n",
    12     27   		prg.desc, "\n\n",
           28  +		"usage: ", _k_internal_binary_name,
           29  +		prg.optc == 0 ? null : " [-",
    13     30   	};
    14         -	for (sz i = 0; i != Kmsz(msg); ++ i) {
    15         -		ksraw str = { 0, msg[i] };
    16         -		kcond c = ksbufput(out, str);
           31  +
           32  +	if (!kokay(c = ksbufwrite(out, msg))) return c;
           33  +
           34  +	u8 longest_opt = 0;
           35  +	u8 opt_lens [prg.optc];
           36  +	for (sz i = 0; i != prg.optc; ++ i) {
           37  +		if (prg.opts[i].id[0] == 0) continue;
           38  +
           39  +		opt_lens[i] = kssz(prg.opts[i].name, max_name_len);
           40  +		if (opt_lens[i] > longest_opt)
           41  +			longest_opt = opt_lens[i];
           42  +
           43  +		ksraw str = { kssz(prg.opts[i].id, 4), prg.opts[i].id };
           44  +		if (!kokay(c = ksbufput(out, str))) return c;
    17     45   	}
           46  +
           47  +	if (!kokay(c = ksbufput(out, Ksraw("]")))) return c;
    18     48   	
           49  +	u8 longest_param = 0;
           50  +	u8 param_lens [prg.paramc];
           51  +	for (sz i = 0; i != prg.paramc; ++ i) {
           52  +		enum kcli_rule r = prg.params[i].rule;
           53  +
           54  +		param_lens[i] = kssz(prg.params[i].name, max_name_len);
           55  +		if (param_lens[i] > longest_param)
           56  +			longest_param = param_lens[i];
           57  +
           58  +		const char* param[] = {
           59  +			" ", param_styles[r].front, prg.params[i].name,
           60  +			param_styles[r].back, null
           61  +		};
           62  +
           63  +		if (!kokay(c = ksbufwrite(out,param))) return c;
           64  +	}
           65  +
           66  +	if (!kokay(c = ksbufput(out, Ksraw("\n")))) return c;
           67  +
           68  +	const char spacing [] = "                                ";
           69  +	Kassert(sizeof spacing - 1 == max_name_len,
           70  +			"spacing string not equal in length to max_name_len");
           71  +	/* yes, yes, i know */
           72  +
           73  +	for (sz i = 0; i != prg.paramc; ++ i) {
           74  +		u8 pad = (longest_param - param_lens[i]) + 1;
           75  +		const char* tpl [] = {
           76  +			"\n    ", spacing + (sizeof spacing - pad),
           77  +			prg.params[i].name, ": ", prg.params[i].desc, null
           78  +		};
           79  +
           80  +		if (!kokay(c = ksbufwrite(out, tpl))) return c;
           81  +	}
           82  +
           83  +	if (!kokay(c = ksbufput(out, (ksraw){1, "\n"}))) return c;
           84  +
           85  +	for (sz i = 0; i != prg.optc; ++ i) {
           86  +		u8 pad = (longest_opt - opt_lens[i]) + 1;
           87  +		const char* tpl [] = {
           88  +			"\n    -", prg.opts[i].id, ", --", prg.opts[i].name,
           89  +			spacing + (sizeof spacing - pad), ": ", prg.opts[i].desc, null
           90  +		};
           91  +
           92  +		if (!kokay(c = ksbufwrite(out, tpl))) return c;
           93  +	}
           94  +
    19     95   	return ksbufflush(out);
    20     96   }