summaryrefslogtreecommitdiff
path: root/src/literal.c
diff options
context:
space:
mode:
authorAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2024-01-05 22:51:33 +0100
committerAnna (navi) Figueiredo Gomes <navi@vlhl.dev>2024-01-06 18:58:13 +0100
commite079370a92766181ff5281c5d6cea03a1fce5b93 (patch)
treec05ffce648ea7cb5e3c3ebb102ac4c80ff9b4c35 /src/literal.c
initial release
Signed-off-by: Anna (navi) Figueiredo Gomes <navi@vlhl.dev>
Diffstat (limited to 'src/literal.c')
-rw-r--r--src/literal.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/literal.c b/src/literal.c
new file mode 100644
index 0000000..8723462
--- /dev/null
+++ b/src/literal.c
@@ -0,0 +1,58 @@
+#include <ctype.h>
+#include <string.h>
+#include <json.h>
+#include "internal.h"
+
+enum json_parse_result parse_literal(struct json **json_out, struct raw_json *raw) {
+ enum json_parse_result ret = JSON_PARSE_OK;
+ struct json *json = NULL;
+
+ bool plus_one = raw->data[raw->index] == '+' || raw->data[raw->index] == '-';
+ if (plus_one || isdigit(raw->data[raw->index])) {
+ if (raw->data[raw->index] == '0' && isdigit(raw->data[raw->index + 1])) {
+ ret = JSON_PARSE_INVALID_NUMBER_ERR;
+ goto err;
+ }
+ const char *start = raw->data + raw->index + plus_one;
+ char *end;
+ /* is probably a number here, strtodl will tell */
+ double num = strtod(start, &end);
+ if (end != start) {
+ if (raw->data[raw->index] == '-')
+ num = -num;
+ json = json_new_number(num);
+ raw->index = end - raw->data;
+ } else {
+ ret = JSON_PARSE_INVALID_NUMBER_ERR;
+ goto err;
+ }
+ } else {
+ size_t end_index;
+ for (end_index = raw->index; end_index < raw->size; end_index++) {
+ if (!isalpha(raw->data[end_index])) {
+ break;
+ }
+ }
+ size_t len = end_index - raw->index;
+ if (len == 4 && strncmp(raw->data + raw->index, "true", len) == 0) {
+ json = json_new_bool(true);
+ } else if (len == 5 && strncmp(raw->data + raw->index, "false", len) == 0) {
+ json = json_new_bool(false);
+ } else if (len == 4 && strncmp(raw->data + raw->index, "null", len) == 0) {
+ json = json_new_null();
+ } else {
+ ret = JSON_PARSE_INVALID_TOKEN_ERR;
+ }
+ raw->index = end_index;
+ }
+
+ if (!json)
+ return JSON_OOM;
+
+ *json_out = json;
+ goto end;
+err:
+ json_delete(json);
+end:
+ return ret;
+}