toml: support empty tables (#12504)
parent
24ea15c8f0
commit
7fba3e65e9
|
@ -254,10 +254,7 @@ fn (p Parser) check_explicitly_declared(key DottedKey) ? {
|
||||||
// See also `find_in_table`.
|
// See also `find_in_table`.
|
||||||
pub fn (mut p Parser) find_table() ?&map[string]ast.Value {
|
pub fn (mut p Parser) find_table() ?&map[string]ast.Value {
|
||||||
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$p.root_map_key" in map ${ptr_str(p.root_map)}')
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$p.root_map_key" in map ${ptr_str(p.root_map)}')
|
||||||
mut t := &map[string]ast.Value{}
|
mut t := unsafe { &p.root_map }
|
||||||
unsafe {
|
|
||||||
t = &p.root_map
|
|
||||||
}
|
|
||||||
if p.root_map_key.len == 0 {
|
if p.root_map_key.len == 0 {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
@ -265,6 +262,16 @@ pub fn (mut p Parser) find_table() ?&map[string]ast.Value {
|
||||||
return p.find_in_table(mut t, p.root_map_key)
|
return p.find_in_table(mut t, p.root_map_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allocate_table allocates all tables in "dotted" `key` (`a.b.c`) in the *root* table.
|
||||||
|
pub fn (mut p Parser) allocate_table(key DottedKey) ? {
|
||||||
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocating "$key" in map ${ptr_str(p.root_map)}')
|
||||||
|
mut t := unsafe { &p.root_map }
|
||||||
|
if key.len == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
p.allocate_in_table(mut t, key) ?
|
||||||
|
}
|
||||||
|
|
||||||
// sub_table_key returns the logic parts of a dotted key (`a.b.c`) for
|
// sub_table_key returns the logic parts of a dotted key (`a.b.c`) for
|
||||||
// use with the `find_sub_table` method.
|
// use with the `find_sub_table` method.
|
||||||
pub fn (mut p Parser) sub_table_key(key DottedKey) (DottedKey, DottedKey) {
|
pub fn (mut p Parser) sub_table_key(key DottedKey) (DottedKey, DottedKey) {
|
||||||
|
@ -286,10 +293,7 @@ pub fn (mut p Parser) find_sub_table(key DottedKey) ?&map[string]ast.Value {
|
||||||
ky = key
|
ky = key
|
||||||
}
|
}
|
||||||
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$ky" in map ${ptr_str(p.root_map)}')
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$ky" in map ${ptr_str(p.root_map)}')
|
||||||
mut t := &map[string]ast.Value{}
|
mut t := unsafe { &p.root_map }
|
||||||
unsafe {
|
|
||||||
t = &p.root_map
|
|
||||||
}
|
|
||||||
if ky.len == 0 {
|
if ky.len == 0 {
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
@ -306,10 +310,7 @@ pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKe
|
||||||
// I'm still not quite sure *exactly* why it works. All I can leave here is a hope
|
// I'm still not quite sure *exactly* why it works. All I can leave here is a hope
|
||||||
// that this kind of minefield someday will be easier in V :)
|
// that this kind of minefield someday will be easier in V :)
|
||||||
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$key" in map ${ptr_str(table)}')
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'locating "$key" in map ${ptr_str(table)}')
|
||||||
mut t := &map[string]ast.Value{}
|
mut t := unsafe { &table }
|
||||||
unsafe {
|
|
||||||
t = &table
|
|
||||||
}
|
|
||||||
unsafe {
|
unsafe {
|
||||||
for k in key {
|
for k in key {
|
||||||
if val := t[k] {
|
if val := t[k] {
|
||||||
|
@ -332,6 +333,30 @@ pub fn (mut p Parser) find_in_table(mut table map[string]ast.Value, key DottedKe
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// allocate_in_table allocates all tables in "dotted" `key` (`a.b.c`) in `table`.
|
||||||
|
pub fn (mut p Parser) allocate_in_table(mut table map[string]ast.Value, key DottedKey) ? {
|
||||||
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocating "$key" in map ${ptr_str(table)}')
|
||||||
|
mut t := unsafe { &table }
|
||||||
|
unsafe {
|
||||||
|
for k in key {
|
||||||
|
if val := t[k] {
|
||||||
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'found key "$k" in $t.keys()')
|
||||||
|
if val is map[string]ast.Value {
|
||||||
|
t = &(val as map[string]ast.Value)
|
||||||
|
} else {
|
||||||
|
return error(@MOD + '.' + @STRUCT + '.' + @FN +
|
||||||
|
' "$k" in "$key" is not a map ($val.type_name())')
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'no key "$k" in "$key" found, allocating new map at key "$k" in map ${ptr_str(t)}"')
|
||||||
|
t[k] = map[string]ast.Value{}
|
||||||
|
t = &(t[k] as map[string]ast.Value)
|
||||||
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'allocated new map ${ptr_str(t)}"')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// dotted_key returns a string of the next tokens parsed as
|
// dotted_key returns a string of the next tokens parsed as
|
||||||
// sub/nested/path keys (e.g. `a.b.c`). In TOML, this form of key is referred to as a "dotted" key.
|
// sub/nested/path keys (e.g. `a.b.c`). In TOML, this form of key is referred to as a "dotted" key.
|
||||||
pub fn (mut p Parser) dotted_key() ?DottedKey {
|
pub fn (mut p Parser) dotted_key() ?DottedKey {
|
||||||
|
@ -476,6 +501,7 @@ pub fn (mut p Parser) root_table() ? {
|
||||||
p.ignore_while(parser.space_formatting)
|
p.ignore_while(parser.space_formatting)
|
||||||
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"')
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"')
|
||||||
p.root_map_key = dotted_key
|
p.root_map_key = dotted_key
|
||||||
|
p.allocate_table(p.root_map_key) ?
|
||||||
p.expect(.rsbr) ?
|
p.expect(.rsbr) ?
|
||||||
p.peek_for_correct_line_ending_or_fail() ?
|
p.peek_for_correct_line_ending_or_fail() ?
|
||||||
} else {
|
} else {
|
||||||
|
@ -497,6 +523,7 @@ pub fn (mut p Parser) root_table() ? {
|
||||||
|
|
||||||
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"')
|
util.printdbg(@MOD + '.' + @STRUCT + '.' + @FN, 'setting root map key to `$dotted_key` at "$p.tok.kind" "$p.tok.lit"')
|
||||||
p.root_map_key = dotted_key
|
p.root_map_key = dotted_key
|
||||||
|
p.allocate_table(p.root_map_key) ?
|
||||||
p.next() ?
|
p.next() ?
|
||||||
p.expect(.rsbr) ?
|
p.expect(.rsbr) ?
|
||||||
p.peek_for_correct_line_ending_or_fail() ?
|
p.peek_for_correct_line_ending_or_fail() ?
|
||||||
|
@ -822,10 +849,7 @@ pub fn (mut p Parser) double_array_of_tables_contents(target_key DottedKey) ?[]a
|
||||||
} else {
|
} else {
|
||||||
key, val := p.key_value() ?
|
key, val := p.key_value() ?
|
||||||
|
|
||||||
mut t := &map[string]ast.Value{}
|
mut t := unsafe { &tbl }
|
||||||
unsafe {
|
|
||||||
t = &tbl
|
|
||||||
}
|
|
||||||
if implicit_allocation_key.len > 0 {
|
if implicit_allocation_key.len > 0 {
|
||||||
t = p.find_in_table(mut tbl, implicit_allocation_key) ?
|
t = p.find_in_table(mut tbl, implicit_allocation_key) ?
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,18 +31,8 @@ const (
|
||||||
// Comment
|
// Comment
|
||||||
'comment/tricky.toml',
|
'comment/tricky.toml',
|
||||||
// Table
|
// Table
|
||||||
'table/empty.toml',
|
|
||||||
'table/array-implicit.toml',
|
'table/array-implicit.toml',
|
||||||
'table/sub-empty.toml',
|
|
||||||
'table/without-super.toml',
|
|
||||||
'table/whitespace.toml',
|
|
||||||
'table/names.toml',
|
'table/names.toml',
|
||||||
'table/no-eol.toml',
|
|
||||||
'table/keyword.toml',
|
|
||||||
// Array
|
|
||||||
'array/string-quote-comma.toml',
|
|
||||||
'array/string-quote-comma-2.toml',
|
|
||||||
'array/table-array-string-backslash.toml',
|
|
||||||
// Date-time
|
// Date-time
|
||||||
'datetime/milliseconds.toml',
|
'datetime/milliseconds.toml',
|
||||||
// Inline-table
|
// Inline-table
|
||||||
|
|
Loading…
Reference in New Issue