[asterisk-commits] murf: trunk r73449 - in /trunk: ./ doc/tex/ include/asterisk/ main/ pbx/ utils/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Jul 5 13:15:23 CDT 2007


Author: murf
Date: Thu Jul  5 13:15:22 2007
New Revision: 73449

URL: http://svn.digium.com/view/asterisk?view=rev&rev=73449
Log:
In regards to changes for 9508, expr2 system choking on floating point numbers, I'm adding this update to round out (no pun intended) and make this FP-capable version of the Expr2 stuff interoperate better with previous integer-only usage, by providing Functions syntax, with 20 builtin functions for floating pt to integer conversions, and some general floating point math routines that might commonly be used also. Along with this, I made it so if a function was not a builtin, it will try and find it in the ast_custom_function list, and if found, execute it and collect the results. Thus, you can call system functions like CDR(), CHANNEL(), etc, from within $\[..\] exprs, without having to wrap them in $\{...\} (curly brace) notation. Did a valgrind on the standalone and made sure there's no mem leaks. Looks good. Updated the docs, too.

Modified:
    trunk/UPGRADE.txt
    trunk/doc/tex/channelvariables.tex
    trunk/include/asterisk/ast_expr.h
    trunk/main/ast_expr2.c
    trunk/main/ast_expr2.fl
    trunk/main/ast_expr2.h
    trunk/main/ast_expr2.y
    trunk/main/ast_expr2f.c
    trunk/main/pbx.c
    trunk/pbx/pbx_ael.c
    trunk/utils/ael_main.c
    trunk/utils/check_expr.c
    trunk/utils/expr2.testinput

Modified: trunk/UPGRADE.txt
URL: http://svn.digium.com/view/asterisk/trunk/UPGRADE.txt?view=diff&rev=73449&r1=73448&r2=73449
==============================================================================
--- trunk/UPGRADE.txt (original)
+++ trunk/UPGRADE.txt Thu Jul  5 13:15:22 2007
@@ -29,6 +29,11 @@
   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:
 

Modified: trunk/doc/tex/channelvariables.tex
URL: http://svn.digium.com/view/asterisk/trunk/doc/tex/channelvariables.tex?view=diff&rev=73449&r1=73448&r2=73449
==============================================================================
--- trunk/doc/tex/channelvariables.tex (original)
+++ trunk/doc/tex/channelvariables.tex Thu Jul  5 13:15:22 2007
@@ -207,19 +207,19 @@
              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 @@
 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 @@
 
 (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 @@
 
 \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}

Modified: trunk/include/asterisk/ast_expr.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/ast_expr.h?view=diff&rev=73449&r1=73448&r2=73449
==============================================================================
--- trunk/include/asterisk/ast_expr.h (original)
+++ trunk/include/asterisk/ast_expr.h Thu Jul  5 13:15:22 2007
@@ -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)
 }

