@ -175,11 +175,11 @@ static double eval_expr(Parser *p, AVExpr *e)
static int parse_expr ( AVExpr * * e , Parser * p ) ;
void av_free_ expr ( AVExpr * e )
void av_expr_free ( AVExpr * e )
{
if ( ! e ) return ;
av_free_ expr ( e - > param [ 0 ] ) ;
av_free_ expr ( e - > param [ 1 ] ) ;
av_expr_free ( e - > param [ 0 ] ) ;
av_expr_free ( e - > param [ 1 ] ) ;
av_freep ( & e ) ;
}
@ -217,7 +217,7 @@ static int parse_primary(AVExpr **e, Parser *p)
if ( p - > s = = NULL ) {
av_log ( p , AV_LOG_ERROR , " Undefined constant or missing '(' in '%s' \n " , s0 ) ;
p - > s = next ;
av_free_ expr ( d ) ;
av_expr_free ( d ) ;
return AVERROR ( EINVAL ) ;
}
p - > s + + ; // "("
@ -227,7 +227,7 @@ static int parse_primary(AVExpr **e, Parser *p)
return ret ;
if ( p - > s [ 0 ] ! = ' ) ' ) {
av_log ( p , AV_LOG_ERROR , " Missing ')' in '%s' \n " , s0 ) ;
av_free_ expr ( d ) ;
av_expr_free ( d ) ;
return AVERROR ( EINVAL ) ;
}
p - > s + + ; // ")"
@ -235,7 +235,7 @@ static int parse_primary(AVExpr **e, Parser *p)
return 0 ;
}
if ( ( ret = parse_expr ( & ( d - > param [ 0 ] ) , p ) ) < 0 ) {
av_free_ expr ( d ) ;
av_expr_free ( d ) ;
return ret ;
}
if ( p - > s [ 0 ] = = ' , ' ) {
@ -244,7 +244,7 @@ static int parse_primary(AVExpr **e, Parser *p)
}
if ( p - > s [ 0 ] ! = ' ) ' ) {
av_log ( p , AV_LOG_ERROR , " Missing ')' or too many args in '%s' \n " , s0 ) ;
av_free_ expr ( d ) ;
av_expr_free ( d ) ;
return AVERROR ( EINVAL ) ;
}
p - > s + + ; // ")"
@ -296,7 +296,7 @@ static int parse_primary(AVExpr **e, Parser *p)
}
av_log ( p , AV_LOG_ERROR , " Unknown function in '%s' \n " , s0 ) ;
av_free_ expr ( d ) ;
av_expr_free ( d ) ;
return AVERROR ( EINVAL ) ;
}
@ -333,13 +333,13 @@ static int parse_factor(AVExpr **e, Parser *p)
e1 = e0 ;
p - > s + + ;
if ( ( ret = parse_pow ( & e2 , p , & sign2 ) ) < 0 ) {
av_free_ expr ( e1 ) ;
av_expr_free ( e1 ) ;
return ret ;
}
e0 = new_eval_expr ( e_pow , 1 , e1 , e2 ) ;
if ( ! e0 ) {
av_free_ expr ( e1 ) ;
av_free_ expr ( e2 ) ;
av_expr_free ( e1 ) ;
av_expr_free ( e2 ) ;
return AVERROR ( ENOMEM ) ;
}
if ( e0 - > param [ 1 ] ) e0 - > param [ 1 ] - > value * = ( sign2 | 1 ) ;
@ -360,13 +360,13 @@ static int parse_term(AVExpr **e, Parser *p)
int c = * p - > s + + ;
e1 = e0 ;
if ( ( ret = parse_factor ( & e2 , p ) ) < 0 ) {
av_free_ expr ( e1 ) ;
av_expr_free ( e1 ) ;
return ret ;
}
e0 = new_eval_expr ( c = = ' * ' ? e_mul : e_div , 1 , e1 , e2 ) ;
if ( ! e0 ) {
av_free_ expr ( e1 ) ;
av_free_ expr ( e2 ) ;
av_expr_free ( e1 ) ;
av_expr_free ( e2 ) ;
return AVERROR ( ENOMEM ) ;
}
}
@ -383,13 +383,13 @@ static int parse_subexpr(AVExpr **e, Parser *p)
while ( * p - > s = = ' + ' | | * p - > s = = ' - ' ) {
e1 = e0 ;
if ( ( ret = parse_term ( & e2 , p ) ) < 0 ) {
av_free_ expr ( e1 ) ;
av_expr_free ( e1 ) ;
return ret ;
}
e0 = new_eval_expr ( e_add , 1 , e1 , e2 ) ;
if ( ! e0 ) {
av_free_ expr ( e1 ) ;
av_free_ expr ( e2 ) ;
av_expr_free ( e1 ) ;
av_expr_free ( e2 ) ;
return AVERROR ( ENOMEM ) ;
}
} ;
@ -412,13 +412,13 @@ static int parse_expr(AVExpr **e, Parser *p)
p - > s + + ;
e1 = e0 ;
if ( ( ret = parse_subexpr ( & e2 , p ) ) < 0 ) {
av_free_ expr ( e1 ) ;
av_expr_free ( e1 ) ;
return ret ;
}
e0 = new_eval_expr ( e_last , 1 , e1 , e2 ) ;
if ( ! e0 ) {
av_free_ expr ( e1 ) ;
av_free_ expr ( e2 ) ;
av_expr_free ( e1 ) ;
av_expr_free ( e2 ) ;
return AVERROR ( ENOMEM ) ;
}
} ;
@ -444,7 +444,7 @@ static int verify_expr(AVExpr *e)
}
}
int av_parse_expr ( AVExpr * * expr , const char * s ,
int av_expr_ parse ( AVExpr * * expr , const char * s ,
const char * const * const_names ,
const char * const * func1_names , double ( * const * funcs1 ) ( void * , double ) ,
const char * const * func2_names , double ( * const * funcs2 ) ( void * , double , double ) ,
@ -483,7 +483,7 @@ int av_parse_expr(AVExpr **expr, const char *s,
goto end ;
}
if ( ! verify_expr ( e ) ) {
av_free_ expr ( e ) ;
av_expr_free ( e ) ;
ret = AVERROR ( EINVAL ) ;
goto end ;
}
@ -493,7 +493,7 @@ end:
return ret ;
}
double av_eval_e xpr ( AVExpr * e , const double * const_values , void * opaque )
double av_expr_eval ( AVExpr * e , const double * const_values , void * opaque )
{
Parser p ;
@ -502,24 +502,56 @@ double av_eval_expr(AVExpr *e, const double *const_values, void *opaque)
return eval_expr ( & p , e ) ;
}
int av_parse_and_eval_expr ( double * d , const char * s ,
int av_expr_ parse_and_eval ( double * d , const char * s ,
const char * const * const_names , const double * const_values ,
const char * const * func1_names , double ( * const * funcs1 ) ( void * , double ) ,
const char * const * func2_names , double ( * const * funcs2 ) ( void * , double , double ) ,
void * opaque , int log_offset , void * log_ctx )
{
AVExpr * e = NULL ;
int ret = av_parse_expr ( & e , s , const_names , func1_names , funcs1 , func2_names , funcs2 , log_offset , log_ctx ) ;
int ret = av_expr_ parse ( & e , s , const_names , func1_names , funcs1 , func2_names , funcs2 , log_offset , log_ctx ) ;
if ( ret < 0 ) {
* d = NAN ;
return ret ;
}
* d = av_eval_e xpr ( e , const_values , opaque ) ;
av_free_ expr ( e ) ;
* d = av_expr_eval ( e , const_values , opaque ) ;
av_expr_free ( e ) ;
return isnan ( * d ) ? AVERROR ( EINVAL ) : 0 ;
}
# if FF_API_OLD_EVAL_NAMES
int av_parse_expr ( AVExpr * * expr , const char * s ,
const char * const * const_names ,
const char * const * func1_names , double ( * const * funcs1 ) ( void * , double ) ,
const char * const * func2_names , double ( * const * funcs2 ) ( void * , double , double ) ,
int log_offset , void * log_ctx )
{
return av_expr_parse ( expr , s , const_names , func1_names , funcs1 , func2_names , funcs2 ,
log_offset , log_ctx ) ;
}
double av_eval_expr ( AVExpr * e , const double * const_values , void * opaque )
{
return av_expr_eval ( e , const_values , opaque ) ;
}
int av_parse_and_eval_expr ( double * res , const char * s ,
const char * const * const_names , const double * const_values ,
const char * const * func1_names , double ( * const * funcs1 ) ( void * , double ) ,
const char * const * func2_names , double ( * const * funcs2 ) ( void * , double , double ) ,
void * opaque , int log_offset , void * log_ctx )
{
return av_expr_parse_and_eval ( res , s , const_names , const_values , func1_names , funcs1 , func2_names , funcs2 ,
opaque , log_offset , log_ctx ) ;
}
void av_free_expr ( AVExpr * e )
{
av_expr_free ( e ) ;
}
# endif /* FF_API_OLD_EVAL_NAMES */
# ifdef TEST
# undef printf
static double const_values [ ] = {
@ -584,27 +616,27 @@ int main(void)
for ( expr = exprs ; * expr ; expr + + ) {
printf ( " Evaluating '%s' \n " , * expr ) ;
av_parse_and_eval_expr ( & d , * expr ,
av_expr_ parse_and_eval ( & d , * expr ,
const_names , const_values ,
NULL , NULL , NULL , NULL , NULL , 0 , NULL ) ;
printf ( " '%s' -> %f \n \n " , * expr , d ) ;
}
av_parse_and_eval_expr ( & d , " 1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1) " ,
av_expr_ parse_and_eval ( & d , " 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 == 12.7 \n " , d ) ;
av_parse_and_eval_expr ( & d , " 80G/80Gi " ,
av_expr_ parse_and_eval ( & d , " 80G/80Gi " ,
const_names , const_values ,
NULL , NULL , NULL , NULL , NULL , 0 , NULL ) ;
printf ( " %f == 0.931322575 \n " , d ) ;
for ( i = 0 ; i < 1050 ; i + + ) {
START_TIMER
av_parse_and_eval_expr ( & d , " 1+(5-2)^(3-1)+1/2+sin(PI)-max(-2.2,-3.1) " ,
av_expr_ parse_and_eval ( & d , " 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 ( " av_parse_and_eval_expr " )
STOP_TIMER ( " av_expr_ parse_and_eval " )
}
return 0 ;
}