📄 channelvariables.tex
字号:
\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 makethe same results possible, some rounding and integer truncation functions have beenadded 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 thatthe arguments to these functions must be specified with a comma. If you try to callthe MATH function, for example, and try to say 3 + MATH(7*8), the expression parser willevaluate 7*8 for you into 56, and the MATH function will most likely complain that itsinput 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, wedon't want to preclude it, either.Here is a list of the 'builtin' functions in Expr2. All other dialplan functionsare available by simply calling them (read-only). In other words, you don't need tosurround 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{astlisting}\begin{verbatim} "One Thousand Five Hundred" =~ "(T[^ ]+)" returns: Thousand "One Thousand Five Hundred" =~ "T[^ ]+" returns: 8 "One Thousand Five Hundred" : "T[^ ]+" returns: 0 "8015551212" : "(...)" returns: 801 "3075551212":"...(...)" returns: 555 ! "One Thousand Five Hundred" =~ "T[^ ]+" returns: 0 (because it applies to the string, which is non-null, which it turns to "0", and then looks for the pattern in the "0", and doesn't find it) !( "One Thousand Five Hundred" : "T[^ ]+" ) returns: 1 (because the string doesn't start with a word starting with T, so the match evals to 0, and the ! operator inverts it to 1 ). 2 + 8 / 2 returns 6. (because of operator precedence; the division is done first, then the addition). 2+8/2 returns 6. Spaces aren't necessary.(2+8)/2 returns 5, of course.(3+8)/2 returns 5.5 now.TRUNC((3+8)/2) returns 5.FLOOR(2.5) returns 2FLOOR(-2.5) returns -3CEIL(2.5) returns 3.CEIL(-2.5) returns -2.ROUND(2.5) returns 3.ROUND(3.5) returns 4.ROUND(-2.5) returns -3RINT(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.\end{verbatim}\end{astlisting}Of course, all of the above examples use constants, but would work thesame if any of the numeric or string constants were replaced with avariable reference \$\{CALLERID(num)\}, for instance.\subsection{Numbers Vs. Strings}Tokens consisting only of numbers are converted to 'long double' if possible, whichare from 80 bits to 128 bits depending on the OS, compiler, and hardware.This means that overflows can occur when thenumbers get above 18 digits (depending on the number of bits involved). Warnings will appear in the logs in thiscase.\subsection{Conditionals}There is one conditional application - the conditional goto :\begin{astlisting}\begin{verbatim} exten => 1,2,GotoIf(condition?label1:label2)\end{verbatim}\end{astlisting}If condition is true go to label1, else go to label2. Labels are interpretedexactly as in the normal goto command."condition" is just a string. If the string is empty or "0", the conditionis considered to be false, if it's anything else, the condition is true.This is designed to be used together with the expression syntax describedabove, eg :\begin{astlisting}\begin{verbatim} exten => 1,2,GotoIf($[${CALLERID(all)} = 123456]?2,1:3,1)\end{verbatim}\end{astlisting}Example of use :\begin{astlisting}\begin{verbatim}exten => s,2,Set(vara=1)exten => s,3,Set(varb=$[${vara} + 2])exten => s,4,Set(varc=$[${varb} * 2])exten => s,5,GotoIf($[${varc} = 6]?99,1:s,6)\end{verbatim}\end{astlisting}\subsection{Parse Errors}Syntax errors are now output with 3 lines.If the extensions.conf file contains a line like:\begin{astlisting}\begin{verbatim}exten => s,6,GotoIf($[ "${CALLERID(num)}" = "3071234567" & & "${CALLERID(name)}" : "Privacy Manager" ]?callerid-liar,s,1:s,7)\end{verbatim}\end{astlisting}You may see an error in \path{/var/log/asterisk/messages} like this:\begin{astlisting}\begin{verbatim}Jul 15 21:27:49 WARNING[1251240752]: ast_yyerror(): syntax error: parse error, unexpected TOK_AND, expecting TOK_MINUS or TOK_LP or TOKEN; Input:"3072312154" = "3071234567" & & "Steves Extension" : "Privacy Manager" ^\end{verbatim}\end{astlisting}The log line tells you that a syntax error was encountered. It nowalso tells you (in grand standard bison format) that it hit an "AND"(\&) token unexpectedly, and that was hoping for for a MINUS (-), LP(left parenthesis), or a plain token (a string or number).The next line shows the evaluated expression, and the line afterthat, the position of the parser in the expression when it became confused,marked with the "\^" character.\subsection{NULL Strings}Testing to see if a string is null can be done in one of two different ways:\begin{astlisting}\begin{verbatim} exten => _XX.,1,GotoIf($["${calledid}" != ""]?3) or exten => _XX.,1,GotoIf($[foo${calledid} != foo]?3)\end{verbatim}\end{astlisting}The second example above is the way suggested by the WIKI. It willwork as long as there are no spaces in the evaluated value.The first way should work in all cases, and indeed, might nowbe the safest way to handle this situation.\subsection{Warning}If you need to do complicated things with strings, asterisk expressionsis most likely NOT the best way to go about it. AGI scripts are anexcellent option to this need, and make available the full power ofwhatever language you desire, be it Perl, C, C++, Cobol, RPG, Java,Snobol, PL/I, Scheme, Common Lisp, Shell scripts, Tcl, Forth, Modula,Pascal, APL, assembler, etc.\subsection{Incompatabilities}The asterisk expression parser has undergone some evolution. It is hopedthat the changes will be viewed as positive.The "original" expression parser had a simple, hand-written scanner,and a simple bison grammar. This was upgraded to a more involved bisongrammar, and a hand-written scanner upgraded to allow extra spaces,and to generate better error diagnostics. This upgrade required bison1.85, and part of the user community felt the pain of having toupgrade their bison version.The next upgrade included new bison and flex input files, and the makefilewas upgraded to detect current version of both flex and bison, conditionallycompiling and linking the new files if the versions of flex and bison wouldallow it.If you have not touched your extensions.conf files in a year or so, theabove upgrades may cause you some heartburn in certain circumstances, asseveral changes have been made, and these will affect asterisk's behavior onlegacy extension.conf constructs. The changes have been engineeredto minimize these conflicts, but there are bound to be problems.The following list gives some (and most likely, not all) of areasof possible concern with "legacy" extension.conf files:\begin{enumerate}\item Tokens separated by space(s). Previously, tokens were separated by spaces. Thus, ' 1 + 1 ' would evaluate to the value '2', but '1+1' would evaluate to the string '1+1'. If this behavior was depended on, then the expression evaluation will break. '1+1' will now evaluate to '2', and something is not going to work right. To keep such strings from being evaluated, simply wrap them in double quotes: ' "1+1" '\item The colon operator. In versions previous to double quoting, the colon operator takes the right hand string, and using it as a regex pattern, looks for it in the left hand string. It is given an implicit \^ operator at the beginning, meaning the pattern will match only at the beginning of the left hand string. If the pattern or the matching string had double quotes around them, these could get in the way of the pattern match. Now, the wrapping double quotes are stripped from both the pattern and the left hand string before applying the pattern. This was done because it recognized that the new way of scanning the expression doesn't use spaces to separate tokens, and the average regex expression is full of operators that the scanner will recognize as expression operators. Thus, unless the pattern is wrapped in double quotes, there will be trouble. For instance, \$\{VAR1\} : (Who$|$What*)+ may have have worked before, but unless you wrap the pattern in double quotes now, look out for trouble! This is better: "\$\{VAR1\}" : "(Who$|$What*)+" and should work as previous.\item Variables and Double Quotes Before these changes, if a variable's value contained one or more double quotes, it was no reason for concern. It is now!\item LE, GE, NE operators removed. The code supported these operators, but they were not documented. The symbolic operators, $<$=, $>$=, and != should be used instead.\item Added the unary '-' operator. So you can 3+ -4 and get -1.\item Added the unary '!' operator, which is a logical complement. Basically, if the string or number is null, empty, or '0', a '1' is returned. Otherwise a '0' is returned.\item Added the '=~' operator, just in case someone is just looking for match anywhere in the string. The only diff with the ':' is that match doesn't have to be anchored to the beginning of the string.\item Added the conditional operator 'expr1 ? true\_expr : false\_expr' First, all 3 exprs are evaluated, and if expr1 is false, the 'false\_expr' is returned as the result. See above for details.\item Unary operators '-' and '!' were made right associative.\end{enumerate}\subsection{Debugging Hints}There are two utilities you can build to help debug the \$[ ] inyour extensions.conf file.The first, and most simplistic, is to issue the command:\begin{astlisting}\begin{verbatim}make testexpr2\end{verbatim}\end{astlisting}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -