summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2025-10-02 22:29:38 -0400
committerIan Moffett <ian@osmora.org>2025-10-02 22:32:35 -0400
commit5376635efb1a3a80ee8c16160afa642b7db6c43b (patch)
tree5f5a18b94130cae58d08699f0aa3cce43010cd3a /src/sys
parent21e2714d90fdfc853159bd08368bb350dc9388e1 (diff)
np: lex: Introduce string tokens
Signed-off-by: Ian Moffett <ian@osmora.org>
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/include/np/lex.h4
-rw-r--r--src/sys/np/core/np_lex.c74
2 files changed, 78 insertions, 0 deletions
diff --git a/src/sys/include/np/lex.h b/src/sys/include/np/lex.h
index ba581b7..b9c8a6a 100644
--- a/src/sys/include/np/lex.h
+++ b/src/sys/include/np/lex.h
@@ -35,6 +35,9 @@
/* End-of-file */
#define LEX_EOF (-2)
+/* Max string length */
+#define LEX_MAX_STRLEN 4096
+
struct np_work;
/* Keywords */
@@ -86,6 +89,7 @@ typedef enum {
TT_I16, /* 'i16' */
TT_I32, /* 'i32' */
TT_I64, /* 'i64' */
+ TT_STR, /* <string> */
/* Values */
TT_NUMBER, /* <numbers> */
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);