Parse inline properties: {key: "value", ...} */
| 500 | |
| 501 | /* Parse inline properties: {key: "value", ...} */ |
| 502 | static int parse_props(parser_t *p, cbm_prop_filter_t **out, int *count) { |
| 503 | *out = NULL; |
| 504 | *count = 0; |
| 505 | if (!match(p, TOK_LBRACE)) { |
| 506 | return 0; |
| 507 | } |
| 508 | |
| 509 | int cap = CYP_INIT_CAP4; |
| 510 | int n = 0; |
| 511 | cbm_prop_filter_t *arr = malloc(cap * sizeof(cbm_prop_filter_t)); |
| 512 | if (!arr) { |
| 513 | return CBM_NOT_FOUND; |
| 514 | } |
| 515 | |
| 516 | while (!check(p, TOK_RBRACE) && !check(p, TOK_EOF)) { |
| 517 | const cbm_token_t *key = expect(p, TOK_IDENT); |
| 518 | if (!key) { |
| 519 | free(arr); |
| 520 | return CBM_NOT_FOUND; |
| 521 | } |
| 522 | if (!expect(p, TOK_COLON)) { |
| 523 | free(arr); |
| 524 | return CBM_NOT_FOUND; |
| 525 | } |
| 526 | const cbm_token_t *val = expect(p, TOK_STRING); |
| 527 | if (!val) { |
| 528 | free(arr); |
| 529 | return CBM_NOT_FOUND; |
| 530 | } |
| 531 | |
| 532 | if (n >= cap) { |
| 533 | int new_cap = cap * PAIR_LEN; |
| 534 | void *tmp = realloc(arr, new_cap * sizeof(cbm_prop_filter_t)); |
| 535 | if (!tmp) { |
| 536 | for (int i = 0; i < n; i++) { |
| 537 | safe_str_free(&arr[i].key); |
| 538 | safe_str_free(&arr[i].value); |
| 539 | } |
| 540 | free(arr); |
| 541 | return CBM_NOT_FOUND; |
| 542 | } |
| 543 | arr = tmp; |
| 544 | cap = new_cap; |
| 545 | } |
| 546 | const char *new_key = heap_strdup(key->text); |
| 547 | const char *new_val = heap_strdup(val->text); |
| 548 | if (!new_key || !new_val) { |
| 549 | safe_str_free(&new_key); |
| 550 | safe_str_free(&new_val); |
| 551 | for (int i = 0; i < n; i++) { |
| 552 | safe_str_free(&arr[i].key); |
| 553 | safe_str_free(&arr[i].value); |
| 554 | } |
| 555 | free(arr); |
| 556 | return CBM_NOT_FOUND; |
| 557 | } |
| 558 | arr[n].key = new_key; |
| 559 | arr[n].value = new_val; |
no test coverage detected