diff options
author | Ian Moffett <ian@osmora.org> | 2025-10-02 22:29:38 -0400 |
---|---|---|
committer | Ian Moffett <ian@osmora.org> | 2025-10-02 22:32:35 -0400 |
commit | 5376635efb1a3a80ee8c16160afa642b7db6c43b (patch) | |
tree | 5f5a18b94130cae58d08699f0aa3cce43010cd3a /src/sys/np | |
parent | 21e2714d90fdfc853159bd08368bb350dc9388e1 (diff) |
np: lex: Introduce string tokens
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys/np')
-rw-r--r-- | src/sys/np/core/np_lex.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/src/sys/np/core/np_lex.c b/src/sys/np/core/np_lex.c index 222feba..9679bdd 100644 --- a/src/sys/np/core/np_lex.c +++ b/src/sys/np/core/np_lex.c @@ -36,6 +36,7 @@ #include <sys/errno.h> #include <sys/syslog.h> #include <os/np.h> +#include <os/kalloc.h> #include <np/lex.h> #include <string.h> @@ -303,6 +304,73 @@ lex_nomnum(struct np_work *work, char c, struct lex_token *res) } /* + * Parse a string and return the result as token + * + * @work: Current work + * @c: Current character + * @res: Result is written here + * + * Returns zero on success, otherwise a less than zero + * value to indicate failure + */ +static int +lex_nomstr(struct np_work *work, char c, struct lex_token *res) +{ + char *strbuf; + size_t strbuf_i = 0, start_line; + bool have_term = false; + int retval = 0; + + if (work == NULL || res == NULL) { + return -EINVAL; + } + + start_line = work->line_no; + + /* + * Create a string buffer. This might be configured to + * be a rather large number so we allocate on the heap + * to not overflow the stack. + */ + if ((strbuf = kalloc(LEX_MAX_STRLEN)) == NULL) { + pr_error("failed to allocate string buffer\n"); + return -1; + } + + while ((c = lex_pop(work)) != 0) { + if (strbuf_i >= (LEX_MAX_STRLEN - 1)) { + pr_error("line %d: string too long!\n", start_line); + retval = -1; + break; + } + + /* End our scanning once we have an end quote */ + if (c == '"') { + strbuf[strbuf_i] = '\0'; + have_term = true; + break; + } + + strbuf[strbuf_i++] = c; + } + + /* + * If everything went well, copy the string into the + * token store. + */ + if (have_term) { + res->val_str = ptrbox_strdup(strbuf, work->work_mem); + } else { + pr_error("line %d: Unterminated string\n", start_line); + retval = -1; + } + + res->token = TT_STR; + kfree(strbuf); + return retval; +} + +/* * Nom a token */ int @@ -355,6 +423,12 @@ lex_nom(struct np_work *work, struct lex_token *res) case ':': res->token = TT_COLON; break; + case '"': + /* Handle a string */ + if ((error = lex_nomstr(work, c, res)) < 0) { + return error; + } + break; default: if (is_num(c)) { lex_nomnum(work, c, res); |