1 #include <lunaix/kcmd.h>
2 #include <lunaix/syslog.h>
3 #include <lunaix/mm/valloc.h>
4 #include <lunaix/spike.h>
6 #include <klibc/string.h>
23 static DECLARE_HASHTABLE(options, 8);
26 extract_next_option(struct extractor* ctx)
28 #define is_valid_char(c) ((unsigned int)(((c) & ~0x80) - 'A') < 'Z')
32 int i = ctx->pos, state = PARSE_KEY;
33 struct substr* s = &ctx->key;
37 if (!ctx->cmdline[i]) {
41 while((c = ctx->cmdline[i++])) {
43 while ((c = ctx->cmdline[i++]) && c == ' ');
48 if (state == PARSE_KEY) {
50 WARN("unexpected character: '=' (pos:%d). skipping...\n", i + 1);
51 while ((c = ctx->cmdline[i++]) && c != ' ');
70 #define MAX_KEYSIZE 16
73 kcmd_parse_cmdline(char* cmd_line)
75 struct extractor ctx = { .cmdline = cmd_line, .pos = 0 };
77 while(extract_next_option(&ctx)) {
82 size_t maxlen = sizeof(struct koption) - offsetof(struct koption, buf);
84 if (ctx.key.len >= maxlen) {
85 WARN("option key too big. skipping...\n");
89 if (ctx.val.len >= 256) {
90 WARN("option value too big. skipping...\n");
94 struct koption* kopt =
95 (struct koption*) vzalloc(sizeof(*kopt));
97 memcpy(kopt->buf, &cmd_line[ctx.key.pos], ctx.key.len);
100 kopt->value = &kopt->buf[ctx.key.len + 1];
101 size_t max_val_len = maxlen - ctx.key.len;
103 // value too big to fit inplace
104 if (max_val_len <= ctx.val.len) {
105 kopt->value = vzalloc(ctx.val.len + 1);
108 memcpy(kopt->value, &cmd_line[ctx.val.pos], ctx.val.len);
111 kopt->hashkey = HSTR(kopt->buf, ctx.key.len);
112 hstr_rehash(&kopt->hashkey, HSTR_FULL_HASH);
114 hashtable_hash_in(options, &kopt->node, kopt->hashkey.hash);
119 kcmd_get_option(char* key, char** out_value)
121 struct hstr hkey = HSTR(key, strlen(key));
122 hstr_rehash(&hkey, HSTR_FULL_HASH);
124 struct koption *pos, *n;
125 hashtable_hash_foreach(options, hkey.hash, pos, n, node) {
126 if (HSTR_EQ(&pos->hashkey, &hkey)) {
135 *out_value = pos->value;