tlibtoml/src/toml_parse/toml_parse_table.c

88 lines
3.0 KiB
C

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "toml_internal.h"
Result(void) toml_parse_table(TomlParser* self, TomlTable* target_table)
{
Deferral(1);
i32 is_array = false;
TomlTable* real_table = target_table;
TomlArray* key_path = TomlArray_new();
Defer(TomlArray_free(key_path));
if (self->ptr < self->end &&* self->ptr == '[') {
is_array = true;
toml_move_next(self);
}
while (1) {
if (*self->ptr == ' ' ||* self->ptr == '\t') {
do {
toml_move_next(self);
} while (*self->ptr <* self->end && (*self->ptr == ' ' ||* self->ptr == '\t'));
} else if (*self->ptr == ']') {
if (is_array) {
if (self->ptr + 2 <= self->end && strncmp(self->ptr, "]]", 2) == 0) {
toml_next_n(self, 2);
break;
}
} else {
toml_move_next(self);
break;
}
} else {
str key_part;
if (isalnum(*self->ptr) ||* self->ptr == '_') {
try_void(toml_parse_bare_key(self, &key_part));
} else if (*self->ptr == '\"') {
toml_move_next(self);
try_void(toml_parse_basic_string(self, &key_part));
} else if (*self->ptr == '\'') {
toml_move_next(self);
try_void(toml_parse_literal_string(self, &key_part));
} else {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: unexpected token",
self->filename, self->lineno, self->colno);
}
TomlValue key_part_value = TomlValue_move_str(key_part);
TomlArray_append(key_path, key_part_value);
while (self->ptr < self->end &&
(*self->ptr == ' ' ||* self->ptr == '\t')) {
toml_move_next(self);
}
if (self->ptr < self->end &&* self->ptr == '.') {
toml_move_next(self);
}
}
}
if (key_path->len == 0) {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: empty table name",
self->filename, self->lineno, self->colno);
}
while (self->ptr < self->end &&
(*self->ptr == ' ' ||* self->ptr == '\t' ||* self->ptr == '\r')) {
toml_move_next(self);
}
if (self->ptr < self->end &&* self->ptr != '\n') {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: new line expected",
self->filename, self->lineno, self->colno);
}
try(real_table, p, toml_walk_table_path(self, target_table, key_path, is_array, true));
try_void(toml_parse_key_value(self, real_table));
Return RESULT_VOID;
}