Parse IN [val, val, ...] list. Returns expr_leaf or NULL on error. */
| 840 | |
| 841 | /* Parse IN [val, val, ...] list. Returns expr_leaf or NULL on error. */ |
| 842 | static cbm_expr_t *parse_in_list(parser_t *p, cbm_condition_t *c) { |
| 843 | advance(p); |
| 844 | c->op = heap_strdup("IN"); |
| 845 | if (!c->op) { |
| 846 | safe_str_free(&c->variable); |
| 847 | safe_str_free(&c->property); |
| 848 | return NULL; |
| 849 | } |
| 850 | if (!expect(p, TOK_LBRACKET)) { |
| 851 | safe_str_free(&c->variable); |
| 852 | safe_str_free(&c->property); |
| 853 | safe_str_free(&c->op); |
| 854 | return NULL; |
| 855 | } |
| 856 | int vcap = CYP_INIT_CAP8; |
| 857 | int vn = 0; |
| 858 | const char **vals = malloc(vcap * sizeof(const char *)); |
| 859 | if (!vals) { |
| 860 | safe_str_free(&c->variable); |
| 861 | safe_str_free(&c->property); |
| 862 | safe_str_free(&c->op); |
| 863 | return NULL; |
| 864 | } |
| 865 | while (!check(p, TOK_RBRACKET) && !check(p, TOK_EOF)) { |
| 866 | if (vn > 0) { |
| 867 | match(p, TOK_COMMA); |
| 868 | } |
| 869 | if (check(p, TOK_STRING) || check(p, TOK_NUMBER)) { |
| 870 | if (vn >= vcap) { |
| 871 | int new_vcap = vcap * PAIR_LEN; |
| 872 | void *tmp = realloc((void *)vals, new_vcap * sizeof(const char *)); |
| 873 | if (!tmp) { |
| 874 | for (int i = 0; i < vn; i++) { |
| 875 | safe_str_free(&vals[i]); |
| 876 | } |
| 877 | safe_free(vals); |
| 878 | safe_str_free(&c->variable); |
| 879 | safe_str_free(&c->property); |
| 880 | safe_str_free(&c->op); |
| 881 | return NULL; |
| 882 | } |
| 883 | vals = (const char **)tmp; |
| 884 | vcap = new_vcap; |
| 885 | } |
| 886 | const char *new_val = heap_strdup(advance(p)->text); |
| 887 | if (!new_val) { |
| 888 | for (int i = 0; i < vn; i++) { |
| 889 | safe_str_free(&vals[i]); |
| 890 | } |
| 891 | safe_free(vals); |
| 892 | safe_str_free(&c->variable); |
| 893 | safe_str_free(&c->property); |
| 894 | safe_str_free(&c->op); |
| 895 | return NULL; |
| 896 | } |
| 897 | vals[vn++] = new_val; |
| 898 | } else { |
| 899 | break; |
no test coverage detected