handle lines like [x.y.z] or [[x.y.z]] */
| 1282 | |
| 1283 | /* handle lines like [x.y.z] or [[x.y.z]] */ |
| 1284 | static int parse_select(context_t* ctx) |
| 1285 | { |
| 1286 | assert(ctx->tok.tok == LBRACKET); |
| 1287 | |
| 1288 | /* true if [[ */ |
| 1289 | int llb = (ctx->tok.ptr + 1 < ctx->stop && ctx->tok.ptr[1] == '['); |
| 1290 | /* need to detect '[[' on our own because next_token() will skip whitespace, |
| 1291 | and '[ [' would be taken as '[[', which is wrong. */ |
| 1292 | |
| 1293 | /* eat [ or [[ */ |
| 1294 | if (eat_token(ctx, LBRACKET, 1, FLINE)) return -1; |
| 1295 | if (llb) { |
| 1296 | assert(ctx->tok.tok == LBRACKET); |
| 1297 | if (eat_token(ctx, LBRACKET, 1, FLINE)) return -1; |
| 1298 | } |
| 1299 | |
| 1300 | if (fill_tabpath(ctx)) return -1; |
| 1301 | |
| 1302 | /* For [x.y.z] or [[x.y.z]], remove z from tpath. |
| 1303 | */ |
| 1304 | token_t z = ctx->tpath.tok[ctx->tpath.top-1]; |
| 1305 | xfree(ctx->tpath.key[ctx->tpath.top-1]); |
| 1306 | ctx->tpath.top--; |
| 1307 | |
| 1308 | /* set up ctx->curtab */ |
| 1309 | if (walk_tabpath(ctx)) return -1; |
| 1310 | |
| 1311 | if (! llb) { |
| 1312 | /* [x.y.z] -> create z = {} in x.y */ |
| 1313 | toml_table_t* curtab = create_keytable_in_table(ctx, ctx->curtab, z); |
| 1314 | if (!curtab) return -1; |
| 1315 | ctx->curtab = curtab; |
| 1316 | } else { |
| 1317 | /* [[x.y.z]] -> create z = [] in x.y */ |
| 1318 | toml_array_t* arr = 0; |
| 1319 | { |
| 1320 | char* zstr = normalize_key(ctx, z); |
| 1321 | if (!zstr) return -1; |
| 1322 | arr = toml_array_in(ctx->curtab, zstr); |
| 1323 | xfree(zstr); |
| 1324 | } |
| 1325 | if (!arr) { |
| 1326 | arr = create_keyarray_in_table(ctx, ctx->curtab, z, 't'); |
| 1327 | if (!arr) return -1; |
| 1328 | } |
| 1329 | if (arr->kind != 't') |
| 1330 | return e_syntax(ctx, z.lineno, "array mismatch"); |
| 1331 | |
| 1332 | /* add to z[] */ |
| 1333 | toml_table_t* dest; |
| 1334 | { |
| 1335 | toml_table_t* t = create_table_in_array(ctx, arr); |
| 1336 | if (!t) return -1; |
| 1337 | |
| 1338 | if (0 == (t->key = STRDUP("__anon__"))) |
| 1339 | return e_outofmemory(ctx, FLINE); |
| 1340 | |
| 1341 | dest = t; |
no test coverage detected