1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#include <k/cli.h>
#include <k/io.h>
#include <k/str.h>
kcond
kcli_usage(kcli_set prg, kiochan ch) {
ubyte buf_space [sizeof(ksbuf) + 256];
ksbuf* out = ksbufmk(buf_space, ch, 256);
const char* msg [] = {
prg.name, " v", prg.version, "\n\n",
prg.desc, "\n\n",
};
for (sz i = 0; i != Kmsz(msg); ++ i) {
ksraw str = { 0, msg[i] };
kcond c = ksbufput(out, str);
}
return ksbufflush(out);
}
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
|
<
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
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
|
#include <k/core.h>
#include <k/cli.h>
#include <k/io.h>
#include <k/str.h>
extern char* _k_internal_binary_name;
static const struct { const char* front, * back; } param_styles [] = {
[kcli_rule_required] = { "<",">" },
[kcli_rule_optional] = { "[","]" },
[kcli_rule_overflow] = { "","..." },
};
kcond
kcli_usage(kcli_set prg, kiochan ch) {
enum { max_name_len = 32 };
kcond c;
ubyte buf_space [sizeof(ksbuf) + 256];
ksbuf* out = ksbufmk(buf_space, ch, 256);
const char* name = prg.name != null ?
prg.name : _k_internal_binary_name;
const char* msg [] = {
name, " v", prg.version, "\n\n",
prg.desc, "\n\n",
"usage: ", _k_internal_binary_name,
prg.optc == 0 ? null : " [-",
};
if (!kokay(c = ksbufwrite(out, msg))) return c;
u8 longest_opt = 0;
u8 opt_lens [prg.optc];
for (sz i = 0; i != prg.optc; ++ i) {
if (prg.opts[i].id[0] == 0) continue;
opt_lens[i] = kssz(prg.opts[i].name, max_name_len);
if (opt_lens[i] > longest_opt)
longest_opt = opt_lens[i];
ksraw str = { kssz(prg.opts[i].id, 4), prg.opts[i].id };
if (!kokay(c = ksbufput(out, str))) return c;
}
if (!kokay(c = ksbufput(out, Ksraw("]")))) return c;
u8 longest_param = 0;
u8 param_lens [prg.paramc];
for (sz i = 0; i != prg.paramc; ++ i) {
enum kcli_rule r = prg.params[i].rule;
param_lens[i] = kssz(prg.params[i].name, max_name_len);
if (param_lens[i] > longest_param)
longest_param = param_lens[i];
const char* param[] = {
" ", param_styles[r].front, prg.params[i].name,
param_styles[r].back, null
};
if (!kokay(c = ksbufwrite(out,param))) return c;
}
if (!kokay(c = ksbufput(out, Ksraw("\n")))) return c;
const char spacing [] = " ";
Kassert(sizeof spacing - 1 == max_name_len,
"spacing string not equal in length to max_name_len");
/* yes, yes, i know */
for (sz i = 0; i != prg.paramc; ++ i) {
u8 pad = (longest_param - param_lens[i]) + 1;
const char* tpl [] = {
"\n ", spacing + (sizeof spacing - pad),
prg.params[i].name, ": ", prg.params[i].desc, null
};
if (!kokay(c = ksbufwrite(out, tpl))) return c;
}
if (!kokay(c = ksbufput(out, (ksraw){1, "\n"}))) return c;
for (sz i = 0; i != prg.optc; ++ i) {
u8 pad = (longest_opt - opt_lens[i]) + 1;
const char* tpl [] = {
"\n -", prg.opts[i].id, ", --", prg.opts[i].name,
spacing + (sizeof spacing - pad), ": ", prg.opts[i].desc, null
};
if (!kokay(c = ksbufwrite(out, tpl))) return c;
}
return ksbufflush(out);
}
|