|
|
|
@ -30,6 +30,7 @@ |
|
|
|
|
#include "eval.h" |
|
|
|
|
|
|
|
|
|
typedef struct Parser{ |
|
|
|
|
const AVClass *class; |
|
|
|
|
int stack_index; |
|
|
|
|
char *s; |
|
|
|
|
const double *const_value; |
|
|
|
@ -39,11 +40,14 @@ typedef struct Parser{ |
|
|
|
|
double (* const *func2)(void *, double a, double b); // NULL terminated
|
|
|
|
|
const char * const *func2_name; // NULL terminated
|
|
|
|
|
void *opaque; |
|
|
|
|
const char **error; |
|
|
|
|
int log_offset; |
|
|
|
|
void *log_ctx; |
|
|
|
|
#define VARS 10 |
|
|
|
|
double var[VARS]; |
|
|
|
|
} Parser; |
|
|
|
|
|
|
|
|
|
static const AVClass class = { "Eval", av_default_item_name, NULL, LIBAVUTIL_VERSION_INT, offsetof(Parser,log_offset), offsetof(Parser,log_ctx) }; |
|
|
|
|
|
|
|
|
|
static const int8_t si_prefixes['z' - 'E' + 1]={ |
|
|
|
|
['y'-'E']= -24, |
|
|
|
|
['z'-'E']= -21, |
|
|
|
@ -201,7 +205,7 @@ static AVExpr * parse_primary(Parser *p) { |
|
|
|
|
|
|
|
|
|
p->s= strchr(p->s, '('); |
|
|
|
|
if(p->s==NULL){ |
|
|
|
|
*p->error = "undefined constant or missing ("; |
|
|
|
|
av_log(p, AV_LOG_ERROR, "undefined constant or missing (\n"); |
|
|
|
|
p->s= next; |
|
|
|
|
ff_free_expr(d); |
|
|
|
|
return NULL; |
|
|
|
@ -211,7 +215,7 @@ static AVExpr * parse_primary(Parser *p) { |
|
|
|
|
av_freep(&d); |
|
|
|
|
d = parse_expr(p); |
|
|
|
|
if(p->s[0] != ')'){ |
|
|
|
|
*p->error = "missing )"; |
|
|
|
|
av_log(p, AV_LOG_ERROR, "missing )\n"); |
|
|
|
|
ff_free_expr(d); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
@ -224,7 +228,7 @@ static AVExpr * parse_primary(Parser *p) { |
|
|
|
|
d->param[1] = parse_expr(p); |
|
|
|
|
} |
|
|
|
|
if(p->s[0] != ')'){ |
|
|
|
|
*p->error = "missing )"; |
|
|
|
|
av_log(p, AV_LOG_ERROR, "missing )\n"); |
|
|
|
|
ff_free_expr(d); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
@ -273,7 +277,7 @@ static AVExpr * parse_primary(Parser *p) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
*p->error = "unknown function"; |
|
|
|
|
av_log(p, AV_LOG_ERROR, "unknown function\n"); |
|
|
|
|
ff_free_expr(d); |
|
|
|
|
return NULL; |
|
|
|
|
} |
|
|
|
@ -373,7 +377,8 @@ AVExpr *ff_parse_expr(const char *s, |
|
|
|
|
const char * const *const_name, |
|
|
|
|
const char * const *func1_name, double (* const *func1)(void *, double), |
|
|
|
|
const char * const *func2_name, double (* const *func2)(void *, double, double), |
|
|
|
|
const char **error){ |
|
|
|
|
int log_offset, void *log_ctx) |
|
|
|
|
{ |
|
|
|
|
Parser p; |
|
|
|
|
AVExpr *e = NULL; |
|
|
|
|
char *w = av_malloc(strlen(s) + 1); |
|
|
|
@ -386,6 +391,7 @@ AVExpr *ff_parse_expr(const char *s, |
|
|
|
|
if (!isspace(*s++)) *wp++ = s[-1]; |
|
|
|
|
*wp++ = 0; |
|
|
|
|
|
|
|
|
|
p.class = &class; |
|
|
|
|
p.stack_index=100; |
|
|
|
|
p.s= w; |
|
|
|
|
p.const_name = const_name; |
|
|
|
@ -393,7 +399,8 @@ AVExpr *ff_parse_expr(const char *s, |
|
|
|
|
p.func1_name = func1_name; |
|
|
|
|
p.func2 = func2; |
|
|
|
|
p.func2_name = func2_name; |
|
|
|
|
p.error= error; |
|
|
|
|
p.log_offset = log_offset; |
|
|
|
|
p.log_ctx = log_ctx; |
|
|
|
|
|
|
|
|
|
e = parse_expr(&p); |
|
|
|
|
if (!verify_expr(e)) { |
|
|
|
@ -417,8 +424,9 @@ double ff_parse_and_eval_expr(const char *s, |
|
|
|
|
const char * const *const_name, const double *const_value, |
|
|
|
|
const char * const *func1_name, double (* const *func1)(void *, double), |
|
|
|
|
const char * const *func2_name, double (* const *func2)(void *, double, double), |
|
|
|
|
void *opaque, const char **error){ |
|
|
|
|
AVExpr *e = ff_parse_expr(s, const_name, func1_name, func1, func2_name, func2, error); |
|
|
|
|
void *opaque, int log_offset, void *log_ctx) |
|
|
|
|
{ |
|
|
|
|
AVExpr *e = ff_parse_expr(s, const_name, func1_name, func1, func2_name, func2, log_offset, log_ctx); |
|
|
|
|
double d; |
|
|
|
|
if (!e) return NAN; |
|
|
|
|
d = ff_eval_expr(e, const_value, opaque); |
|
|
|
@ -440,12 +448,12 @@ static const char *const_names[]={ |
|
|
|
|
}; |
|
|
|
|
int main(void){ |
|
|
|
|
int i; |
|
|
|
|
printf("%f == 12.7\n", ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL)); |
|
|
|
|
printf("%f == 12.7\n", ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, NULL)); |
|
|
|
|
printf("%f == 0.931322575\n", ff_parse_and_eval_expr("80G/80Gi", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL)); |
|
|
|
|
|
|
|
|
|
for(i=0; i<1050; i++){ |
|
|
|
|
START_TIMER |
|
|
|
|
ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, NULL); |
|
|
|
|
ff_parse_and_eval_expr("1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1)", const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, NULL); |
|
|
|
|
STOP_TIMER("ff_parse_and_eval_expr") |
|
|
|
|
} |
|
|
|
|
return 0; |
|
|
|
|