1212#include "decode_inline_value.h"
1313
1414#define DECODE_RESULT_IDX 2
15- #define DECODE_ERR_IDX 3
1615// @type { [table]: len if array or -1 for defined table }
17- #define DECODE_DEFINED_IDX 4
16+ // or error userdata type on error
17+ #define DECODE_DEFINED_IDX 3
1818
1919// pops keys, leaves new root on top
2020static inline bool heading_nav (lua_State * L , int keys_len , bool array_type ) {
21- if (keys_len <= 0 ) return set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 28 , "no keys provided to navigate" );
21+ if (keys_len <= 0 ) return set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 28 , "no keys provided to navigate" );
2222 int keys_start = absindex (lua_gettop (L ), - keys_len );
2323 lua_pushvalue (L , DECODE_RESULT_IDX );
2424 for (int key_idx = keys_start ; key_idx < keys_start + keys_len ; key_idx ++ ) {
@@ -33,7 +33,7 @@ static inline bool heading_nav(lua_State *L, int keys_len, bool array_type) {
3333 lua_pushvalue (L , -2 );
3434 lua_rawset (L , parent_idx ); // t[key] = new table
3535 } else if (vtype != LUA_TTABLE ) {
36- return set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 33 , "cannot navigate through non-table" );
36+ return set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 33 , "cannot navigate through non-table" );
3737 }
3838 lua_remove (L , parent_idx ); // remove parent table, keep child on top
3939 lua_pushvalue (L , -1 );
@@ -54,7 +54,7 @@ static inline bool heading_nav(lua_State *L, int keys_len, bool array_type) {
5454 lua_rawseti (L , parent_idx , len );
5555 lua_remove (L , parent_idx ); // remove parent table, keep child on top
5656 } else if (len != 0 ) {
57- return set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 22 , "table already defined!" );
57+ return set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 22 , "table already defined!" );
5858 } else {
5959 lua_pushvalue (L , -1 );
6060 lua_pushinteger (L , -1 );
@@ -64,58 +64,14 @@ static inline bool heading_nav(lua_State *L, int keys_len, bool array_type) {
6464 lua_rawgeti (L , -1 , len );
6565 lua_remove (L , -2 );
6666 if (!lua_istable (L , -1 ))
67- return set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 33 , "cannot navigate through non-table" );
67+ return set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 33 , "cannot navigate through non-table" );
6868 }
6969 }
7070 lua_insert (L , keys_start );
7171 lua_settop (L , keys_start );
7272 return true;
7373}
7474
75- // pops value and keys, leaves root on top
76- static inline bool set_kv (lua_State * L , int keys_len , int value_idx , int erridx ) {
77- if (keys_len <= 0 ) return set_tmlerr (new_tmlerr (L , erridx ), false, 22 , "no key provided to set" );
78- int keys_start = value_idx + 1 ;
79- int root_idx = value_idx - 1 ;
80- lua_pushvalue (L , root_idx ); // copy root table to top
81-
82- // Navigate through all keys except the last
83- for (int key_idx = keys_start ; key_idx < keys_start + keys_len - 1 ; key_idx ++ ) {
84- int parent_idx = lua_gettop (L );
85- lua_pushvalue (L , key_idx );
86- lua_rawget (L , parent_idx );
87- int vtype = lua_type (L , -1 );
88- if (vtype == LUA_TNIL ) {
89- lua_pop (L , 1 ); // remove nil
90- lua_newtable (L ); // create new table
91- lua_pushvalue (L , key_idx );
92- lua_pushvalue (L , -2 ); // copy so we can continue with it after rawset
93- lua_rawset (L , parent_idx ); // t[key] = new table
94- } else if (vtype != LUA_TTABLE ) {
95- return set_tmlerr (new_tmlerr (L , erridx ), false, 18 , "key is not a table" );
96- }
97- lua_remove (L , parent_idx );
98- // NOTE: set_kv in decode_inline_value does not do the next 3 lines
99- lua_pushvalue (L , -1 );
100- lua_pushinteger (L , -1 );
101- lua_rawset (L , DECODE_DEFINED_IDX );
102- }
103-
104- lua_pushvalue (L , -2 );
105- lua_rawget (L , -2 );
106- if (!lua_isnil (L , -1 )) {
107- return set_tmlerr (new_tmlerr (L , erridx ), false, 18 , "key already defined!" );
108- }
109- lua_pop (L , 1 );
110-
111- lua_pushvalue (L , -2 ); // push last key
112- lua_pushvalue (L , value_idx ); // push value
113- lua_rawset (L , -3 ); // parent[last_key] = value
114-
115- lua_settop (L , root_idx );
116- return true;
117- }
118-
11975int tomlua_decode (lua_State * L ) {
12076 // process arguments and options
12177 str_iter src = lua_str_to_iter (L , 1 );
@@ -131,10 +87,9 @@ int tomlua_decode(lua_State *L) {
13187 lua_settop (L , 1 );
13288 // DECODE_RESULT_IDX == 2 == here
13389 lua_newtable (L );
134- // DECODE_ERR_IDX == 3 == here
135- lua_pushnil (L );
136- // DECODE_DEFINED_IDX == 4 == here
90+ // DECODE_DEFINED_IDX == 3 == here
13791 // @type { [table]: len if array or -1 for defined table }
92+ // or error if error
13893 lua_newtable (L );
13994
14095 // set top as the starting location
@@ -157,56 +112,56 @@ int tomlua_decode(lua_State *L) {
157112 if (iter_starts_with (& src , "[[" , 2 )) {
158113 iter_skip_n (& src , 2 );
159114 lua_pop (L , 1 ); // pop current location, we are moving
160- int keys_len = parse_keys (L , & src , & scratch , int_keys , DECODE_ERR_IDX );
115+ int keys_len = parse_keys (L , & src , & scratch , int_keys , DECODE_DEFINED_IDX );
161116 if (!keys_len ) goto fail ;
162117 if (!iter_starts_with (& src , "]]" , 2 )) {
163- set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 30 , "table heading must end with ]]" );
118+ set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 30 , "table heading must end with ]]" );
164119 goto fail ;
165120 }
166121 iter_skip_n (& src , 2 ); // consume ]]
167122 if (!consume_whitespace_to_line (& src )) {
168- set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 56 , "array [[headers]] must have a new line before new values" );
123+ set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 56 , "array [[headers]] must have a new line before new values" );
169124 goto fail ;
170125 }
171126 if (!heading_nav (L , keys_len , true)) goto fail ;
172127 } else if (iter_peek (& src ).v == '[' ) {
173128 iter_skip (& src );
174129 lua_pop (L , 1 ); // pop current location, we are moving
175- int keys_len = parse_keys (L , & src , & scratch , int_keys , DECODE_ERR_IDX );
130+ int keys_len = parse_keys (L , & src , & scratch , int_keys , DECODE_DEFINED_IDX );
176131 if (!keys_len ) goto fail ;
177132 if (iter_peek (& src ).v != ']' ) {
178- set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 29 , "table heading must end with ]" );
133+ set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 29 , "table heading must end with ]" );
179134 goto fail ;
180135 }
181136 iter_skip (& src ); // consume ]
182137 if (!consume_whitespace_to_line (& src )) {
183- set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 54 , "table [headers] must have a new line before new values" );
138+ set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 54 , "table [headers] must have a new line before new values" );
184139 goto fail ;
185140 }
186141 if (!heading_nav (L , keys_len , false)) goto fail ;
187142 } else {
188143 lua_pushnil (L );
189144 int val_spacer = lua_gettop (L );
190- int keys_len = parse_keys (L , & src , & scratch , int_keys , DECODE_ERR_IDX );
145+ int keys_len = parse_keys (L , & src , & scratch , int_keys , DECODE_DEFINED_IDX );
191146 if (!keys_len ) goto fail ;
192147 if (iter_peek (& src ).v != '=' ) {
193- set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 35 , "keys for assignment must end with =" );
148+ set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 35 , "keys for assignment must end with =" );
194149 goto fail ;
195150 }
196151 iter_skip (& src ); // consume =
197152 if (consume_whitespace_to_line (& src )) {
198- set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 76 , "the value in key = value expressions must begin on the same line as the key!" );
153+ set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 76 , "the value in key = value expressions must begin on the same line as the key!" );
199154 goto fail ;
200155 }
201- if (!decode_inline_value (L , & src , & scratch , uopts , DECODE_ERR_IDX )) goto fail ;
156+ if (!decode_inline_value (L , & src , & scratch , uopts , DECODE_DEFINED_IDX )) goto fail ;
202157 lua_replace (L , val_spacer );
203158 // [-1?] keys
204159 // [-?] value
205160 // [-?-1] current root table
206- if (!set_kv (L , keys_len , val_spacer , DECODE_ERR_IDX )) goto fail ;
161+ if (!set_kv (L , keys_len , val_spacer , DECODE_DEFINED_IDX )) goto fail ;
207162 // [-1] current root table
208163 if (!consume_whitespace_to_line (& src )) {
209- set_tmlerr (new_tmlerr (L , DECODE_ERR_IDX ), false, 66 , "key value pairs must be followed by a new line (or end of content)" );
164+ set_tmlerr (new_tmlerr (L , DECODE_DEFINED_IDX ), false, 66 , "key value pairs must be followed by a new line (or end of content)" );
210165 goto fail ;
211166 }
212167 }
@@ -217,10 +172,10 @@ int tomlua_decode(lua_State *L) {
217172 return 1 ;
218173
219174fail :
220- lua_settop (L , DECODE_ERR_IDX );
221- tmlerr_push_ctx_from_iter (get_err_val (L , DECODE_ERR_IDX ), 7 , & src );
175+ lua_settop (L , DECODE_DEFINED_IDX );
176+ tmlerr_push_ctx_from_iter (get_err_val (L , DECODE_DEFINED_IDX ), 7 , & src );
222177 free_str_buf (& scratch );
223178 lua_pushnil (L );
224- push_tmlerr_string (L , get_err_val (L , DECODE_ERR_IDX ));
179+ push_tmlerr_string (L , get_err_val (L , DECODE_DEFINED_IDX ));
225180 return 2 ;
226181}
0 commit comments