tlibtoml/src/toml_parse/toml_parse_inline_table.c

93 lines
2.8 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_inline_table(TomlParser* self, TomlValue* out_value)
{
Deferral(1);
TomlValue table_value = TomlValue_new_table();
bool success = false;
Defer(if(!success) TomlValue_destroy(&table_value));
while (self->ptr < self->end) {
char ch = *self->ptr;
while (self->ptr < self->end && (ch == ' ' || ch == '\t')) {
toml_move_next(self);
ch = *self->ptr;
}
str key;
if (isalnum(ch) || ch == '_') {
try_void(toml_parse_bare_key(self, &key));
} else if (ch == '\"') {
toml_move_next(self);
try_void(toml_parse_basic_string(self, &key));
} else if (ch == '\'') {
toml_move_next(self);
try_void(toml_parse_literal_string(self, &key));
} else if (ch == '}') {
break;
} else {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: unexpected token",
self->filename, self->lineno, self->colno);
}
ch = *self->ptr;
while (self->ptr < self->end && (ch == ' ' || ch == '\t')) {
toml_move_next(self);
ch = *self->ptr;
}
if (self->ptr == self->end) {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: unterminated key value pair",
self->filename, self->lineno, self->colno);
}
if (ch != '=') {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: unexpected token",
self->filename, self->lineno, self->colno);
}
toml_move_next(self);
ch = *self->ptr;
while (self->ptr < self->end && (ch == ' ' || ch == '\t')) {
toml_move_next(self);
ch = *self->ptr;
}
if (self->ptr == self->end) {
Return RESULT_ERROR_CODE_FMT(TLIBTOML, TLIBTOML_ERR_SYNTAX,
"%s:%d:%d: unterminated key value pair",
self->filename, self->lineno, self->colno);
}
TomlValue value;
try_void(toml_parse_value(self, &value));
TomlTable_set(table_value.table, key, value);
str_destroy(key);
while (self->ptr < self->end && (*self->ptr == ' ' ||* self->ptr == '\t')) {
toml_move_next(self);
}
if (*self->ptr == ',') {
toml_move_next(self);
} else if (*self->ptr == '}') {
toml_move_next(self);
break;
}
}
success = true;
*out_value = table_value;
Return RESULT_VOID;
}