diff options
-rw-r--r-- | UPGRADE.txt | 5 | ||||
-rw-r--r-- | doc/tex/channelvariables.tex | 130 | ||||
-rw-r--r-- | include/asterisk/ast_expr.h | 6 | ||||
-rw-r--r-- | main/ast_expr2.c | 894 | ||||
-rw-r--r-- | main/ast_expr2.fl | 16 | ||||
-rw-r--r-- | main/ast_expr2.h | 91 | ||||
-rw-r--r-- | main/ast_expr2.y | 407 | ||||
-rw-r--r-- | main/ast_expr2f.c | 884 | ||||
-rw-r--r-- | main/pbx.c | 2 | ||||
-rw-r--r-- | pbx/pbx_ael.c | 16 | ||||
-rw-r--r-- | utils/ael_main.c | 9 | ||||
-rw-r--r-- | utils/check_expr.c | 9 | ||||
-rw-r--r-- | utils/expr2.testinput | 32 |
13 files changed, 1752 insertions, 749 deletions
diff --git a/UPGRADE.txt b/UPGRADE.txt index c396e1cd6..f98654452 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -29,6 +29,11 @@ Core: Where D is a string of base-10 digits. All math is now done in "long double", if it is available on your compiler/architecture. This was half-way between a bug-fix (because the MATH func returns fp by default), and an enhancement. + Also, for those counting on, or needing, integer operations, a series of + 'functions' were also added to the expr language, to allow several styles + of rounding/truncation, along with a set of common floating point operations, + like sin, cos, tan, log, pow, etc. The ability to call external functions + like CDR(), etc. was also added, without having to use the ${...} notation. Voicemail: diff --git a/doc/tex/channelvariables.tex b/doc/tex/channelvariables.tex index 8b50d0459..77fcca48c 100644 --- a/doc/tex/channelvariables.tex +++ b/doc/tex/channelvariables.tex @@ -207,19 +207,19 @@ with equal precedence are grouped within { } symbols. an empty string or zero; otherwise, returns zero. expr1 {=, >, >=, <, <=, !=} expr2 - Return the results of integer comparison if both arguments are - integers; otherwise, returns the results of string comparison + Return the results of floating point comparison if both arguments are + numbers; otherwise, returns the results of string comparison using the locale-specific collation sequence. The result of each comparison is 1 if the specified relation is true, or 0 if the relation is false. expr1 {+, -} expr2 - Return the results of addition or subtraction of integer-valued + Return the results of addition or subtraction of floating point-valued arguments. expr1 {*, /, %} expr2 - Return the results of multiplication, integer division, or - remainder of integer-valued arguments. + Return the results of multiplication, floating point division, or + remainder of arguments. - expr1 Return the result of subtracting expr1 from 0. @@ -274,7 +274,69 @@ Parentheses are used for grouping in the usual manner. Operator precedence is applied as one would expect in any of the C or C derived languages. -\subsection{Examples} +subsection{Floating Point Numbers} + +In 1.6 and above, we shifted the \$\[...\] expressions to be calculated +via floating point numbers instead of integers. We use 'long double' numbers +when possible, which provide around 16 digits of precision with 12 byte numbers. + +To specify a floating point constant, the number has to have this format: D.D, where D is +a string of base 10 digits. So, you can say 0.10, but you can't say .10 or 20.-- we hope +this is not an excessive restriction! + +Floating point numbers are turned into strings via the '%g'/'%Lg' format of the printf +function set. This allows numbers to still 'look' like integers to those counting +on integer behavior. If you were counting on 1/4 evaluating to 0, you need to now say +TRUNC(1/4). For a list of all the truncation/rounding capabilities, see the next section. + + +subsection{Functions} + +In 1.6 and above, we upgraded the $[] expressions to handle floating point numbers. +Because of this, folks counting on integer behavior would be disrupted. To make +the same results possible, some rounding and integer truncation functions have been +added to the core of the Expr2 parser. Indeed, dialplan functions can be called from +$[..] expressions without the ${...} operators. The only trouble might be in the fact that +the arguments to these functions must be specified with a comma. If you try to call +the MATH function, for example, and try to say 3 + MATH(7*8), the expression parser will +evaluate 7*8 for you into 56, and the MATH function will most likely complain that its +input doesn't make any sense. + +We also provide access to most of the floating point functions in the C library. (but not all of them). + +While we don't expect someone to want to do Fourier analysis in the dialplan, we +don't want to preclude it, either. + +Here is a list of the 'builtin' functions in Expr2. All other dialplan functions +are available by simply calling them (read-only). In other words, you don't need to +surround function calls in \$\[...\] expressions with \$\{...\}. Don't jump to conclusions, +though! -- you still need to wrap variable names in curly braces! + +\begin{Enumerate} +\item COS(x) x is in radians. Results vary from -1 to 1. +\item SIN(x) x is in radians. Results vary from -1 to 1. +\item TAN(x) x is in radians. +\item ACOS(x) x should be a value between -1 and 1. +\item ASIN(x) x should be a value between -1 and 1. +\item ATAN(x) returns the arc tangent in radians; between -PI/2 and PI/2. +\item ATAN2(x,y) returns a result resembling y/x, except that the signs of both args are used to determine the quadrant of the result. Its result is in radians, between -PI and PI. +\item POW(x,y) returns the value of x raised to the power of y. +\item SQRT(x) returns the square root of x. +\item FLOOR(x) rounds x down to the nearest integer. +\item CEIL(x) rounds x up to the nearest integer. +\item ROUND(x) rounds x to the nearest integer, but round halfway cases away from zero. +\item RINT(x) rounds x to the nearest integer, rounding halfway cases to the nearest even integer. +\item TRUNC(x) rounds x to the nearest integer not larger in absolute value. +\item REMAINDER(x,y) computes the remainder of dividing x by y. The return value is x - n*y, where n is the value x/y, rounded to the nearest integer. +If this quotient is 1/2, it is rounded to the nearest even number. +\item EXP(x) returns e to the x power. +\item EXP2(x) returns 2 to the x power. +\item LOG(x) returns the natural logarithm of x. +\item LOG2(x) returns the base 2 log of x. +\item LOG10(x) returns the base 10 log of x. +\end{Enumerate} + +subsection{Examples} \begin{verbatim} "One Thousand Five Hundred" =~ "(T[^ ]+)" @@ -310,6 +372,55 @@ or C derived languages. (2+8)/2 returns 5, of course. + +(3+8)/2 + returns 5.5 now. + +TRUNC((3+8)/2) + returns 5. + +FLOOR(2.5) + returns 2 + +FLOOR(-2.5) + returns -3 + +CEIL(2.5) + returns 3. + +CEIL(-2.5) + returns -2. + +ROUND(2.5) + returns 3. + +ROUND(3.5) + returns 4. + +ROUND(-2.5) + returns -3 + +RINT(2.5) + returns 2. + +RINT(3.5) + returns 4. + +RINT(-2.5) + returns -2. + +RINT(-3.5) + returns -4. + +TRUNC(2.5) + returns 2. + +TRUNC(3.5) + returns 3. + +TRUNC(-3.5) + returns -3. + \begin{verbatim} Of course, all of the above examples use constants, but would work the @@ -319,9 +430,10 @@ variable reference \${CALLERIDNUM}, for instance. \subsection{Numbers Vs. Strings} -Tokens consisting only of numbers are converted to 64-bit numbers for -most of the operators. This means that overflows can occur when the -numbers get above 18 digits. Warnings will appear in the logs in this +Tokens consisting only of numbers are converted to 'long double' if possible, which +are from 80 bits to 128 bits depending on the OS, compiler, and hardware. +This means that overflows can occur when the +numbers get above 18 digits (depending on the number of bits involved). Warnings will appear in the logs in this case. \subsection{Conditionals} diff --git a/include/asterisk/ast_expr.h b/include/asterisk/ast_expr.h index bc0331309..6ca201f42 100644 --- a/include/asterisk/ast_expr.h +++ b/include/asterisk/ast_expr.h @@ -18,12 +18,14 @@ #ifndef _ASTERISK_EXPR_H #define _ASTERISK_EXPR_H - +#ifndef STANDALONE +#include "asterisk/channel.h" +#endif #if defined(__cplusplus) || defined(c_plusplus) extern "C" { #endif -int ast_expr(char *expr, char *buf, int length); +int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan); #if defined(__cplusplus) || defined(c_plusplus) } diff --git a/main/ast_expr2.c b/main/ast_expr2.c index 1d0ee0cb9..2154a4d8c 100644 --- a/main/ast_expr2.c +++ b/main/ast_expr2.c @@ -64,51 +64,53 @@ /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - TOK_COLONCOLON = 258, - TOK_COND = 259, - TOK_OR = 260, - TOK_AND = 261, - TOK_NE = 262, - TOK_LE = 263, - TOK_GE = 264, - TOK_LT = 265, - TOK_GT = 266, - TOK_EQ = 267, - TOK_MINUS = 268, - TOK_PLUS = 269, - TOK_MOD = 270, - TOK_DIV = 271, - TOK_MULT = 272, - TOK_COMPL = 273, - TOK_EQTILDE = 274, - TOK_COLON = 275, - TOK_LP = 276, - TOK_RP = 277, - TOKEN = 278 + TOK_COMMA = 258, + TOK_COLONCOLON = 259, + TOK_COND = 260, + TOK_OR = 261, + TOK_AND = 262, + TOK_NE = 263, + TOK_LE = 264, + TOK_GE = 265, + TOK_LT = 266, + TOK_GT = 267, + TOK_EQ = 268, + TOK_MINUS = 269, + TOK_PLUS = 270, + TOK_MOD = 271, + TOK_DIV = 272, + TOK_MULT = 273, + TOK_COMPL = 274, + TOK_EQTILDE = 275, + TOK_COLON = 276, + TOK_LP = 277, + TOK_RP = 278, + TOKEN = 279 }; #endif /* Tokens. */ -#define TOK_COLONCOLON 258 -#define TOK_COND 259 -#define TOK_OR 260 -#define TOK_AND 261 -#define TOK_NE 262 -#define TOK_LE 263 -#define TOK_GE 264 -#define TOK_LT 265 -#define TOK_GT 266 -#define TOK_EQ 267 -#define TOK_MINUS 268 -#define TOK_PLUS 269 -#define TOK_MOD 270 -#define TOK_DIV 271 -#define TOK_MULT 272 -#define TOK_COMPL 273 -#define TOK_EQTILDE 274 -#define TOK_COLON 275 -#define TOK_LP 276 -#define TOK_RP 277 -#define TOKEN 278 +#define TOK_COMMA 258 +#define TOK_COLONCOLON 259 +#define TOK_COND 260 +#define TOK_OR 261 +#define TOK_AND 262 +#define TOK_NE 263 +#define TOK_LE 264 +#define TOK_GE 265 +#define TOK_LT 266 +#define TOK_GT 267 +#define TOK_EQ 268 +#define TOK_MINUS 269 +#define TOK_PLUS 270 +#define TOK_MOD 271 +#define TOK_DIV 272 +#define TOK_MULT 273 +#define TOK_COMPL 274 +#define TOK_EQTILDE 275 +#define TOK_COLON 276 +#define TOK_LP 277 +#define TOK_RP 278 +#define TOKEN 279 @@ -139,15 +141,55 @@ #endif #ifdef __USE_ISOC99 -#define FP___PRINTF "%.16Lg" +#define FP___PRINTF "%.18Lg" #define FP___FMOD fmodl #define FP___STRTOD strtold #define FP___TYPE long double +#define FUNC_COS cosl +#define FUNC_SIN sinl +#define FUNC_TAN tanl +#define FUNC_ACOS acosl +#define FUNC_ASIN asinl +#define FUNC_ATAN atanl +#define FUNC_ATAN2 atan2l +#define FUNC_POW powl +#define FUNC_SQRT sqrtl +#define FUNC_FLOOR floorl +#define FUNC_CEIL ceill +#define FUNC_ROUND roundl +#define FUNC_RINT rintl +#define FUNC_TRUNC truncl +#define FUNC_EXP expl +#define FUNC_EXP2 exp2l +#define FUNC_LOG logl +#define FUNC_LOG2 log2l +#define FUNC_LOG10 log10l +#define FUNC_REMAINDER remainderl #else -#define FP___PRINTF "%.8g" +#define FP___PRINTF "%.16g" #define FP___FMOD fmod #define FP___STRTOD strtod #define FP___TYPE double +#define FUNC_COS cos +#define FUNC_SIN sin +#define FUNC_TAN tan +#define FUNC_ACOS acos +#define FUNC_ASIN asin +#define FUNC_ATAN atan +#define FUNC_ATAN2 atan2 +#define FUNC_POW pow +#define FUNC_SQRT sqrt +#define FUNC_FLOOR floor +#define FUNC_CEIL ceil +#define FUNC_ROUND round +#define FUNC_RINT rint +#define FUNC_TRUNC trunc +#define FUNC_EXP exp +#define FUNC_EXP2 exp2 +#define FUNC_LOG log +#define FUNC_LOG2 log2 +#define FUNC_LOG10 log10 +#define FUNC_REMAINDER remainder #endif #include <stdlib.h> @@ -171,6 +213,9 @@ #include "asterisk.h" #include "asterisk/ast_expr.h" #include "asterisk/logger.h" +#ifndef STANDALONE +#include "asterisk/pbx.h" +#endif #if defined(LONG_LONG_MIN) && !defined(QUAD_MIN) #define QUAD_MIN LONG_LONG_MIN @@ -208,6 +253,19 @@ struct val { } u; } ; +enum node_type { + AST_EXPR_NODE_COMMA, AST_EXPR_NODE_STRING, AST_EXPR_NODE_VAL +} ; + +struct expr_node +{ + enum node_type type; + struct val *val; + struct expr_node *left; + struct expr_node *right; +}; + + typedef void *yyscan_t; struct parse_io @@ -215,6 +273,7 @@ struct parse_io char *string; struct val *val; yyscan_t scanner; + struct ast_channel *chan; }; static int chk_div __P((FP___TYPE, FP___TYPE)); @@ -244,8 +303,12 @@ static struct val *op_or __P((struct val *, struct val *)); static struct val *op_plus __P((struct val *, struct val *)); static struct val *op_rem __P((struct val *, struct val *)); static struct val *op_times __P((struct val *, struct val *)); +static struct val *op_func(struct val *funcname, struct expr_node *arglist, struct ast_channel *chan); static int to_number __P((struct val *)); static void to_string __P((struct val *)); +static struct expr_node *alloc_expr_node(enum node_type); +static void destroy_arglist(struct expr_node *arglist); +static int is_really_num(char *str); /* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */ typedef struct yyltype @@ -292,12 +355,13 @@ int ast_yyerror(const char *,YYLTYPE *, struct parse_io *); #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 165 "ast_expr2.y" +#line 226 "ast_expr2.y" { struct val *val; + struct expr_node *arglist; } /* Line 198 of yacc.c. */ -#line 301 "ast_expr2.c" +#line 365 "ast_expr2.c" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 @@ -319,13 +383,13 @@ typedef struct YYLTYPE /* Copy the second part of user declarations. */ -#line 169 "ast_expr2.y" +#line 231 "ast_expr2.y" extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t)); /* Line 221 of yacc.c. */ -#line 329 "ast_expr2.c" +#line 393 "ast_expr2.c" #ifdef short # undef short @@ -538,22 +602,22 @@ union yyalloc #endif /* YYFINAL -- State number of the termination state. */ -#define YYFINAL 10 +#define YYFINAL 11 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 140 +#define YYLAST 150 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 24 +#define YYNTOKENS 25 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 3 +#define YYNNTS 4 /* YYNRULES -- Number of rules. */ -#define YYNRULES 23 +#define YYNRULES 26 /* YYNRULES -- Number of states. */ -#define YYNSTATES 46 +#define YYNSTATES 52 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 278 +#define YYMAXUTOK 279 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -588,7 +652,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23 + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24 }; #if YYDEBUG @@ -596,31 +660,32 @@ static const yytype_uint8 yytranslate[] = YYRHS. */ static const yytype_uint8 yyprhs[] = { - 0, 0, 3, 5, 6, 8, 12, 16, 20, 24, - 28, 32, 36, 40, 44, 48, 52, 55, 58, 62, - 66, 70, 74, 78 + 0, 0, 3, 5, 6, 8, 12, 17, 19, 23, + 27, 31, 35, 39, 43, 47, 51, 55, 59, 63, + 66, 69, 73, 77, 81, 85, 89 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 25, 0, -1, 26, -1, -1, 23, -1, 21, 26, - 22, -1, 26, 5, 26, -1, 26, 6, 26, -1, - 26, 12, 26, -1, 26, 11, 26, -1, 26, 10, - 26, -1, 26, 9, 26, -1, 26, 8, 26, -1, - 26, 7, 26, -1, 26, 14, 26, -1, 26, 13, - 26, -1, 13, 26, -1, 18, 26, -1, 26, 17, - 26, -1, 26, 16, 26, -1, 26, 15, 26, -1, - 26, 20, 26, -1, 26, 19, 26, -1, 26, 4, - 26, 3, 26, -1 + 26, 0, -1, 28, -1, -1, 28, -1, 27, 3, + 28, -1, 24, 22, 27, 23, -1, 24, -1, 22, + 28, 23, -1, 28, 6, 28, -1, 28, 7, 28, + -1, 28, 13, 28, -1, 28, 12, 28, -1, 28, + 11, 28, -1, 28, 10, 28, -1, 28, 9, 28, + -1, 28, 8, 28, -1, 28, 15, 28, -1, 28, + 14, 28, -1, 14, 28, -1, 19, 28, -1, 28, + 18, 28, -1, 28, 17, 28, -1, 28, 16, 28, + -1, 28, 21, 28, -1, 28, 20, 28, -1, 28, + 5, 28, 4, 28, -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 193, 193, 201, 208, 209, 213, 217, 221, 225, - 229, 233, 237, 241, 245, 249, 253, 257, 261, 265, - 269, 273, 277, 281 + 0, 257, 257, 265, 272, 273, 282, 288, 289, 293, + 297, 301, 305, 309, 313, 317, 321, 325, 329, 333, + 337, 341, 345, 349, 353, 357, 361 }; #endif @@ -629,11 +694,11 @@ static const yytype_uint16 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "TOK_COLONCOLON", "TOK_COND", "TOK_OR", - "TOK_AND", "TOK_NE", "TOK_LE", "TOK_GE", "TOK_LT", "TOK_GT", "TOK_EQ", - "TOK_MINUS", "TOK_PLUS", "TOK_MOD", "TOK_DIV", "TOK_MULT", "TOK_COMPL", - "TOK_EQTILDE", "TOK_COLON", "TOK_LP", "TOK_RP", "TOKEN", "$accept", - "start", "expr", 0 + "$end", "error", "$undefined", "TOK_COMMA", "TOK_COLONCOLON", + "TOK_COND", "TOK_OR", "TOK_AND", "TOK_NE", "TOK_LE", "TOK_GE", "TOK_LT", + "TOK_GT", "TOK_EQ", "TOK_MINUS", "TOK_PLUS", "TOK_MOD", "TOK_DIV", + "TOK_MULT", "TOK_COMPL", "TOK_EQTILDE", "TOK_COLON", "TOK_LP", "TOK_RP", + "TOKEN", "$accept", "start", "arglist", "expr", 0 }; #endif @@ -644,24 +709,24 @@ static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278 + 275, 276, 277, 278, 279 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 24, 25, 25, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26 + 0, 25, 26, 26, 27, 27, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { - 0, 2, 1, 0, 1, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, - 3, 3, 3, 5 + 0, 2, 1, 0, 1, 3, 4, 1, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, + 2, 3, 3, 3, 3, 3, 5 }; /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state @@ -669,35 +734,37 @@ static const yytype_uint8 yyr2[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 3, 0, 0, 0, 4, 0, 2, 16, 17, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 5, 0, 6, - 7, 13, 12, 11, 10, 9, 8, 15, 14, 20, - 19, 18, 22, 21, 0, 23 + 3, 0, 0, 0, 7, 0, 2, 19, 20, 0, + 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, + 4, 0, 9, 10, 16, 15, 14, 13, 12, 11, + 18, 17, 23, 22, 21, 25, 24, 0, 6, 0, + 5, 26 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 5, 6 + -1, 5, 29, 6 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -13 -static const yytype_int8 yypact[] = -{ - 109, 109, 109, 109, -13, 6, 59, 106, 106, 22, - -13, 109, 109, 109, 109, 109, 109, 109, 109, 109, - 109, 109, 109, 109, 109, 109, 109, -13, 42, 90, - 104, 120, 120, 120, 120, 120, 120, -12, -12, 106, - 106, 106, -13, -13, 109, 75 +#define YYPACT_NINF -18 +static const yytype_int16 yypact[] = +{ + 112, 112, 112, 112, -16, 5, 62, -17, -17, 24, + 112, -18, 112, 112, 112, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 112, 112, -18, 4, + 62, 45, 93, 107, 123, 123, 123, 123, 123, 123, + 129, 129, -17, -17, -17, -18, -18, 112, -18, 112, + 62, 78 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -13, -13, -1 + -18, -18, -18, -1 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -707,51 +774,54 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 7, 8, 9, 22, 23, 24, 10, 25, 26, 0, - 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 0, 25, 26, 45, 27, 44, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, - 0, 25, 26, 11, 12, 13, 14, 15, 16, 17, - 18, 19, 20, 21, 22, 23, 24, 0, 25, 26, + 7, 8, 9, 26, 27, 11, 10, 47, 0, 30, + 0, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 48, 0, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, + 23, 24, 25, 0, 26, 27, 50, 28, 51, 49, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 22, 23, 24, 0, 25, 26, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 0, 25, - 26, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 23, 24, 1, 25, 26, 25, 26, 2, 0, 0, - 3, 0, 4, 20, 21, 22, 23, 24, 0, 25, - 26 + 22, 23, 24, 25, 0, 26, 27, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 0, 26, 27, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 23, 24, 25, 0, 26, 27, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 0, 26, 27, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 1, 26, 27, 0, + 0, 2, 0, 0, 3, 0, 4, 21, 22, 23, + 24, 25, 0, 26, 27, 23, 24, 25, 0, 26, + 27 }; static const yytype_int8 yycheck[] = { - 1, 2, 3, 15, 16, 17, 0, 19, 20, -1, - 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, - 21, 22, 23, 24, 25, 26, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - -1, 19, 20, 44, 22, 3, 4, 5, 6, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, - -1, 19, 20, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, 15, 16, 17, -1, 19, 20, + 1, 2, 3, 20, 21, 0, 22, 3, -1, 10, + -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 23, 24, 25, 26, 27, 23, -1, 5, + 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, + 16, 17, 18, -1, 20, 21, 47, 23, 49, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, -1, 19, 20, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, -1, 19, - 20, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 13, 19, 20, 19, 20, 18, -1, -1, - 21, -1, 23, 13, 14, 15, 16, 17, -1, 19, - 20 + 15, 16, 17, 18, -1, 20, 21, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, -1, 20, 21, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, -1, 20, 21, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, -1, 20, 21, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 14, 20, 21, -1, + -1, 19, -1, -1, 22, -1, 24, 14, 15, 16, + 17, 18, -1, 20, 21, 16, 17, 18, -1, 20, + 21 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 13, 18, 21, 23, 25, 26, 26, 26, 26, - 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 19, 20, 22, 26, 26, - 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, - 26, 26, 26, 26, 3, 26 + 0, 14, 19, 22, 24, 26, 28, 28, 28, 28, + 22, 0, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 20, 21, 23, 27, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 3, 23, 4, + 28, 28 }; #define yyerrok (yyerrstatus = 0) @@ -1268,115 +1338,115 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp) switch (yytype) { - case 3: /* "TOK_COLONCOLON" */ -#line 187 "ast_expr2.y" + case 4: /* "TOK_COLONCOLON" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1275 "ast_expr2.c" +#line 1345 "ast_expr2.c" break; - case 4: /* "TOK_COND" */ -#line 187 "ast_expr2.y" + case 5: /* "TOK_COND" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1280 "ast_expr2.c" +#line 1350 "ast_expr2.c" break; - case 5: /* "TOK_OR" */ -#line 187 "ast_expr2.y" + case 6: /* "TOK_OR" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1285 "ast_expr2.c" +#line 1355 "ast_expr2.c" break; - case 6: /* "TOK_AND" */ -#line 187 "ast_expr2.y" + case 7: /* "TOK_AND" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1290 "ast_expr2.c" +#line 1360 "ast_expr2.c" break; - case 7: /* "TOK_NE" */ -#line 187 "ast_expr2.y" + case 8: /* "TOK_NE" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1295 "ast_expr2.c" +#line 1365 "ast_expr2.c" break; - case 8: /* "TOK_LE" */ -#line 187 "ast_expr2.y" + case 9: /* "TOK_LE" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1300 "ast_expr2.c" +#line 1370 "ast_expr2.c" break; - case 9: /* "TOK_GE" */ -#line 187 "ast_expr2.y" + case 10: /* "TOK_GE" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1305 "ast_expr2.c" +#line 1375 "ast_expr2.c" break; - case 10: /* "TOK_LT" */ -#line 187 "ast_expr2.y" + case 11: /* "TOK_LT" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1310 "ast_expr2.c" +#line 1380 "ast_expr2.c" break; - case 11: /* "TOK_GT" */ -#line 187 "ast_expr2.y" + case 12: /* "TOK_GT" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1315 "ast_expr2.c" +#line 1385 "ast_expr2.c" break; - case 12: /* "TOK_EQ" */ -#line 187 "ast_expr2.y" + case 13: /* "TOK_EQ" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1320 "ast_expr2.c" +#line 1390 "ast_expr2.c" break; - case 13: /* "TOK_MINUS" */ -#line 187 "ast_expr2.y" + case 14: /* "TOK_MINUS" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1325 "ast_expr2.c" +#line 1395 "ast_expr2.c" break; - case 14: /* "TOK_PLUS" */ -#line 187 "ast_expr2.y" + case 15: /* "TOK_PLUS" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1330 "ast_expr2.c" +#line 1400 "ast_expr2.c" break; - case 15: /* "TOK_MOD" */ -#line 187 "ast_expr2.y" + case 16: /* "TOK_MOD" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1335 "ast_expr2.c" +#line 1405 "ast_expr2.c" break; - case 16: /* "TOK_DIV" */ -#line 187 "ast_expr2.y" + case 17: /* "TOK_DIV" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1340 "ast_expr2.c" +#line 1410 "ast_expr2.c" break; - case 17: /* "TOK_MULT" */ -#line 187 "ast_expr2.y" + case 18: /* "TOK_MULT" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1345 "ast_expr2.c" +#line 1415 "ast_expr2.c" break; - case 18: /* "TOK_COMPL" */ -#line 187 "ast_expr2.y" + case 19: /* "TOK_COMPL" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1350 "ast_expr2.c" +#line 1420 "ast_expr2.c" break; - case 19: /* "TOK_EQTILDE" */ -#line 187 "ast_expr2.y" + case 20: /* "TOK_EQTILDE" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1355 "ast_expr2.c" +#line 1425 "ast_expr2.c" break; - case 20: /* "TOK_COLON" */ -#line 187 "ast_expr2.y" + case 21: /* "TOK_COLON" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1360 "ast_expr2.c" +#line 1430 "ast_expr2.c" break; - case 21: /* "TOK_LP" */ -#line 187 "ast_expr2.y" + case 22: /* "TOK_LP" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1365 "ast_expr2.c" +#line 1435 "ast_expr2.c" break; - case 22: /* "TOK_RP" */ -#line 187 "ast_expr2.y" + case 23: /* "TOK_RP" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1370 "ast_expr2.c" +#line 1440 "ast_expr2.c" break; - case 23: /* "TOKEN" */ -#line 187 "ast_expr2.y" + case 24: /* "TOKEN" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1375 "ast_expr2.c" +#line 1445 "ast_expr2.c" break; - case 26: /* "expr" */ -#line 187 "ast_expr2.y" + case 28: /* "expr" */ +#line 251 "ast_expr2.y" { free_value((yyvaluep->val)); }; -#line 1380 "ast_expr2.c" +#line 1450 "ast_expr2.c" break; default: @@ -1699,7 +1769,7 @@ yyreduce: switch (yyn) { case 2: -#line 193 "ast_expr2.y" +#line 257 "ast_expr2.y" { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1); ((struct parse_io *)parseio)->val->type = (yyvsp[(1) - (1)].val)->type; if( (yyvsp[(1) - (1)].val)->type == AST_EXPR_number ) @@ -1711,7 +1781,7 @@ yyreduce: break; case 3: -#line 201 "ast_expr2.y" +#line 265 "ast_expr2.y" {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1); ((struct parse_io *)parseio)->val->type = AST_EXPR_string; ((struct parse_io *)parseio)->val->u.s = strdup(""); @@ -1719,156 +1789,181 @@ yyreduce: break; case 4: -#line 208 "ast_expr2.y" - { (yyval.val)= (yyvsp[(1) - (1)].val);;} +#line 272 "ast_expr2.y" + { (yyval.arglist) = alloc_expr_node(AST_EXPR_NODE_VAL); (yyval.arglist)->val = (yyvsp[(1) - (1)].val);;} break; case 5: -#line 209 "ast_expr2.y" - { (yyval.val) = (yyvsp[(2) - (3)].val); +#line 273 "ast_expr2.y" + {struct expr_node *x = alloc_expr_node(AST_EXPR_NODE_VAL); + struct expr_node *t; + DESTROY((yyvsp[(2) - (3)].val)); + for (t=(yyvsp[(1) - (3)].arglist);t->right;t=t->right) + ; + (yyval.arglist) = (yyvsp[(1) - (3)].arglist); t->right = x; x->val = (yyvsp[(3) - (3)].val);;} + break; + + case 6: +#line 282 "ast_expr2.y" + { (yyval.val) = op_func((yyvsp[(1) - (4)].val),(yyvsp[(3) - (4)].arglist), ((struct parse_io *)parseio)->chan); + DESTROY((yyvsp[(2) - (4)].val)); + DESTROY((yyvsp[(4) - (4)].val)); + DESTROY((yyvsp[(1) - (4)].val)); + destroy_arglist((yyvsp[(3) - (4)].arglist)); + ;} + break; + + case 7: +#line 288 "ast_expr2.y" + {(yyval.val) = (yyvsp[(1) - (1)].val);;} + break; + + case 8: +#line 289 "ast_expr2.y" + { (yyval.val) = (yyvsp[(2) - (3)].val); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0; DESTROY((yyvsp[(1) - (3)].val)); DESTROY((yyvsp[(3) - (3)].val)); ;} break; - case 6: -#line 213 "ast_expr2.y" + case 9: +#line 293 "ast_expr2.y" { (yyval.val) = op_or ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 7: -#line 217 "ast_expr2.y" + case 10: +#line 297 "ast_expr2.y" { (yyval.val) = op_and ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 8: -#line 221 "ast_expr2.y" + case 11: +#line 301 "ast_expr2.y" { (yyval.val) = op_eq ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 9: -#line 225 "ast_expr2.y" + case 12: +#line 305 "ast_expr2.y" { (yyval.val) = op_gt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 10: -#line 229 "ast_expr2.y" + case 13: +#line 309 "ast_expr2.y" { (yyval.val) = op_lt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 11: -#line 233 "ast_expr2.y" + case 14: +#line 313 "ast_expr2.y" { (yyval.val) = op_ge ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 12: -#line 237 "ast_expr2.y" + case 15: +#line 317 "ast_expr2.y" { (yyval.val) = op_le ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 13: -#line 241 "ast_expr2.y" + case 16: +#line 321 "ast_expr2.y" { (yyval.val) = op_ne ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 14: -#line 245 "ast_expr2.y" + case 17: +#line 325 "ast_expr2.y" { (yyval.val) = op_plus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 15: -#line 249 "ast_expr2.y" + case 18: +#line 329 "ast_expr2.y" { (yyval.val) = op_minus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 16: -#line 253 "ast_expr2.y" + case 19: +#line 333 "ast_expr2.y" { (yyval.val) = op_negate ((yyvsp[(2) - (2)].val)); DESTROY((yyvsp[(1) - (2)].val)); (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 17: -#line 257 "ast_expr2.y" + case 20: +#line 337 "ast_expr2.y" { (yyval.val) = op_compl ((yyvsp[(2) - (2)].val)); DESTROY((yyvsp[(1) - (2)].val)); (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 18: -#line 261 "ast_expr2.y" + case 21: +#line 341 "ast_expr2.y" { (yyval.val) = op_times ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 19: -#line 265 "ast_expr2.y" + case 22: +#line 345 "ast_expr2.y" { (yyval.val) = op_div ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 20: -#line 269 "ast_expr2.y" + case 23: +#line 349 "ast_expr2.y" { (yyval.val) = op_rem ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 21: -#line 273 "ast_expr2.y" + case 24: +#line 353 "ast_expr2.y" { (yyval.val) = op_colon ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 22: -#line 277 "ast_expr2.y" + case 25: +#line 357 "ast_expr2.y" { (yyval.val) = op_eqtilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); DESTROY((yyvsp[(2) - (3)].val)); (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;} break; - case 23: -#line 281 "ast_expr2.y" + case 26: +#line 361 "ast_expr2.y" { (yyval.val) = op_cond ((yyvsp[(1) - (5)].val), (yyvsp[(3) - (5)].val), (yyvsp[(5) - (5)].val)); DESTROY((yyvsp[(2) - (5)].val)); DESTROY((yyvsp[(4) - (5)].val)); @@ -1878,7 +1973,7 @@ yyreduce: /* Line 1270 of yacc.c. */ -#line 1882 "ast_expr2.c" +#line 1977 "ast_expr2.c" default: break; } YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); @@ -2097,7 +2192,20 @@ yyreturn: } -#line 288 "ast_expr2.y" +#line 368 "ast_expr2.y" + + +static struct expr_node *alloc_expr_node(enum node_type nt) +{ + struct expr_node *x = calloc(1,sizeof(struct expr_node)); + if (!x) { + ast_log(LOG_ERROR, "Allocation for expr_node FAILED!!\n"); + return 0; + } + x->type = nt; + return x; +} + static struct val * @@ -2288,7 +2396,7 @@ int main(int argc,char **argv) { if( s[strlen(s)-1] == '\n' ) s[strlen(s)-1] = 0; - ret = ast_expr(s, out, sizeof(out)); + ret = ast_expr(s, out, sizeof(out),NULL); printf("Expression: %s Result: [%d] '%s'\n", s, ret, out); } @@ -2296,7 +2404,7 @@ int main(int argc,char **argv) { } else { - if (ast_expr(argv[1], s, sizeof(s))) + if (ast_expr(argv[1], s, sizeof(s), NULL)) printf("=====%s======\n",s); else printf("No result\n"); @@ -2313,6 +2421,304 @@ int main(int argc,char **argv) { let it access the BUFFER stuff there and not trying define all the structs, macros etc. in this file! */ +static void destroy_arglist(struct expr_node *arglist) +{ + struct expr_node *arglist_next; + + while (arglist) + { + arglist_next = arglist->right; + if (arglist->val) + free_value(arglist->val); + arglist->val = 0; + arglist->right = 0; + free(arglist); + arglist = arglist_next; + } +} + +static char *compose_func_args(struct expr_node *arglist) +{ + struct expr_node *t = arglist; + char *argbuf; + int total_len = 0; + + while (t) { + if (t != arglist) + total_len += 1; /* for the sep */ + if (t->val) { + if (t->val->type == AST_EXPR_number) + total_len += 25; /* worst case */ + else + total_len += strlen(t->val->u.s); + } + + t = t->right; + } + total_len++; /* for the null */ + ast_log(LOG_NOTICE,"argbuf allocated %d bytes;\n", total_len); + argbuf = malloc(total_len); + argbuf[0] = 0; + t = arglist; + while (t) { + char numbuf[30]; + + if (t != arglist) + strcat(argbuf,"|"); + + if (t->val) { + if (t->val->type == AST_EXPR_number) { + sprintf(numbuf,FP___PRINTF,t->val->u.i); + strcat(argbuf,numbuf); + } else + strcat(argbuf,t->val->u.s); + } + t = t->right; + } + ast_log(LOG_NOTICE,"argbuf uses %d bytes;\n", strlen(argbuf)); + return argbuf; +} + +static int is_really_num(char *str) +{ + if ( strspn(str,"-0123456789. ") == strlen(str)) + return 1; + else + return 0; +} + + +static struct val *op_func(struct val *funcname, struct expr_node *arglist, struct ast_channel *chan) +{ + if (strspn(funcname->u.s,"ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789") == strlen(funcname->u.s)) + { + struct val *result; + + if (strcmp(funcname->u.s,"COS") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_COS(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"SIN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_SIN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"TAN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_TAN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ACOS") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ACOS(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ASIN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ASIN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ATAN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ATAN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ATAN2") == 0) { + if (arglist && arglist->right && !arglist->right->right && arglist->val && arglist->right->val){ + to_number(arglist->val); + to_number(arglist->right->val); + result = make_number(FUNC_ATAN2(arglist->val->u.i, arglist->right->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"POW") == 0) { + if (arglist && arglist->right && !arglist->right->right && arglist->val && arglist->right->val){ + to_number(arglist->val); + to_number(arglist->right->val); + result = make_number(FUNC_POW(arglist->val->u.i, arglist->right->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"SQRT") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_SQRT(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"FLOOR") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_FLOOR(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"CEIL") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_CEIL(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ROUND") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ROUND(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"RINT") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_RINT(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"TRUNC") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_TRUNC(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"EXP") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_EXP(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"EXP2") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_EXP2(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"LOG") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_LOG(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"LOG2") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_LOG2(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"LOG10") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_LOG10(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"REMAINDER") == 0) { + if (arglist && arglist->right && !arglist->right->right && arglist->val && arglist->right->val){ + to_number(arglist->val); + to_number(arglist->right->val); + result = make_number(FUNC_REMAINDER(arglist->val->u.i, arglist->right->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else { + /* is this a custom function we should execute and collect the results of? */ +#ifndef STANDALONE + struct ast_custom_function *f = ast_custom_function_find(funcname->u.s); + if (!chan) + ast_log(LOG_WARNING,"Hey! chan is NULL.\n"); + if (!f) + ast_log(LOG_WARNING,"Hey! could not find func %s.\n", funcname->u.s); + + if (f && chan) { + if (f->read) { + char workspace[512]; + char *argbuf = compose_func_args(arglist); + f->read(chan, funcname->u.s, argbuf, workspace, sizeof(workspace)); + free(argbuf); + if (is_really_num(workspace)) + return make_number(FP___STRTOD(workspace,(char **)NULL)); + else + return make_str(workspace); + } else { + ast_log(LOG_ERROR,"Error! Function '%s' cannot be read!\n", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); + } + + } else { + ast_log(LOG_ERROR,"Error! '%s' doesn't appear to be an available function!", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); + } +#else + ast_log(LOG_ERROR,"Error! '%s' is not available in the standalone version!", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); +#endif + } + } + else + { + ast_log(LOG_ERROR,"Error! '%s' is not possibly a function name!", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); + } + return (make_number ((FP___TYPE)0.0)); +} + static struct val * op_or (struct val *a, struct val *b) @@ -2332,7 +2738,7 @@ op_and (struct val *a, struct val *b) if (is_zero_or_null (a) || is_zero_or_null (b)) { free_value (a); free_value (b); - return (make_number ((double)0.0)); + return (make_number ((FP___TYPE)0.0)); } else { free_value (b); return (a); diff --git a/main/ast_expr2.fl b/main/ast_expr2.fl index 49c051bd9..725205304 100644 --- a/main/ast_expr2.fl +++ b/main/ast_expr2.fl @@ -36,12 +36,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #endif #ifdef __USE_ISOC99 -#define FP___PRINTF "%.16Lg" +#define FP___PRINTF "%.18Lg" #define FP___FMOD fmodl #define FP___STRTOD strtold #define FP___TYPE long double #else -#define FP___PRINTF "%.8g" +#define FP___PRINTF "%.16g" #define FP___FMOD fmod #define FP___STRTOD strtod #define FP___TYPE double @@ -62,7 +62,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/ast_expr.h" #include "asterisk/logger.h" +#ifndef STANDALONE #include "asterisk/strings.h" +#include "asterisk/channel.h" +#endif enum valtype { AST_EXPR_number, AST_EXPR_numeric_string, AST_EXPR_string @@ -101,6 +104,7 @@ struct parse_io char *string; struct val *val; yyscan_t scanner; + struct ast_channel *chan; }; void ast_yyset_column(int column_no, yyscan_t yyscanner); @@ -133,6 +137,7 @@ static char *expr2_token_subst(char *mess); \<\= { SET_COLUMNS; SET_STRING; return TOK_LE;} \!\= { SET_COLUMNS; SET_STRING; return TOK_NE;} \+ { SET_COLUMNS; SET_STRING; return TOK_PLUS;} +\, { SET_COLUMNS; SET_STRING; return TOK_COMMA;} \- { SET_COLUMNS; SET_STRING; return TOK_MINUS;} \* { SET_COLUMNS; SET_STRING; return TOK_MULT;} \/ { SET_COLUMNS; SET_STRING; return TOK_DIV;} @@ -166,7 +171,7 @@ static char *expr2_token_subst(char *mess); return TOKEN; } -[a-zA-Z0-9,.';\\_^$#@]+ { +[a-zA-Z0-9\.';\\_^$#@]+ { SET_COLUMNS; SET_STRING; return TOKEN; @@ -230,13 +235,14 @@ static char *expr2_token_subst(char *mess); int ast_yyparse(void *); /* need to/should define this prototype for the call to yyparse */ int ast_yyerror(const char *, YYLTYPE *, struct parse_io *); /* likewise */ -int ast_expr(char *expr, char *buf, int length) +int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan) { struct parse_io io; int return_value = 0; memset(&io, 0, sizeof(io)); io.string = expr; /* to pass to the error routine */ + io.chan = chan; ast_yylex_init(&io.scanner); @@ -310,6 +316,7 @@ static char *expr2_token_equivs1[] = "TOK_COMPL", "TOK_COLON", "TOK_EQTILDE", + "TOK_COMMA", "TOK_RP", "TOK_LP" }; @@ -335,6 +342,7 @@ static char *expr2_token_equivs2[] = "!", ":", "=~", + ",", ")", "(" }; diff --git a/main/ast_expr2.h b/main/ast_expr2.h index 4bff4d872..517402cfb 100644 --- a/main/ast_expr2.h +++ b/main/ast_expr2.h @@ -29,63 +29,66 @@ /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - TOK_COLONCOLON = 258, - TOK_COND = 259, - TOK_OR = 260, - TOK_AND = 261, - TOK_NE = 262, - TOK_LE = 263, - TOK_GE = 264, - TOK_LT = 265, - TOK_GT = 266, - TOK_EQ = 267, - TOK_MINUS = 268, - TOK_PLUS = 269, - TOK_MOD = 270, - TOK_DIV = 271, - TOK_MULT = 272, - TOK_COMPL = 273, - TOK_EQTILDE = 274, - TOK_COLON = 275, - TOK_LP = 276, - TOK_RP = 277, - TOKEN = 278 + TOK_COMMA = 258, + TOK_COLONCOLON = 259, + TOK_COND = 260, + TOK_OR = 261, + TOK_AND = 262, + TOK_NE = 263, + TOK_LE = 264, + TOK_GE = 265, + TOK_LT = 266, + TOK_GT = 267, + TOK_EQ = 268, + TOK_MINUS = 269, + TOK_PLUS = 270, + TOK_MOD = 271, + TOK_DIV = 272, + TOK_MULT = 273, + TOK_COMPL = 274, + TOK_EQTILDE = 275, + TOK_COLON = 276, + TOK_LP = 277, + TOK_RP = 278, + TOKEN = 279 }; #endif /* Tokens. */ -#define TOK_COLONCOLON 258 -#define TOK_COND 259 -#define TOK_OR 260 -#define TOK_AND 261 -#define TOK_NE 262 -#define TOK_LE 263 -#define TOK_GE 264 -#define TOK_LT 265 -#define TOK_GT 266 -#define TOK_EQ 267 -#define TOK_MINUS 268 -#define TOK_PLUS 269 -#define TOK_MOD 270 -#define TOK_DIV 271 -#define TOK_MULT 272 -#define TOK_COMPL 273 -#define TOK_EQTILDE 274 -#define TOK_COLON 275 -#define TOK_LP 276 -#define TOK_RP 277 -#define TOKEN 278 +#define TOK_COMMA 258 +#define TOK_COLONCOLON 259 +#define TOK_COND 260 +#define TOK_OR 261 +#define TOK_AND 262 +#define TOK_NE 263 +#define TOK_LE 264 +#define TOK_GE 265 +#define TOK_LT 266 +#define TOK_GT 267 +#define TOK_EQ 268 +#define TOK_MINUS 269 +#define TOK_PLUS 270 +#define TOK_MOD 271 +#define TOK_DIV 272 +#define TOK_MULT 273 +#define TOK_COMPL 274 +#define TOK_EQTILDE 275 +#define TOK_COLON 276 +#define TOK_LP 277 +#define TOK_RP 278 +#define TOKEN 279 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED typedef union YYSTYPE -#line 165 "ast_expr2.y" +#line 226 "ast_expr2.y" { struct val *val; + struct expr_node *arglist; } /* Line 1536 of yacc.c. */ -#line 89 "ast_expr2.h" +#line 92 "ast_expr2.h" YYSTYPE; # define yystype YYSTYPE /* obsolescent; will be withdrawn */ # define YYSTYPE_IS_DECLARED 1 diff --git a/main/ast_expr2.y b/main/ast_expr2.y index 8b43223fc..d6c5e8eaa 100644 --- a/main/ast_expr2.y +++ b/main/ast_expr2.y @@ -22,15 +22,55 @@ #endif #ifdef __USE_ISOC99 -#define FP___PRINTF "%.16Lg" +#define FP___PRINTF "%.18Lg" #define FP___FMOD fmodl #define FP___STRTOD strtold #define FP___TYPE long double +#define FUNC_COS cosl +#define FUNC_SIN sinl +#define FUNC_TAN tanl +#define FUNC_ACOS acosl +#define FUNC_ASIN asinl +#define FUNC_ATAN atanl +#define FUNC_ATAN2 atan2l +#define FUNC_POW powl +#define FUNC_SQRT sqrtl +#define FUNC_FLOOR floorl +#define FUNC_CEIL ceill +#define FUNC_ROUND roundl +#define FUNC_RINT rintl +#define FUNC_TRUNC truncl +#define FUNC_EXP expl +#define FUNC_EXP2 exp2l +#define FUNC_LOG logl +#define FUNC_LOG2 log2l +#define FUNC_LOG10 log10l +#define FUNC_REMAINDER remainderl #else -#define FP___PRINTF "%.8g" +#define FP___PRINTF "%.16g" #define FP___FMOD fmod #define FP___STRTOD strtod #define FP___TYPE double +#define FUNC_COS cos +#define FUNC_SIN sin +#define FUNC_TAN tan +#define FUNC_ACOS acos +#define FUNC_ASIN asin +#define FUNC_ATAN atan +#define FUNC_ATAN2 atan2 +#define FUNC_POW pow +#define FUNC_SQRT sqrt +#define FUNC_FLOOR floor +#define FUNC_CEIL ceil +#define FUNC_ROUND round +#define FUNC_RINT rint +#define FUNC_TRUNC trunc +#define FUNC_EXP exp +#define FUNC_EXP2 exp2 +#define FUNC_LOG log +#define FUNC_LOG2 log2 +#define FUNC_LOG10 log10 +#define FUNC_REMAINDER remainder #endif #include <stdlib.h> @@ -54,6 +94,9 @@ #include "asterisk.h" #include "asterisk/ast_expr.h" #include "asterisk/logger.h" +#ifndef STANDALONE +#include "asterisk/pbx.h" +#endif #if defined(LONG_LONG_MIN) && !defined(QUAD_MIN) #define QUAD_MIN LONG_LONG_MIN @@ -91,6 +134,19 @@ struct val { } u; } ; +enum node_type { + AST_EXPR_NODE_COMMA, AST_EXPR_NODE_STRING, AST_EXPR_NODE_VAL +} ; + +struct expr_node +{ + enum node_type type; + struct val *val; + struct expr_node *left; + struct expr_node *right; +}; + + typedef void *yyscan_t; struct parse_io @@ -98,6 +154,7 @@ struct parse_io char *string; struct val *val; yyscan_t scanner; + struct ast_channel *chan; }; static int chk_div __P((FP___TYPE, FP___TYPE)); @@ -127,8 +184,12 @@ static struct val *op_or __P((struct val *, struct val *)); static struct val *op_plus __P((struct val *, struct val *)); static struct val *op_rem __P((struct val *, struct val *)); static struct val *op_times __P((struct val *, struct val *)); +static struct val *op_func(struct val *funcname, struct expr_node *arglist, struct ast_channel *chan); static int to_number __P((struct val *)); static void to_string __P((struct val *)); +static struct expr_node *alloc_expr_node(enum node_type); +static void destroy_arglist(struct expr_node *arglist); +static int is_really_num(char *str); /* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */ typedef struct yyltype @@ -164,23 +225,26 @@ int ast_yyerror(const char *,YYLTYPE *, struct parse_io *); %union { struct val *val; + struct expr_node *arglist; } %{ extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t)); %} +%left <val> TOK_COMMA %left <val> TOK_COND TOK_COLONCOLON %left <val> TOK_OR %left <val> TOK_AND %left <val> TOK_EQ TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE %left <val> TOK_PLUS TOK_MINUS -%left <val> TOK_MULT TOK_DIV TOK_MOD +%left <val> TOK_MULT TOK_DIV TOK_MOD %right <val> TOK_COMPL %left <val> TOK_COLON TOK_EQTILDE %left <val> TOK_RP TOK_LP %token <val> TOKEN +%type <arglist> arglist %type <val> start expr @@ -205,8 +269,24 @@ start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(st ; -expr: TOKEN { $$= $1;} - | TOK_LP expr TOK_RP { $$ = $2; +arglist: expr { $$ = alloc_expr_node(AST_EXPR_NODE_VAL); $$->val = $1;} + | arglist TOK_COMMA expr %prec TOK_RP{struct expr_node *x = alloc_expr_node(AST_EXPR_NODE_VAL); + struct expr_node *t; + DESTROY($2); + for (t=$1;t->right;t=t->right) + ; + $$ = $1; t->right = x; x->val = $3;} + ; + +expr: + TOKEN TOK_LP arglist TOK_RP { $$ = op_func($1,$3, ((struct parse_io *)parseio)->chan); + DESTROY($2); + DESTROY($4); + DESTROY($1); + destroy_arglist($3); + } + | TOKEN {$$ = $1;} + | TOK_LP expr TOK_RP { $$ = $2; @$.first_column = @1.first_column; @$.last_column = @3.last_column; @$.first_line=0; @$.last_line=0; DESTROY($1); DESTROY($3); } @@ -287,6 +367,19 @@ expr: TOKEN { $$= $1;} %% +static struct expr_node *alloc_expr_node(enum node_type nt) +{ + struct expr_node *x = calloc(1,sizeof(struct expr_node)); + if (!x) { + ast_log(LOG_ERROR, "Allocation for expr_node FAILED!!\n"); + return 0; + } + x->type = nt; + return x; +} + + + static struct val * make_number (FP___TYPE i) { @@ -475,7 +568,7 @@ int main(int argc,char **argv) { if( s[strlen(s)-1] == '\n' ) s[strlen(s)-1] = 0; - ret = ast_expr(s, out, sizeof(out)); + ret = ast_expr(s, out, sizeof(out),NULL); printf("Expression: %s Result: [%d] '%s'\n", s, ret, out); } @@ -483,7 +576,7 @@ int main(int argc,char **argv) { } else { - if (ast_expr(argv[1], s, sizeof(s))) + if (ast_expr(argv[1], s, sizeof(s), NULL)) printf("=====%s======\n",s); else printf("No result\n"); @@ -500,6 +593,304 @@ int main(int argc,char **argv) { let it access the BUFFER stuff there and not trying define all the structs, macros etc. in this file! */ +static void destroy_arglist(struct expr_node *arglist) +{ + struct expr_node *arglist_next; + + while (arglist) + { + arglist_next = arglist->right; + if (arglist->val) + free_value(arglist->val); + arglist->val = 0; + arglist->right = 0; + free(arglist); + arglist = arglist_next; + } +} + +static char *compose_func_args(struct expr_node *arglist) +{ + struct expr_node *t = arglist; + char *argbuf; + int total_len = 0; + + while (t) { + if (t != arglist) + total_len += 1; /* for the sep */ + if (t->val) { + if (t->val->type == AST_EXPR_number) + total_len += 25; /* worst case */ + else + total_len += strlen(t->val->u.s); + } + + t = t->right; + } + total_len++; /* for the null */ + ast_log(LOG_NOTICE,"argbuf allocated %d bytes;\n", total_len); + argbuf = malloc(total_len); + argbuf[0] = 0; + t = arglist; + while (t) { + char numbuf[30]; + + if (t != arglist) + strcat(argbuf,"|"); + + if (t->val) { + if (t->val->type == AST_EXPR_number) { + sprintf(numbuf,FP___PRINTF,t->val->u.i); + strcat(argbuf,numbuf); + } else + strcat(argbuf,t->val->u.s); + } + t = t->right; + } + ast_log(LOG_NOTICE,"argbuf uses %d bytes;\n", strlen(argbuf)); + return argbuf; +} + +static int is_really_num(char *str) +{ + if ( strspn(str,"-0123456789. ") == strlen(str)) + return 1; + else + return 0; +} + + +static struct val *op_func(struct val *funcname, struct expr_node *arglist, struct ast_channel *chan) +{ + if (strspn(funcname->u.s,"ABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789") == strlen(funcname->u.s)) + { + struct val *result; + + if (strcmp(funcname->u.s,"COS") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_COS(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"SIN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_SIN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"TAN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_TAN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ACOS") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ACOS(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ASIN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ASIN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ATAN") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ATAN(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ATAN2") == 0) { + if (arglist && arglist->right && !arglist->right->right && arglist->val && arglist->right->val){ + to_number(arglist->val); + to_number(arglist->right->val); + result = make_number(FUNC_ATAN2(arglist->val->u.i, arglist->right->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"POW") == 0) { + if (arglist && arglist->right && !arglist->right->right && arglist->val && arglist->right->val){ + to_number(arglist->val); + to_number(arglist->right->val); + result = make_number(FUNC_POW(arglist->val->u.i, arglist->right->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"SQRT") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_SQRT(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"FLOOR") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_FLOOR(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"CEIL") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_CEIL(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"ROUND") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_ROUND(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"RINT") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_RINT(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"TRUNC") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_TRUNC(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"EXP") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_EXP(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"EXP2") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_EXP2(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"LOG") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_LOG(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"LOG2") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_LOG2(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"LOG10") == 0) { + if (arglist && !arglist->right && arglist->val){ + to_number(arglist->val); + result = make_number(FUNC_LOG10(arglist->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else if (strcmp(funcname->u.s,"REMAINDER") == 0) { + if (arglist && arglist->right && !arglist->right->right && arglist->val && arglist->right->val){ + to_number(arglist->val); + to_number(arglist->right->val); + result = make_number(FUNC_REMAINDER(arglist->val->u.i, arglist->right->val->u.i)); + return result; + } else { + ast_log(LOG_WARNING,"Wrong args to %s() function\n",funcname->u.s); + return make_number(0.0); + } + } else { + /* is this a custom function we should execute and collect the results of? */ +#ifndef STANDALONE + struct ast_custom_function *f = ast_custom_function_find(funcname->u.s); + if (!chan) + ast_log(LOG_WARNING,"Hey! chan is NULL.\n"); + if (!f) + ast_log(LOG_WARNING,"Hey! could not find func %s.\n", funcname->u.s); + + if (f && chan) { + if (f->read) { + char workspace[512]; + char *argbuf = compose_func_args(arglist); + f->read(chan, funcname->u.s, argbuf, workspace, sizeof(workspace)); + free(argbuf); + if (is_really_num(workspace)) + return make_number(FP___STRTOD(workspace,(char **)NULL)); + else + return make_str(workspace); + } else { + ast_log(LOG_ERROR,"Error! Function '%s' cannot be read!\n", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); + } + + } else { + ast_log(LOG_ERROR,"Error! '%s' doesn't appear to be an available function!", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); + } +#else + ast_log(LOG_ERROR,"Error! '%s' is not available in the standalone version!", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); +#endif + } + } + else + { + ast_log(LOG_ERROR,"Error! '%s' is not possibly a function name!", funcname->u.s); + return (make_number ((FP___TYPE)0.0)); + } + return (make_number ((FP___TYPE)0.0)); +} + static struct val * op_or (struct val *a, struct val *b) @@ -519,7 +910,7 @@ op_and (struct val *a, struct val *b) if (is_zero_or_null (a) || is_zero_or_null (b)) { free_value (a); free_value (b); - return (make_number ((double)0.0)); + return (make_number ((FP___TYPE)0.0)); } else { free_value (b); return (a); diff --git a/main/ast_expr2f.c b/main/ast_expr2f.c index aa84e2b63..7888a594a 100644 --- a/main/ast_expr2f.c +++ b/main/ast_expr2f.c @@ -351,16 +351,16 @@ static yyconst flex_int16_t yy_nxt[][128] = 10, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 11, 12, 13, 14, 15, 16, 13, - 17, 18, 19, 20, 13, 21, 13, 22, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 13, - 25, 26, 27, 28, 13, 13, 13, 13, 13, 13, + 17, 18, 19, 20, 21, 22, 13, 23, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 25, 13, + 26, 27, 28, 29, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 13, 8, 13, 13, 8, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 8, 29, 8, 8, 8 + 13, 13, 13, 8, 30, 8, 8, 8 }, { @@ -369,85 +369,85 @@ static yyconst flex_int16_t yy_nxt[][128] = 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 11, 12, 13, 14, 15, 16, 13, - 17, 18, 19, 20, 13, 21, 13, 22, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 24, 13, - 25, 26, 27, 28, 13, 13, 13, 13, 13, 13, + 17, 18, 19, 20, 21, 22, 13, 23, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 25, 13, + 26, 27, 28, 29, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 8, 13, 8, 13, 13, 8, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 8, 29, 8, 8, 8 + 13, 13, 13, 8, 30, 8, 8, 8 }, { - 7, 30, 30, 30, 30, 30, 30, 30, 30, 30, - - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 31, 30, 32, 30, 30 + 7, 31, 31, 31, 31, 31, 31, 31, 31, 31, + + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 32, 31, 33, 31, 31 }, { - 7, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, - 30, 30, 30, 31, 30, 32, 30, 30 + 7, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, + 31, 31, 31, 32, 31, 33, 31, 31 }, { - 7, 33, 33, 33, 33, 33, 33, 33, 33, 34, - 34, 33, 33, 34, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 34, 34, 33, 33, 35, 34, 34, 33, - 34, 34, 34, 34, 33, 34, 33, 34, 33, 33, - - 33, 33, 33, 33, 33, 33, 33, 33, 34, 33, - 34, 34, 34, 34, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 34, 33, 33, 33 + 7, 34, 34, 34, 34, 34, 34, 34, 34, 35, + 35, 34, 34, 35, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 35, 35, 34, 34, 36, 35, 35, 34, + 35, 35, 35, 35, 34, 35, 34, 35, 34, 34, + + 34, 34, 34, 34, 34, 34, 34, 34, 35, 34, + 35, 35, 35, 35, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 35, 34, 34, 34 }, { - 7, 33, 33, 33, 33, 33, 33, 33, 33, 34, - 34, 33, 33, 34, 33, 33, 33, 33, 33, 33, - - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 34, 34, 33, 33, 35, 34, 34, 33, - 34, 34, 34, 34, 33, 34, 33, 34, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 34, 33, - 34, 34, 34, 34, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, - - 33, 33, 33, 33, 34, 33, 33, 33 + 7, 34, 34, 34, 34, 34, 34, 34, 34, 35, + 35, 34, 34, 35, 34, 34, 34, 34, 34, 34, + + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 35, 35, 34, 34, 36, 35, 35, 34, + 35, 35, 35, 35, 34, 35, 34, 35, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 35, 34, + 35, 35, 35, 35, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, + + 34, 34, 34, 34, 35, 34, 34, 34 }, { @@ -526,7 +526,7 @@ static yyconst flex_int16_t yy_nxt[][128] = -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, - -11, 36, -11, -11, -11, -11, -11, -11, -11, -11, + -11, 37, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, -11, @@ -537,20 +537,20 @@ static yyconst flex_int16_t yy_nxt[][128] = }, { - 7, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, - - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37 + 7, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 39, 38, 38, 38, 38, 38, + + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38 }, { @@ -558,34 +558,34 @@ static yyconst flex_int16_t yy_nxt[][128] = -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, -13, - -13, -13, -13, -13, -13, 39, 39, -13, -13, 39, - -13, -13, -13, -13, 39, -13, 39, -13, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, -13, 39, - -13, -13, -13, -13, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, -13, 39, -13, 39, 39, -13, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, -13, -13, -13, -13, -13 + -13, -13, -13, -13, -13, 40, 40, -13, -13, 40, + -13, -13, -13, -13, -13, -13, 40, -13, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, -13, 40, + -13, -13, -13, -13, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, -13, 40, -13, 40, 40, -13, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, -13, -13, -13, -13, -13 }, { 7, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, -14, - -14, -14, -14, -14, -14, 39, 39, -14, -14, 39, - -14, -14, -14, -14, 39, -14, 39, -14, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, -14, 39, - -14, -14, -14, -14, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, -14, 39, -14, 39, 39, -14, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 40, -14, -14, -14, -14 + -14, -14, -14, -14, -14, 40, 40, -14, -14, 40, + -14, -14, -14, -14, -14, -14, 40, -14, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, -14, 40, + -14, -14, -14, -14, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, -14, 40, -14, 40, 40, -14, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 41, -14, -14, -14, -14 }, { @@ -610,7 +610,7 @@ static yyconst flex_int16_t yy_nxt[][128] = -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, - -16, -16, -16, -16, -16, -16, -16, -16, 41, -16, + -16, -16, -16, -16, -16, -16, -16, -16, 42, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, -16, @@ -731,34 +731,34 @@ static yyconst flex_int16_t yy_nxt[][128] = -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, - -23, -23, -23, -23, -23, 39, 39, -23, -23, 39, - -23, -23, -23, -23, 39, -23, 42, -23, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, -23, 39, - -23, -23, -23, -23, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, -23, 39, -23, 39, 39, -23, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, -23, -23, -23, -23, -23 + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + + -23, -23, -23, -23, -23, -23, -23, -23, -23, -23, + -23, -23, -23, -23, -23, -23, -23, -23 }, { 7, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24, 44, -24, - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24, -24, -24, - -24, -24, -24, -24, -24, -24, -24, -24 + -24, -24, -24, -24, -24, 40, 40, -24, -24, 40, + -24, -24, -24, -24, -24, -24, 43, -24, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, -24, 40, + -24, -24, -24, -24, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, -24, 40, -24, 40, 40, -24, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, -24, -24, -24, -24, -24 }, { @@ -768,8 +768,8 @@ static yyconst flex_int16_t yy_nxt[][128] = -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, + -25, -25, -25, -25, -25, -25, -25, -25, 45, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, - -25, 45, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, -25, @@ -793,7 +793,7 @@ static yyconst flex_int16_t yy_nxt[][128] = -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, -26, - -26, -26, -26, -26, -26, -26, 47, -26 + -26, -26, -26, -26, -26, -26, -26, -26 }, { @@ -803,14 +803,14 @@ static yyconst flex_int16_t yy_nxt[][128] = -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, 48, -27, -27, -27, -27, -27, -27, -27, -27, + -27, 47, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27 + -27, -27, -27, -27, -27, -27, 48, -27 }, { @@ -821,7 +821,7 @@ static yyconst flex_int16_t yy_nxt[][128] = -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, - -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, + -28, 49, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, -28, @@ -844,42 +844,42 @@ static yyconst flex_int16_t yy_nxt[][128] = -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, -29, - -29, -29, -29, -29, 49, -29, -29, -29 + -29, -29, -29, -29, -29, -29, -29, -29 }, { - 7, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 51, 50, 52, 50, 50 + 7, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, 50, -30, -30, -30 }, { - 7, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31, -31, -31, - -31, -31, -31, -31, -31, -31, -31, -31 + 7, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 52, 51, 53, 51, 51 }, { @@ -900,38 +900,38 @@ static yyconst flex_int16_t yy_nxt[][128] = }, { - 7, 53, 53, 53, 53, 53, 53, 53, 53, -33, - - -33, 53, 53, -33, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, -33, -33, 53, 53, -33, -33, -33, 53, - -33, -33, -33, -33, 53, -33, 53, -33, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, -33, 53, - -33, -33, -33, -33, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, -33, 53, 53, 53 + 7, -33, -33, -33, -33, -33, -33, -33, -33, -33, + + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + + -33, -33, -33, -33, -33, -33, -33, -33, -33, -33, + -33, -33, -33, -33, -33, -33, -33, -33 }, { - 7, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34, -34, -34, - -34, -34, -34, -34, -34, -34, -34, -34 + 7, 54, 54, 54, 54, 54, 54, 54, 54, -34, + -34, 54, 54, -34, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, -34, -34, 54, 54, -34, -34, -34, 54, + -34, -34, -34, -34, 54, -34, 54, -34, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, -34, 54, + -34, -34, -34, -34, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, -34, 54, 54, 54 }, { @@ -948,7 +948,7 @@ static yyconst flex_int16_t yy_nxt[][128] = -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, -35, - -35, -35, -35, 54, -35, -35, -35, -35 + -35, -35, -35, -35, -35, -35, -35, -35 }, { @@ -966,41 +966,41 @@ static yyconst flex_int16_t yy_nxt[][128] = -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, -36, - -36, -36, -36, -36, -36, -36, -36, -36 + -36, -36, -36, 55, -36, -36, -36, -36 }, { - 7, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 38, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37 + 7, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37, -37, -37, + -37, -37, -37, -37, -37, -37, -37, -37 }, { - 7, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38, -38, -38, - -38, -38, -38, -38, -38, -38, -38, -38 + 7, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 39, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38, 38, 38, + 38, 38, 38, 38, 38, 38, 38, 38 }, { @@ -1008,16 +1008,16 @@ static yyconst flex_int16_t yy_nxt[][128] = -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, - -39, -39, -39, -39, -39, 39, 39, -39, -39, 39, - -39, -39, -39, -39, 39, -39, 39, -39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, -39, 39, - -39, -39, -39, -39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, -39, 39, -39, 39, 39, -39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, -39, -39, -39, -39, -39 + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39, -39, -39, + -39, -39, -39, -39, -39, -39, -39, -39 }, @@ -1025,17 +1025,17 @@ static yyconst flex_int16_t yy_nxt[][128] = 7, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40, -40, -40, - -40, -40, -40, -40, -40, -40, -40, -40 + -40, -40, -40, -40, -40, 40, 40, -40, -40, 40, + -40, -40, -40, -40, -40, -40, 40, -40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, -40, 40, + -40, -40, -40, -40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, -40, 40, -40, 40, 40, -40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, -40, -40, -40, -40, -40 }, { @@ -1059,17 +1059,17 @@ static yyconst flex_int16_t yy_nxt[][128] = 7, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, 39, 39, -42, -42, 39, - - -42, -42, -42, -42, 39, -42, 39, -42, 55, 55, - 55, 55, 55, 55, 55, 55, 55, 55, -42, 39, - -42, -42, -42, -42, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, -42, 39, -42, 39, 39, -42, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, -42, -42, -42, -42, -42 + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, + -42, -42, -42, -42, -42, -42, -42, -42 }, { @@ -1077,34 +1077,34 @@ static yyconst flex_int16_t yy_nxt[][128] = -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, -43, - -43, -43, -43, -43, -43, 39, 39, -43, -43, 39, - -43, -43, -43, -43, 39, -43, 42, -43, 43, 43, - 43, 43, 43, 43, 43, 43, 43, 43, -43, 39, - -43, -43, -43, -43, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, -43, 39, -43, 39, 39, -43, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, -43, -43, -43, -43, -43 + -43, -43, -43, -43, -43, 40, 40, -43, -43, 40, + -43, -43, -43, -43, -43, -43, 40, -43, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, -43, 40, + -43, -43, -43, -43, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, -43, 40, -43, 40, 40, -43, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, -43, -43, -43, -43, -43 }, { 7, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, - -44, -44, -44, -44, -44, -44, -44, -44 + -44, -44, -44, -44, -44, 40, 40, -44, -44, 40, + -44, -44, -44, -44, -44, -44, 43, -44, 44, 44, + 44, 44, 44, 44, 44, 44, 44, 44, -44, 40, + -44, -44, -44, -44, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, -44, 40, -44, 40, 40, -44, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, -44, -44, -44, -44, -44 }, { @@ -1195,37 +1195,37 @@ static yyconst flex_int16_t yy_nxt[][128] = }, { - 7, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, - 50, 50, 50, 51, 50, 52, 50, 50 + 7, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50, -50, -50, + -50, -50, -50, -50, -50, -50, -50, -50 }, { - 7, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51, -51, -51, - -51, -51, -51, -51, -51, -51, -51, -51 + 7, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 52, 51, 53, 51, 51 }, { @@ -1246,55 +1246,73 @@ static yyconst flex_int16_t yy_nxt[][128] = }, { - 7, 53, 53, 53, 53, 53, 53, 53, 53, -53, - - -53, 53, 53, -53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, -53, -53, 53, 53, -53, -53, -53, 53, - -53, -53, -53, -53, 53, -53, 53, -53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, -53, 53, - -53, -53, -53, -53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, -53, 53, 53, 53 + 7, -53, -53, -53, -53, -53, -53, -53, -53, -53, + + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + + -53, -53, -53, -53, -53, -53, -53, -53, -53, -53, + -53, -53, -53, -53, -53, -53, -53, -53 }, { - 7, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54, -54, -54, - -54, -54, -54, -54, -54, -54, -54, -54 + 7, 54, 54, 54, 54, 54, 54, 54, 54, -54, + -54, 54, 54, -54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, -54, -54, 54, 54, -54, -54, -54, 54, + -54, -54, -54, -54, 54, -54, 54, -54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, -54, 54, + -54, -54, -54, -54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, -54, 54, 54, 54 }, { 7, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, - -55, -55, -55, -55, -55, 39, 39, -55, -55, 39, - -55, -55, -55, -55, 39, -55, 39, -55, 55, 55, - - 55, 55, 55, 55, 55, 55, 55, 55, -55, 39, - -55, -55, -55, -55, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, -55, 39, -55, 39, 39, -55, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, 39, 39, 39, 39, 39, 39, 39, - 39, 39, 39, -55, -55, -55, -55, -55 + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55, -55, -55, + -55, -55, -55, -55, -55, -55, -55, -55 + }, + + { + 7, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + + -56, -56, -56, -56, -56, -56, -56, -56, -56, -56, + -56, -56, -56, -56, -56, 40, 40, -56, -56, 40, + -56, -56, -56, -56, -56, -56, 40, -56, 56, 56, + 56, 56, 56, 56, 56, 56, 56, 56, -56, 40, + -56, -56, -56, -56, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, -56, 40, -56, 40, 40, -56, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, + + 40, 40, 40, -56, -56, -56, -56, -56 }, } ; @@ -1315,8 +1333,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 35 -#define YY_END_OF_BUFFER 36 +#define YY_NUM_RULES 36 +#define YY_END_OF_BUFFER 37 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -1324,24 +1342,24 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[56] = +static yyconst flex_int16_t yy_accept[57] = { 0, - 0, 0, 0, 0, 32, 32, 36, 35, 25, 27, - 19, 35, 29, 29, 17, 2, 22, 23, 15, 13, - 14, 16, 28, 20, 9, 3, 8, 18, 1, 35, - 31, 30, 32, 33, 33, 12, 0, 26, 29, 24, - 5, 29, 28, 21, 11, 6, 7, 10, 4, 0, - 31, 30, 32, 34, 28 + 0, 0, 0, 0, 33, 33, 37, 36, 26, 28, + 20, 36, 30, 30, 18, 2, 23, 24, 16, 13, + 14, 15, 17, 29, 21, 9, 3, 8, 19, 1, + 36, 32, 31, 33, 34, 34, 12, 0, 27, 30, + 25, 5, 30, 29, 22, 11, 6, 7, 10, 4, + 0, 32, 31, 33, 35, 29 } ; -static yyconst yy_state_type yy_NUL_trans[56] = +static yyconst yy_state_type yy_NUL_trans[57] = { 0, - 8, 8, 30, 30, 33, 33, 0, 0, 0, 0, - 0, 37, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 0, 0, 53, 0, 0, 0, 37, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 50, - 0, 0, 53, 0, 0 + 8, 8, 31, 31, 34, 34, 0, 0, 0, 0, + 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 51, 0, 0, 54, 0, 0, 0, 38, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 51, 0, 0, 54, 0, 0 } ; /* The intent behind this definition is that it'll catch @@ -1390,12 +1408,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #endif #ifdef __USE_ISOC99 -#define FP___PRINTF "%.16Lg" +#define FP___PRINTF "%.18Lg" #define FP___FMOD fmodl #define FP___STRTOD strtold #define FP___TYPE long double #else -#define FP___PRINTF "%.8g" +#define FP___PRINTF "%.16g" #define FP___FMOD fmod #define FP___STRTOD strtod #define FP___TYPE double @@ -1416,7 +1434,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/ast_expr.h" #include "asterisk/logger.h" +#ifndef STANDALONE #include "asterisk/strings.h" +#include "asterisk/channel.h" +#endif enum valtype { AST_EXPR_number, AST_EXPR_numeric_string, AST_EXPR_string @@ -1455,6 +1476,7 @@ struct parse_io char *string; struct val *val; yyscan_t scanner; + struct ast_channel *chan; }; void ast_yyset_column(int column_no, yyscan_t yyscanner); @@ -1462,7 +1484,7 @@ int ast_yyget_column(yyscan_t yyscanner); static int curlycount = 0; static char *expr2_token_subst(char *mess); -#line 1466 "ast_expr2f.c" +#line 1488 "ast_expr2f.c" #define INITIAL 0 #define var 1 @@ -1685,10 +1707,10 @@ YY_DECL register int yy_act; struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; -#line 121 "ast_expr2.fl" +#line 125 "ast_expr2.fl" -#line 1692 "ast_expr2f.c" +#line 1714 "ast_expr2f.c" yylval = yylval_param; @@ -1771,122 +1793,127 @@ do_action: /* This label is used only to access EOF actions. */ case 1: YY_RULE_SETUP -#line 123 "ast_expr2.fl" +#line 127 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_OR;} YY_BREAK case 2: YY_RULE_SETUP -#line 124 "ast_expr2.fl" +#line 128 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_AND;} YY_BREAK case 3: YY_RULE_SETUP -#line 125 "ast_expr2.fl" +#line 129 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_EQ;} YY_BREAK case 4: YY_RULE_SETUP -#line 126 "ast_expr2.fl" +#line 130 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_OR;} YY_BREAK case 5: YY_RULE_SETUP -#line 127 "ast_expr2.fl" +#line 131 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_AND;} YY_BREAK case 6: YY_RULE_SETUP -#line 128 "ast_expr2.fl" +#line 132 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_EQ;} YY_BREAK case 7: YY_RULE_SETUP -#line 129 "ast_expr2.fl" +#line 133 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_EQTILDE;} YY_BREAK case 8: YY_RULE_SETUP -#line 130 "ast_expr2.fl" +#line 134 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_GT;} YY_BREAK case 9: YY_RULE_SETUP -#line 131 "ast_expr2.fl" +#line 135 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_LT;} YY_BREAK case 10: YY_RULE_SETUP -#line 132 "ast_expr2.fl" +#line 136 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_GE;} YY_BREAK case 11: YY_RULE_SETUP -#line 133 "ast_expr2.fl" +#line 137 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_LE;} YY_BREAK case 12: YY_RULE_SETUP -#line 134 "ast_expr2.fl" +#line 138 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_NE;} YY_BREAK case 13: YY_RULE_SETUP -#line 135 "ast_expr2.fl" +#line 139 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOK_PLUS;} YY_BREAK case 14: YY_RULE_SETUP -#line 136 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_MINUS;} +#line 140 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_COMMA;} YY_BREAK case 15: YY_RULE_SETUP -#line 137 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_MULT;} +#line 141 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_MINUS;} YY_BREAK case 16: YY_RULE_SETUP -#line 138 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_DIV;} +#line 142 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_MULT;} YY_BREAK case 17: YY_RULE_SETUP -#line 139 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_MOD;} +#line 143 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_DIV;} YY_BREAK case 18: YY_RULE_SETUP -#line 140 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_COND;} +#line 144 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_MOD;} YY_BREAK case 19: YY_RULE_SETUP -#line 141 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_COMPL;} +#line 145 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_COND;} YY_BREAK case 20: YY_RULE_SETUP -#line 142 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_COLON;} +#line 146 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_COMPL;} YY_BREAK case 21: YY_RULE_SETUP -#line 143 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;} +#line 147 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_COLON;} YY_BREAK case 22: YY_RULE_SETUP -#line 144 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_LP;} +#line 148 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;} YY_BREAK case 23: YY_RULE_SETUP -#line 145 "ast_expr2.fl" -{ SET_COLUMNS; SET_STRING; return TOK_RP;} +#line 149 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_LP;} YY_BREAK case 24: YY_RULE_SETUP -#line 146 "ast_expr2.fl" +#line 150 "ast_expr2.fl" +{ SET_COLUMNS; SET_STRING; return TOK_RP;} + YY_BREAK +case 25: +YY_RULE_SETUP +#line 151 "ast_expr2.fl" { /* gather the contents of ${} expressions, with trailing stuff, * into a single TOKEN. @@ -1897,26 +1924,26 @@ YY_RULE_SETUP yymore(); } YY_BREAK -case 25: +case 26: YY_RULE_SETUP -#line 156 "ast_expr2.fl" +#line 161 "ast_expr2.fl" {} YY_BREAK -case 26: -/* rule 26 can match eol */ +case 27: +/* rule 27 can match eol */ YY_RULE_SETUP -#line 157 "ast_expr2.fl" +#line 162 "ast_expr2.fl" {SET_COLUMNS; SET_STRING; return TOKEN;} YY_BREAK -case 27: -/* rule 27 can match eol */ +case 28: +/* rule 28 can match eol */ YY_RULE_SETUP -#line 159 "ast_expr2.fl" +#line 164 "ast_expr2.fl" {/* what to do with eol */} YY_BREAK -case 28: +case 29: YY_RULE_SETUP -#line 160 "ast_expr2.fl" +#line 165 "ast_expr2.fl" { SET_COLUMNS; /* the original behavior of the expression parser was @@ -1926,19 +1953,19 @@ YY_RULE_SETUP return TOKEN; } YY_BREAK -case 29: +case 30: YY_RULE_SETUP -#line 169 "ast_expr2.fl" +#line 174 "ast_expr2.fl" { SET_COLUMNS; SET_STRING; return TOKEN; } YY_BREAK -case 30: -/* rule 30 can match eol */ +case 31: +/* rule 31 can match eol */ YY_RULE_SETUP -#line 176 "ast_expr2.fl" +#line 181 "ast_expr2.fl" { curlycount--; if (curlycount < 0) { @@ -1949,18 +1976,18 @@ YY_RULE_SETUP } } YY_BREAK -case 31: -/* rule 31 can match eol */ +case 32: +/* rule 32 can match eol */ YY_RULE_SETUP -#line 186 "ast_expr2.fl" +#line 191 "ast_expr2.fl" { curlycount++; yymore(); } YY_BREAK -case 32: +case 33: YY_RULE_SETUP -#line 192 "ast_expr2.fl" +#line 197 "ast_expr2.fl" { BEGIN(0); SET_COLUMNS; @@ -1968,10 +1995,10 @@ YY_RULE_SETUP return TOKEN; } YY_BREAK -case 33: -/* rule 33 can match eol */ +case 34: +/* rule 34 can match eol */ YY_RULE_SETUP -#line 199 "ast_expr2.fl" +#line 204 "ast_expr2.fl" { char c = yytext[yyleng-1]; BEGIN(0); @@ -1981,9 +2008,9 @@ YY_RULE_SETUP return TOKEN; } YY_BREAK -case 34: +case 35: YY_RULE_SETUP -#line 208 "ast_expr2.fl" +#line 213 "ast_expr2.fl" { curlycount = 0; BEGIN(var); @@ -1991,7 +2018,7 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(trail): -#line 214 "ast_expr2.fl" +#line 219 "ast_expr2.fl" { BEGIN(0); SET_COLUMNS; @@ -2000,12 +2027,12 @@ case YY_STATE_EOF(trail): /*actually, if an expr is only a variable ref, this could happen a LOT */ } YY_BREAK -case 35: +case 36: YY_RULE_SETUP -#line 222 "ast_expr2.fl" +#line 227 "ast_expr2.fl" ECHO; YY_BREAK -#line 2009 "ast_expr2f.c" +#line 2036 "ast_expr2f.c" case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(var): yyterminate(); @@ -3138,7 +3165,7 @@ void ast_yyfree (void * ptr , yyscan_t yyscanner) #undef YY_DECL_IS_OURS #undef YY_DECL #endif -#line 222 "ast_expr2.fl" +#line 227 "ast_expr2.fl" @@ -3151,13 +3178,14 @@ void ast_yyfree (void * ptr , yyscan_t yyscanner) int ast_yyparse(void *); /* need to/should define this prototype for the call to yyparse */ int ast_yyerror(const char *, YYLTYPE *, struct parse_io *); /* likewise */ -int ast_expr(char *expr, char *buf, int length) +int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan) { struct parse_io io; int return_value = 0; memset(&io, 0, sizeof(io)); io.string = expr; /* to pass to the error routine */ + io.chan = chan; ast_yylex_init(&io.scanner); @@ -3231,6 +3259,7 @@ static char *expr2_token_equivs1[] = "TOK_COMPL", "TOK_COLON", "TOK_EQTILDE", + "TOK_COMMA", "TOK_RP", "TOK_LP" }; @@ -3256,6 +3285,7 @@ static char *expr2_token_equivs2[] = "!", ":", "=~", + ",", ")", "(" }; diff --git a/main/pbx.c b/main/pbx.c index 440e58479..44f507a01 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -1677,7 +1677,7 @@ static void pbx_substitute_variables_helper_full(struct ast_channel *c, struct v vars = var; } - length = ast_expr(vars, cp2, count); + length = ast_expr(vars, cp2, count, c); if (length) { ast_debug(1, "Expression result is '%s'\n", cp2); diff --git a/pbx/pbx_ael.c b/pbx/pbx_ael.c index d5d58b316..243193eee 100644 --- a/pbx/pbx_ael.c +++ b/pbx/pbx_ael.c @@ -90,7 +90,7 @@ void check_pval_item(pval *item, struct argapp *apps, int in_globals); void check_switch_expr(pval *item, struct argapp *apps); void ast_expr_register_extra_error_info(char *errmsg); void ast_expr_clear_extra_error_info(void); -int ast_expr(char *expr, char *buf, int length); +int ast_expr(char *expr, char *buf, int length,struct ast_channel *chan); struct pval *find_macro(char *name); struct pval *find_context(char *name); struct pval *find_context(char *name); @@ -2640,7 +2640,7 @@ void check_pval_item(pval *item, struct argapp *apps, int in_globals) if( !in_globals ) { /* don't check stuff inside the globals context; no wrapping in $[ ] there... */ snprintf(errmsg,sizeof(errmsg), "file %s, line %d, columns %d-%d, variable declaration expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.val); ast_expr_register_extra_error_info(errmsg); - ast_expr(item->u2.val, expr_output, sizeof(expr_output)); + ast_expr(item->u2.val, expr_output, sizeof(expr_output),NULL); ast_expr_clear_extra_error_info(); if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) { ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", @@ -2686,12 +2686,12 @@ void check_pval_item(pval *item, struct argapp *apps, int in_globals) strp = strchr(item->u1.for_init, '='); if (strp) { - ast_expr(strp+1, expr_output, sizeof(expr_output)); + ast_expr(strp+1, expr_output, sizeof(expr_output),NULL); } - ast_expr(item->u2.for_test, expr_output, sizeof(expr_output)); + ast_expr(item->u2.for_test, expr_output, sizeof(expr_output),NULL); strp = strchr(item->u3.for_inc, '='); if (strp) { - ast_expr(strp+1, expr_output, sizeof(expr_output)); + ast_expr(strp+1, expr_output, sizeof(expr_output),NULL); } if ( strpbrk(item->u2.for_test,"~!-+<>=*/&^") && !strstr(item->u2.for_test,"${") ) { ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", @@ -2717,7 +2717,7 @@ void check_pval_item(pval *item, struct argapp *apps, int in_globals) */ snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, while expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str); ast_expr_register_extra_error_info(errmsg); - ast_expr(item->u1.str, expr_output, sizeof(expr_output)); + ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL); ast_expr_clear_extra_error_info(); if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", @@ -2754,7 +2754,7 @@ void check_pval_item(pval *item, struct argapp *apps, int in_globals) */ snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, random expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str); ast_expr_register_extra_error_info(errmsg); - ast_expr(item->u1.str, expr_output, sizeof(expr_output)); + ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL); ast_expr_clear_extra_error_info(); if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n", @@ -2797,7 +2797,7 @@ void check_pval_item(pval *item, struct argapp *apps, int in_globals) */ snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, if expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str); ast_expr_register_extra_error_info(errmsg); - ast_expr(item->u1.str, expr_output, sizeof(expr_output)); + ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL); ast_expr_clear_extra_error_info(); if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n", diff --git a/utils/ael_main.c b/utils/ael_main.c index f32e0b5ec..9cd0bfd08 100644 --- a/utils/ael_main.c +++ b/utils/ael_main.c @@ -110,6 +110,15 @@ struct ast_app *pbx_findapp(const char *app) return (struct ast_app*)1; /* so as not to trigger an error */ } +struct ast_custom_function *ast_custom_function_find(const char *name); + + +struct ast_custom_function *ast_custom_function_find(const char *name) +{ + return 0; /* in "standalone" mode, functions are just not avail */ +} + + void ast_add_profile(void) { if (!no_comp) diff --git a/utils/check_expr.c b/utils/check_expr.c index df74b7150..7f0378b16 100644 --- a/utils/check_expr.c +++ b/utils/check_expr.c @@ -161,6 +161,13 @@ unsigned int check_expr(char* buffer, char* error_report) return warn_found; } +struct ast_custom_function *ast_custom_function_find(const char *name); + +struct ast_custom_function *ast_custom_function_find(const char *name) +{ + return 0; +} + int check_eval(char *buffer, char *error_report) { char *cp, *ep; @@ -221,7 +228,7 @@ int check_eval(char *buffer, char *error_report) *ep++ = 0; /* now, run the test */ - result = ast_expr(evalbuf, s, sizeof(s)); + result = ast_expr(evalbuf, s, sizeof(s),NULL); if (result) { sprintf(error_report,"line %d, evaluation of $[ %s ] result: %s\n", global_lineno, evalbuf, s); return 1; diff --git a/utils/expr2.testinput b/utils/expr2.testinput index 0dfc862bc..9e1532b27 100644 --- a/utils/expr2.testinput +++ b/utils/expr2.testinput @@ -93,4 +93,34 @@ something 2.1+4.2 1.500003+1.4999999999999898989898989898989898989889898 1/4 - +2.3 + COS(3.141592653) +REMAINDER(13,3) +2.3 + SIN(3.1415823) +TAN(45) + 2.3 +POW(10.0,4.0) +SQRT(4) +SQRT(2) +FLOOR(2.4) +FLOOR(2.6) +CEIL(2.4) +CEIL(2.6) +ROUND(2.4) +ROUND(2.5) +ROUND(2.6) +RINT(2.4) +RINT(2.5) +RINT(2.6) +TRUNC(2.4) +TRUNC(2.5) +TRUNC(2.6) +EXP(1.0) +EXP2(1.0) +LOG(10) +LOG2(10) +LOG10(10) +ATAN2(4,5) +ACOS(12) +ASIN(1) +ATAN(10) +SQRT(2)*SQRT(2) +MATH(3*9) |