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