Modified: trunk/main/ast_expr2.c
URL: http://svn.digium.com/view/asterisk/trunk/main/ast_expr2.c?view=diff&rev=73449&r1=73448&r2=73449
==============================================================================
--- trunk/main/ast_expr2.c (original)
+++ trunk/main/ast_expr2.c Thu Jul  5 13:15:22 2007
@@ -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 @@
 	} 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 @@
 	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_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 @@
 
 #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 @@
 
 
 /* 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 @@
 #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 @@
        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 @@
    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 @@
    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 @@
 {
        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 @@
    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 @@
 #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,
+       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,    25,     0,    26,    27,    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,
-      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
+      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,
+       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,    18,    -1,    20,    21,     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,
-       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
+      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 @@
 
   switch (yytype)
     {
-      case 3: /* "TOK_COLONCOLON" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1275 "ast_expr2.c"
-	break;
-      case 4: /* "TOK_COND" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1280 "ast_expr2.c"
-	break;
-      case 5: /* "TOK_OR" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1285 "ast_expr2.c"
-	break;
-      case 6: /* "TOK_AND" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1290 "ast_expr2.c"
-	break;
-      case 7: /* "TOK_NE" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1295 "ast_expr2.c"
-	break;
-      case 8: /* "TOK_LE" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1300 "ast_expr2.c"
-	break;
-      case 9: /* "TOK_GE" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1305 "ast_expr2.c"
-	break;
-      case 10: /* "TOK_LT" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1310 "ast_expr2.c"
-	break;
-      case 11: /* "TOK_GT" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1315 "ast_expr2.c"
-	break;
-      case 12: /* "TOK_EQ" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1320 "ast_expr2.c"
-	break;
-      case 13: /* "TOK_MINUS" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1325 "ast_expr2.c"
-	break;
-      case 14: /* "TOK_PLUS" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1330 "ast_expr2.c"
-	break;
-      case 15: /* "TOK_MOD" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1335 "ast_expr2.c"
-	break;
-      case 16: /* "TOK_DIV" */
-#line 187 "ast_expr2.y"
-	{  free_value((yyvaluep->val)); };
-#line 1340 "ast_expr2.c"
-	break;
-      case 17: /* "TOK_MULT" */
-#line 187 "ast_expr2.y"
+      case 4: /* "TOK_COLONCOLON" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1345 "ast_expr2.c"
 	break;
-      case 18: /* "TOK_COMPL" */
-#line 187 "ast_expr2.y"
+      case 5: /* "TOK_COND" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1350 "ast_expr2.c"
 	break;
-      case 19: /* "TOK_EQTILDE" */
-#line 187 "ast_expr2.y"
+      case 6: /* "TOK_OR" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1355 "ast_expr2.c"
 	break;
-      case 20: /* "TOK_COLON" */
-#line 187 "ast_expr2.y"
+      case 7: /* "TOK_AND" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1360 "ast_expr2.c"
 	break;
-      case 21: /* "TOK_LP" */
-#line 187 "ast_expr2.y"
+      case 8: /* "TOK_NE" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1365 "ast_expr2.c"
 	break;
-      case 22: /* "TOK_RP" */
-#line 187 "ast_expr2.y"
+      case 9: /* "TOK_LE" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1370 "ast_expr2.c"
 	break;
-      case 23: /* "TOKEN" */
-#line 187 "ast_expr2.y"
+      case 10: /* "TOK_GE" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1375 "ast_expr2.c"
 	break;
-      case 26: /* "expr" */
-#line 187 "ast_expr2.y"
+      case 11: /* "TOK_LT" */
+#line 251 "ast_expr2.y"
 	{  free_value((yyvaluep->val)); };
 #line 1380 "ast_expr2.c"
+	break;
+      case 12: /* "TOK_GT" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1385 "ast_expr2.c"
+	break;
+      case 13: /* "TOK_EQ" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1390 "ast_expr2.c"
+	break;
+      case 14: /* "TOK_MINUS" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1395 "ast_expr2.c"
+	break;
+      case 15: /* "TOK_PLUS" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1400 "ast_expr2.c"
+	break;
+      case 16: /* "TOK_MOD" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1405 "ast_expr2.c"
+	break;
+      case 17: /* "TOK_DIV" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1410 "ast_expr2.c"
+	break;
+      case 18: /* "TOK_MULT" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1415 "ast_expr2.c"
+	break;
+      case 19: /* "TOK_COMPL" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1420 "ast_expr2.c"
+	break;
+      case 20: /* "TOK_EQTILDE" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1425 "ast_expr2.c"
+	break;
+      case 21: /* "TOK_COLON" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1430 "ast_expr2.c"
+	break;
+      case 22: /* "TOK_LP" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1435 "ast_expr2.c"
+	break;
+      case 23: /* "TOK_RP" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1440 "ast_expr2.c"
+	break;
+      case 24: /* "TOKEN" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1445 "ast_expr2.c"
+	break;
+      case 28: /* "expr" */
+#line 251 "ast_expr2.y"
+	{  free_value((yyvaluep->val)); };
+#line 1450 "ast_expr2.c"
 	break;
 
       default:
@@ -1699,7 +1769,7 @@
   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 @@
     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 @@
     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)); 

[... 2781 lines stripped ...]



More information about the asterisk-commits mailing list