1576a65b6SJiri Olsa // SPDX-License-Identifier: GPL-2.0 226226a97SJiri Olsa #include <stdbool.h> 3576a65b6SJiri Olsa #include <assert.h> 4576a65b6SJiri Olsa #include "expr.h" 526226a97SJiri Olsa #include "expr-bison.h" 626226a97SJiri Olsa #define YY_EXTRA_TYPE int 726226a97SJiri Olsa #include "expr-flex.h" 826226a97SJiri Olsa 926226a97SJiri Olsa #ifdef PARSER_DEBUG 1026226a97SJiri Olsa extern int expr_debug; 1126226a97SJiri Olsa #endif 12576a65b6SJiri Olsa 13576a65b6SJiri Olsa /* Caller must make sure id is allocated */ 14aecce63eSJiri Olsa void expr__add_id(struct expr_parse_ctx *ctx, const char *name, double val) 15576a65b6SJiri Olsa { 16576a65b6SJiri Olsa int idx; 17576a65b6SJiri Olsa 18576a65b6SJiri Olsa assert(ctx->num_ids < MAX_PARSE_ID); 19576a65b6SJiri Olsa idx = ctx->num_ids++; 20576a65b6SJiri Olsa ctx->ids[idx].name = name; 21576a65b6SJiri Olsa ctx->ids[idx].val = val; 22576a65b6SJiri Olsa } 23576a65b6SJiri Olsa 24aecce63eSJiri Olsa void expr__ctx_init(struct expr_parse_ctx *ctx) 25576a65b6SJiri Olsa { 26576a65b6SJiri Olsa ctx->num_ids = 0; 27576a65b6SJiri Olsa } 2826226a97SJiri Olsa 2926226a97SJiri Olsa static int 30aecce63eSJiri Olsa __expr__parse(double *val, struct expr_parse_ctx *ctx, const char *expr, 3126226a97SJiri Olsa int start) 3226226a97SJiri Olsa { 3326226a97SJiri Olsa YY_BUFFER_STATE buffer; 3426226a97SJiri Olsa void *scanner; 3526226a97SJiri Olsa int ret; 3626226a97SJiri Olsa 3726226a97SJiri Olsa ret = expr_lex_init_extra(start, &scanner); 3826226a97SJiri Olsa if (ret) 3926226a97SJiri Olsa return ret; 4026226a97SJiri Olsa 4126226a97SJiri Olsa buffer = expr__scan_string(expr, scanner); 4226226a97SJiri Olsa 4326226a97SJiri Olsa #ifdef PARSER_DEBUG 4426226a97SJiri Olsa expr_debug = 1; 4526226a97SJiri Olsa #endif 4626226a97SJiri Olsa 4726226a97SJiri Olsa ret = expr_parse(val, ctx, scanner); 4826226a97SJiri Olsa 4926226a97SJiri Olsa expr__flush_buffer(buffer, scanner); 5026226a97SJiri Olsa expr__delete_buffer(buffer, scanner); 5126226a97SJiri Olsa expr_lex_destroy(scanner); 5226226a97SJiri Olsa return ret; 5326226a97SJiri Olsa } 5426226a97SJiri Olsa 55aecce63eSJiri Olsa int expr__parse(double *final_val, struct expr_parse_ctx *ctx, const char *expr) 5626226a97SJiri Olsa { 57d942815aSJiri Olsa return __expr__parse(final_val, ctx, expr, EXPR_PARSE) ? -1 : 0; 5826226a97SJiri Olsa } 5926226a97SJiri Olsa 6026226a97SJiri Olsa static bool 6126226a97SJiri Olsa already_seen(const char *val, const char *one, const char **other, 6226226a97SJiri Olsa int num_other) 6326226a97SJiri Olsa { 6426226a97SJiri Olsa int i; 6526226a97SJiri Olsa 6626226a97SJiri Olsa if (one && !strcasecmp(one, val)) 6726226a97SJiri Olsa return true; 6826226a97SJiri Olsa for (i = 0; i < num_other; i++) 6926226a97SJiri Olsa if (!strcasecmp(other[i], val)) 7026226a97SJiri Olsa return true; 7126226a97SJiri Olsa return false; 7226226a97SJiri Olsa } 7326226a97SJiri Olsa 740f9b1e12SJiri Olsa int expr__find_other(const char *expr, const char *one, const char ***other, 7526226a97SJiri Olsa int *num_other) 7626226a97SJiri Olsa { 7726226a97SJiri Olsa int err, i = 0, j = 0; 78aecce63eSJiri Olsa struct expr_parse_ctx ctx; 7926226a97SJiri Olsa 8026226a97SJiri Olsa expr__ctx_init(&ctx); 810f9b1e12SJiri Olsa err = __expr__parse(NULL, &ctx, expr, EXPR_OTHER); 8226226a97SJiri Olsa if (err) 8326226a97SJiri Olsa return -1; 8426226a97SJiri Olsa 8526226a97SJiri Olsa *other = malloc((ctx.num_ids + 1) * sizeof(char *)); 8626226a97SJiri Olsa if (!*other) 8726226a97SJiri Olsa return -ENOMEM; 8826226a97SJiri Olsa 8926226a97SJiri Olsa for (i = 0, j = 0; i < ctx.num_ids; i++) { 9026226a97SJiri Olsa const char *str = ctx.ids[i].name; 9126226a97SJiri Olsa 9226226a97SJiri Olsa if (already_seen(str, one, *other, j)) 9326226a97SJiri Olsa continue; 9426226a97SJiri Olsa 9526226a97SJiri Olsa str = strdup(str); 9626226a97SJiri Olsa if (!str) 9726226a97SJiri Olsa goto out; 9826226a97SJiri Olsa (*other)[j++] = str; 9926226a97SJiri Olsa } 10026226a97SJiri Olsa (*other)[j] = NULL; 10126226a97SJiri Olsa 10226226a97SJiri Olsa out: 10326226a97SJiri Olsa if (i != ctx.num_ids) { 10426226a97SJiri Olsa while (--j) 10526226a97SJiri Olsa free((char *) (*other)[i]); 10626226a97SJiri Olsa free(*other); 10726226a97SJiri Olsa err = -1; 10826226a97SJiri Olsa } 10926226a97SJiri Olsa 11026226a97SJiri Olsa *num_other = j; 11126226a97SJiri Olsa return err; 11226226a97SJiri Olsa } 113