diff options
author | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2024-01-05 22:51:33 +0100 |
---|---|---|
committer | Anna (navi) Figueiredo Gomes <navi@vlhl.dev> | 2024-01-06 18:58:13 +0100 |
commit | e079370a92766181ff5281c5d6cea03a1fce5b93 (patch) | |
tree | c05ffce648ea7cb5e3c3ebb102ac4c80ff9b4c35 /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.c | 58 |
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; +} |