| 733 | } |
| 734 | |
| 735 | int av_expr_parse(AVExpr **expr, const char *s, |
| 736 | const char * const *const_names, |
| 737 | const char * const *func1_names, double (* const *funcs1)(void *, double), |
| 738 | const char * const *func2_names, double (* const *funcs2)(void *, double, double), |
| 739 | int log_offset, void *log_ctx) |
| 740 | { |
| 741 | Parser p = { 0 }; |
| 742 | AVExpr *e = NULL; |
| 743 | char *w = av_malloc(strlen(s) + 1); |
| 744 | char *wp = w; |
| 745 | const char *s0 = s; |
| 746 | int ret = 0; |
| 747 | |
| 748 | if (!w) |
| 749 | return AVERROR(ENOMEM); |
| 750 | |
| 751 | while (*s) |
| 752 | if (!av_isspace(*s++)) *wp++ = s[-1]; |
| 753 | *wp++ = 0; |
| 754 | |
| 755 | p.class = &eval_class; |
| 756 | p.stack_index=100; |
| 757 | p.s= w; |
| 758 | p.const_names = const_names; |
| 759 | p.funcs1 = funcs1; |
| 760 | p.func1_names = func1_names; |
| 761 | p.funcs2 = funcs2; |
| 762 | p.func2_names = func2_names; |
| 763 | p.log_offset = log_offset; |
| 764 | p.log_ctx = log_ctx; |
| 765 | |
| 766 | if ((ret = parse_expr(&e, &p)) < 0) |
| 767 | goto end; |
| 768 | if (*p.s) { |
| 769 | av_log(&p, AV_LOG_ERROR, "Invalid chars '%s' at the end of expression '%s'\n", p.s, s0); |
| 770 | ret = AVERROR(EINVAL); |
| 771 | goto end; |
| 772 | } |
| 773 | if (!verify_expr(e)) { |
| 774 | ret = AVERROR(EINVAL); |
| 775 | goto end; |
| 776 | } |
| 777 | AVExprRoot *r = av_realloc(e, sizeof(*r)); |
| 778 | if (!r) { |
| 779 | ret = AVERROR(ENOMEM); |
| 780 | goto end; |
| 781 | } |
| 782 | e = (AVExpr*)r; |
| 783 | e->root = 1; |
| 784 | r->var= av_mallocz(sizeof(double) *VARS); |
| 785 | r->prng_state = av_mallocz(sizeof(*r->prng_state) *VARS); |
| 786 | if (!r->var || !r->prng_state) { |
| 787 | ret = AVERROR(ENOMEM); |
| 788 | goto end; |
| 789 | } |
| 790 | *expr = e; |
| 791 | e = NULL; |
| 792 | end: |
no test coverage detected