| 2175 | /* ── Convenience: lex + parse ───────────────────────────────────── */ |
| 2176 | |
| 2177 | int cbm_cypher_parse(const char *query, cbm_query_t **out, char **error) { |
| 2178 | *out = NULL; |
| 2179 | *error = NULL; |
| 2180 | |
| 2181 | cbm_lex_result_t lr = {0}; |
| 2182 | if (cbm_lex(query, &lr) < 0 || lr.error) { |
| 2183 | *error = heap_strdup(lr.error ? lr.error : "lex error"); |
| 2184 | cbm_lex_free(&lr); |
| 2185 | return CBM_NOT_FOUND; |
| 2186 | } |
| 2187 | |
| 2188 | cbm_parse_result_t pr = {0}; |
| 2189 | if (cbm_parse(lr.tokens, lr.count, &pr) < 0) { |
| 2190 | *error = heap_strdup(pr.error ? pr.error : "parse error"); |
| 2191 | cbm_parse_free(&pr); |
| 2192 | cbm_lex_free(&lr); |
| 2193 | return CBM_NOT_FOUND; |
| 2194 | } |
| 2195 | |
| 2196 | *out = pr.query; |
| 2197 | pr.query = NULL; |
| 2198 | cbm_parse_free(&pr); |
| 2199 | cbm_lex_free(&lr); |
| 2200 | return 0; |
| 2201 | } |
| 2202 | |
| 2203 | /* ══════════════════════════════════════════════════════════════════ |
| 2204 | * EXECUTOR |
no test coverage detected