ael.tex

来自「asterisk 是一个很有知名度开源软件」· TEX 代码 · 共 1,306 行 · 第 1/3 页

TEX
1,306
字号
    }    _777X => {         switch (${EXTEN}) {              case 7771:                   NoOp(You called 7771!);                   break;              case 7772:                   NoOp(You called 7772!);                   break;              case 7773:                   NoOp(You called 7773!);                   // fall thru-              pattern 777[4-9]:                    NoOp(You called 777 something!);              default:                   NoOp(In the default clause!);         }    }}\end{verbatim}\end{astlisting}NOTE: The conditional expression in if() statements (the      "\$\{DIALSTATUS\}" = "BUSY" above) is wrapped by the compiler in      \$[] for evaluation.NOTE: Neither the switch nor case values are wrapped in \$[ ]; they can      be constants, or \$\{var\} type references only.NOTE: AEL generates each case as a separate extension. case clauses      with no terminating 'break', or 'goto', have a goto inserted, to      the next clause, which creates a 'fall thru' effect.NOTE: AEL introduces the ifTime keyword/statement, which works just      like the if() statement, but the expression is a time value,      exactly like that used by the application GotoIfTime(). See      Asterisk cmd GotoIfTimeNOTE: The pattern statement makes sure the new extension that is      created has an '\_' preceding it to make sure asterisk recognizes      the extension name as a pattern.NOTE: Every character enclosed by the switch expression's parenthesis      are included verbatim in the labels generated. So watch out for      spaces!NOTE: NEW: Previous to version 0.13, the random statement used the      "Random()" application, which has been deprecated. It now uses      the RAND() function instead, in the GotoIf application.\subsection{Break, Continue, and Return}Three keywords, break, continue, and return, are included in thesyntax to provide flow of control to loops, and switches.The break can be used in switches and loops, to jump to the end of theloop or switch.The continue can be used in loops (while and for) to immediately jumpto the end of the loop. In the case of a for loop, the increment andtest will then be performed. In the case of the while loop, thecontinue will jump to the test at the top of the loop.The return keyword will cause an immediate jump to the end of thecontext, or macro, and can be used anywhere.\subsection{goto, jump, and labels}This is an example of how to do a goto in AEL.\begin{astlisting}\begin{verbatim}context gotoexample {    s => {begin:         NoOp(Infinite Loop!  yay!);         Wait(1);         goto begin;    // go to label in same extension    }    3 => {            goto s,begin;   // go to label in different extension     }     4 => {            goto gotoexample,s,begin;  // overkill go to label in same context     }}context gotoexample2 {     s =>  {   end:           goto gotoexample,s,begin;   // go to label in different context     }}\end{verbatim}\end{astlisting}You can use the special label of "1" in the goto and jumpstatements. It means the "first" statement in the extension. I wouldnot advise trying to use numeric labels other than "1" in goto's orjumps, nor would I advise declaring a "1" label anywhere! As a matterof fact, it would be bad form to declare a numeric label, and it mightconflict with the priority numbers used internally by asterisk.The syntax of the jump statement is: jumpextension[,priority][@context] If priority is absent, it defaults to"1". If context is not present, it is assumed to be the same as thatwhich contains the "jump".\begin{astlisting}\begin{verbatim}context gotoexample {    s => {begin:         NoOp(Infinite Loop!  yay!);         Wait(1);         jump s;    // go to first extension in same extension    }    3 => {            jump s,begin;   // go to label in different extension     }     4 => {            jump s,begin@gotoexample;  // overkill go to label in same context     }}context gotoexample2 {     s =>  {   end:           jump s@gotoexample;   // go to label in different context     }}\end{verbatim}\end{astlisting}NOTE: goto labels follow the same requirements as the Goto()      application, except the last value has to be a label. If the      label does not exist, you will have run-time errors. If the      label exists, but in a different extension, you have to specify      both the extension name and label in the goto, as in: goto s,z;      if the label is in a different context, you specify      context,extension,label. There is a note about using goto's in a      switch statement below...NOTE  AEL introduces the special label "1", which is the beginning      context number for most extensions.\subsection{Macros}A macro is defined in its own block like this. The arguments to themacro are specified with the name of the macro. They are then referredto by that same name. A catch block can be specified to catch specialextensions.\begin{astlisting}\begin{verbatim}macro std-exten( ext , dev ) {       Dial(${dev}/${ext},20);       switch(${DIALSTATUS) {       case BUSY:               Voicemail(${ext},b);               break;       default:               Voicemail(${ext},u);       }       catch a {               VoiceMailMain(${ext});               return;       }}\end{verbatim}\end{astlisting}A macro is then called by preceding the macro name with anampersand. Empty arguments can be passed simply with nothing betweencomments(0.11).\begin{astlisting}\begin{verbatim}context example {    _5XXX => &std-exten(${EXTEN}, "IAX2");    _6XXX => &std-exten(, "IAX2");    _7XXX => &std-exten(${EXTEN},);    _8XXX => &std-exten(,);}\end{verbatim}\end{astlisting}\section{Examples}\begin{astlisting}\begin{verbatim}context demo {    s => {         Wait(1);         Answer();         TIMEOUT(digit)=5;         TIMEOUT(response)=10;restart:         Background(demo-congrats);instructions:         for (x=0; ${x} < 3; x=${x} + 1) {              Background(demo-instruct);              WaitExten();         }    }    2 => {         Background(demo-moreinfo);         goto s,instructions;    }    3 => {         LANGUAGE()=fr;         goto s,restart;    }    500 => {         Playback(demo-abouttotry);         Dial(IAX2/guest@misery.digium.com);         Playback(demo-nogo);         goto s,instructions;    }    600 => {         Playback(demo-echotest);         Echo();         Playback(demo-echodone);         goto s,instructions;    }    # => {hangup:         Playback(demo-thanks);         Hangup();    }    t => goto #,hangup;    i => Playback(invalid);}\end{verbatim}\end{astlisting}\section{Semantic Checks}AEL, after parsing, but before compiling, traverses the dialplantree, and makes several checks:\begin{itemize}    \item Macro calls to non-existent macros.    \item Macro calls to contexts.    \item Macro calls with argument count not matching the definition.    \item application call to macro. (missing the '\&')    \item application calls to "GotoIf", "GotoIfTime", "while",      "endwhile", "Random", and "execIf", will generate a message to      consider converting the call to AEL goto, while, etc. constructs.    \item goto a label in an empty extension.    \item goto a non-existent label, either a within-extension,      within-context, or in a different context, or in any included      contexts. Will even check "sister" context references.    \item All the checks done on the time values in the dial plan, are      done on the time values in the ifTime() and includes times:          o the time range has to have two times separated by a dash;          o the times have to be in range of 0 to 24 hours.          o The weekdays have to match the internal list, if they are provided;          o the day of the month, if provided, must be in range of 1 to 31;          o the month name or names have to match those in the internal list.    \item (0.5) If an expression is wrapped in \$[ ... ], and the compiler      will wrap it again, a warning is issued.    \item (0.5) If an expression had operators (you know,      +,-,*,/,%,!,etc), but no \${ } variables, a warning is      issued. Maybe someone forgot to wrap a variable name?    \item (0.12) check for duplicate context names.    \item (0.12) check for abstract contexts that are not included by any context.    \item (0.13) Issue a warning if a label is a numeric value.\end{itemize}There are a subset of checks that have been removed until the proposedAAL (Asterisk Argument Language) is developed and incorporated into Asterisk.These checks will be:\begin{itemize}    \item (if the application argument analyzer is working: the presence      of the 'j' option is reported as error.    \item if options are specified, that are not available in an      application.    \item if you specify too many arguments to an application.    \item a required argument is not present in an application call.    \item Switch-case using "known" variables that applications set, that      does not cover all the possible values. (a "default" case will      solve this problem. Each "unhandled" value is listed.    \item a Switch construct is used, which is uses a known variable, and      the application that would set that variable is not called in      the same extension. This is a warning only...    \item Calls to applications not in the "applist" database (installed      in \path{/var/lib/asterisk/applist}" on most systems).    \item In an assignment statement, if the assignment is to a function,      the function name used is checked to see if it one of the      currently known functions. A warning is issued if it is not.\end{itemize}\section{Differences with the original version of AEL}\begin{enumerate}   \item The \$[...] expressions have been enhanced to include the ==, $|$$|$,      and \&\& operators. These operators are exactly equivalent to the      =, $|$, and \& operators, respectively. Why? So the C, Java, C++      hackers feel at home here.   \item It is more free-form. The newline character means very little,      and is pulled out of the white-space only for line numbers in      error messages.   \item It generates more error messages -- by this I mean that any      difference between the input and the grammar are reported, by      file, line number, and column.   \item It checks the contents of \$[ ] expressions (or what will end up      being \$[ ] expressions!) for syntax errors. It also does      matching paren/bracket counts.   \item It runs several semantic checks after the parsing is over, but      before the compiling begins, see the list above.   \item It handles \#include "filepath" directives. -- ALMOST      anywhere, in fact. You could easily include a file in a context,      in an extension, or at the root level. Files can be included in      files that are included in files, down to 50 levels of hierarchy...   \item Local Goto's inside Switch statements automatically have the      extension of the location of the switch statement appended to them.   \item A pretty printer function is available within pbx\_ael.so.   \item In the utils directory, two standalone programs are supplied for      debugging AEL files. One is called "aelparse", and it reads in      the \path{/etc/asterisk/extensions.ael} file, and shows the results of      syntax and semantic checking on stdout, and also shows the      results of compilation to stdout. The other is "aelparse1",      which uses the original ael compiler to do the same work,      reading in "\path{/etc/asterisk/extensions.ael}", using the original      'pbx\_ael.so' instead.  \item AEL supports the "jump" statement, and the "pattern" statement      in switch constructs. Hopefully these will be documented in the      AEL README.  \item Added the "return" keyword, which will jump to the end of an      extension/Macro.  \item Added the ifTime ($<$time range$>$$|$$<$days of week$>$$|$$<$days of      month$>$$|$$<$months$>$ ) {} [else {}] construct, which executes much      like an if () statement, but the decision is based on the      current time, and the time spec provided in the ifTime. See the      example above. (Note: all the other time-dependent Applications      can be used via ifTime)  \item Added the optional time spec to the contexts in the includes      construct. See examples above.  \item You don't have to wrap a single "true" statement in curly      braces, as in the original AEL. An "else" is attached to the      closest if. As usual, be careful about nested if statements!      When in doubt, use curlies!  \item Added the syntax [regexten] [hint(channel)] to precede an      extension declaration. See examples above, under      "Extension". The regexten keyword will cause the priorities in      the extension to begin with 2 instead of 1. The hint keyword      will cause its arguments to be inserted in the extension under      the hint priority. They are both optional, of course, but the      order is fixed at the moment-- the regexten must come before the      hint, if they are both present.  \item Empty case/default/pattern statements will "fall thru" as      expected. (0.6)  \item A trailing label in an extension, will automatically have a      NoOp() added, to make sure the label exists in the extension on      Asterisk. (0.6)  \item (0.9) the semicolon is no longer required after a closing brace!      (i.e. "];" ===$>$ "\}". You can have them there if you like, but      they are not necessary. Someday they may be rejected as a syntax      error, maybe.  \item (0.9) the // comments are not recognized and removed in the      spots where expressions are gathered, nor in application call      arguments. You may have to move a comment if you get errors in      existing files.  \item (0.10) the random statement has been added. Syntax: random (      $<$expr$>$ ) $<$lucky-statement$>$ [ else $<$unlucky-statement$>$ ]. The      probability of the lucky-statement getting executed is $<$expr$>$,      which should evaluate to an integer between 0 and 100. If the      $<$lucky-statement$>$ isn't so lucky this time around, then the      $<$unlucky-statement$>$ gets executed, if it is present.\end{enumerate}\section{Hints and Bugs}     The safest way to check for a null strings is to say \$[ "\$\{x\}" =     "" ] The old way would do as shell scripts often do, and append     something on both sides, like this: \$[ \$\{x\}foo = foo ]. The     trouble with the old way, is that, if x contains any spaces, then     problems occur, usually syntax errors. It is better practice and     safer wrap all such tests with double quotes! Also, there are now     some functions that can be used in a variable reference,     ISNULL(), and LEN(), that can be used to test for an empty string:     \$\{ISNULL(\$\{x\})\} or \$[ \$\{LEN(\$\{x\})\} = 0 ].      Assignment vs. Set(). Keep in mind that setting a variable to      value can be done two different ways. If you choose say 'x=y;',      keep in mind that AEL will wrap the right-hand-side with      \$[]. So, when compiled into extension language format, the end      result will be 'Set(x=\$[y])'. If you don't want this effect,      then say "Set(x=y);" instead.\section{The Full Power of AEL}A newcomer to Asterisk will look at the above constructs anddescriptions, and ask, "Where's the string manipulation functions?","Where's all the cool operators that other languages have to offer?",etc.The answer is that the rich capabilities of Asterisk are madeavailable through AEL, via:\begin{itemize}    \item Applications: See Asterisk - documentation of application      commands    \item Functions: Functions were implemented inside \$\{ .. \} variable      references, and supply many useful capabilities.    \item Expressions: An expression evaluation engine handles items      wrapped inside \$[...]. This includes some string manipulation      facilities, arithmetic expressions, etc.    \item Application Gateway Interface: Asterisk can fork external      processes that communicate via pipe. AGI applications can be      written in any language. Very powerful applications can be added      this way.    \item Variables: Channels of communication have variables associated      with them, and asterisk provides some global variables. These can be      manipulated and/or consulted by the above mechanisms.\end{itemize}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?