Merge Steve Murphy's (murf) complete re-implementation of AEL, which is now no longer considered experimental :-)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@22273 f38db490-d61c-443f-a65b-d21fe96a405b
This commit is contained in:
parent
e196b45892
commit
6baa8fbab8
2
CREDITS
2
CREDITS
|
@ -76,7 +76,7 @@ Olle E. Johansson - SIP RFC compliance, documentation and testing, testing, test
|
|||
Steve Kann - new jitter buffer for IAX2
|
||||
stevek@stevek.com
|
||||
Constantine Filin - major contributions to the Asterisk Realtime Architecture
|
||||
Steve Murphy - privacy support
|
||||
Steve Murphy - privacy support, $[ ] parser upgrade, AEL2 parser upgrade
|
||||
Claude Patry - bug fixes, feature enhancements, and bug marshalling
|
||||
cpatry@gmail.com
|
||||
|
||||
|
|
1250
ast_expr2.c
1250
ast_expr2.c
File diff suppressed because it is too large
Load Diff
137
ast_expr2.fl
137
ast_expr2.fl
|
@ -19,7 +19,7 @@
|
|||
|
||||
/*! \file
|
||||
*
|
||||
* \brief Dialplan Expression Parser
|
||||
* \brief Dialplan Expression Lexical Scanner
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -73,6 +73,7 @@ struct parse_io
|
|||
void ast_yyset_column(int column_no, yyscan_t yyscanner);
|
||||
int ast_yyget_column(yyscan_t yyscanner);
|
||||
static int curlycount = 0;
|
||||
static char *expr2_token_subst(char *mess);
|
||||
%}
|
||||
|
||||
%option prefix="ast_yy"
|
||||
|
@ -89,6 +90,10 @@ static int curlycount = 0;
|
|||
\| { SET_COLUMNS; SET_STRING; return TOK_OR;}
|
||||
\& { SET_COLUMNS; SET_STRING; return TOK_AND;}
|
||||
\= { SET_COLUMNS; SET_STRING; return TOK_EQ;}
|
||||
\|\| { SET_COLUMNS; SET_STRING; return TOK_OR;}
|
||||
\&\& { SET_COLUMNS; SET_STRING; return TOK_AND;}
|
||||
\=\= { SET_COLUMNS; SET_STRING; return TOK_EQ;}
|
||||
\=~ { SET_COLUMNS; SET_STRING; return TOK_EQTILDE;}
|
||||
\> { SET_COLUMNS; SET_STRING; return TOK_GT;}
|
||||
\< { SET_COLUMNS; SET_STRING; return TOK_LT;}
|
||||
\>\= { SET_COLUMNS; SET_STRING; return TOK_GE;}
|
||||
|
@ -100,6 +105,7 @@ static int curlycount = 0;
|
|||
\/ { SET_COLUMNS; SET_STRING; return TOK_DIV;}
|
||||
\% { SET_COLUMNS; SET_STRING; return TOK_MOD;}
|
||||
\? { SET_COLUMNS; SET_STRING; return TOK_COND;}
|
||||
\! { SET_COLUMNS; SET_STRING; return TOK_COMPL;}
|
||||
\: { SET_COLUMNS; SET_STRING; return TOK_COLON;}
|
||||
\:\: { SET_COLUMNS; SET_STRING; return TOK_COLONCOLON;}
|
||||
\( { SET_COLUMNS; SET_STRING; return TOK_LP;}
|
||||
|
@ -114,14 +120,15 @@ static int curlycount = 0;
|
|||
[0-9]+ { SET_COLUMNS; /* the original behavior of the expression parser was to bring in numbers as a numeric string */
|
||||
SET_NUMERIC_STRING;
|
||||
return TOKEN;}
|
||||
[a-zA-Z0-9,.';\\_^%$#@!]+ {SET_COLUMNS; SET_STRING; return TOKEN;}
|
||||
|
||||
[a-zA-Z0-9,.';\\_^$#@]+ {SET_COLUMNS; SET_STRING; return TOKEN;}
|
||||
|
||||
<var>[^{}]*\} {curlycount--; if(curlycount < 0){ BEGIN(trail); yymore();} else { yymore();}}
|
||||
<var>[^{}]*\{ {curlycount++; yymore(); }
|
||||
<trail>[^-\t\r \n$():?%/+=*<>!|&]* {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN;}
|
||||
<trail>[-\t\r \n$():?%/+=*<>!|&] {char c = yytext[yyleng-1]; BEGIN(0); unput(c); SET_COLUMNS; SET_STRING; return TOKEN;}
|
||||
<trail>\$\{ {curlycount = 0; BEGIN(var); yymore(); }
|
||||
<trail><<EOF>> {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /* actually, if an expr is only a variable ref, this could happen a LOT */}
|
||||
<trail><<EOF>> {BEGIN(0); SET_COLUMNS; SET_STRING; return TOKEN; /*actually, if an expr is only a variable ref, this could happen a LOT */}
|
||||
|
||||
%%
|
||||
|
||||
|
@ -175,16 +182,129 @@ int ast_expr(char *expr, char *buf, int length)
|
|||
return return_value;
|
||||
}
|
||||
|
||||
|
||||
char extra_error_message[4095];
|
||||
int extra_error_message_supplied = 0;
|
||||
void ast_expr_register_extra_error_info(char *message);
|
||||
void ast_expr_clear_extra_error_info(void);
|
||||
|
||||
void ast_expr_register_extra_error_info(char *message)
|
||||
{
|
||||
extra_error_message_supplied=1;
|
||||
strcpy(extra_error_message, message);
|
||||
}
|
||||
|
||||
void ast_expr_clear_extra_error_info(void)
|
||||
{
|
||||
extra_error_message_supplied=0;
|
||||
extra_error_message[0] = 0;
|
||||
}
|
||||
|
||||
static char *expr2_token_equivs1[] =
|
||||
{
|
||||
"TOKEN",
|
||||
"TOK_COND",
|
||||
"TOK_COLONCOLON",
|
||||
"TOK_OR",
|
||||
"TOK_AND",
|
||||
"TOK_EQ",
|
||||
"TOK_GT",
|
||||
"TOK_LT",
|
||||
"TOK_GE",
|
||||
"TOK_LE",
|
||||
"TOK_NE",
|
||||
"TOK_PLUS",
|
||||
"TOK_MINUS",
|
||||
"TOK_MULT",
|
||||
"TOK_DIV",
|
||||
"TOK_MOD",
|
||||
"TOK_COMPL",
|
||||
"TOK_COLON",
|
||||
"TOK_EQTILDE",
|
||||
"TOK_RP",
|
||||
"TOK_LP"
|
||||
};
|
||||
|
||||
static char *expr2_token_equivs2[] =
|
||||
{
|
||||
"<token>",
|
||||
"?",
|
||||
"::",
|
||||
"|",
|
||||
"&",
|
||||
"=",
|
||||
">",
|
||||
"<",
|
||||
">=",
|
||||
"<=",
|
||||
"!=",
|
||||
"+",
|
||||
"-",
|
||||
"*",
|
||||
"/",
|
||||
"%",
|
||||
"!",
|
||||
":",
|
||||
"=~",
|
||||
")",
|
||||
"("
|
||||
};
|
||||
|
||||
|
||||
static char *expr2_token_subst(char *mess)
|
||||
{
|
||||
/* calc a length, malloc, fill, and return; yyerror had better free it! */
|
||||
int len=0,i;
|
||||
char *p;
|
||||
char *res, *s,*t;
|
||||
int expr2_token_equivs_entries = sizeof(expr2_token_equivs1)/sizeof(char*);
|
||||
|
||||
for (p=mess; *p; p++) {
|
||||
for (i=0; i<expr2_token_equivs_entries; i++) {
|
||||
if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 )
|
||||
{
|
||||
len+=strlen(expr2_token_equivs2[i])+2;
|
||||
p += strlen(expr2_token_equivs1[i])-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
len++;
|
||||
}
|
||||
res = (char*)malloc(len+1);
|
||||
res[0] = 0;
|
||||
s = res;
|
||||
for (p=mess; *p;) {
|
||||
int found = 0;
|
||||
for (i=0; i<expr2_token_equivs_entries; i++) {
|
||||
if ( strncmp(p,expr2_token_equivs1[i],strlen(expr2_token_equivs1[i])) == 0 ) {
|
||||
*s++ = '\'';
|
||||
for (t=expr2_token_equivs2[i]; *t;) {
|
||||
*s++ = *t++;
|
||||
}
|
||||
*s++ = '\'';
|
||||
p += strlen(expr2_token_equivs1[i]);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
*s++ = *p++;
|
||||
}
|
||||
*s++ = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio )
|
||||
{
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)(parseio->scanner);
|
||||
char spacebuf[8000]; /* best safe than sorry */
|
||||
char spacebuf2[8000]; /* best safe than sorry */
|
||||
int i=0;
|
||||
char *s2 = expr2_token_subst((char *)s);
|
||||
spacebuf[0] = 0;
|
||||
|
||||
for(i=0;i< (int)(yytext - YY_CURRENT_BUFFER_LVALUE->yy_ch_buf);i++) spacebuf2[i] = ' '; /* uh... assuming yyg is defined, then I can use the yycolumn macro,
|
||||
which is the same thing as... get this:
|
||||
which is the same thing as... get this:
|
||||
yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]->yy_bs_column
|
||||
I was tempted to just use yy_buf_pos in the STATE, but..., well:
|
||||
a. the yy_buf_pos is the current position in the buffer, which
|
||||
|
@ -199,14 +319,15 @@ int ast_yyerror (const char *s, yyltype *loc, struct parse_io *parseio )
|
|||
|
||||
#ifdef STANDALONE3
|
||||
/* easier to read in the standalone version */
|
||||
printf("ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",
|
||||
s, parseio->string,spacebuf2);
|
||||
printf("ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
|
||||
(extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
|
||||
#else
|
||||
ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n",
|
||||
s, parseio->string,spacebuf2);
|
||||
ast_log(LOG_WARNING,"ast_yyerror(): %s syntax error: %s; Input:\n%s\n%s\n",
|
||||
(extra_error_message_supplied?extra_error_message:""), s2, parseio->string,spacebuf2);
|
||||
#endif
|
||||
#ifndef STANDALONE
|
||||
ast_log(LOG_WARNING,"If you have questions, please refer to doc/channelvariables.txt in the asterisk source.\n");
|
||||
#endif
|
||||
free(s2);
|
||||
return(0);
|
||||
}
|
||||
|
|
20
ast_expr2.h
20
ast_expr2.h
|
@ -1,7 +1,7 @@
|
|||
/* A Bison parser, made by GNU Bison 2.1. */
|
||||
/* A Bison parser, made by GNU Bison 2.1a. */
|
||||
|
||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -78,13 +78,15 @@
|
|||
|
||||
|
||||
|
||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||
#line 142 "ast_expr2.y"
|
||||
typedef union YYSTYPE {
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
typedef union YYSTYPE
|
||||
#line 140 "ast_expr2.y"
|
||||
{
|
||||
struct val *val;
|
||||
} YYSTYPE;
|
||||
/* Line 1447 of yacc.c. */
|
||||
#line 88 "ast_expr2.h"
|
||||
}
|
||||
/* Line 1536 of yacc.c. */
|
||||
#line 89 "ast_expr2.h"
|
||||
YYSTYPE;
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
|
@ -92,7 +94,7 @@ typedef union YYSTYPE {
|
|||
|
||||
|
||||
|
||||
#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
|
||||
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
|
||||
typedef struct YYLTYPE
|
||||
{
|
||||
int first_line;
|
||||
|
|
79
ast_expr2.y
79
ast_expr2.y
|
@ -17,6 +17,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#if !defined(SOLARIS) && !defined(__CYGWIN__)
|
||||
#include <err.h>
|
||||
|
@ -51,6 +52,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
|
|||
#define YYPARSE_PARAM parseio
|
||||
#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
|
||||
#define YYERROR_VERBOSE 1
|
||||
extern char extra_error_message[4095];
|
||||
extern int extra_error_message_supplied;
|
||||
|
||||
enum valtype {
|
||||
AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
|
||||
|
@ -129,12 +132,7 @@ int ast_yyerror(const char *,YYLTYPE *, struct parse_io *);
|
|||
some useful info about the error. Not as easy as it looks, but it
|
||||
is possible. */
|
||||
#define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
|
||||
#define DESTROY(x) { \
|
||||
if ((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) \
|
||||
free((x)->u.s); \
|
||||
(x)->u.s = 0; \
|
||||
free(x); \
|
||||
}
|
||||
#define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);}
|
||||
%}
|
||||
|
||||
%pure-parser
|
||||
|
@ -165,6 +163,11 @@ extern int ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
|
|||
%token <val> TOKEN
|
||||
%type <val> start expr
|
||||
|
||||
|
||||
%destructor { free_value($$); } expr TOKEN TOK_COND TOK_COLONCOLON TOK_OR TOK_AND TOK_EQ
|
||||
TOK_GT TOK_LT TOK_GE TOK_LE TOK_NE TOK_PLUS TOK_MINUS TOK_MULT TOK_DIV TOK_MOD TOK_COMPL TOK_COLON TOK_EQTILDE
|
||||
TOK_RP TOK_LP
|
||||
|
||||
%%
|
||||
|
||||
start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
|
||||
|
@ -175,6 +178,11 @@ start: expr { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(st
|
|||
((struct parse_io *)parseio)->val->u.s = $1->u.s;
|
||||
free($1);
|
||||
}
|
||||
| {/* 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("");
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
expr: TOKEN { $$= $1;}
|
||||
|
@ -427,11 +435,40 @@ void ast_log(int level, const char *file, int line, const char *function, const
|
|||
|
||||
int main(int argc,char **argv) {
|
||||
char s[4096];
|
||||
char out[4096];
|
||||
FILE *infile;
|
||||
|
||||
if (ast_expr(argv[1], s, sizeof(s)))
|
||||
printf("=====%s======\n",s);
|
||||
if( !argv[1] )
|
||||
exit(20);
|
||||
|
||||
if( access(argv[1],F_OK)== 0 )
|
||||
{
|
||||
int ret;
|
||||
|
||||
infile = fopen(argv[1],"r");
|
||||
if( !infile )
|
||||
{
|
||||
printf("Sorry, couldn't open %s for reading!\n", argv[1]);
|
||||
exit(10);
|
||||
}
|
||||
while( fgets(s,sizeof(s),infile) )
|
||||
{
|
||||
if( s[strlen(s)-1] == '\n' )
|
||||
s[strlen(s)-1] = 0;
|
||||
|
||||
ret = ast_expr(s, out, sizeof(out));
|
||||
printf("Expression: %s Result: [%d] '%s'\n",
|
||||
s, ret, out);
|
||||
}
|
||||
fclose(infile);
|
||||
}
|
||||
else
|
||||
printf("No result\n");
|
||||
{
|
||||
if (ast_expr(argv[1], s, sizeof(s)))
|
||||
printf("=====%s======\n",s);
|
||||
else
|
||||
printf("No result\n");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -655,7 +692,8 @@ op_plus (struct val *a, struct val *b)
|
|||
struct val *r;
|
||||
|
||||
if (!to_integer (a)) {
|
||||
ast_log(LOG_WARNING,"non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING,"non-numeric argument\n");
|
||||
if (!to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
|
@ -698,7 +736,8 @@ op_minus (struct val *a, struct val *b)
|
|||
struct val *r;
|
||||
|
||||
if (!to_integer (a)) {
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if (!to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
|
@ -710,7 +749,8 @@ op_minus (struct val *a, struct val *b)
|
|||
return (r);
|
||||
}
|
||||
} else if (!to_integer(b)) {
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
free_value(b);
|
||||
return (a);
|
||||
}
|
||||
|
@ -731,7 +771,8 @@ op_negate (struct val *a)
|
|||
|
||||
if (!to_integer (a) ) {
|
||||
free_value(a);
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
return make_integer(0);
|
||||
}
|
||||
|
||||
|
@ -813,7 +854,8 @@ op_times (struct val *a, struct val *b)
|
|||
if (!to_integer (a) || !to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
return(make_integer(0));
|
||||
}
|
||||
|
||||
|
@ -845,12 +887,14 @@ op_div (struct val *a, struct val *b)
|
|||
if (!to_integer (a)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
return make_integer(0);
|
||||
} else if (!to_integer (b)) {
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
return make_integer(INT_MAX);
|
||||
}
|
||||
|
||||
|
@ -876,7 +920,8 @@ op_rem (struct val *a, struct val *b)
|
|||
struct val *r;
|
||||
|
||||
if (!to_integer (a) || !to_integer (b)) {
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
if( !extra_error_message_supplied )
|
||||
ast_log(LOG_WARNING, "non-numeric argument\n");
|
||||
free_value(a);
|
||||
free_value(b);
|
||||
return make_integer(0);
|
||||
|
|
811
ast_expr2f.c
811
ast_expr2f.c
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,307 @@
|
|||
//
|
||||
// Example AEL config file
|
||||
//
|
||||
//
|
||||
// Static extension configuration file, used by
|
||||
// the pbx_config module. This is where you configure all your
|
||||
// inbound and outbound calls in Asterisk.
|
||||
//
|
||||
// This configuration file is reloaded
|
||||
// - With the "extensions reload" command in the CLI
|
||||
// - With the "reload" command (that reloads everything) in the CLI
|
||||
|
||||
// The "Globals" category contains global variables that can be referenced
|
||||
// in the dialplan with ${VARIABLE} or ${ENV(VARIABLE)} for Environmental
|
||||
// variables,
|
||||
// ${${VARIABLE}} or ${text${VARIABLE}} or any hybrid
|
||||
//
|
||||
|
||||
globals {
|
||||
CONSOLE="Console/dsp"; // Console interface for demo
|
||||
//CONSOLE=Zap/1
|
||||
//CONSOLE=Phone/phone0
|
||||
IAXINFO=guest; // IAXtel username/password
|
||||
//IAXINFO="myuser:mypass";
|
||||
TRUNK="Zap/g2"; // Trunk interface
|
||||
//
|
||||
// Note the 'g2' in the TRUNK variable above. It specifies which group (defined
|
||||
// in zapata.conf) to dial, i.e. group 2, and how to choose a channel to use in
|
||||
// the specified group. The four possible options are:
|
||||
//
|
||||
// g: select the lowest-numbered non-busy Zap channel
|
||||
// (aka. ascending sequential hunt group).
|
||||
// G: select the highest-numbered non-busy Zap channel
|
||||
// (aka. descending sequential hunt group).
|
||||
// r: use a round-robin search, starting at the next highest channel than last
|
||||
// time (aka. ascending rotary hunt group).
|
||||
// R: use a round-robin search, starting at the next lowest channel than last
|
||||
// time (aka. descending rotary hunt group).
|
||||
//
|
||||
TRUNKMSD=1; // MSD digits to strip (usually 1 or 0)
|
||||
//TRUNK=IAX2/user:pass@provider
|
||||
};
|
||||
|
||||
//
|
||||
// Any category other than "General" and "Globals" represent
|
||||
// extension contexts, which are collections of extensions.
|
||||
//
|
||||
// Extension names may be numbers, letters, or combinations
|
||||
// thereof. If an extension name is prefixed by a '_'
|
||||
// character, it is interpreted as a pattern rather than a
|
||||
// literal. In patterns, some characters have special meanings:
|
||||
//
|
||||
// X - any digit from 0-9
|
||||
// Z - any digit from 1-9
|
||||
// N - any digit from 2-9
|
||||
// [1235-9] - any digit in the brackets (in this example, 1,2,3,5,6,7,8,9)
|
||||
// . - wildcard, matches anything remaining (e.g. _9011. matches
|
||||
// anything starting with 9011 excluding 9011 itself)
|
||||
// ! - wildcard, causes the matching process to complete as soon as
|
||||
// it can unambiguously determine that no other matches are possible
|
||||
//
|
||||
// For example the extension _NXXXXXX would match normal 7 digit dialings,
|
||||
// while _1NXXNXXXXXX would represent an area code plus phone number
|
||||
// preceeded by a one.
|
||||
//
|
||||
// Each step of an extension is ordered by priority, which must
|
||||
// always start with 1 to be considered a valid extension. The priority
|
||||
// "next" or "n" means the previous priority plus one, regardless of whether
|
||||
// the previous priority was associated with the current extension or not.
|
||||
// The priority "same" or "s" means the same as the previously specified
|
||||
// priority, again regardless of whether the previous entry was for the
|
||||
// same extension. Priorities may be immediately followed by a plus sign
|
||||
// and another integer to add that amount (most useful with 's' or 'n').
|
||||
// Priorities may then also have an alias, or label, in
|
||||
// parenthesis after their name which can be used in goto situations
|
||||
//
|
||||
// Contexts contain several lines, one for each step of each
|
||||
// extension, which can take one of two forms as listed below,
|
||||
// with the first form being preferred. One may include another
|
||||
// context in the current one as well, optionally with a
|
||||
// date and time. Included contexts are included in the order
|
||||
// they are listed.
|
||||
//
|
||||
//context name {
|
||||
// exten-name => {
|
||||
// application(arg1,arg2,...);
|
||||
//
|
||||
// Timing list for includes is
|
||||
//
|
||||
// <time range>|<days of week>|<days of month>|<months>
|
||||
//
|
||||
// includes {
|
||||
// daytime|9:00-17:00|mon-fri|*|*;
|
||||
// };
|
||||
//
|
||||
// ignorepat can be used to instruct drivers to not cancel dialtone upon
|
||||
// receipt of a particular pattern. The most commonly used example is
|
||||
// of course '9' like this:
|
||||
//
|
||||
// ignorepat => 9;
|
||||
//
|
||||
// so that dialtone remains even after dialing a 9.
|
||||
//};
|
||||
|
||||
|
||||
//
|
||||
// Sample entries for extensions.conf
|
||||
//
|
||||
//
|
||||
context dundi-e164-canonical {
|
||||
//
|
||||
// List canonical entries here
|
||||
//
|
||||
// 12564286000 => &std-exten(6000,IAX2/foo);
|
||||
// _125642860XX => Dial(IAX2/otherbox/${EXTEN:7});
|
||||
};
|
||||
|
||||
context dundi-e164-customers {
|
||||
//
|
||||
// If you are an ITSP or Reseller, list your customers here.
|
||||
//
|
||||
//_12564286000 => Dial(SIP/customer1);
|
||||
//_12564286001 => Dial(IAX2/customer2);
|
||||
};
|
||||
|
||||
context dundi-e164-via-pstn {
|
||||
//
|
||||
// If you are freely delivering calls to the PSTN, list them here
|
||||
//
|
||||
//_1256428XXXX => Dial(Zap/g2/${EXTEN:7}); // Expose all of 256-428
|
||||
//_1256325XXXX => Dial(Zap/g2/${EXTEN:7}); // Ditto for 256-325
|
||||
};
|
||||
|
||||
context dundi-e164-local {
|
||||
//
|
||||
// Context to put your dundi IAX2 or SIP user in for
|
||||
// full access
|
||||
//
|
||||
includes {
|
||||
dundi-e164-canonical;
|
||||
dundi-e164-customers;
|
||||
dundi-e164-via-pstn;
|
||||
};
|
||||
};
|
||||
|
||||
context dundi-e164-switch {
|
||||
//
|
||||
// Just a wrapper for the switch
|
||||
//
|
||||
|
||||
switches {
|
||||
DUNDi/e164;
|
||||
};
|
||||
};
|
||||
|
||||
context dundi-e164-lookup {
|
||||
//
|
||||
// Locally to lookup, try looking for a local E.164 solution
|
||||
// then try DUNDi if we don't have one.
|
||||
//
|
||||
includes {
|
||||
dundi-e164-local;
|
||||
dundi-e164-switch;
|
||||
};
|
||||
//
|
||||
};
|
||||
|
||||
//
|
||||
// DUNDi can also be implemented as a Macro instead of using
|
||||
// the Local channel driver.
|
||||
//
|
||||
macro dundi-e164(exten) {
|
||||
//
|
||||
// ARG1 is the extension to Dial
|
||||
//
|
||||
goto ${exten}|1;
|
||||
};
|
||||
|
||||
//
|
||||
// Here are the entries you need to participate in the IAXTEL
|
||||
// call routing system. Most IAXTEL numbers begin with 1-700, but
|
||||
// there are exceptions. For more information, and to sign
|
||||
// up, please go to www.gnophone.com or www.iaxtel.com
|
||||
//
|
||||
context iaxtel700 {
|
||||
_91700XXXXXXX => Dial(IAX2/${IAXINFO}@iaxtel.com/${EXTEN:1}@iaxtel);
|
||||
};
|
||||
|
||||
//
|
||||
// The SWITCH statement permits a server to share the dialplain with
|
||||
// another server. Use with care: Reciprocal switch statements are not
|
||||
// allowed (e.g. both A -> B and B -> A), and the switched server needs
|
||||
// to be on-line or else dialing can be severly delayed.
|
||||
//
|
||||
context iaxprovider {
|
||||
switches {
|
||||
// IAX2/user:[key]@myserver/mycontext;
|
||||
};
|
||||
};
|
||||
|
||||
context trunkint {
|
||||
//
|
||||
// International long distance through trunk
|
||||
//
|
||||
includes {
|
||||
dundi-e164-lookup;
|
||||
};
|
||||
_9011. => {
|
||||
&dundi-e164(${EXTEN:4});
|
||||
Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
|
||||
};
|
||||
};
|
||||
|
||||
context trunkld {
|
||||
//
|
||||
// Long distance context accessed through trunk
|
||||
//
|
||||
includes {
|
||||
dundi-e164-lookup;
|
||||
};
|
||||
_91NXXNXXXXXX => {
|
||||
&dundi-e164(${EXTEN:1});
|
||||
Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
|
||||
};
|
||||
};
|
||||
|
||||
context trunklocal {
|
||||
//
|
||||
// Local seven-digit dialing accessed through trunk interface
|
||||
//
|
||||
_9NXXXXXX => {
|
||||
Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
|
||||
};
|
||||
};
|
||||
|
||||
context trunktollfree {
|
||||
//
|
||||
// Long distance context accessed through trunk interface
|
||||
//
|
||||
|
||||
_91800NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
|
||||
_91888NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
|
||||
_91877NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
|
||||
_91866NXXXXXX => Dial(${TRUNK}/${EXTEN:${TRUNKMSD}});
|
||||
};
|
||||
|
||||
context international {
|
||||
//
|
||||
// Master context for international long distance
|
||||
//
|
||||
ignorepat => 9;
|
||||
includes {
|
||||
longdistance;
|
||||
trunkint;
|
||||
};
|
||||
};
|
||||
|
||||
context longdistance {
|
||||
//
|
||||
// Master context for long distance
|
||||
//
|
||||
ignorepat => 9;
|
||||
includes {
|
||||
local;
|
||||
trunkld;
|
||||
};
|
||||
};
|
||||
|
||||
context local {
|
||||
//
|
||||
// Master context for local, toll-free, and iaxtel calls only
|
||||
//
|
||||
ignorepat => 9;
|
||||
includes {
|
||||
default;
|
||||
parkedcalls;
|
||||
trunklocal;
|
||||
iaxtel700;
|
||||
trunktollfree;
|
||||
iaxprovider;
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
// You can use an alternative switch type as well, to resolve
|
||||
// extensions that are not known here, for example with remote
|
||||
// IAX switching you transparently get access to the remote
|
||||
// Asterisk PBX
|
||||
//
|
||||
// switch => IAX2/user:password@bigserver/local
|
||||
//
|
||||
// An "lswitch" is like a switch but is literal, in that
|
||||
// variable substitution is not performed at load time
|
||||
// but is passed to the switch directly (presumably to
|
||||
// be substituted in the switch routine itself)
|
||||
//
|
||||
// lswitch => Loopback/12${EXTEN}@othercontext
|
||||
//
|
||||
// An "eswitch" is like a switch but the evaluation of
|
||||
// variable substitution is performed at runtime before
|
||||
// being passed to the switch routine.
|
||||
//
|
||||
// eswitch => IAX2/context@${CURSERVER}
|
||||
|
||||
|
||||
macro std-exten-ael( ext , dev ) {
|
||||
Dial(${dev}/${ext},20);
|
||||
|
@ -21,8 +322,8 @@ context ael-demo {
|
|||
s => {
|
||||
Wait(1);
|
||||
Answer();
|
||||
TIMEOUT(digit)=5;
|
||||
TIMEOUT(response)=10;
|
||||
Set(TIMEOUT(digit)=5);
|
||||
Set(TIMEOUT(response)=10);
|
||||
restart:
|
||||
Background(demo-congrats);
|
||||
instructions:
|
||||
|
@ -36,12 +337,15 @@ instructions:
|
|||
goto s|instructions;
|
||||
};
|
||||
3 => {
|
||||
LANGUAGE()=fr;
|
||||
Set(LANGUAGE()=fr);
|
||||
goto s|restart;
|
||||
};
|
||||
1000 => {
|
||||
goto default|s|1;
|
||||
};
|
||||
500 => {
|
||||
Playback(demo-abouttotry);
|
||||
Dial(IAX2/guest@misery.digium.com);
|
||||
Dial(IAX2/guest@misery.digium.com/s@default);
|
||||
Playback(demo-nogo);
|
||||
goto s|instructions;
|
||||
};
|
||||
|
@ -52,11 +356,83 @@ instructions:
|
|||
goto s|instructions;
|
||||
};
|
||||
_1234 => &std-exten-ael(${EXTEN}, "IAX2");
|
||||
8500 => {
|
||||
VoicemailMain();
|
||||
goto s|instructions;
|
||||
};
|
||||
# => {
|
||||
Playback(demo-thanks);
|
||||
Hangup();
|
||||
};
|
||||
t => jump #;
|
||||
t => goto #|1;
|
||||
i => Playback(invalid);
|
||||
};
|
||||
|
||||
context default {
|
||||
|
||||
// By default we include the demo. In a production system, you
|
||||
// probably don't want to have the demo there.
|
||||
|
||||
includes {
|
||||
ael-demo;
|
||||
};
|
||||
//
|
||||
// Extensions like the two below can be used for FWD, Nikotel, sipgate etc.
|
||||
// Note that you must have a [sipprovider] section in sip.conf whereas
|
||||
// the otherprovider.net example does not require such a peer definition
|
||||
//
|
||||
//_41X. => Dial(SIP/${EXTEN:2}@sipprovider,,r);
|
||||
//_42X. => Dial(SIP/user:passwd@${EXTEN:2}@otherprovider.net,30,rT);
|
||||
|
||||
// Real extensions would go here. Generally you want real extensions to be
|
||||
// 4 or 5 digits long (although there is no such requirement) and start with a
|
||||
// single digit that is fairly large (like 6 or 7) so that you have plenty of
|
||||
// room to overlap extensions and menu options without conflict. You can alias
|
||||
// them with names, too, and use global variables
|
||||
|
||||
// 6245 => {
|
||||
// hint(SIP/Grandstream1&SIP/Xlite1,Joe Schmoe); // Channel hints for presence
|
||||
// Dial(SIP/Grandstream1,20,rt); // permit transfer
|
||||
// Dial(${HINT}/5245},20,rtT); // Use hint as listed
|
||||
// switch(${DIALSTATUS}) {
|
||||
// case BUSY:
|
||||
// Voicemail(b6245);
|
||||
// return;
|
||||
// default:
|
||||
// Voicemail(u6245);
|
||||
// return;
|
||||
// };
|
||||
// };
|
||||
|
||||
// 6361 => Dial(IAX2/JaneDoe,,rm); // ring without time limit
|
||||
// 6389 => Dial(MGCP/aaln/1@192.168.0.14);
|
||||
// 6394 => Dial(Local/6275/n); // this will dial ${MARK}
|
||||
|
||||
// 6275 => &ael-stdexten(6275,${MARK}); // assuming ${MARK} is something like Zap/2
|
||||
// mark => goto 6275|1; // alias mark to 6275
|
||||
// 6536 => &ael-stdexten(6236,${WIL}); // Ditto for wil
|
||||
// wil => goto 6236|1;
|
||||
//
|
||||
// Some other handy things are an extension for checking voicemail via
|
||||
// voicemailmain
|
||||
//
|
||||
// 8500 => {
|
||||
// VoicemailMain();
|
||||
// Hangup();
|
||||
// };
|
||||
//
|
||||
// Or a conference room (you'll need to edit meetme.conf to enable this room)
|
||||
//
|
||||
// 8600 => Meetme(1234);
|
||||
//
|
||||
// Or playing an announcement to the called party, as soon it answers
|
||||
//
|
||||
// 8700 => Dial(${MARK},30,A(/path/to/my/announcemsg))
|
||||
//
|
||||
// For more information on applications, just type "show applications" at your
|
||||
// friendly Asterisk CLI prompt.
|
||||
//
|
||||
// 'show application <command>' will show details of how you
|
||||
// use that particular application in this file, the dial plan.
|
||||
//
|
||||
};
|
||||
|
|
1355
doc/ael.txt
1355
doc/ael.txt
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,178 @@
|
|||
#if !defined(SOLARIS) && !defined(__CYGWIN__)
|
||||
#include <err.h>
|
||||
#else
|
||||
#define quad_t int64_t
|
||||
#endif
|
||||
|
||||
#ifdef LONG_LONG_MIN
|
||||
#define QUAD_MIN LONG_LONG_MIN
|
||||
#endif
|
||||
#ifdef LONG_LONG_MAX
|
||||
#define QUAD_MAX LONG_LONG_MAX
|
||||
#endif
|
||||
|
||||
# if ! defined(QUAD_MIN)
|
||||
# define QUAD_MIN (-0x7fffffffffffffffLL-1)
|
||||
# endif
|
||||
# if ! defined(QUAD_MAX)
|
||||
# define QUAD_MAX (0x7fffffffffffffffLL)
|
||||
# endif
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PV_WORD, /* an ident, string, name, label, etc. A user-supplied string. */
|
||||
PV_MACRO,
|
||||
PV_CONTEXT,
|
||||
PV_MACRO_CALL,
|
||||
PV_APPLICATION_CALL,
|
||||
PV_CASE,
|
||||
PV_PATTERN,
|
||||
PV_DEFAULT,
|
||||
PV_CATCH,
|
||||
PV_SWITCHES,
|
||||
PV_ESWITCHES,
|
||||
PV_INCLUDES,
|
||||
PV_STATEMENTBLOCK,
|
||||
PV_VARDEC, /* you know, var=val; */
|
||||
PV_GOTO,
|
||||
PV_LABEL,
|
||||
PV_FOR,
|
||||
PV_WHILE,
|
||||
PV_BREAK,
|
||||
PV_RETURN,
|
||||
PV_CONTINUE,
|
||||
PV_IF,
|
||||
PV_IFTIME,
|
||||
PV_RANDOM,
|
||||
PV_SWITCH,
|
||||
PV_EXTENSION,
|
||||
PV_IGNOREPAT,
|
||||
PV_GLOBALS,
|
||||
|
||||
} pvaltype;
|
||||
|
||||
/* why this horrible mess? It's always been a tradeoff-- tons of structs,
|
||||
each storing it's specific lists of goodies, or a 'simple' single struct,
|
||||
with lots of fields, that catches all uses at once. Either you have a long
|
||||
list of struct names and subnames, or you have a long list of field names,
|
||||
and where/how they are used. I'm going with a single struct, using unions
|
||||
to reduce storage. Some simple generalizations, and a long list of types,
|
||||
and a book about what is used with what types.... Sorry!
|
||||
*/
|
||||
|
||||
struct pval
|
||||
{
|
||||
pvaltype type;
|
||||
int startline;
|
||||
int endline;
|
||||
int startcol;
|
||||
int endcol;
|
||||
char *filename;
|
||||
|
||||
union
|
||||
{
|
||||
char *str; /* wow, used almost everywhere! */
|
||||
struct pval *list; /* used in SWITCHES, ESWITCHES, INCLUDES, STATEMENTBLOCK, GOTO */
|
||||
struct pval *statements;/* used in EXTENSION */
|
||||
char *for_init; /* used in FOR */
|
||||
} u1;
|
||||
struct pval *u1_last; /* to build in-order lists -- looks like we only need one */
|
||||
|
||||
union
|
||||
{
|
||||
struct pval *arglist; /* used in macro_call, application_call, MACRO def, also attached to PWORD, the 4 timevals for includes */
|
||||
struct pval *statements; /* used in case, default, catch, while's statement, CONTEXT elements, GLOBALS */
|
||||
char *val; /* used in VARDEC */
|
||||
char *for_test; /* used in FOR */
|
||||
|
||||
} u2;
|
||||
|
||||
union
|
||||
{
|
||||
char *for_inc; /* used in FOR */
|
||||
struct pval *else_statements; /* used in IF */
|
||||
struct pval *macro_statements; /* used in MACRO */
|
||||
int abstract; /* used for context */
|
||||
char *hints; /* used in EXTENSION */
|
||||
} u3;
|
||||
|
||||
union
|
||||
{
|
||||
struct pval *for_statements; /* used in PV_FOR */
|
||||
int regexten; /* used in EXTENSION */
|
||||
} u4;
|
||||
|
||||
|
||||
struct pval *next; /* the pval at the end of this ptr will ALWAYS be of the same type as this one!
|
||||
EXCEPT for objects of the different types, that are in the same list, like contexts & macros, etc */
|
||||
|
||||
|
||||
} ;
|
||||
|
||||
|
||||
typedef struct pval pval;
|
||||
|
||||
pval *npval(pvaltype type, int first_line, int last_line, int first_column, int last_column);
|
||||
void linku1(pval *head, pval *tail);
|
||||
void print_pval_list(FILE *f, pval *item, int depth);
|
||||
void print_pval(FILE *f, pval *item, int depth);
|
||||
void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes);
|
||||
struct pval *find_label_in_current_context(char *exten, char *label);
|
||||
struct pval *find_label_in_current_extension(char *label);
|
||||
int count_labels_in_current_context(char *label);
|
||||
struct pval *find_label_in_current_db(char *context, char *exten, char *label);
|
||||
struct pval *ael2_parse(char *fname, int *errs);
|
||||
void destroy_pval(pval *item);
|
||||
void ael2_print(char *fname, pval *tree);
|
||||
#ifndef YY_TYPEDEF_YY_SCANNER_T
|
||||
#define YY_TYPEDEF_YY_SCANNER_T
|
||||
typedef void* yyscan_t;
|
||||
#endif
|
||||
|
||||
/* for passing info into and out of yyparse */
|
||||
struct parse_io
|
||||
{
|
||||
struct pval *pval; /* yyparse will set this to point to the parse tree */
|
||||
yyscan_t scanner; /* yylex needs a scanner. Set it up, and pass it in */
|
||||
int syntax_error_count; /* the count of syntax errors encountered */
|
||||
};
|
||||
|
||||
/* for CODE GENERATION */
|
||||
|
||||
typedef enum { AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_RAND_CONTROL, AEL_LABEL, AEL_RETURN } ael_priority_type;
|
||||
|
||||
|
||||
struct ael_priority
|
||||
{
|
||||
int priority_num;
|
||||
ael_priority_type type;
|
||||
|
||||
char *app;
|
||||
char *appargs;
|
||||
|
||||
struct pval *origin;
|
||||
struct ael_extension *exten;
|
||||
|
||||
struct ael_priority *goto_true;
|
||||
struct ael_priority *goto_false;
|
||||
struct ael_priority *next;
|
||||
};
|
||||
|
||||
struct ael_extension
|
||||
{
|
||||
char *name;
|
||||
char *hints;
|
||||
int regexten;
|
||||
|
||||
struct ael_priority *plist;
|
||||
struct ael_priority *plist_last;
|
||||
struct ael_extension *next_exten;
|
||||
|
||||
struct ael_priority *loop_break; /* set by latest loop for breaks */
|
||||
struct ael_priority *loop_continue; /* set by lastest loop for continuing */
|
||||
struct ael_priority *return_target;
|
||||
int return_needed;
|
||||
};
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
17
pbx/Makefile
17
pbx/Makefile
|
@ -48,6 +48,23 @@ pbx_dundi.so: pbx_dundi.o dundi-parser.o
|
|||
pbx_dundi.o: pbx_dundi.c
|
||||
$(CC) -c -o $@ $(CFLAGS) $(Z_INCLUDE) $<
|
||||
|
||||
pbx_ael.o: ael/aelflex.o ael/aelbison.o ../include/asterisk/ael_structs.h
|
||||
|
||||
pbx_ael.so: pbx_ael.o ael/aelbison.o ael/aelflex.o
|
||||
$(CC) $(SOLINK) -o $@ pbx_ael.o ael/aelbison.o ael/aelflex.o
|
||||
|
||||
ael/aelflex.o: ael/ael_lex.c ../include/asterisk/ael_structs.h ael/ael.tab.h
|
||||
$(CC) $(CFLAGS) -c -o ael/aelflex.o ael/ael_lex.c
|
||||
|
||||
ael/aelbison.o: ael/ael.tab.c ael/ael.tab.h ../include/asterisk/ael_structs.h
|
||||
$(CC) $(CFLAGS) -c -o ael/aelbison.o ael/ael.tab.c
|
||||
|
||||
ael/ael_lex.c: ael/ael.flex
|
||||
(cd ael; flex ael.flex)
|
||||
|
||||
ael/ael.tab.c ael/ael.tab.h: ael/ael.y
|
||||
(cd ael; bison -v -d ael.y)
|
||||
|
||||
%.moc : %.h
|
||||
$(MOC) $< -o $@
|
||||
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
|
||||
macro testdial(number, timeout) {
|
||||
Dial(IAX2/vpconnect-t02/${number},${timeout},${OG_DIAL_FLAGS});
|
||||
switch (${DIALSTATUS}) {
|
||||
case CHANUNAVAIL:
|
||||
goto dial-trunk2;
|
||||
break;
|
||||
default:
|
||||
NoOp(t02 Unavailable - ${DIALSTATUS});
|
||||
return;
|
||||
}
|
||||
|
||||
dial-trunk2:
|
||||
Dial(IAX2/vpconnect-t01/${number},${timeout},${OG_DIAL_FLAGS});
|
||||
|
||||
}
|
||||
|
||||
macro exten-gen(name,pword)
|
||||
{
|
||||
if( ${DB_EXISTS(org/${GroupID}/${name}/secret)} = 0 )
|
||||
goto other|nomatch|begin;
|
||||
if( ${DB(org/${GroupID}/${name}/secret)}foo != ${pword}foo )
|
||||
goto other|nomatch|begin;
|
||||
|
||||
};
|
||||
|
||||
context what {
|
||||
who =>
|
||||
{
|
||||
random(51) NoOp(This should appear 51% of the time);
|
||||
|
||||
random( 60 )
|
||||
{
|
||||
NoOp( This should appear 60% of the time );
|
||||
}
|
||||
else
|
||||
{
|
||||
random(75)
|
||||
{
|
||||
NoOp( This should appear 30% of the time! );
|
||||
}
|
||||
else
|
||||
{
|
||||
NoOp( This should appear 10% of the time! );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context other {
|
||||
nomatch => {
|
||||
begin:
|
||||
NoOp(Hello!);
|
||||
switch(${DIALSTATUS})
|
||||
{
|
||||
case BUSY:
|
||||
NoOp(wow);
|
||||
case TORTURE:
|
||||
NoOp(woow);
|
||||
};
|
||||
NoOp(woohoo);
|
||||
};
|
||||
};
|
||||
|
||||
context testloop {
|
||||
includes {
|
||||
other|16:00-23:59|m0n-fri|*|*;
|
||||
};
|
||||
|
||||
1 => {
|
||||
for (x=0; ${x} < 3; x=${x} + 1) {
|
||||
Verbose(x is ${x} !);
|
||||
if( ${x} = 1 )
|
||||
continue;
|
||||
if( ${x} = 2 )
|
||||
break;
|
||||
};
|
||||
ifTime(14:00-25:00|sat-sun|*|*) {
|
||||
BackGround(Hello);
|
||||
} else
|
||||
BackGround(Sorry);
|
||||
NoOp(This is a totally useless NOOP);
|
||||
};
|
||||
2 => {
|
||||
y=10;
|
||||
while (${y} >= 0) {
|
||||
Verbose(y is ${y} !);
|
||||
if( ${y} = 1 )
|
||||
continue;
|
||||
if( ${y} = 2 )
|
||||
break;
|
||||
if( ${y} = 3 )
|
||||
return;
|
||||
y=${y}-1;
|
||||
};
|
||||
};
|
||||
regexten hint(nasty/Thingy) 3 => {
|
||||
for (x=0; ${x} < 3; x=${x} + 1)
|
||||
{
|
||||
Verbose(x is ${x} !);
|
||||
if( ${x} = 4 )
|
||||
break;
|
||||
if( ${x} = 5 )
|
||||
continue;
|
||||
if( ${x} = 6 )
|
||||
return;
|
||||
|
||||
y=10;
|
||||
while (${y} >= 0)
|
||||
{
|
||||
Verbose(y is ${y} !);
|
||||
if( ${y} = 4 )
|
||||
break;
|
||||
if( ${y} = 5 )
|
||||
continue;
|
||||
if( ${y} = 6 )
|
||||
return;
|
||||
y=${y}-1;
|
||||
};
|
||||
};
|
||||
};
|
||||
4 => {
|
||||
y=10;
|
||||
while (${y} >= 0)
|
||||
{
|
||||
Verbose(y is ${y} !);
|
||||
if( ${y} = 4 )
|
||||
break;
|
||||
if( ${y} = 5 )
|
||||
continue;
|
||||
if( ${y} = 6 )
|
||||
return;
|
||||
for (x=0; ${x} < 3; x=${x} + 1)
|
||||
{
|
||||
Verbose(x is ${x} !);
|
||||
if( ${x} = 4 )
|
||||
break;
|
||||
if( ${x} = 5 )
|
||||
continue;
|
||||
if( ${x} = 6 )
|
||||
return;
|
||||
for (z=0; ${z} < 17; z=${z} + 1)
|
||||
{
|
||||
Verbose(z is ${z} !);
|
||||
Verbose(z is ${z} !);
|
||||
if( ${z} = 4 )
|
||||
break;
|
||||
if( ${z} = 5 )
|
||||
continue;
|
||||
if( ${z} = 6 )
|
||||
return;
|
||||
Verbose(z is ${z} !);
|
||||
Verbose(z is ${z} !);
|
||||
};
|
||||
|
||||
};
|
||||
y=${y}-1;
|
||||
};
|
||||
};
|
||||
5 => {
|
||||
&exten-gen(axel,brain);
|
||||
};
|
||||
};
|
|
@ -0,0 +1,146 @@
|
|||
// this is a quick test to see how many of the apps we can spot j options in
|
||||
// include this in a macro or extension
|
||||
// at this moment, there are 18 apps that accept the j option.
|
||||
|
||||
AddQueueMember(zork,iface,20,j);
|
||||
ADSIProg(sfile);
|
||||
AgentCallbackLogin(agent,s,30@cont);
|
||||
AgentLogin(agent,s);
|
||||
AgentMonitorOutgoing(dcn);
|
||||
AGI(whatever);
|
||||
AlarmReceiver();
|
||||
Answer(2);
|
||||
AppendCDRUserField(value);
|
||||
Authenticate(pword,adjmr);
|
||||
BackGround(filename,snm,eng);
|
||||
BackgroundDetect(filename,20,2,10);
|
||||
Busy(10);
|
||||
ChangeMonitor(fnamebase);
|
||||
ChanIsAvail(Zap/5,sj);
|
||||
ChanSpy(prefix,bg()qrv);
|
||||
Congestion(5);
|
||||
ControlPlayback(filename,10,6,4,0,5,7,j);
|
||||
DateTime(unixtime,tz,fmt);
|
||||
DBdel(fam/key);
|
||||
DBdeltree(fam);
|
||||
DeadAGI(command);
|
||||
Dial(zap/1,45,A()CdD()fgG()hHjL()m()M()nNoprS()tTwW);
|
||||
Dictate(basedir);
|
||||
Directory(cont,dcont,f);
|
||||
DISA(68986869876,context);
|
||||
DumpChan(verblev);
|
||||
DUNDiLookup(90709780978,context,bj);
|
||||
EAGI(command);
|
||||
Echo();
|
||||
EndWhile();
|
||||
Exec(appname,args);
|
||||
ExecIf(expr,app,data);
|
||||
ExecIfTime(*,*,*,*,appname);
|
||||
ExternalIVR(command,arg1);
|
||||
Festival(text);
|
||||
Flash();
|
||||
ForkCDR(v);
|
||||
GetCPEID();
|
||||
Gosub(cont,exten,priority);
|
||||
GosubIf(cond?label);
|
||||
Goto(cont,exten,prior);
|
||||
GotoIf(cond?t:f);
|
||||
GotoIfTime(*,*,*,*?cont,ext,prior);
|
||||
Hangup();
|
||||
HasNewVoicemail(vmbox,var,j);
|
||||
HasVoicemail(vmbox,var,j);
|
||||
IAX2Provision(template);
|
||||
ICES(xmlconfig);
|
||||
ImportVar(nevar@chann,var);
|
||||
Log(NOTICE,message);
|
||||
LookupBlacklist(j);
|
||||
LookupCIDName();
|
||||
Macro(macro,arg1);
|
||||
MacroExit();
|
||||
MacroIf(expr?etc);
|
||||
MailboxExists(mbox@cont,j);
|
||||
Math(v,2+2);
|
||||
MeetMe(5555,aAbcdDeimMpPqrstTovwxX);
|
||||
MeetMeAdmin(5555,e,user);
|
||||
MeetMeCount(5555,var);
|
||||
Milliwatt();
|
||||
MixMonitor(filename,abv()V()W(),command);
|
||||
Monitor(file.fmt,base,mb);
|
||||
MP3Player(location);
|
||||
MusicOnHold(class);
|
||||
NBScat();
|
||||
NoCDR();
|
||||
NoOp(ignored);
|
||||
Page(Zap/1,dq);
|
||||
Park(exten);
|
||||
ParkAndAnnounce(template,5,238,retcont);
|
||||
ParkedCall(exten);
|
||||
PauseQueueMember(queue,zap,j);
|
||||
Pickup(ext@cont);
|
||||
Playback(file,j);
|
||||
PlayTones(arg);
|
||||
PrivacyManager(3,4,j);
|
||||
Progress();
|
||||
Queue(queuename,dhHnrtTwW,http://www.where.what,over,5);
|
||||
Random(30,cont,ext,pri);
|
||||
Read(var,fname,10,skip,2,5);
|
||||
ReadFile(var=file,10);
|
||||
RealTime(fam,2,val,prefix);
|
||||
RealTimeUpdate(fam,2,val,2,newval);
|
||||
Record(file,2,10,anqst);
|
||||
RemoveQueueMember(queuename,iface,j);
|
||||
ResetCDR(wav);
|
||||
RetryDial(annound,4,2);
|
||||
Return();
|
||||
Ringing();
|
||||
RxFAX(fname,caller);
|
||||
SayAlpha(string);
|
||||
SayDigits(string);
|
||||
SayNumber(digits);
|
||||
SayPhonetic(string);
|
||||
SayUnixTime(unixtime,tz,fmt);
|
||||
SendDTMF(digits,10);
|
||||
SendImage(filename);
|
||||
SendText(text,j);
|
||||
SendURL(URL);
|
||||
Set(a=b);
|
||||
SetAMAFlags();
|
||||
SetCallerID(clid,a);
|
||||
SetCallerPres(allowed_passed_screen);
|
||||
SetCDRUserField(value);
|
||||
SetGlobalVar(var=val);
|
||||
SetMusicOnHold(class);
|
||||
SetTransferCapability(SPEECH);
|
||||
SIPAddHeader(header);
|
||||
SIPDtmfMode(inband,info,rfc);
|
||||
SIPGetHeader(var@headername);
|
||||
SMS(name);
|
||||
SoftHangup(zap/1,a);
|
||||
StackPop();
|
||||
StartMusicOnHold(class);
|
||||
StopMonitor();
|
||||
StopMusicOnHold();
|
||||
StopPlayTones();
|
||||
System(command);
|
||||
TestClient(testid);
|
||||
TestServer();
|
||||
Transfer(zap/1,j);
|
||||
TrySystem(command);
|
||||
TxFAX(filename,caller,debug);
|
||||
UnpauseQueueMember(queuename,iface,j);
|
||||
UserEvent(eventanme,body);
|
||||
Verbose(5,message);
|
||||
VMAuthenticate(mailbox@cont,s);
|
||||
VoiceMail(mailbox@cont,bg()suj);
|
||||
VoiceMailMain(mailbox@cont,pg()s);
|
||||
Wait(2);
|
||||
WaitExten(3,m());
|
||||
WaitForRing(2);
|
||||
WaitForSilence(2,y);
|
||||
WaitMusicOnHold(2);
|
||||
While(expr);
|
||||
Zapateller(answer,5);
|
||||
ZapBarge(channel);
|
||||
ZapRAS(arg);
|
||||
ZapScan(group);
|
||||
ZapSendKeypadFacility();
|
|
@ -0,0 +1,8 @@
|
|||
context test1
|
||||
{
|
||||
s =>
|
||||
{
|
||||
#include "apptest.ael2";
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,3 @@
|
|||
NoOp(Hello, this is included from include1.ael2);
|
||||
#include "include2.ael2"
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
NoOp(This was included from include2.ael2);
|
||||
#include "include3.ael2"
|
||||
#include "include4.ael2"
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
NoOp(This is include3.ael2!);
|
||||
#include "include5.ael2"
|
|
@ -0,0 +1,2 @@
|
|||
NoOp(This is include4.ael2! Isn't it cool!?!?!?!);
|
||||
NoOp(4 doesn't include anything);
|
|
@ -0,0 +1 @@
|
|||
NoOp(Include5.ael2 doesn't include anything, either!);
|
|
@ -0,0 +1,146 @@
|
|||
// this is a quick test to see how many of the apps we can spot j options in
|
||||
// include this in a macro or extension
|
||||
// at this moment, there are 18 apps that accept the j option.
|
||||
|
||||
AddQueueMember(zork,iface,20,j);
|
||||
ADSIProg(sfile);
|
||||
AgentCallbackLogin(agent,s,30@cont);
|
||||
AgentLogin(agent,s);
|
||||
AgentMonitorOutgoing(dcn);
|
||||
AGI(whatever);
|
||||
AlarmReceiver();
|
||||
Answer(2);
|
||||
AppendCDRUserField(value);
|
||||
Authenticate(pword,adjmr);
|
||||
BackGround(filename,snm,eng);
|
||||
BackgroundDetect(filename,20,2,10);
|
||||
Busy(10);
|
||||
ChangeMonitor(fnamebase);
|
||||
ChanIsAvail(Zap/5,sj);
|
||||
ChanSpy(prefix,bg()qrv);
|
||||
Congestion(5);
|
||||
ControlPlayback(filename,10,6,4,0,5,7,j);
|
||||
DateTime(unixtime,tz,fmt);
|
||||
DBdel(fam/key);
|
||||
DBdeltree(fam);
|
||||
DeadAGI(command);
|
||||
Dial(zap/1,45,A()CdD()fgG()hHjL()m()M()nNoprS()tTwW);
|
||||
Dictate(basedir);
|
||||
Directory(cont,dcont,f);
|
||||
DISA(68986869876,context);
|
||||
DumpChan(verblev);
|
||||
DUNDiLookup(90709780978,context,bj);
|
||||
EAGI(command);
|
||||
Echo();
|
||||
EndWhile();
|
||||
Exec(appname,args);
|
||||
ExecIf(expr,app,data);
|
||||
ExecIfTime(*,*,*,*,appname);
|
||||
ExternalIVR(command,arg1);
|
||||
Festival(text);
|
||||
Flash();
|
||||
ForkCDR(v);
|
||||
GetCPEID();
|
||||
Gosub(cont,exten,priority);
|
||||
GosubIf(cond?label);
|
||||
Goto(cont,exten,prior);
|
||||
GotoIf(cond?t:f);
|
||||
GotoIfTime(*,*,*,*?cont,ext,prior);
|
||||
Hangup();
|
||||
HasNewVoicemail(vmbox,var,j);
|
||||
HasVoicemail(vmbox,var,j);
|
||||
IAX2Provision(template);
|
||||
ICES(xmlconfig);
|
||||
ImportVar(nevar@chann,var);
|
||||
Log(NOTICE,message);
|
||||
LookupBlacklist(j);
|
||||
LookupCIDName();
|
||||
Macro(macro,arg1);
|
||||
MacroExit();
|
||||
MacroIf(expr?etc);
|
||||
MailboxExists(mbox@cont,j);
|
||||
Math(v,2+2);
|
||||
MeetMe(5555,aAbcdDeimMpPqrstTovwxX);
|
||||
MeetMeAdmin(5555,e,user);
|
||||
MeetMeCount(5555,var);
|
||||
Milliwatt();
|
||||
MixMonitor(filename,abv()V()W(),command);
|
||||
Monitor(file.fmt,base,mb);
|
||||
MP3Player(location);
|
||||
MusicOnHold(class);
|
||||
NBScat();
|
||||
NoCDR();
|
||||
NoOp(ignored);
|
||||
Page(Zap/1,dq);
|
||||
Park(exten);
|
||||
ParkAndAnnounce(template,5,238,retcont);
|
||||
ParkedCall(exten);
|
||||
PauseQueueMember(queue,zap,j);
|
||||
Pickup(ext@cont);
|
||||
Playback(file,j);
|
||||
PlayTones(arg);
|
||||
PrivacyManager(3,4,j);
|
||||
Progress();
|
||||
Queue(queuename,dhHnrtTwW,http://www.where.what,over,5);
|
||||
Random(30,cont,ext,pri);
|
||||
Read(var,fname,10,skip,2,5);
|
||||
ReadFile(var=file,10);
|
||||
RealTime(fam,2,val,prefix);
|
||||
RealTimeUpdate(fam,2,val,2,newval);
|
||||
Record(file,2,10,anqst);
|
||||
RemoveQueueMember(queuename,iface,j);
|
||||
ResetCDR(wav);
|
||||
RetryDial(annound,4,2);
|
||||
Return();
|
||||
Ringing();
|
||||
RxFAX(fname,caller);
|
||||
SayAlpha(string);
|
||||
SayDigits(string);
|
||||
SayNumber(digits);
|
||||
SayPhonetic(string);
|
||||
SayUnixTime(unixtime,tz,fmt);
|
||||
SendDTMF(digits,10);
|
||||
SendImage(filename);
|
||||
SendText(text,j);
|
||||
SendURL(URL);
|
||||
Set(a=b);
|
||||
SetAMAFlags();
|
||||
SetCallerID(clid,a);
|
||||
SetCallerPres(allowed_passed_screen);
|
||||
SetCDRUserField(value);
|
||||
SetGlobalVar(var=val);
|
||||
SetMusicOnHold(class);
|
||||
SetTransferCapability(SPEECH);
|
||||
SIPAddHeader(header);
|
||||
SIPDtmfMode(inband,info,rfc);
|
||||
SIPGetHeader(var@headername);
|
||||
SMS(name);
|
||||
SoftHangup(zap/1,a);
|
||||
StackPop();
|
||||
StartMusicOnHold(class);
|
||||
StopMonitor();
|
||||
StopMusicOnHold();
|
||||
StopPlayTones();
|
||||
System(command);
|
||||
TestClient(testid);
|
||||
TestServer();
|
||||
Transfer(zap/1,j);
|
||||
TrySystem(command);
|
||||
TxFAX(filename,caller,debug);
|
||||
UnpauseQueueMember(queuename,iface,j);
|
||||
UserEvent(eventanme,body);
|
||||
Verbose(5,message);
|
||||
VMAuthenticate(mailbox@cont,s);
|
||||
VoiceMail(mailbox@cont,bg()suj);
|
||||
VoiceMailMain(mailbox@cont,pg()s);
|
||||
Wait(2);
|
||||
WaitExten(3,m());
|
||||
WaitForRing(2);
|
||||
WaitForSilence(2,y);
|
||||
WaitMusicOnHold(2);
|
||||
While(expr);
|
||||
Zapateller(answer,5);
|
||||
ZapBarge(channel);
|
||||
ZapRAS(arg);
|
||||
ZapScan(group);
|
||||
ZapSendKeypadFacility();
|
|
@ -0,0 +1,8 @@
|
|||
context test1
|
||||
{
|
||||
test2 =>
|
||||
{
|
||||
#include "apptest.ael2";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,833 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Helpdesk Queue
|
||||
|
||||
context hd-queue {
|
||||
s => {
|
||||
NoOp(Add a background sound to tell the user their options);
|
||||
Queue(helpdesk|t);
|
||||
NoOp(Put in options to apologize and send user to voicemail);
|
||||
};
|
||||
|
||||
0 => goto default|0|1;
|
||||
1 => {
|
||||
Dial(u41950@svm1.shsu.edu);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
context l903-calling {
|
||||
_9903NXXXXXX => {
|
||||
Realtime(l903_ext,exchange,${EXTEN:4:3},l903_);
|
||||
if ("${l903_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from houston.conf
|
||||
// Converted the extension list to the database
|
||||
|
||||
context houston-calling {
|
||||
_9713NXXXXXX => {
|
||||
Realtime(hou_713_ext,exchange,${EXTEN:4:3},hou_713_);
|
||||
if ("${hou_713_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_9281NXXXXXX => {
|
||||
Realtime(hou_281_ext,exchange,${EXTEN:4:3},hou_281_);
|
||||
if ("${hou_281_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_9832NXXXXXX => {
|
||||
Realtime(hou_832_ext,exchange,${EXTEN:4:3},hou_832_);
|
||||
if ("${hou_832_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from huntsville.conf
|
||||
// Converted the extension list to the database
|
||||
|
||||
context huntsville-calling {
|
||||
_9NXXXXXX => {
|
||||
Realtime(hv_ext,exchange,${EXTEN:1:3},hv_);
|
||||
if ("${hv_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_NXXXXXX => {
|
||||
NoOp(Stripping last four to see what extension we're dialing);
|
||||
Set(LAST4=${EXTEN:3});
|
||||
StripLSD(4);
|
||||
};
|
||||
|
||||
i => Playback(pbx-invalid);
|
||||
h => Hangup;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from macros.conf
|
||||
|
||||
macro dialout( number ) {
|
||||
Realtime(call_info,exten,${CALLERIDNUM:5},mon_);
|
||||
if ("${mon_monitor}" = "YES") {
|
||||
Dial(SIP/${number}@sgw1.shsu.edu,,wW);
|
||||
Dial(SIP/${number}@sgw2.shsu.edu,,wW);
|
||||
} else {
|
||||
Dial(SIP/${number}@sgw1.shsu.edu);
|
||||
Dial(SIP/${number}@sgw2.shsu.edu);
|
||||
};
|
||||
};
|
||||
|
||||
// Standard extension macro:
|
||||
// ${ext} - Extension
|
||||
macro stdexten( ext ) {
|
||||
Realtime(sipusers,name,${ext},sip_user_);
|
||||
Realtime(call_info,exten|${ext},info_);
|
||||
if ("${sip_user_name}foo" = "foo") {
|
||||
Wait(1);
|
||||
&dialout(${ext});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
NoOp(${CALLERIDNUM});
|
||||
RealtimeUpdate(call_info,exten,${ext},calltrace,${CALLERIDNUM});
|
||||
System(/usr/local/bin/db_update.sh call_info calltrace ${CALLERIDNUM} exten ${ext} &);
|
||||
&checkdnd(${ext});
|
||||
&checkcf(${ext});
|
||||
Realtime(call_info,exten,${CALLERIDNUM:5},mon_);
|
||||
if ("${mon_monitor}" = "YES") {
|
||||
Dial(SIP/${info_forwardto},25,wW);
|
||||
} else {
|
||||
Dial(SIP/${info_forwardto},25);
|
||||
};
|
||||
switch ("${DIALSTATUS}") {
|
||||
case "BUSY":
|
||||
&checkcfb(${ext});
|
||||
break;
|
||||
case "CHANUNAVAIL":
|
||||
Dial(IAX2/asterisk:password@scm2.shsu.edu/${info_forwardto},25,wW);
|
||||
MailboxExists(${ext});
|
||||
// if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
// Congestion(10);
|
||||
// Hangup;
|
||||
// };
|
||||
&uvm(${ext});
|
||||
Hangup;
|
||||
break;
|
||||
case "CONGESTION":
|
||||
MailboxExists(${ext});
|
||||
if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
&bvm(${ext});
|
||||
Hangup;
|
||||
break;
|
||||
default:
|
||||
MailboxExists(${ext});
|
||||
if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
&uvm(${ext});
|
||||
Hangup;
|
||||
};
|
||||
Hangup;
|
||||
};
|
||||
|
||||
macro uvm( ext ) {
|
||||
Dial(SIP/u${ext}@svm1.shsu.edu);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
macro bvm( ext ) {
|
||||
Dial(SIP/b${ext}@svm1.shsu.edu);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
macro checkdnd( ext ) {
|
||||
if ("${info_donotdisturb}foo" = "foo") {
|
||||
NoOp(Do Not Disturb is not active);
|
||||
} else
|
||||
&uvm(${ext});
|
||||
};
|
||||
|
||||
macro checkcf( ext ) {
|
||||
if ("${info_forwardto}foo" = "foo")
|
||||
if ("${ext}" = "43974") {
|
||||
Set(info_forwardto=${ext}&SCCP/${ext});
|
||||
} else {
|
||||
Set(info_forwardto=${ext}&SIP/${ext}w);
|
||||
};
|
||||
};
|
||||
|
||||
macro checkcfb( ext ) {
|
||||
if ("${info_forwardbusy}foo" = "foo") {
|
||||
Wait(1);
|
||||
MailboxExists(${ext});
|
||||
if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
&dialout(${ext});
|
||||
Hangup;
|
||||
};
|
||||
&bvm(${ext});
|
||||
Hangup;
|
||||
};
|
||||
&stdexten(${info_forwardbusy});
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from test.conf
|
||||
|
||||
context test-include {
|
||||
includes {
|
||||
test-digium;
|
||||
test-sounds;
|
||||
test-phinfo;
|
||||
};
|
||||
};
|
||||
|
||||
context test-digium {
|
||||
*500 => {
|
||||
Dial(IAX2/guest@misery.digium.com/s@default);
|
||||
Playback(demo-nogo);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context test-sounds {
|
||||
*501 => {
|
||||
Answer;
|
||||
Musiconhold;
|
||||
Wait(1);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context test-phinfo {
|
||||
*505 => {
|
||||
Answer;
|
||||
NoOp(${CALLERIDNUM:5});
|
||||
SayDigits(${CALLERIDNUM:5});
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from external.conf
|
||||
|
||||
context long-distance {
|
||||
includes {
|
||||
local;
|
||||
};
|
||||
|
||||
_91XXXXXXXXXX => &dialout(${EXTEN});
|
||||
_9011. => &dialout(${EXTEN});
|
||||
};
|
||||
|
||||
context local {
|
||||
includes {
|
||||
default;
|
||||
};
|
||||
|
||||
911 => &dialout(911);
|
||||
9911 => &dialout(9911);
|
||||
|
||||
_9NXXXXXX => goto huntsville-calling|${EXTEN}|1;
|
||||
_936NXXXXXX => {
|
||||
goto 9${EXTEN:3}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_832NXXXXXX => {
|
||||
goto 9${EXTEN}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_713NXXXXXX => {
|
||||
goto 9${EXTEN}|1 ;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_281NXXXXXX => {
|
||||
goto 9${EXTEN}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
|
||||
};
|
||||
|
||||
_NXXNXXXXXX => {
|
||||
goto 9${EXTEN}|1;
|
||||
goto 91${EXTEN}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_91800NXXXXXX => &dialout(${EXTEN});
|
||||
_91866NXXXXXX => &dialout(${EXTEN});
|
||||
_91877NXXXXXX => &dialout(${EXTEN});
|
||||
_91888NXXXXXX => &dialout(${EXTEN});
|
||||
_91900NXXXXXX => &dialout(${EXTEN});
|
||||
_91976NXXXXXX => &dialout(${EXTEN});
|
||||
_9713NXXXXXX => goto houston-calling|${EXTEN}|1;
|
||||
_9281NXXXXXX => goto houston-calling|${EXTEN}|1;
|
||||
_9832NXXXXXX => goto houston-calling|${EXTEN}|1;
|
||||
_9903NXXXXXX => goto l903-calling|${EXTEN}|1;
|
||||
|
||||
_31NXXNXXXXXX => &dialout(${EXTEN});
|
||||
|
||||
h => Hangup;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from internal.conf
|
||||
|
||||
context from-scm2 {
|
||||
_4XXXX => {
|
||||
NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
|
||||
Dial(SIP/${EXTEN},20,wW);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_6XXXX => {
|
||||
NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
|
||||
Dial(SIP/${EXTEN},20,wW);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// All internal extensions work through the default context
|
||||
// Phones that can only make internal calls should be in
|
||||
// this context.
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
context default {
|
||||
// Include the contexts in the files that allow us to make these phone calls
|
||||
includes {
|
||||
vm-include;
|
||||
apps-include;
|
||||
test-include;
|
||||
};
|
||||
|
||||
// ALWAYS have an 'h' extension
|
||||
h => {
|
||||
NoOp(Hangup cause was: ${HANGUPCAUSE});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// We like to hear that we dialed an invalid extension
|
||||
i => Playback(pbx-invalid);
|
||||
|
||||
// Dial the operator
|
||||
0 => &dialout(0);
|
||||
|
||||
// Send voicemail calls to the vm-* contexts to be handled
|
||||
voicemail => goto vm-direct|s|1;
|
||||
5555 => goto vm-direct|s|1;
|
||||
62100 => goto vm-extension|s|1;
|
||||
|
||||
// These are our campus extensions, send them to the macro
|
||||
_6XXXX => &stdexten(${EXTEN});
|
||||
_4XXXX => &stdexten(${EXTEN});
|
||||
// These are campus extensions as well, might need to take this out though.
|
||||
_9294XXXX => goto _4XXXX|1;
|
||||
_9496XXXX => goto _6XXXX|1;
|
||||
|
||||
// These allows us to dial from the directory in our phone without worrying about dialing 9
|
||||
_936294XXXX => {
|
||||
goto ${EXTEN:5}|1;
|
||||
goto 9${EXTEN:3}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_936496XXXX => {
|
||||
goto ${EXTEN:5}|1;
|
||||
goto 9${EXTEN:3}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from apps.conf
|
||||
|
||||
context apps-include {
|
||||
includes {
|
||||
app-agents;
|
||||
app-dnd;
|
||||
app-callforward;
|
||||
app-calltrace;
|
||||
app-conferences;
|
||||
app-ssd;
|
||||
app-psd;
|
||||
app-idblock;
|
||||
app-helpdesk;
|
||||
app-dictate;
|
||||
app-set-monitor;
|
||||
};
|
||||
};
|
||||
|
||||
context app-agents {
|
||||
*54 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Read(agent_no|agent-user);
|
||||
AgentCallbackLogin(${agent_no}|s${CALLERIDNUM:5});
|
||||
Playback(agent-loginok);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
*55 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
AgentCallbackLogin(${agent_no});
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-calltrace {
|
||||
// caller dials this to find out the last call missed and possibly call back
|
||||
*69 => goto app-calltrace-perform|s|1;
|
||||
};
|
||||
|
||||
context app-calltrace-perform {
|
||||
s => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Background(info-about-last-call);
|
||||
Background(telephone-number);
|
||||
RealTime(call_info|exten|${CALLERIDNUM:5}|ct_);
|
||||
if ("${ct_calltrace}foo" = "foo") {
|
||||
Playback(loligo/from-unknown-caller);
|
||||
Hangup;
|
||||
} else {
|
||||
SayDigits("${ct_calltrace}");
|
||||
Set(TIMEOUT(digit)=3);
|
||||
Set(TIMEOUT(response)=7);
|
||||
Background(loligo/to-call-this-number);
|
||||
Background(press-1);
|
||||
Background(loligo/silence/5);
|
||||
};
|
||||
};
|
||||
|
||||
1 => goto local|${ct_calltrace}|1;
|
||||
|
||||
i => {
|
||||
Playback(vm-goodbye);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
t => {
|
||||
Playback(vm-goodbye);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-set-monitor {
|
||||
*50 => {
|
||||
Realtime(call_info,exten,${CALLERIDNUM:5},mon_set_);
|
||||
if ("${mon_set_monitor}" = "YES") {
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor|);
|
||||
System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
|
||||
} else {
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},monitor,YES);
|
||||
System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
|
||||
};
|
||||
NoOp(${mon_set_monitor});
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-dnd {
|
||||
*78 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},donotdisturb,YES);
|
||||
System(/usr/local/bin/db_update.sh call_info donotdisturb YES exten ${CALLERIDNUM:5} &);
|
||||
Playback(do-not-disturb);
|
||||
Playback(loligo/activated);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
*79 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},donotdisturb|);
|
||||
System(/usr/local/bin/db_update.sh call_info donotdisturb '' exten ${CALLERIDNUM:5} &);
|
||||
Playback(do-not-disturb);
|
||||
Playback(loligo/de-activated);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-callforward {
|
||||
// forwards calling extension to input number *72{EXTEN}
|
||||
_*72. => {
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardto,${EXTEN:3});
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto ${EXTEN:3} exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-unconditional);
|
||||
Playback(loligo/for);
|
||||
Playback(loligo/extension);
|
||||
SayDigits(${CALLERIDNUM:5});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${EXTEN:3});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// prompts for extension to forward to
|
||||
*72 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(please-enter-your);
|
||||
Playback(extension);
|
||||
Background(then-press-pound);
|
||||
VMAuthenticate(|s);
|
||||
Background(loligo/ent-target-attendant);
|
||||
Read(toext,loligo/then-press-pound);
|
||||
Wait(1);
|
||||
RealtimeUpdate(call_info,exten,${AUTH_MAILBOX},forwardto,${toext});
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto ${toext} exten ${AUTH_MAILBOX} &);
|
||||
Playback(loligo/call-fwd-unconditional);
|
||||
Playback(loligo/for);
|
||||
Playback(loligo/extension);
|
||||
SayDigits(${AUTH_MAILBOX});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${toext});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// cancels dialed extension call forward
|
||||
_*73. => {
|
||||
Realtime(voicemail,mailbox,${EXTEN:3},auth_);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Authenticate(${auth_password});
|
||||
RealtimeUpdate(call_info,exten,${EXTEN:3},forwardto,);
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${EXTEN:3} &);
|
||||
Wait(1);
|
||||
SayDigits(${EXTEN:3});
|
||||
Playback(loligo/call-fwd-cancelled);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// cancels call forward for calling extension
|
||||
*73 => {
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardto,);
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-cancelled);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// dialed call forward on busy
|
||||
_*90. => {
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardbusy,${EXTEN:3});
|
||||
System(/usr/local/bin/db_update.sh call_info forwardbusy ${EXTEN:3} exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-on-busy);
|
||||
Playback(loligo/for);
|
||||
Playback(loligo/extension);
|
||||
SayDigits(${CALLERIDNUM:5});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${EXTEN:3});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// cancels call forward on busy for calling extension
|
||||
*91 => {
|
||||
RealtimeUpdate(call_info,exten,${CALLERIDNUM:5},forwardbusy|);
|
||||
System(/usr/local/bin/db_update.sh call_info forwardbusy '' exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-on-busy);
|
||||
Playback(loligo/de-activated);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
h => Hangup;
|
||||
};
|
||||
|
||||
context app-idblock {
|
||||
_*67. => {
|
||||
Set(CALLERID(name)=Anonymous);
|
||||
&stdexten(${EXTEN:3});
|
||||
};
|
||||
};
|
||||
|
||||
context app-dictate {
|
||||
*1 => {
|
||||
Dictate();
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-ssd {
|
||||
// *59 <xx> <y.> - Set system speed dial <xx> to digits <y.>
|
||||
// *59 <xx> 0 - Delete system speed dial <xx>
|
||||
// *59 <xx> - Review system speed dial <xx>
|
||||
// *1xx - Dial speed dial <xx>
|
||||
_*59XXX. => {
|
||||
Answer;
|
||||
RealtimeUpdate(ssd,sd,${EXTEN:3:2},extension,${EXTEN:5});
|
||||
System(/usr/local/bin/db_update.sh systemsd extension ${EXTEN:5} sd ${EXTEN:3:2} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-set-to);
|
||||
SayDigits(${EXTEN:5});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*59XX0 => {
|
||||
Answer;
|
||||
RealtimeUpdate(ssd,sd,${EXTEN:3:2},extension,);
|
||||
System(/usr/local/bin/db_update.sh systemsd extension '' sd ${EXTEN:3:2} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-cleared);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*59XX => {
|
||||
Answer;
|
||||
Realtime(ssd,sd,${EXTEN:3},ssd_);
|
||||
if ("${ssd_extension}foo" = "foo") {
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${ssd_extension});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// NTC = number to call
|
||||
_*1XX => {
|
||||
Realtime(ssd,sd,${EXTEN:2},ssd_);
|
||||
if ("${ssd_extension}foo" = "foo") {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
&stdexten(${ssd_extension});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
macro check-psd-exists ( ext ) {
|
||||
Realtime(psd,extension,${ext},psd_);
|
||||
if ("${psd_extension}foo" = "foo") {
|
||||
System(/usr/local/bin/create_psd.sh ${ext});
|
||||
} else
|
||||
NoOp(PSD set for ${ext});
|
||||
};
|
||||
|
||||
context app-psd {
|
||||
// *89 <xx> <y.> - Set personal speed dial <xx> to digits <y.>
|
||||
// *89 <xx> 0 - Delete personal speed dial <xx>
|
||||
// *89 <xx> - Review personal speed dial <xx>
|
||||
// *2xx - Dial personal speed dial <xx>
|
||||
_*89XXX. => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Answer;
|
||||
RealtimeUpdate(psd,extension,${CALLERIDNUM:5},s${EXTEN:3:2},${EXTEN:5});
|
||||
System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} ${EXTEN:5} extension ${CALLERIDNUM:5} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-set-to);
|
||||
SayDigits(${EXTEN:5});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*89XX0 => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Answer;
|
||||
RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|);
|
||||
System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} '' extension ${CALLERIDNUM:5} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-cleared);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*89XX => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Answer;
|
||||
Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
|
||||
Wait(1);
|
||||
if ("${psd_s${EXTEN:3:2}}foo" = "foo") {
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${psd_s${EXTEN:3:2}});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// NTC = number to call
|
||||
_*2XX => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
|
||||
if ("${psd_s${EXTEN:2}}foo" = "foo") {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
&stdexten(${psd_s${EXTEN:2}});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-helpdesk {
|
||||
*4357 => {
|
||||
&stdexten(41950);
|
||||
Congestion;
|
||||
};
|
||||
};
|
||||
|
||||
context app-conferences {
|
||||
// waiting for room number announcement
|
||||
*86 => goto app-conf-hidden|s|1;
|
||||
};
|
||||
|
||||
context app-conf-hidden {
|
||||
s => {
|
||||
Wait(1);
|
||||
Playback(loligo/please-enter-the);
|
||||
Playback(loligo/extension);
|
||||
read(roomtoenter,loligo/then-press-pound);
|
||||
Meetme(${roomtoenter});
|
||||
Waitexten(8);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_1. => Meetme(${EXTEN});
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from vm.conf:
|
||||
|
||||
context vm-include {
|
||||
includes {
|
||||
vm-direct;
|
||||
vm-extension;
|
||||
vm-directory;
|
||||
};
|
||||
};
|
||||
|
||||
context vm-direct {
|
||||
s => {
|
||||
Dial(SIP/5555@svm1.shsu.edu,20);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Playback(extra/pls-try-call-later);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context vm-extension {
|
||||
s => {
|
||||
Dial(SIP/62100@svm1.shsu.edu,20);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Playback(extra/pls-try-call-later);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context vm-directory {
|
||||
5556 => {
|
||||
Dial(SIP/5556@svm1.shsu.edu);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Playback(extra/pls-try-call-later);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,833 @@
|
|||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Helpdesk Queue
|
||||
|
||||
context hd-queue {
|
||||
s => {
|
||||
NoOp(Add a background sound to tell the user their options);
|
||||
Queue(helpdesk|t);
|
||||
NoOp(Put in options to apologize and send user to voicemail);
|
||||
};
|
||||
|
||||
0 => goto default|0|1;
|
||||
1 => {
|
||||
Dial(u41950@svm1.shsu.edu);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
context l903-calling {
|
||||
_9903NXXXXXX => {
|
||||
Realtime(l903_ext|exchange|${EXTEN:4:3}|l903_);
|
||||
if ("${l903_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from houston.conf
|
||||
// Converted the extension list to the database
|
||||
|
||||
context houston-calling {
|
||||
_9713NXXXXXX => {
|
||||
Realtime(hou_713_ext|exchange|${EXTEN:4:3}|hou_713_);
|
||||
if ("${hou_713_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_9281NXXXXXX => {
|
||||
Realtime(hou_281_ext|exchange|${EXTEN:4:3}|hou_281_);
|
||||
if ("${hou_281_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_9832NXXXXXX => {
|
||||
Realtime(hou_832_ext|exchange|${EXTEN:4:3}|hou_832_);
|
||||
if ("${hou_832_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from huntsville.conf
|
||||
// Converted the extension list to the database
|
||||
|
||||
context huntsville-calling {
|
||||
_9NXXXXXX => {
|
||||
Realtime(hv_ext|exchange|${EXTEN:1:3}|hv_);
|
||||
if ("${hv_exchange}foo" = "foo") {
|
||||
Playback(num-outside-area);
|
||||
SayDigits(1);
|
||||
Playback(and-area-code);
|
||||
Playback(before-the-number);
|
||||
Hangup;
|
||||
};
|
||||
&dialout(${EXTEN});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_NXXXXXX => {
|
||||
NoOp(Stripping last four to see what extension we're dialing);
|
||||
Set(LAST4=${EXTEN:3});
|
||||
StripLSD(4);
|
||||
};
|
||||
|
||||
i => Playback(pbx-invalid);
|
||||
h => Hangup;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from macros.conf
|
||||
|
||||
macro dialout( number ) {
|
||||
Realtime(call_info|exten|${CALLERIDNUM:5}|mon_);
|
||||
if ("${mon_monitor}" = "YES") {
|
||||
Dial(SIP/${number}@sgw1.shsu.edu,,wW);
|
||||
Dial(SIP/${number}@sgw2.shsu.edu,,wW);
|
||||
} else {
|
||||
Dial(SIP/${number}@sgw1.shsu.edu);
|
||||
Dial(SIP/${number}@sgw2.shsu.edu);
|
||||
};
|
||||
};
|
||||
|
||||
// Standard extension macro:
|
||||
// ${ext} - Extension
|
||||
macro stdexten( ext ) {
|
||||
Realtime(sipusers|name|${ext}|sip_user_);
|
||||
Realtime(call_info|exten|${ext}|info_);
|
||||
if ("${sip_user_name}foo" = "foo") {
|
||||
Wait(1);
|
||||
&dialout(${ext});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
NoOp(${CALLERIDNUM});
|
||||
RealtimeUpdate(call_info|exten|${ext}|calltrace|${CALLERIDNUM});
|
||||
System(/usr/local/bin/db_update.sh call_info calltrace ${CALLERIDNUM} exten ${ext} &);
|
||||
&checkdnd(${ext});
|
||||
&checkcf(${ext});
|
||||
Realtime(call_info|exten|${CALLERIDNUM:5}|mon_);
|
||||
if ("${mon_monitor}" = "YES") {
|
||||
Dial(SIP/${info_forwardto},25,wW);
|
||||
} else {
|
||||
Dial(SIP/${info_forwardto},25);
|
||||
};
|
||||
switch ("${DIALSTATUS}") {
|
||||
case "BUSY":
|
||||
&checkcfb(${ext});
|
||||
break;
|
||||
case "CHANUNAVAIL":
|
||||
Dial(IAX2/asterisk:password@scm2.shsu.edu/${info_forwardto},25,wW);
|
||||
MailboxExists(${ext});
|
||||
// if ("${VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
// Congestion(10);
|
||||
// Hangup;
|
||||
// };
|
||||
&uvm(${ext});
|
||||
Hangup;
|
||||
break;
|
||||
case "CONGESTION":
|
||||
MailboxExists(${ext});
|
||||
if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
&bvm(${ext});
|
||||
Hangup;
|
||||
break;
|
||||
default:
|
||||
MailboxExists(${ext});
|
||||
if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
&uvm(${ext});
|
||||
Hangup;
|
||||
};
|
||||
Hangup;
|
||||
};
|
||||
|
||||
macro uvm( ext ) {
|
||||
Dial(SIP/u${ext}@svm1.shsu.edu);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
macro bvm( ext ) {
|
||||
Dial(SIP/b${ext}@svm1.shsu.edu);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
macro checkdnd( ext ) {
|
||||
if ("${info_donotdisturb}foo" = "foo") {
|
||||
NoOp(Do Not Disturb is not active);
|
||||
} else
|
||||
&uvm(${ext});
|
||||
};
|
||||
|
||||
macro checkcf( ext ) {
|
||||
if ("${info_forwardto}foo" = "foo")
|
||||
if ("${ext}" = "43974") {
|
||||
Set(info_forwardto=${ext}&SCCP/${ext});
|
||||
} else {
|
||||
Set(info_forwardto=${ext}&SIP/${ext}w);
|
||||
};
|
||||
};
|
||||
|
||||
macro checkcfb( ext ) {
|
||||
if ("${info_forwardbusy}foo" = "foo") {
|
||||
Wait(1);
|
||||
MailboxExists(${ext});
|
||||
if ("$(VMBOXEXISTSSTATUS}" = "FAILED") {
|
||||
&dialout(${ext});
|
||||
Hangup;
|
||||
};
|
||||
&bvm(${ext});
|
||||
Hangup;
|
||||
};
|
||||
&stdexten(${info_forwardbusy});
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from test.conf
|
||||
|
||||
context test-include {
|
||||
includes {
|
||||
test-digium;
|
||||
test-sounds;
|
||||
test-phinfo;
|
||||
};
|
||||
};
|
||||
|
||||
context test-digium {
|
||||
*500 => {
|
||||
Dial(IAX2/guest@misery.digium.com/s@default);
|
||||
Playback(demo-nogo);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context test-sounds {
|
||||
*501 => {
|
||||
Answer;
|
||||
Musiconhold;
|
||||
Wait(1);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context test-phinfo {
|
||||
*505 => {
|
||||
Answer;
|
||||
NoOp(${CALLERIDNUM:5});
|
||||
SayDigits(${CALLERIDNUM:5});
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from external.conf
|
||||
|
||||
context long-distance {
|
||||
includes {
|
||||
local;
|
||||
};
|
||||
|
||||
_91XXXXXXXXXX => &dialout(${EXTEN});
|
||||
_9011. => &dialout(${EXTEN});
|
||||
};
|
||||
|
||||
context local {
|
||||
includes {
|
||||
default;
|
||||
};
|
||||
|
||||
911 => &dialout(911);
|
||||
9911 => &dialout(9911);
|
||||
|
||||
_9NXXXXXX => goto huntsville-calling|${EXTEN}|1;
|
||||
_936NXXXXXX => {
|
||||
Goto 9${EXTEN:3}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_832NXXXXXX => {
|
||||
goto 9${EXTEN}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_713NXXXXXX => {
|
||||
goto 9${EXTEN}|1 ;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_281NXXXXXX => {
|
||||
goto 9${EXTEN}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
|
||||
};
|
||||
|
||||
_NXXNXXXXXX => {
|
||||
goto 9${EXTEN}|1;
|
||||
goto 91${EXTEN}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_91800NXXXXXX => &dialout(${EXTEN});
|
||||
_91866NXXXXXX => &dialout(${EXTEN});
|
||||
_91877NXXXXXX => &dialout(${EXTEN});
|
||||
_91888NXXXXXX => &dialout(${EXTEN});
|
||||
_91900NXXXXXX => &dialout(${EXTEN});
|
||||
_91976NXXXXXX => &dialout(${EXTEN});
|
||||
_9713NXXXXXX => goto houston-calling|${EXTEN}|1;
|
||||
_9281NXXXXXX => goto houston-calling|${EXTEN}|1;
|
||||
_9832NXXXXXX => goto houston-calling|${EXTEN}|1;
|
||||
_9903NXXXXXX => goto l903-calling|${EXTEN}|1;
|
||||
|
||||
_31NXXNXXXXXX => &dialout(${EXTEN});
|
||||
|
||||
h => Hangup;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from internal.conf
|
||||
|
||||
context from-scm2 {
|
||||
_4XXXX => {
|
||||
NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
|
||||
Dial(SIP/${EXTEN},20,wW);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_6XXXX => {
|
||||
NoOp(DIALING SIP EXTENSION ${EXTEN} - FROM ${CALLERIDNUM});
|
||||
Dial(SIP/${EXTEN},20,wW);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// All internal extensions work through the default context
|
||||
// Phones that can only make internal calls should be in
|
||||
// this context.
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
context default {
|
||||
// Include the contexts in the files that allow us to make these phone calls
|
||||
includes {
|
||||
vm-include;
|
||||
apps-include;
|
||||
test-include;
|
||||
};
|
||||
|
||||
// ALWAYS have an 'h' extension
|
||||
h => {
|
||||
NoOp(Hangup cause was: ${HANGUPCAUSE});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// We like to hear that we dialed an invalid extension
|
||||
i => Playback(pbx-invalid);
|
||||
|
||||
// Dial the operator
|
||||
0 => &dialout(0);
|
||||
|
||||
// Send voicemail calls to the vm-* contexts to be handled
|
||||
voicemail => goto vm-direct|s|1;
|
||||
5555 => goto vm-direct|s|1;
|
||||
62100 => goto vm-extension|s|1;
|
||||
|
||||
// These are our campus extensions, send them to the macro
|
||||
_6XXXX => &stdexten(${EXTEN});
|
||||
_4XXXX => &stdexten(${EXTEN});
|
||||
// These are campus extensions as well, might need to take this out though.
|
||||
_9294XXXX => goto _4XXXX|1;
|
||||
_9496XXXX => goto _6XXXX|1;
|
||||
|
||||
// These allows us to dial from the directory in our phone without worrying about dialing 9
|
||||
_936294XXXX => {
|
||||
goto ${EXTEN:5}|1;
|
||||
goto 9${EXTEN:3}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_936496XXXX => {
|
||||
goto ${EXTEN:5}|1;
|
||||
goto 9${EXTEN:3}|1;
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from apps.conf
|
||||
|
||||
context apps-include {
|
||||
includes {
|
||||
app-agents;
|
||||
app-dnd;
|
||||
app-callforward;
|
||||
app-calltrace;
|
||||
app-conferences;
|
||||
app-ssd;
|
||||
app-psd;
|
||||
app-idblock;
|
||||
app-helpdesk;
|
||||
app-dictate;
|
||||
app-set-monitor;
|
||||
};
|
||||
};
|
||||
|
||||
context app-agents {
|
||||
*54 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Read(agent_no|agent-user);
|
||||
AgentCallbackLogin(${agent_no}|s${CALLERIDNUM:5});
|
||||
Playback(agent-loginok);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
*55 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
AgentCallbackLogin(${agent_no});
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-calltrace {
|
||||
// caller dials this to find out the last call missed and possibly call back
|
||||
*69 => goto app-calltrace-perform|s|1;
|
||||
};
|
||||
|
||||
context app-calltrace-perform {
|
||||
s => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Background(info-about-last-call);
|
||||
Background(telephone-number);
|
||||
RealTime(call_info|exten|${CALLERIDNUM:5}|ct_);
|
||||
if ("${ct_calltrace}foo" = "foo") {
|
||||
Playback(loligo/from-unknown-caller);
|
||||
Hangup;
|
||||
} else {
|
||||
SayDigits("${ct_calltrace}");
|
||||
Set(TIMEOUT(digit)=3);
|
||||
Set(TIMEOUT(response)=7);
|
||||
Background(loligo/to-call-this-number);
|
||||
Background(press-1);
|
||||
Background(loligo/silence/5);
|
||||
};
|
||||
};
|
||||
|
||||
1 => goto local|${ct_calltrace}|1;
|
||||
|
||||
i => {
|
||||
Playback(vm-goodbye);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
t => {
|
||||
Playback(vm-goodbye);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-set-monitor {
|
||||
*50 => {
|
||||
Realtime(call_info|exten|${CALLERIDNUM:5}|mon_set_);
|
||||
if ("${mon_set_monitor}" = "YES") {
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|);
|
||||
System(/usr/local/bin/db_update.sh call_info monitor '' exten ${CALLERIDNUM:5} &);
|
||||
} else {
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|monitor|YES);
|
||||
System(/usr/local/bin/db_update.sh call_info monitor YES exten ${CALLERIDNUM:5} &);
|
||||
};
|
||||
NoOp(${mon_set_monitor});
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-dnd {
|
||||
*78 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|donotdisturb|YES);
|
||||
System(/usr/local/bin/db_update.sh call_info donotdisturb YES exten ${CALLERIDNUM:5} &);
|
||||
Playback(do-not-disturb);
|
||||
Playback(loligo/activated);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
*79 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|donotdisturb|);
|
||||
System(/usr/local/bin/db_update.sh call_info donotdisturb '' exten ${CALLERIDNUM:5} &);
|
||||
Playback(do-not-disturb);
|
||||
Playback(loligo/de-activated);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-callforward {
|
||||
// forwards calling extension to input number *72{EXTEN}
|
||||
_*72. => {
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardto|${EXTEN:3});
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto ${EXTEN:3} exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-unconditional);
|
||||
Playback(loligo/for);
|
||||
Playback(loligo/extension);
|
||||
SayDigits(${CALLERIDNUM:5});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${EXTEN:3});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// prompts for extension to forward to
|
||||
*72 => {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(please-enter-your);
|
||||
Playback(extension);
|
||||
Background(then-press-pound);
|
||||
VMAuthenticate(|s);
|
||||
Background(loligo/ent-target-attendant);
|
||||
Read(toext,loligo/then-press-pound);
|
||||
Wait(1);
|
||||
RealtimeUpdate(call_info|exten|${AUTH_MAILBOX}|forwardto|${toext});
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto ${toext} exten ${AUTH_MAILBOX} &);
|
||||
Playback(loligo/call-fwd-unconditional);
|
||||
Playback(loligo/for);
|
||||
Playback(loligo/extension);
|
||||
SayDigits(${AUTH_MAILBOX});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${toext});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// cancels dialed extension call forward
|
||||
_*73. => {
|
||||
Realtime(voicemail|mailbox|${EXTEN:3}|auth_);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Authenticate(${auth_password});
|
||||
RealtimeUpdate(call_info|exten|${EXTEN:3}|forwardto|);
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${EXTEN:3} &);
|
||||
Wait(1);
|
||||
SayDigits(${EXTEN:3});
|
||||
Playback(loligo/call-fwd-cancelled);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// cancels call forward for calling extension
|
||||
*73 => {
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardto|);
|
||||
System(/usr/local/bin/db_update.sh call_info forwardto '' exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-cancelled);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// dialed call forward on busy
|
||||
_*90. => {
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardbusy|${EXTEN:3});
|
||||
System(/usr/local/bin/db_update.sh call_info forwardbusy ${EXTEN:3} exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-on-busy);
|
||||
Playback(loligo/for);
|
||||
Playback(loligo/extension);
|
||||
SayDigits(${CALLERIDNUM:5});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${EXTEN:3});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// cancels call forward on busy for calling extension
|
||||
*91 => {
|
||||
RealtimeUpdate(call_info|exten|${CALLERIDNUM:5}|forwardbusy|);
|
||||
System(/usr/local/bin/db_update.sh call_info forwardbusy '' exten ${CALLERIDNUM:5} &);
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/call-fwd-on-busy);
|
||||
Playback(loligo/de-activated);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
h => Hangup;
|
||||
};
|
||||
|
||||
context app-idblock {
|
||||
_*67. => {
|
||||
Set(CALLERID(name)=Anonymous);
|
||||
&stdexten(${EXTEN:3});
|
||||
};
|
||||
};
|
||||
|
||||
context app-dictate {
|
||||
*1 => {
|
||||
Dictate();
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-ssd {
|
||||
// *59 <xx> <y.> - Set system speed dial <xx> to digits <y.>
|
||||
// *59 <xx> 0 - Delete system speed dial <xx>
|
||||
// *59 <xx> - Review system speed dial <xx>
|
||||
// *1xx - Dial speed dial <xx>
|
||||
_*59XXX. => {
|
||||
Answer;
|
||||
RealtimeUpdate(ssd|sd|${EXTEN:3:2}|extension|${EXTEN:5});
|
||||
System(/usr/local/bin/db_update.sh systemsd extension ${EXTEN:5} sd ${EXTEN:3:2} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-set-to);
|
||||
SayDigits(${EXTEN:5});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*59XX0 => {
|
||||
Answer;
|
||||
RealtimeUpdate(ssd|sd|${EXTEN:3:2}|extension|);
|
||||
System(/usr/local/bin/db_update.sh systemsd extension '' sd ${EXTEN:3:2} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-cleared);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*59XX => {
|
||||
Answer;
|
||||
Realtime(ssd|sd|${EXTEN:3}|ssd_);
|
||||
if ("${ssd_extension}foo" = "foo") {
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${ssd_extension});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// NTC = number to call
|
||||
_*1XX => {
|
||||
Realtime(ssd|sd|${EXTEN:2}|ssd_);
|
||||
if ("${ssd_extension}foo" = "foo") {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
&stdexten(${ssd_extension});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
macro check-psd-exists ( ext ) {
|
||||
Realtime(psd|extension|${ext}|psd_);
|
||||
if ("${psd_extension}foo" = "foo") {
|
||||
System(/usr/local/bin/create_psd.sh ${ext});
|
||||
} else
|
||||
NoOp(PSD set for ${ext});
|
||||
};
|
||||
|
||||
context app-psd {
|
||||
// *89 <xx> <y.> - Set personal speed dial <xx> to digits <y.>
|
||||
// *89 <xx> 0 - Delete personal speed dial <xx>
|
||||
// *89 <xx> - Review personal speed dial <xx>
|
||||
// *2xx - Dial personal speed dial <xx>
|
||||
_*89XXX. => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Answer;
|
||||
RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|${EXTEN:5});
|
||||
System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} ${EXTEN:5} extension ${CALLERIDNUM:5} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-set-to);
|
||||
SayDigits(${EXTEN:5});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*89XX0 => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Answer;
|
||||
RealtimeUpdate(psd|extension|${CALLERIDNUM:5}|s${EXTEN:3:2}|);
|
||||
System(/usr/local/bin/db_update.sh personalsd s${EXTEN:3:2} '' extension ${CALLERIDNUM:5} &);
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/has-been-cleared);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_*89XX => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Answer;
|
||||
Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
|
||||
Wait(1);
|
||||
if ("${psd_s${EXTEN:3:2}}foo" = "foo") {
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:3:2});
|
||||
Playback(loligo/is-set-to);
|
||||
SayDigits(${psd_s${EXTEN:3:2}});
|
||||
Hangup;
|
||||
};
|
||||
|
||||
// NTC = number to call
|
||||
_*2XX => {
|
||||
&check-psd-exists(${CALLERIDNUM:5});
|
||||
Realtime(psd|extension|${CALLERIDNUM:5}|psd_);
|
||||
if ("${psd_s${EXTEN:2}}foo" = "foo") {
|
||||
Answer;
|
||||
Wait(1);
|
||||
Playback(loligo/speed-dial);
|
||||
SayDigits(${EXTEN:2});
|
||||
Playback(loligo/is-not-set);
|
||||
Hangup;
|
||||
};
|
||||
&stdexten(${psd_s${EXTEN:2}});
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context app-helpdesk {
|
||||
*4357 => {
|
||||
&stdexten(41950);
|
||||
Congestion;
|
||||
};
|
||||
};
|
||||
|
||||
context app-conferences {
|
||||
// waiting for room number announcement
|
||||
*86 => goto app-conf-hidden|s|1;
|
||||
};
|
||||
|
||||
context app-conf-hidden {
|
||||
s => {
|
||||
Wait(1);
|
||||
Playback(loligo/please-enter-the);
|
||||
Playback(loligo/extension);
|
||||
read(roomtoenter,loligo/then-press-pound);
|
||||
Meetme(${roomtoenter});
|
||||
Waitexten(8);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
_1. => Meetme(${EXTEN});
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Extensions pulled from vm.conf:
|
||||
|
||||
context vm-include {
|
||||
includes {
|
||||
vm-direct;
|
||||
vm-extension;
|
||||
vm-directory;
|
||||
};
|
||||
};
|
||||
|
||||
context vm-direct {
|
||||
s => {
|
||||
Dial(SIP/5555@svm1.shsu.edu,20);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Playback(extra/pls-try-call-later);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context vm-extension {
|
||||
s => {
|
||||
Dial(SIP/62100@svm1.shsu.edu,20);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Playback(extra/pls-try-call-later);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
||||
|
||||
context vm-directory {
|
||||
5556 => {
|
||||
Dial(SIP/5556@svm1.shsu.edu);
|
||||
Playback(im-sorry);
|
||||
Playback(voice-mail-system);
|
||||
Playback(down);
|
||||
Playback(extra/pls-try-call-later);
|
||||
Congestion(10);
|
||||
Hangup;
|
||||
};
|
||||
};
|
|
@ -0,0 +1,460 @@
|
|||
//
|
||||
// Example AEL config file
|
||||
//
|
||||
|
||||
globals {
|
||||
CONSOLE=Console/dsp;
|
||||
TRUNKMSD=0; //MSD digits to strip (usually 1 or 0)
|
||||
TRUNCPROTO=SIP;
|
||||
TRUNK=sunrocket;
|
||||
PSTN=pstn-spa3k;
|
||||
PSTNPROTO=SIP;
|
||||
TARIOPROTO=SIP;
|
||||
TARIO=tario;
|
||||
CPPROTO=SIP;
|
||||
CPACKET1=callpacket1;
|
||||
CPACKET2=callpacket2;
|
||||
SELLVOIP=1577040314;
|
||||
SVPROTO=IAX2;
|
||||
};
|
||||
|
||||
|
||||
macro stdexten (ext , dev ) {
|
||||
PrivacyManager(3,10);
|
||||
if("${PRIVACYMGRSTATUS}" = "FAILED") {
|
||||
Playback(vm-goodbye);
|
||||
Hangup();
|
||||
};
|
||||
|
||||
AGI(calleridnamelookup.agi);
|
||||
Dial(${dev}/${ext},30,t);
|
||||
switch(${DIALSTATUS}) {
|
||||
case BUSY:
|
||||
Voicemail(b${ext});
|
||||
break;
|
||||
default:
|
||||
Voicemail(u${ext});
|
||||
};
|
||||
catch a {
|
||||
VoiceMailMain(${ext});
|
||||
return;
|
||||
};
|
||||
};
|
||||
|
||||
macro announce_minutes(minutes) {
|
||||
Playback(vm-youhave);
|
||||
SayNumber(${minutes});
|
||||
Playback(vm-minutes);
|
||||
Wait(1);
|
||||
};
|
||||
|
||||
// Check if given provider allows only some free minutes per month
|
||||
// and announce number of free minutes remaining.
|
||||
// The limit will be reset monthly by cron job.
|
||||
// The macro sets the following variables:
|
||||
// MINUTES_LIMIT - number of free minutes per month
|
||||
// MINUTES_USED - number of free minutes used in the current month
|
||||
// PROVIDER - provider name
|
||||
|
||||
macro checkanddial(prov,proto,ext,arg1,arg2,arg3,arg4) {
|
||||
Set(MINUTES_LIMIT=0);
|
||||
Set(MINUTES_USED=0);
|
||||
Set(PROVIDER=${prov});
|
||||
|
||||
if(${DB_EXISTS(Provider/${prov}/used)})
|
||||
Set(MINUTES_USED=${DB_RESULT});
|
||||
|
||||
country_c = 0;
|
||||
switch(${LEN(${ext})}) { //assuming all international numbers are 11 digits long.
|
||||
case 10: //NXXNXXXXXX
|
||||
country_c=1;
|
||||
break;
|
||||
case 11: //XNXXNXXXXXX
|
||||
country_c = ${ext:0:1};
|
||||
break;
|
||||
default: //011XNXXNXXXXXX
|
||||
country_c = ${ext:3:1};
|
||||
break;
|
||||
};
|
||||
|
||||
if("${prov}" = "${TRUNK}" & ${country_c} != 1) { // SunRocket international calls
|
||||
Set(MINUTES_LIMIT=${DB(Provider/${prov}/limit)});
|
||||
&announce_minutes($[${MINUTES_LIMIT} - ${MINUTES_USED}]);
|
||||
};
|
||||
if("${prov}" = "${CPACKET1}" | "${prov}" = "${CPACKET2}") { // Callpacket has a limit on domestic calls
|
||||
Set(MINUTES_LIMIT=${DB(Provider/${prov}/limit)});
|
||||
&announce_minutes($[${MINUTES_LIMIT} - ${MINUTES_USED}]);
|
||||
};
|
||||
DeadAGI(dial.agi,${proto}/${ext}@${prov},${arg1},${arg2},${arg3},${arg4});
|
||||
};
|
||||
|
||||
macro trunkdial(ext) { // Dial sunrocket and set correct collerid
|
||||
if("${CALLERID(number)}" = "1") {
|
||||
Set(CALLERID(number)=7322271653);
|
||||
} else {
|
||||
Set(CALLERID(number)=7326260100);
|
||||
};
|
||||
Set(CALLERID(name)=Sergey Okhapkin);
|
||||
&checkanddial(${TRUNK},${TRUNCPROTO},${ext},60,T);
|
||||
Hangup;
|
||||
};
|
||||
|
||||
macro checklocal(ext) { // lookup the number in DB and call the number via pstn or sunrocket
|
||||
Set(AREACODE=${ext:0:3});
|
||||
Set(EXCHANGE=${ext:3:3});
|
||||
Set(IS_LOCAL=${DB_EXISTS(localnum/${AREACODE}/${EXCHANGE})});
|
||||
if(${IS_LOCAL}) {
|
||||
&checkanddial(${PSTN},${PSTNPROTO},${ext},60,T);
|
||||
if ("${DIALSTATUS}" = "BUSY")
|
||||
&trunkdial(${ext});
|
||||
} else
|
||||
&trunkdial(${ext});
|
||||
};
|
||||
|
||||
macro autodial(ext) { // Find Least Cost Route
|
||||
LCDial(${ext},60,T);
|
||||
if("${DIALSTATUS}" = "NOPROVIDER")
|
||||
Playback(invalid);
|
||||
Hangup();
|
||||
};
|
||||
|
||||
context default { // Calls to us
|
||||
s => {
|
||||
Wait(1);
|
||||
Answer;
|
||||
start:
|
||||
Set(TIMEOUT(digit)=3);
|
||||
Set(TIMEOUT(response)=10);
|
||||
repeat:
|
||||
for (x=0; ${x} < 5; x=${x} + 1) {
|
||||
Background(home/greeting);
|
||||
WaitExten();
|
||||
};
|
||||
};
|
||||
t => jump *;
|
||||
i => { // invalid extension
|
||||
Playback(invalid);
|
||||
goto s|repeat;
|
||||
};
|
||||
_* => {
|
||||
Playback(vm-goodbye);
|
||||
Wait(1);
|
||||
Hangup;
|
||||
};
|
||||
1 => &stdexten(1,SIP/1);
|
||||
2 => &stdexten(2,SIP/2);
|
||||
3 => &stdexten(3,SIP/3);
|
||||
|
||||
2271653 => jump 1;
|
||||
7322271653 => jump 1;
|
||||
17322271653 => jump 1;
|
||||
|
||||
6260100 => jump 2;
|
||||
7326260100 => jump 2;
|
||||
17326260100 => jump 2;
|
||||
8058701100 => jump 2;
|
||||
3103622835 => jump 2;
|
||||
sos => jump 2;
|
||||
1400898 => jump 2;
|
||||
|
||||
6260101 => jump s;
|
||||
7326260101 => jump s;
|
||||
17326260101 => jump s;
|
||||
|
||||
2271677 => jump 3;
|
||||
7322271677 => jump 3;
|
||||
17322271677 => jump 3;
|
||||
galka => jump 3;
|
||||
911 => Dial(${PSTNPROTO}/911@${PSTN},60,);
|
||||
380 => Dial(SIP/topspeen@212.40.38.70,60,T);
|
||||
|
||||
// Fun stuff
|
||||
100 => {
|
||||
SayUnixTime();
|
||||
goto s|start;
|
||||
};
|
||||
101 => { // Voicemail
|
||||
VoicemailMain(${CALLERID(number)});
|
||||
Hangup;
|
||||
};
|
||||
102 => MusicOnHold();
|
||||
// 103 => {
|
||||
// Wait(1);
|
||||
//start:
|
||||
// Read(NUMBER,vm-enter-num-to-call);
|
||||
// LCDial(${NUMBER},T);
|
||||
// goto start;
|
||||
// };
|
||||
105 => jump s@phrase-menu;
|
||||
7312 => {
|
||||
ForkCDR;
|
||||
Set(CALLERID(name)=Sergey Okhapkin);
|
||||
Set(CALLERID(number)=7326260100);
|
||||
DISA(1111|home);
|
||||
};
|
||||
};
|
||||
|
||||
context goiax {
|
||||
s => {
|
||||
Answer();
|
||||
Ringing();
|
||||
Wait(1);
|
||||
start:
|
||||
Read(NUMBER,vm-enter-num-to-call);
|
||||
Set(CALLERID(name)=Central NJ);
|
||||
Dial(IAX2/14301@fwdOUT/q${NUMBER},60,T);
|
||||
goto start;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
context phrase-menu {
|
||||
|
||||
s => {
|
||||
Answer; // Answer the line
|
||||
TIMEOUT(digit)=2; // Set Digit Timeout to 5 seconds
|
||||
TIMEOUT(response)=10; // Set Response Timeout to 10 seconds
|
||||
BackGround(custom/phrase-menu); // Play main menu.
|
||||
};
|
||||
1 => { // Phrase Recording
|
||||
Wait(1);
|
||||
Read(PHRASEID|custom/enter-phrase-num);
|
||||
Wait(2); // give yourself 2 secs to take a breath and wait for beep
|
||||
Record(custom/${PHRASEID}:gsm);
|
||||
Wait(2);
|
||||
Playback(custom/${PHRASEID});
|
||||
Wait(1);
|
||||
jump s;
|
||||
};
|
||||
2 => { // Phrase review
|
||||
Wait(1);
|
||||
Read(PHRASEID|custom/enter-phrase-num);
|
||||
Wait(1);
|
||||
Playback(custom/${PHRASEID});
|
||||
Wait(1);
|
||||
jump s;
|
||||
};
|
||||
t => Hangup;
|
||||
i => {
|
||||
Playback(custom/invalid-option);
|
||||
jump s;
|
||||
};
|
||||
};
|
||||
|
||||
context outbound {
|
||||
// North America seven-, ten- and eleven digits
|
||||
_NXXXXXX => &autodial(1732${EXTEN});
|
||||
_NXXNXXXXXX => &autodial(1${EXTEN});
|
||||
_ZNXXNXXXXX. => &autodial(${EXTEN});
|
||||
// Toll free numbers via PSTN
|
||||
// _1800NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
|
||||
// _1888NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
|
||||
// _1877NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
|
||||
// _1866NXXXXXX => &checkanddial(${PSTN},${PSTNPROTO},${EXTEN},60,T);
|
||||
|
||||
_011. => { //International context accessed through trunk
|
||||
&trunkdial(${EXTEN});
|
||||
};
|
||||
_012. => { //fwdOUT
|
||||
Set(CALLERID(name)=Central NJ);
|
||||
Dial(IAX2/14301@fwdOUT/q${EXTEN:3},60,T);
|
||||
};
|
||||
_013X. => { //NECC
|
||||
Dial(${PSTNPROTO}/011${EXTEN:3}@${PSTN},60,T);
|
||||
};
|
||||
_0131. => { //NECC to US
|
||||
Dial(${PSTNPROTO}/${EXTEN:3}@${PSTN},60,T);
|
||||
};
|
||||
_014. => { //TARIO by SIP ID
|
||||
Set(CALLERID(name)=Sergey Okhapkin);
|
||||
Set(CALLERID(number)=1400898);
|
||||
Dial(${TARIOPROTO}/${EXTEN:3}@${TARIO},60,T);
|
||||
};
|
||||
_0157. => { //TARIO outbound Russia
|
||||
Set(CALLERID(name)=Sergey Okhapkin);
|
||||
Set(CALLERID(number)=1400898);
|
||||
Dial(${TARIOPROTO}/8${EXTEN:4}@${TARIO},60,T);
|
||||
};
|
||||
// _015. => { //TARIO outbound international
|
||||
// CALLERID(name)="Sergey Okhapkin";
|
||||
// CALLERID(number)=1400898;
|
||||
// Dial(${TARIOPROTO}/810${EXTEN:3}@${TARIO},60,T);
|
||||
// };
|
||||
_0161NXXNXXXXXX => { //Callpacket outbound USA/Canada
|
||||
&checkanddial(${CPACKET1},${CPPROTO},${EXTEN:3},60,T);
|
||||
};
|
||||
_0171NXXNXXXXXX => { //Callpacket outbound USA/Canada
|
||||
&checkanddial(${CPACKET2},${CPPROTO},${EXTEN:3},60,T);
|
||||
};
|
||||
_0181NXXNXXXXXX => { //sellvoip outbound USA/Canada
|
||||
Dial(${SVPROTO}/${SELLVOIP}@${SELLVOIP}/${EXTEN:3},60,T);
|
||||
};
|
||||
_019. => { //Voipbuster
|
||||
Dial(IAX2/sokhapkin@voipbuster/00${EXTEN:3},60,T);
|
||||
};
|
||||
};
|
||||
|
||||
context home { //calls from us
|
||||
includes {
|
||||
default;
|
||||
outbound;
|
||||
};
|
||||
};
|
||||
|
||||
context sunrocket-in {
|
||||
7322271653 => jump s;
|
||||
7326260100 => jump 2@default;
|
||||
s => {
|
||||
if("${CALLERID(number)}" = "sunrocketcom")
|
||||
Set(CALLERID(number)=);
|
||||
switch(${CALLERID(RDNIS)}) {
|
||||
case 7326260100:
|
||||
jump 2@default;
|
||||
break;
|
||||
case 7326260101:
|
||||
jump s@default;
|
||||
break;
|
||||
default:
|
||||
jump 1@default;
|
||||
break;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
context pstn-in {
|
||||
3 => {
|
||||
if ("${CALLERID(number)}" = "7322271677")
|
||||
Set(CALLERID(number)=);
|
||||
jump 3@default;
|
||||
};
|
||||
};
|
||||
|
||||
context tario.net-in {
|
||||
_X. => {
|
||||
Set(CALLERID(name)=);
|
||||
if("${CALLERID(number):-11:1}" = "8")
|
||||
Set(CALLERID(number)=7${CALLERID(number):1});
|
||||
if("${SIP_HEADER(To)}" = "<sip:2271677@sipnet.ru>") {
|
||||
jump 3@default;
|
||||
} else if("${SIP_HEADER(To)}" = "<sip:2271653@sipnet.ru>") {
|
||||
jump 1@default;
|
||||
} else
|
||||
jump 2@default;
|
||||
};
|
||||
};
|
||||
|
||||
context from-callpacket {
|
||||
8058701100 => jump 2@default;
|
||||
3103622835 => {
|
||||
Answer;
|
||||
Ringing;
|
||||
Wait(10);
|
||||
Voicemail(b3103622835);
|
||||
Hangup;
|
||||
};
|
||||
a => Hangup;
|
||||
};
|
||||
|
||||
context fromfwdOUT { // make sure we only accept US and Canada calls, limit to 30 minutes
|
||||
includes {
|
||||
fromfwdOUT-catchbad;
|
||||
fromfwdOUT-isgood;
|
||||
fromfwdOUT-catchall;
|
||||
};
|
||||
};
|
||||
|
||||
context fromfwdOUT-isgood {
|
||||
_17326260100 => jump 2@default;
|
||||
_17326260101 => jump s@default;
|
||||
_17322271653 => jump 1@default;
|
||||
_17322271677 => jump 3@default;
|
||||
_1NXXNXXXXXX => {
|
||||
Set(CALLERID(name)=Sergey Okhapkin);
|
||||
// Set(CALLERID(number)=7326260100);
|
||||
// Dial(${TRUNCPROTO}/*67${EXTEN:${TRUNKMSD}}@${TRUNK},60,,L(1800000:60000));
|
||||
Dial(${CPPROTO}/${EXTEN}@${CPACKET2},60,,L(1800000:60000));
|
||||
};
|
||||
};
|
||||
|
||||
context fromfwdOUT-catchbad { //block bahamas, etc
|
||||
_1900. => congestion ; //N11
|
||||
_1XXX976. => congestion ; //N11
|
||||
_1XXX555. => congestion ; //N11
|
||||
_1X11. => congestion ; //N11
|
||||
_1867. => congestion ; //Yukon (sorry mike)
|
||||
|
||||
// exten => _1NPA Country
|
||||
_1242. => congestion; //BAHAMAS
|
||||
_1246. => congestion; //BARBADOS
|
||||
_1264. => congestion; //ANGUILLA
|
||||
_1268. => congestion; //ANTIGUA/BARBUDA
|
||||
_1284. => congestion; //BRITISH VIRGIN ISLANDS
|
||||
_1345. => congestion; //CAYMAN ISLANDS
|
||||
_1441. => congestion; //BERMUDA
|
||||
_1473. => congestion; //GRENADA
|
||||
_1649. => congestion; //TURKS & CAICOS ISLANDS
|
||||
_1664. => congestion; //MONTSERRAT
|
||||
_1758. => congestion; //ST. LUCIA
|
||||
_1767. => congestion; //DOMINICA
|
||||
_1784. => congestion; //ST. VINCENT & GRENADINES
|
||||
_1809. => congestion; //DOMINICAN REPUBLIC
|
||||
_1829. => congestion; //DOMINICAN REPUBLIC
|
||||
_1868. => congestion; //TRINIDAD AND TOBAGO
|
||||
_1869. => congestion; //ST. KITTS AND NEVIS
|
||||
_1876. => congestion; //JAMAICA
|
||||
_1787. => congestion; //Puerto Rico 787, 939 $0.07
|
||||
_1939. => congestion; //Puerto Rico 787, 939 $0.07
|
||||
_1671. => congestion; //Guam 671 $0.08
|
||||
_1340. => congestion; //U.S. Virgin Islands 340 $0.06
|
||||
};
|
||||
|
||||
context fromfwdOUT-catchall {
|
||||
_X. => Congestion;
|
||||
h => Hangup ; //hangup event
|
||||
i => Hangup ; //invalid event
|
||||
t => Hangup ; //timeout event
|
||||
};
|
||||
|
||||
context ael-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;
|
||||
};
|
||||
_1234 => &std-exten-ael(${EXTEN}, "IAX2");
|
||||
# => {
|
||||
Playback(demo-thanks);
|
||||
Hangup();
|
||||
};
|
||||
t => jump #;
|
||||
i => Playback(invalid);
|
||||
};
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
Executed ast_register_file_version();
|
||||
LOG: lev:2 file:pbx_ael.c line:3428 func: pbx_load_module Starting AEL load process.
|
||||
LOG: lev:2 file:pbx_ael.c line:3435 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3438 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
|
||||
LOG: lev:3 file:pbx_ael.c line:891 func: check_dow Warning: file ./extensions.ael, line 67-67: The day (m0n) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!
|
||||
LOG: lev:3 file:pbx_ael.c line:849 func: check_timerange Warning: file ./extensions.ael, line 78-78: The end time (25:00) is out of range!
|
||||
LOG: lev:2 file:pbx_ael.c line:3441 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3443 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3446 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3449 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
|
||||
LOG: lev:4 file:ael2_parse line:261 func: main 5 contexts, 13 extensions, 156 priorities
|
|
@ -0,0 +1,15 @@
|
|||
Executed ast_register_file_version();
|
||||
LOG: lev:2 file:pbx_ael.c line:3428 func: pbx_load_module Starting AEL load process.
|
||||
LOG: lev:2 file:pbx_ael.c line:3435 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file ./apptest.ael2, 3474 chars
|
||||
LOG: lev:3 file:ael.y line:405 func: ael_yyparse ==== File: ./apptest.ael2, Line 46, Cols: 8-11: Suggestion: Use the goto statement instead of the Goto() application call in AEL.
|
||||
LOG: lev:2 file:pbx_ael.c line:3438 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 35-35: application call to EndWhile needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 37-37: application call to ExecIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:4 file:pbx_ael.c line:1100 func: check_goto Error: file ./apptest.ael2, line 46-46: goto: no context cont could be found that matches the goto target!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 47-47: application call to GotoIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 48-48: application call to GotoIfTime needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 85-85: application call to Random needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 141-141: application call to While needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:4 file:pbx_ael.c line:3451 func: pbx_load_module Sorry, but 0 syntax errors and 1 semantic errors were detected. It doesn't make sense to compile.
|
||||
LOG: lev:4 file:ael2_parse line:261 func: main 0 contexts, 0 extensions, 0 priorities
|
|
@ -0,0 +1,18 @@
|
|||
Executed ast_register_file_version();
|
||||
LOG: lev:2 file:pbx_ael.c line:3428 func: pbx_load_module Starting AEL load process.
|
||||
LOG: lev:2 file:pbx_ael.c line:3435 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file ./include1.ael2, 78 chars
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file ./include2.ael2, 98 chars
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file ./include3.ael2, 57 chars
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file ./include5.ael2, 56 chars
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file ./include4.ael2, 87 chars
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file /etc/asterisk/telemarket_torture.ael2, 28036 chars
|
||||
LOG: lev:2 file:pbx_ael.c line:3438 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
|
||||
LOG: lev:3 file:pbx_ael.c line:2186 func: check_pval_item Warning: file ./extensions.ael, line 5-5: expression Console/dsp has operators, but no variables. Interesting...
|
||||
LOG: lev:3 file:pbx_ael.c line:2186 func: check_pval_item Warning: file ./extensions.ael, line 8-8: expression "Joe-Worker" has operators, but no variables. Interesting...
|
||||
LOG: lev:3 file:pbx_ael.c line:2186 func: check_pval_item Warning: file ./extensions.ael, line 10-10: expression Zap/6 has operators, but no variables. Interesting...
|
||||
LOG: lev:2 file:pbx_ael.c line:3441 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3443 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3446 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3449 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
|
||||
LOG: lev:4 file:ael2_parse line:261 func: main 172 contexts, 858 extensions, 2326 priorities
|
|
@ -0,0 +1,15 @@
|
|||
Executed ast_register_file_version();
|
||||
LOG: lev:2 file:pbx_ael.c line:3428 func: pbx_load_module Starting AEL load process.
|
||||
LOG: lev:2 file:pbx_ael.c line:3435 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
|
||||
LOG: lev:2 file:ael.flex line:467 func: ael_yylex --Read in included file ./apptest.ael2, 3474 chars
|
||||
LOG: lev:3 file:ael.y line:405 func: ael_yyparse ==== File: ./apptest.ael2, Line 46, Cols: 8-11: Suggestion: Use the goto statement instead of the Goto() application call in AEL.
|
||||
LOG: lev:2 file:pbx_ael.c line:3438 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 35-35: application call to EndWhile needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 37-37: application call to ExecIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:4 file:pbx_ael.c line:1100 func: check_goto Error: file ./apptest.ael2, line 46-46: goto: no context cont could be found that matches the goto target!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 47-47: application call to GotoIf needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 48-48: application call to GotoIfTime needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 85-85: application call to Random needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:3 file:pbx_ael.c line:2081 func: check_pval_item Warning: file ./apptest.ael2, line 141-141: application call to While needs to be re-written using AEL if, while, goto, etc. keywords instead!
|
||||
LOG: lev:4 file:pbx_ael.c line:3451 func: pbx_load_module Sorry, but 0 syntax errors and 1 semantic errors were detected. It doesn't make sense to compile.
|
||||
LOG: lev:4 file:ael2_parse line:261 func: main 0 contexts, 0 extensions, 0 priorities
|
|
@ -0,0 +1,9 @@
|
|||
Executed ast_register_file_version();
|
||||
LOG: lev:2 file:pbx_ael.c line:3428 func: pbx_load_module Starting AEL load process.
|
||||
LOG: lev:2 file:pbx_ael.c line:3435 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3438 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3441 func: pbx_load_module AEL load process: checked config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3443 func: pbx_load_module AEL load process: compiled config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3446 func: pbx_load_module AEL load process: merged config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3449 func: pbx_load_module AEL load process: verified config file name './extensions.ael'.
|
||||
LOG: lev:4 file:ael2_parse line:261 func: main 38 contexts, 90 extensions, 484 priorities
|
|
@ -0,0 +1,20 @@
|
|||
Executed ast_register_file_version();
|
||||
LOG: lev:2 file:pbx_ael.c line:3428 func: pbx_load_module Starting AEL load process.
|
||||
LOG: lev:2 file:pbx_ael.c line:3435 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
|
||||
LOG: lev:4 file:ael.flex line:193 func: ael_yylex File=./extensions.ael, line=165, column=21: Mismatched '}' in expression!
|
||||
LOG: lev:4 file:ael.y line:674 func: ael_yyerror ==== File: ./extensions.ael, Line 165, Cols: 23-23: Error: syntax error, unexpected '=', expecting ')'
|
||||
LOG: lev:4 file:ael.flex line:317 func: ael_yylex File=./extensions.ael, line=174, column=63: Mismatched '}' in expression!
|
||||
LOG: lev:4 file:ael.flex line:317 func: ael_yylex File=./extensions.ael, line=180, column=46: Mismatched '}' in expression!
|
||||
LOG: lev:4 file:ael.y line:674 func: ael_yyerror ==== File: ./extensions.ael, Line 184, Cols: 0-4: Error: syntax error, unexpected 'macro'
|
||||
LOG: lev:4 file:ael.flex line:193 func: ael_yylex File=./extensions.ael, line=222, column=21: Mismatched '}' in expression!
|
||||
LOG: lev:4 file:ael.y line:674 func: ael_yyerror ==== File: ./extensions.ael, Line 222, Cols: 23-23: Error: syntax error, unexpected '=', expecting ')'
|
||||
LOG: lev:4 file:ael.flex line:317 func: ael_yylex File=./extensions.ael, line=228, column=37: Mismatched '}' in expression!
|
||||
LOG: lev:4 file:ael.y line:674 func: ael_yyerror ==== File: ./extensions.ael, Line 235, Cols: 0-6: Error: syntax error, unexpected 'context'
|
||||
LOG: lev:4 file:ael.y line:674 func: ael_yyerror ==== File: ./extensions.ael, Line 344, Cols: 32-32: Error: syntax error, unexpected ';', expecting '{'
|
||||
LOG: lev:4 file:ael.y line:674 func: ael_yyerror ==== File: ./extensions.ael, Line 350, Cols: 32-32: Error: syntax error, unexpected ';', expecting '{'
|
||||
LOG: lev:4 file:ael.y line:674 func: ael_yyerror ==== File: ./extensions.ael, Line 461, Cols: 10-13: Error: syntax error, unexpected 'else'
|
||||
LOG: lev:2 file:pbx_ael.c line:3438 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
|
||||
LOG: lev:4 file:pbx_ael.c line:1100 func: check_goto Error: file ./extensions.ael, line 11-11: goto: no context default could be found that matches the goto target!
|
||||
LOG: lev:4 file:pbx_ael.c line:2036 func: check_pval_item Error: file ./extensions.ael, line 206-206: macro call to non-existent uvm !
|
||||
LOG: lev:4 file:pbx_ael.c line:3451 func: pbx_load_module Sorry, but 7 syntax errors and 2 semantic errors were detected. It doesn't make sense to compile.
|
||||
LOG: lev:4 file:ael2_parse line:261 func: main 0 contexts, 0 extensions, 0 priorities
|
|
@ -0,0 +1,13 @@
|
|||
Executed ast_register_file_version();
|
||||
LOG: lev:2 file:pbx_ael.c line:3428 func: pbx_load_module Starting AEL load process.
|
||||
LOG: lev:2 file:pbx_ael.c line:3435 func: pbx_load_module AEL load process: calculated config file name './extensions.ael'.
|
||||
LOG: lev:2 file:pbx_ael.c line:3438 func: pbx_load_module AEL load process: parsed config file name './extensions.ael'.
|
||||
LOG: lev:3 file:pbx_ael.c line:2186 func: check_pval_item Warning: file ./extensions.ael, line 6-6: expression Console/dsp has operators, but no variables. Interesting...
|
||||
LOG: lev:3 file:pbx_ael.c line:2186 func: check_pval_item Warning: file ./extensions.ael, line 10-10: expression pstn-spa3k has operators, but no variables. Interesting...
|
||||
LOG: lev:4 file:pbx_ael.c line:2055 func: check_pval_item Error: file ./extensions.ael, line 98-98: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
|
||||
LOG: lev:4 file:pbx_ael.c line:2055 func: check_pval_item Error: file ./extensions.ael, line 107-107: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
|
||||
LOG: lev:4 file:pbx_ael.c line:2055 func: check_pval_item Error: file ./extensions.ael, line 284-284: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
|
||||
LOG: lev:4 file:pbx_ael.c line:2055 func: check_pval_item Error: file ./extensions.ael, line 287-287: The macro call to checkanddial has 5 arguments, but the macro definition has 7 arguments
|
||||
LOG: lev:4 file:pbx_ael.c line:2036 func: check_pval_item Error: file ./extensions.ael, line 452-452: macro call to non-existent std-exten-ael !
|
||||
LOG: lev:4 file:pbx_ael.c line:3451 func: pbx_load_module Sorry, but 0 syntax errors and 5 semantic errors were detected. It doesn't make sense to compile.
|
||||
LOG: lev:4 file:ael2_parse line:261 func: main 0 contexts, 0 extensions, 0 priorities
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/bash
|
||||
|
||||
for i in ael-test*; do
|
||||
echo -n Test: $i..................
|
||||
(cd $i; ../../../../utils/aelparse -n -d | grep -v -i 'seconds' > ../res.$i)
|
||||
if (diff -q res.$i ref.$i > /dev/null 2>&1 ) then
|
||||
echo PASSED
|
||||
rm res.$i
|
||||
else
|
||||
echo %%%%%%FAILED%%%%%%
|
||||
diff -u ref.$i res.$i
|
||||
fi
|
||||
|
||||
done
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
for i in res.*; do
|
||||
refname=`echo $i | sed 's/^res/ref/'`
|
||||
echo $refname
|
||||
mv $i $refname
|
||||
done
|
|
@ -0,0 +1,633 @@
|
|||
%{
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2006, Digium, Inc.
|
||||
*
|
||||
* Steve Murphy <murf@parsetree.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
/*! \file
|
||||
*
|
||||
* \brief Flex scanner description of tokens used in AEL2 .
|
||||
*
|
||||
*/#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "asterisk.h"
|
||||
#include "asterisk/logger.h"
|
||||
#include "ael.tab.h"
|
||||
#include "asterisk/ael_structs.h"
|
||||
|
||||
static char pbcstack[400];
|
||||
static int pbcpos = 0;
|
||||
|
||||
static int parencount = 0;
|
||||
static int commaout = 0;
|
||||
int my_lineno = 1;
|
||||
int my_col = 0;
|
||||
char *my_file = 0;
|
||||
char *prev_word;
|
||||
#define MAX_INCLUDE_DEPTH 50
|
||||
|
||||
void reset_parencount(yyscan_t yyscanner );
|
||||
void reset_semicount(yyscan_t yyscanner );
|
||||
void reset_argcount(yyscan_t yyscanner );
|
||||
struct pval *ael2_parse(char *filename, int *errors);
|
||||
int ael_yyget_column (yyscan_t yyscanner);
|
||||
void ael_yyset_column (int column_no , yyscan_t yyscanner);
|
||||
int ael_yyparse (struct parse_io *);
|
||||
static void pbcpush(char x);
|
||||
static int pbcpop(char x);
|
||||
static void pbcwhere(char *text, int *line, int *col );
|
||||
static int c_prevword(void);
|
||||
|
||||
struct stackelement
|
||||
{
|
||||
char *fname;
|
||||
int lineno;
|
||||
int colno;
|
||||
YY_BUFFER_STATE bufstate;
|
||||
};
|
||||
struct stackelement include_stack[MAX_INCLUDE_DEPTH];
|
||||
int include_stack_index = 0;
|
||||
|
||||
%}
|
||||
|
||||
%x paren semic argg
|
||||
%option prefix="ael_yy"
|
||||
%option batch
|
||||
%option outfile="ael_lex.c"
|
||||
%option reentrant
|
||||
%option bison-bridge
|
||||
%option bison-locations
|
||||
/* %option yylineno I've tried hard, but haven't been able to use this */
|
||||
%option noyywrap
|
||||
|
||||
%%
|
||||
\{ {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LC;}
|
||||
\} {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RC;}
|
||||
\( {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return LP;}
|
||||
\) {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return RP;}
|
||||
\; {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return SEMI;}
|
||||
\= {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EQ;}
|
||||
\, {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COMMA;}
|
||||
\: {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return COLON;}
|
||||
\& {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AMPER;}
|
||||
\| {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return BAR;}
|
||||
\=\> {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return EXTENMARK;}
|
||||
\@ {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return AT;}
|
||||
\/\/[^\n]* {/*comment*/}
|
||||
context {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTEXT;}
|
||||
abstract {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ABSTRACT;}
|
||||
macro {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_MACRO;};
|
||||
globals {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GLOBALS;}
|
||||
ignorepat {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IGNOREPAT;}
|
||||
switch {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCH;}
|
||||
if {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IF;}
|
||||
ifTime {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_IFTIME;}
|
||||
random {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RANDOM;}
|
||||
regexten {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_REGEXTEN;}
|
||||
hint {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_HINT;}
|
||||
else {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ELSE;}
|
||||
goto {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_GOTO;}
|
||||
jump {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_JUMP;}
|
||||
return {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_RETURN;}
|
||||
break {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_BREAK;}
|
||||
continue {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CONTINUE;}
|
||||
for {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_FOR;}
|
||||
while {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_WHILE;}
|
||||
case {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CASE;}
|
||||
default {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_DEFAULT;}
|
||||
pattern {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_PATTERN;}
|
||||
catch {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_CATCH;}
|
||||
switches {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_SWITCHES;}
|
||||
eswitches {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_ESWITCHES;}
|
||||
includes {yylloc->first_line = yylloc->last_line = my_lineno; yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col;my_col+=yyleng;return KW_INCLUDES;}
|
||||
|
||||
\n {my_lineno++;my_col=0;}
|
||||
[ ]+ {/* nothing */ my_col+=yyleng;}
|
||||
[ ]+ {/* nothing */ int wid = 8-(my_col%8); my_col+=wid;}
|
||||
|
||||
[-a-zA-Z0-9'"_/.\<\>\*\+!$#\[\]][-a-zA-Z0-9'"_/.!\*\+\<\>\{\}$#\[\]]* {
|
||||
yylloc->first_line = yylloc->last_line = my_lineno;yylloc->last_column=my_col+yyleng-1; yylloc->first_column=my_col; /* set up the ptr */
|
||||
yylval->str = strdup(yytext);
|
||||
/* printf("\nGot WORD %s[%d][%d:%d]\n", yylval->str, my_lineno ,yylloc->first_column,yylloc->last_column ); */
|
||||
my_col+=yyleng;
|
||||
prev_word = yylval->str;
|
||||
return word;
|
||||
}
|
||||
|
||||
<paren>[^()\[\]\{\}]*\) {yylloc->first_line = my_lineno; yylloc->first_column=my_col;
|
||||
if ( pbcpop(')') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression: %s !\n", my_file, my_lineno+l4, c4, yytext);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
prev_word = 0;
|
||||
return word;
|
||||
}
|
||||
parencount--;
|
||||
if ( parencount >= 0) {
|
||||
yymore();
|
||||
} else {
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=c4;
|
||||
yylval->str = strdup(yytext);
|
||||
*(yylval->str+strlen(yylval->str)-1)=0;
|
||||
/* printf("Got paren word %s\n", yylval->str); */
|
||||
unput(')');
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
BEGIN(0);
|
||||
return word;
|
||||
}
|
||||
}
|
||||
|
||||
<paren>[^()\[\]\{\}]*\( {yylloc->first_line = my_lineno; yylloc->first_column=my_col;
|
||||
parencount++; pbcpush('(');
|
||||
yymore();
|
||||
}
|
||||
<paren>[^()\[\]\{\}]*\[ {yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
|
||||
<paren>[^()\[\]\{\}]*\] {yylloc->first_line = my_lineno;yylloc->first_column=my_col;
|
||||
if ( pbcpop(']') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
yymore();
|
||||
}
|
||||
<paren>[^()\[\]\{\}]*\{ {yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('{'); }
|
||||
<paren>[^()\[\]\{\}]*\} {yylloc->first_line = my_lineno;
|
||||
yylloc->first_column=my_col;
|
||||
if ( pbcpop('}') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
yymore();
|
||||
}
|
||||
|
||||
|
||||
<argg>[^(),\{\}\[\]]*\) {/* printf("ARGG:%s\n",yytext); */
|
||||
int linecount = 0;
|
||||
int colcount = my_col;
|
||||
char *pt = yytext;
|
||||
|
||||
yylloc->first_line = my_lineno;
|
||||
yylloc->first_column=my_col;
|
||||
if ( pbcpop(')') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
|
||||
|
||||
while (*pt) {
|
||||
if (*pt == '\n') {
|
||||
linecount++;
|
||||
colcount=0;
|
||||
}
|
||||
pt++;
|
||||
colcount++;
|
||||
}
|
||||
yylloc->last_line = my_lineno+linecount;
|
||||
yylloc->last_column=colcount;
|
||||
parencount--;
|
||||
if( parencount >= 0){
|
||||
yymore();
|
||||
} else {
|
||||
yylval->str = strdup(yytext);
|
||||
if(yyleng > 1 )
|
||||
*(yylval->str+yyleng-1)=0;
|
||||
/* printf("Got argg word '%s'\n", yylval->str); */
|
||||
BEGIN(0);
|
||||
if ( !strcmp(yylval->str,")") ) {
|
||||
free(yylval->str);
|
||||
yylval->str = 0;
|
||||
my_col+=1;
|
||||
return RP;
|
||||
} else {
|
||||
unput(')');
|
||||
my_col=colcount;
|
||||
my_lineno+=linecount;
|
||||
return word;
|
||||
}
|
||||
}
|
||||
}
|
||||
<argg>[^(),\{\}\[\]]*\( { /* printf("ARGG:%s\n",yytext); */
|
||||
/* printf("GOT AN LP!!!\n"); */
|
||||
yylloc->first_line = my_lineno;
|
||||
yylloc->first_column=my_col;
|
||||
parencount++;
|
||||
pbcpush('(');
|
||||
yymore();
|
||||
}
|
||||
|
||||
<argg>[^(),\{\}\[\]]*\, { /* printf("ARGG:%s\n",yytext); */
|
||||
if( parencount != 0) {
|
||||
/* printf("Folding in a comma!\n"); */
|
||||
yymore();
|
||||
} else {
|
||||
/* printf("got a comma!\n\n"); */
|
||||
int linecount = 0;
|
||||
int colcount = my_col;
|
||||
char *pt;
|
||||
|
||||
pt = yytext;
|
||||
while (*pt) {
|
||||
if ( *pt == '\n' ) {
|
||||
linecount++;
|
||||
colcount=0;
|
||||
}
|
||||
pt++;
|
||||
colcount++;
|
||||
}
|
||||
yylloc->first_line = my_lineno;
|
||||
yylloc->last_line = my_lineno+linecount;
|
||||
yylloc->last_column=colcount;
|
||||
yylloc->first_column=my_col;
|
||||
if( !commaout ) {
|
||||
if( !strcmp(yytext,"," ) )
|
||||
{commaout = 0; my_col+=1; return COMMA;}
|
||||
yylval->str = strdup(yytext); /* printf("Got argg2 word %s\n", yylval->str); */
|
||||
unput(',');
|
||||
commaout = 1;
|
||||
if(yyleng > 1 )
|
||||
*(yylval->str+yyleng-1)=0;
|
||||
my_lineno+=linecount;
|
||||
my_col=colcount;
|
||||
return word;
|
||||
} else {
|
||||
commaout = 0;
|
||||
my_col+=1;
|
||||
return COMMA;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<argg>[^(),\{\}\[\]]*\{ {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; pbcpush('{'); yymore(); }
|
||||
<argg>[^(),\{\}\[\]]*\} {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
|
||||
if ( pbcpop('}') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=my_col+c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
yymore();
|
||||
}
|
||||
<argg>[^(),\{\}\[\]]*\[ {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
|
||||
<argg>[^(),\{\}\[\]]*\] {/*printf("ARGG:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
|
||||
if ( pbcpop(']') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
yymore();
|
||||
}
|
||||
|
||||
|
||||
<semic>[^;()\{\}\[\]]*\[ {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('['); }
|
||||
<semic>[^;()\{\}\[\]]*\] {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
|
||||
if ( pbcpop(']') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ']' in expression!\n", my_file, my_lineno+l4, c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
yymore();}
|
||||
<semic>[^;()\{\}\[\]]*\{ {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('{');}
|
||||
<semic>[^;()\{\}\[\]]*\} {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
|
||||
if ( pbcpop('}') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched '}' in expression!\n", my_file, my_lineno+l4, my_col+c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=my_col+c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
yymore();}
|
||||
<semic>[^;()\{\}\[\]]*\( {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col; yymore(); pbcpush('(');}
|
||||
<semic>[^;()\{\}\[\]]*\) {/*printf("SEMIC:%s\n",yytext);*/yylloc->first_line = my_lineno;yylloc->first_column=my_col;
|
||||
if ( pbcpop(')') ) {
|
||||
/* error */
|
||||
int l4,c4;
|
||||
pbcwhere(yytext, &l4, &c4);
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Mismatched ')' in expression!\n", my_file, my_lineno+l4, my_col+c4);
|
||||
BEGIN(0);
|
||||
yylloc->last_line = my_lineno+l4;
|
||||
yylloc->last_column=my_col+c4;
|
||||
my_col=c4;
|
||||
my_lineno += l4;
|
||||
yylval->str = strdup(yytext);
|
||||
return word;
|
||||
}
|
||||
yymore();}
|
||||
<semic>[^;()\{\}\[\]]*; {
|
||||
int linecount = 0;
|
||||
int colcount = my_col;
|
||||
char *pt = yytext;
|
||||
while (*pt) {
|
||||
if ( *pt == '\n' ) {
|
||||
linecount++;
|
||||
colcount=0;
|
||||
}
|
||||
pt++;
|
||||
colcount++;
|
||||
}
|
||||
yylloc->first_line = my_lineno;
|
||||
yylloc->last_line = my_lineno+linecount;
|
||||
yylloc->last_column=colcount;
|
||||
yylloc->first_column=my_col;
|
||||
yylval->str = strdup(yytext);
|
||||
if(yyleng > 1)
|
||||
*(yylval->str+yyleng-1)=0;
|
||||
/* printf("Got semic word %s\n", yylval->str); */
|
||||
unput(';');
|
||||
BEGIN(0);
|
||||
my_col=colcount;
|
||||
my_lineno += linecount;
|
||||
return word;
|
||||
}
|
||||
|
||||
\#include[ \t]+\"[^\"]+\" {
|
||||
FILE *in1;
|
||||
char fnamebuf[1024],*p1,*p2;
|
||||
if ( include_stack_index >= MAX_INCLUDE_DEPTH ) {
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Includes nested too deeply! Wow!!! How did you do that?\n", my_file, my_lineno, my_col);
|
||||
} else {
|
||||
p1 = strchr(yytext,'"');
|
||||
p2 = strrchr(yytext,'"');
|
||||
if ( (int)(p2-p1) > 1023 ) {
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Filename is incredibly way too long (%d chars!). Inclusion ignored!\n", my_file, my_lineno, my_col, yyleng - 10);
|
||||
} else {
|
||||
int i;
|
||||
int found = 0;
|
||||
strncpy(fnamebuf,p1,p2-p1);
|
||||
fnamebuf[p2-p1] = 0;
|
||||
for (i=0; i<include_stack_index; i++) {
|
||||
if ( !strcmp(fnamebuf,include_stack[i].fname )) {
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Nice Try!!! But %s has already been included (perhaps by another file), and would cause an infinite loop of file inclusions!!! Include directive ignored\n",
|
||||
my_file, my_lineno, my_col, fnamebuf);
|
||||
found=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
{
|
||||
*p2 = 0;
|
||||
/* relative vs. absolute */
|
||||
if ( *(p1+1) != '/' )
|
||||
{
|
||||
strcpy(fnamebuf,ast_config_AST_CONFIG_DIR);
|
||||
strcat(fnamebuf,"/");
|
||||
strcat(fnamebuf,p1+1);
|
||||
}
|
||||
else
|
||||
strcpy(fnamebuf,p1+1);
|
||||
in1 = fopen( fnamebuf, "r" );
|
||||
if ( ! in1 ) {
|
||||
ast_log(LOG_ERROR,"File=%s, line=%d, column=%d: Couldn't find the include file: %s; ignoring the Include directive!\n", my_file, my_lineno, my_col, fnamebuf);
|
||||
} else {
|
||||
char *buffer;
|
||||
struct stat stats;
|
||||
stat(fnamebuf, &stats);
|
||||
buffer = (char*)malloc(stats.st_size+1);
|
||||
fread(buffer, 1, stats.st_size, in1);
|
||||
buffer[stats.st_size] = 0;
|
||||
ast_log(LOG_NOTICE," --Read in included file %s, %d chars\n",fnamebuf, (int)stats.st_size);
|
||||
fclose(in1);
|
||||
|
||||
include_stack[include_stack_index].fname = my_file;
|
||||
my_file = strdup(fnamebuf);
|
||||
include_stack[include_stack_index].lineno = my_lineno;
|
||||
include_stack[include_stack_index].colno = my_col+yyleng;
|
||||
include_stack[include_stack_index++].bufstate = YY_CURRENT_BUFFER;
|
||||
|
||||
yy_switch_to_buffer(ael_yy_scan_string (buffer ,yyscanner),yyscanner);
|
||||
free(buffer);
|
||||
my_lineno = 1;
|
||||
my_col = 1;
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<<EOF>> {
|
||||
if ( --include_stack_index < 0 ) {
|
||||
yyterminate();
|
||||
} else {
|
||||
free(my_file);
|
||||
yy_delete_buffer( YY_CURRENT_BUFFER, yyscanner );
|
||||
yy_switch_to_buffer(include_stack[include_stack_index].bufstate, yyscanner );
|
||||
my_lineno = include_stack[include_stack_index].lineno;
|
||||
my_col = include_stack[include_stack_index].colno;
|
||||
my_file = include_stack[include_stack_index].fname;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
%%
|
||||
|
||||
static void pbcpush(char x)
|
||||
{
|
||||
pbcstack[pbcpos++] = x;
|
||||
}
|
||||
|
||||
static int pbcpop(char x)
|
||||
{
|
||||
if ( ( x == ')' && pbcstack[pbcpos-1] == '(' )
|
||||
|| ( x == ']' && pbcstack[pbcpos-1] == '[' )
|
||||
|| ( x == '}' && pbcstack[pbcpos-1] == '{' )) {
|
||||
pbcpos--;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1; /* error */
|
||||
}
|
||||
|
||||
static int c_prevword(void)
|
||||
{
|
||||
char *c = prev_word;
|
||||
int ret = 0;
|
||||
while ( c && *c ) {
|
||||
switch (*c) {
|
||||
case '{': pbcpush('{');break;
|
||||
case '}': ret = pbcpop('}');break;
|
||||
case '[':pbcpush('[');break;
|
||||
case ']':ret = pbcpop(']');break;
|
||||
case '(':pbcpush('(');break;
|
||||
case ')':ret = pbcpop(')'); break;
|
||||
}
|
||||
if( ret )
|
||||
return 1;
|
||||
c++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void pbcwhere(char *text, int *line, int *col )
|
||||
{
|
||||
int loc_line = 0;
|
||||
int loc_col = 0;
|
||||
while ( *text ) {
|
||||
if ( *text == '\n' ) {
|
||||
loc_line++;
|
||||
loc_col = 1;
|
||||
} else {
|
||||
loc_col++;
|
||||
}
|
||||
text++;
|
||||
}
|
||||
*line = loc_line;
|
||||
*col = loc_col;
|
||||
}
|
||||
|
||||
void reset_parencount(yyscan_t yyscanner )
|
||||
{
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
||||
parencount = 0;
|
||||
pbcpos = 0;
|
||||
pbcpush('(');
|
||||
c_prevword();
|
||||
BEGIN(paren);
|
||||
}
|
||||
|
||||
void reset_semicount(yyscan_t yyscanner )
|
||||
{
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
||||
pbcpos = 0;
|
||||
BEGIN(semic);
|
||||
}
|
||||
|
||||
void reset_argcount(yyscan_t yyscanner )
|
||||
{
|
||||
struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
|
||||
parencount = 0;
|
||||
pbcpos = 0;
|
||||
commaout = 0;
|
||||
pbcpush('(');
|
||||
c_prevword();
|
||||
BEGIN(argg);
|
||||
}
|
||||
|
||||
|
||||
struct pval *ael2_parse(char *filename, int *errors)
|
||||
{
|
||||
struct pval *pval;
|
||||
struct parse_io *io;
|
||||
char *buffer;
|
||||
struct stat stats;
|
||||
FILE *fin;
|
||||
|
||||
/* extern int ael_yydebug; */
|
||||
|
||||
io = calloc(sizeof(struct parse_io),1);
|
||||
/* reset the global counters */
|
||||
prev_word = 0;
|
||||
my_lineno = 1;
|
||||
include_stack_index=0;
|
||||
my_col = 0;
|
||||
/* ael_yydebug = 1; */
|
||||
ael_yylex_init(&io->scanner);
|
||||
fin = fopen(filename,"r");
|
||||
if ( !fin ) {
|
||||
ast_log(LOG_ERROR,"File %s could not be opened\n", filename);
|
||||
*errors = 1;
|
||||
return 0;
|
||||
}
|
||||
my_file = strdup(filename);
|
||||
stat(filename, &stats);
|
||||
buffer = (char*)malloc(stats.st_size+2);
|
||||
fread(buffer, 1, stats.st_size, fin);
|
||||
buffer[stats.st_size]=0;
|
||||
fclose(fin);
|
||||
|
||||
ael_yy_scan_string (buffer ,io->scanner);
|
||||
ael_yyset_lineno(1 , io->scanner);
|
||||
|
||||
/* ael_yyset_in (fin , io->scanner); OLD WAY */
|
||||
|
||||
ael_yyparse(io);
|
||||
|
||||
|
||||
pval = io->pval;
|
||||
*errors = io->syntax_error_count;
|
||||
|
||||
ael_yylex_destroy(io->scanner);
|
||||
free(buffer);
|
||||
free(io);
|
||||
|
||||
return pval;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,147 @@
|
|||
/* A Bison parser, made by GNU Bison 2.1. */
|
||||
|
||||
/* Skeleton parser for Yacc-like parsing with Bison,
|
||||
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, or (at your option)
|
||||
any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110-1301, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
This special exception was added by the Free Software Foundation
|
||||
in version 1.24 of Bison. */
|
||||
|
||||
/* Tokens. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
/* Put the tokens into the symbol table, so that GDB and other debuggers
|
||||
know about them. */
|
||||
enum yytokentype {
|
||||
KW_CONTEXT = 258,
|
||||
LC = 259,
|
||||
RC = 260,
|
||||
LP = 261,
|
||||
RP = 262,
|
||||
SEMI = 263,
|
||||
EQ = 264,
|
||||
COMMA = 265,
|
||||
COLON = 266,
|
||||
AMPER = 267,
|
||||
BAR = 268,
|
||||
AT = 269,
|
||||
KW_MACRO = 270,
|
||||
KW_GLOBALS = 271,
|
||||
KW_IGNOREPAT = 272,
|
||||
KW_SWITCH = 273,
|
||||
KW_IF = 274,
|
||||
KW_IFTIME = 275,
|
||||
KW_ELSE = 276,
|
||||
KW_RANDOM = 277,
|
||||
KW_ABSTRACT = 278,
|
||||
EXTENMARK = 279,
|
||||
KW_GOTO = 280,
|
||||
KW_JUMP = 281,
|
||||
KW_RETURN = 282,
|
||||
KW_BREAK = 283,
|
||||
KW_CONTINUE = 284,
|
||||
KW_REGEXTEN = 285,
|
||||
KW_HINT = 286,
|
||||
KW_FOR = 287,
|
||||
KW_WHILE = 288,
|
||||
KW_CASE = 289,
|
||||
KW_PATTERN = 290,
|
||||
KW_DEFAULT = 291,
|
||||
KW_CATCH = 292,
|
||||
KW_SWITCHES = 293,
|
||||
KW_ESWITCHES = 294,
|
||||
KW_INCLUDES = 295,
|
||||
word = 296
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define KW_CONTEXT 258
|
||||
#define LC 259
|
||||
#define RC 260
|
||||
#define LP 261
|
||||
#define RP 262
|
||||
#define SEMI 263
|
||||
#define EQ 264
|
||||
#define COMMA 265
|
||||
#define COLON 266
|
||||
#define AMPER 267
|
||||
#define BAR 268
|
||||
#define AT 269
|
||||
#define KW_MACRO 270
|
||||
#define KW_GLOBALS 271
|
||||
#define KW_IGNOREPAT 272
|
||||
#define KW_SWITCH 273
|
||||
#define KW_IF 274
|
||||
#define KW_IFTIME 275
|
||||
#define KW_ELSE 276
|
||||
#define KW_RANDOM 277
|
||||
#define KW_ABSTRACT 278
|
||||
#define EXTENMARK 279
|
||||
#define KW_GOTO 280
|
||||
#define KW_JUMP 281
|
||||
#define KW_RETURN 282
|
||||
#define KW_BREAK 283
|
||||
#define KW_CONTINUE 284
|
||||
#define KW_REGEXTEN 285
|
||||
#define KW_HINT 286
|
||||
#define KW_FOR 287
|
||||
#define KW_WHILE 288
|
||||
#define KW_CASE 289
|
||||
#define KW_PATTERN 290
|
||||
#define KW_DEFAULT 291
|
||||
#define KW_CATCH 292
|
||||
#define KW_SWITCHES 293
|
||||
#define KW_ESWITCHES 294
|
||||
#define KW_INCLUDES 295
|
||||
#define word 296
|
||||
|
||||
|
||||
|
||||
|
||||
#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
|
||||
#line 47 "ael.y"
|
||||
typedef union YYSTYPE {
|
||||
char *str;
|
||||
struct pval *pval;
|
||||
} YYSTYPE;
|
||||
/* Line 1447 of yacc.c. */
|
||||
#line 125 "ael.tab.h"
|
||||
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
|
||||
typedef struct YYLTYPE
|
||||
{
|
||||
int first_line;
|
||||
int first_column;
|
||||
int last_line;
|
||||
int last_column;
|
||||
} YYLTYPE;
|
||||
# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
|
||||
# define YYLTYPE_IS_DECLARED 1
|
||||
# define YYLTYPE_IS_TRIVIAL 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,705 @@
|
|||
%{
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2006, Digium, Inc.
|
||||
*
|
||||
* Steve Murphy <murf@parsetree.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
/*! \file
|
||||
*
|
||||
* \brief Bison Grammar description of AEL2.
|
||||
*
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "asterisk/logger.h"
|
||||
#include "asterisk/ael_structs.h"
|
||||
|
||||
extern void reset_parencount(yyscan_t yyscanner);
|
||||
extern void reset_semicount(yyscan_t yyscanner);
|
||||
extern void reset_argcount(yyscan_t yyscanner );
|
||||
|
||||
#define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
|
||||
#define YYERROR_VERBOSE 1
|
||||
|
||||
extern char *my_file;
|
||||
#ifdef AAL_ARGCHECK
|
||||
int ael_is_funcname(char *name);
|
||||
#endif
|
||||
static char *ael_token_subst(char *mess);
|
||||
extern char *prev_word;
|
||||
|
||||
%}
|
||||
|
||||
|
||||
%union {
|
||||
char *str;
|
||||
struct pval *pval;
|
||||
}
|
||||
|
||||
%{
|
||||
/* declaring these AFTER the union makes things a lot simpler! */
|
||||
void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s);
|
||||
int ael_yylex (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , void * yyscanner);
|
||||
|
||||
%}
|
||||
|
||||
|
||||
%token KW_CONTEXT LC RC LP RP SEMI EQ COMMA COLON AMPER BAR AT
|
||||
%token KW_MACRO KW_GLOBALS KW_IGNOREPAT KW_SWITCH KW_IF KW_IFTIME KW_ELSE KW_RANDOM KW_ABSTRACT
|
||||
%token EXTENMARK KW_GOTO KW_JUMP KW_RETURN KW_BREAK KW_CONTINUE KW_REGEXTEN KW_HINT
|
||||
%token KW_FOR KW_WHILE KW_CASE KW_PATTERN KW_DEFAULT KW_CATCH KW_SWITCHES KW_ESWITCHES
|
||||
%token KW_INCLUDES
|
||||
|
||||
%token <str> word
|
||||
|
||||
%type <pval>includes
|
||||
%type <pval>includeslist
|
||||
%type <pval>switchlist
|
||||
%type <pval>eswitches
|
||||
%type <pval>switches
|
||||
%type <pval>macro_statement
|
||||
%type <pval>macro_statements
|
||||
%type <pval>case_statement
|
||||
%type <pval>case_statements
|
||||
%type <pval>eval_arglist
|
||||
%type <pval>application_call
|
||||
%type <pval>application_call_head
|
||||
%type <pval>macro_call
|
||||
%type <pval>target jumptarget
|
||||
%type <pval>statement
|
||||
%type <pval>switch_head
|
||||
%type <str>word_list goto_word
|
||||
%type <str>word3_list
|
||||
%type <str>includedname
|
||||
%type <pval>if_head
|
||||
%type <pval>random_head
|
||||
%type <pval>iftime_head
|
||||
%type <pval>statements
|
||||
%type <pval>extension
|
||||
%type <pval>ignorepat
|
||||
%type <pval>element
|
||||
%type <pval>elements
|
||||
%type <pval>arglist
|
||||
%type <pval>global_statement
|
||||
%type <pval>global_statements
|
||||
%type <pval>globals
|
||||
%type <pval>macro
|
||||
%type <pval>context
|
||||
%type <pval>object
|
||||
%type <pval>objects
|
||||
%type <pval>file
|
||||
|
||||
/* OPTIONS */
|
||||
%locations
|
||||
%pure-parser
|
||||
%name-prefix="ael_yy"
|
||||
/* the following option does two things:
|
||||
it adds the locp arg to the yyerror
|
||||
and it adds the NULL to the yyerrr arg list, and calls yyerror with NULL for that arg.
|
||||
You can't get the locp arg without the NULL arg, don't ask me why. */
|
||||
%parse-param {struct parse_io *parseio}
|
||||
/* there will be two shift/reduce conflicts, they involve the if statement, where a single statement occurs not wrapped in curlies in the "true" section
|
||||
the default action to shift will attach the else to the preceeding if. */
|
||||
%expect 5
|
||||
%error-verbose
|
||||
%destructor { if (yymsg[0] != 'C') {destroy_pval($$); prev_word=0;} else {printf("Cleanup destructor called for pvals\n");} } includes includeslist switchlist eswitches switches macro_statement macro_statements case_statement case_statements eval_arglist application_call
|
||||
application_call_head macro_call target jumptarget statement switch_head if_head random_head iftime_head statements extension ignorepat element
|
||||
elements arglist global_statement global_statements globals macro context object objects
|
||||
%destructor { free($$);} word word_list goto_word word3_list includedname
|
||||
|
||||
|
||||
%%
|
||||
|
||||
file : objects { $$ = parseio->pval = $1; }
|
||||
;
|
||||
|
||||
objects : object {$$=$1;}
|
||||
| objects object {if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
|
||||
else if ( $1 ) {$$=$1;}
|
||||
else if ( $2 ) {$$=$2;} }
|
||||
| objects error {$$=$1;}
|
||||
;
|
||||
|
||||
object : context {$$=$1;}
|
||||
| macro {$$=$1;}
|
||||
| globals {$$=$1;}
|
||||
| SEMI {$$=0;/* allow older docs to be read */}
|
||||
;
|
||||
|
||||
context : KW_CONTEXT word LC elements RC {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $2; $$->u2.statements = $4; }
|
||||
| KW_CONTEXT word LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.str = $2; }
|
||||
| KW_CONTEXT KW_DEFAULT LC elements RC {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = strdup("default"); $$->u2.statements = $4; }
|
||||
| KW_CONTEXT KW_DEFAULT LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.str = strdup("default"); }
|
||||
| KW_ABSTRACT KW_CONTEXT word LC elements RC {$$=npval(PV_CONTEXT,@1.first_line,@6.last_line, @1.first_column, @6.last_column); $$->u1.str = $3; $$->u2.statements = $5; $$->u3.abstract = 1;}
|
||||
| KW_ABSTRACT KW_CONTEXT word LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $3; $$->u3.abstract = 1; }
|
||||
| KW_ABSTRACT KW_CONTEXT KW_DEFAULT LC elements RC {$$=npval(PV_CONTEXT,@1.first_line,@6.last_line, @1.first_column, @6.last_column); $$->u1.str = strdup("default"); $$->u2.statements = $5; $$->u3.abstract = 1; }
|
||||
| KW_ABSTRACT KW_CONTEXT KW_DEFAULT LC RC /* empty context OK */ {$$=npval(PV_CONTEXT,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = strdup("default"); $$->u3.abstract = 1; }
|
||||
;
|
||||
|
||||
macro : KW_MACRO word LP arglist RP LC macro_statements RC {$$=npval(PV_MACRO,@1.first_line,@8.last_line, @1.first_column, @8.last_column);
|
||||
$$->u1.str = $2; $$->u2.arglist = $4; $$->u3.macro_statements = $7; }
|
||||
| KW_MACRO word LP arglist RP LC RC {$$=npval(PV_MACRO,@1.first_line,@7.last_line, @1.first_column, @7.last_column); $$->u1.str = $2; $$->u2.arglist = $4; }
|
||||
| KW_MACRO word LP RP LC macro_statements RC {$$=npval(PV_MACRO,@1.first_line,@7.last_line, @1.first_column, @7.last_column); $$->u1.str = $2; $$->u3.macro_statements = $6; }
|
||||
| KW_MACRO word LP RP LC RC {$$=npval(PV_MACRO,@1.first_line,@6.last_line, @1.first_column, @6.last_column); $$->u1.str = $2; /* pretty empty! */ }
|
||||
;
|
||||
|
||||
globals : KW_GLOBALS LC global_statements RC {$$=npval(PV_GLOBALS,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.statements = $3;}
|
||||
| KW_GLOBALS LC RC /* empty global is OK */ {$$=npval(PV_GLOBALS,@1.first_line,@3.last_line, @1.first_column, @3.last_column); /* and that's all */ }
|
||||
;
|
||||
|
||||
global_statements : global_statement {$$=$1;}
|
||||
| global_statements global_statement {$$=$1; linku1($$,$2);}
|
||||
| global_statements error {$$=$1;}
|
||||
;
|
||||
|
||||
global_statement : word EQ { reset_semicount(parseio->scanner); } word SEMI {$$=npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $1;$$->u2.val = $4; }
|
||||
;
|
||||
|
||||
arglist : word {$$= npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); $$->u1.str = $1; }
|
||||
| arglist COMMA word {pval *z = npval(PV_WORD,@1.first_line,@3.last_line, @1.first_column, @3.last_column); z->u1.str = $3; $$=$1; linku1($$,z); }
|
||||
| arglist error {$$=$1;}
|
||||
;
|
||||
|
||||
elements : element { $$=$1;}
|
||||
| error {$$=0;}
|
||||
| elements element { if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
|
||||
else if ( $1 ) {$$=$1;}
|
||||
else if ( $2 ) {$$=$2;} }
|
||||
| elements error { $$=$1;}
|
||||
;
|
||||
|
||||
element : extension {$$=$1;}
|
||||
| includes {$$=$1;}
|
||||
| switches {$$=$1;}
|
||||
| eswitches {$$=$1;}
|
||||
| ignorepat {$$=$1;}
|
||||
| word EQ { reset_semicount(parseio->scanner); } word SEMI {$$=npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $1;$$->u2.val = $4; }
|
||||
| word error {free($1); $$=0;}
|
||||
| SEMI {$$=0;/* allow older docs to be read */}
|
||||
;
|
||||
|
||||
ignorepat : KW_IGNOREPAT EXTENMARK word SEMI { $$=npval(PV_IGNOREPAT,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.str = $3;}
|
||||
;
|
||||
|
||||
extension : word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $1; $$->u2.statements = $3; }
|
||||
| KW_REGEXTEN word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@3.last_line, @1.first_column, @4.last_column); $$->u1.str = $2; $$->u2.statements = $4; $$->u4.regexten=1;}
|
||||
| KW_HINT LP word3_list RP word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@7.last_line, @1.first_column, @7.last_column); $$->u1.str = $5; $$->u2.statements = $7; $$->u3.hints = $3;}
|
||||
| KW_REGEXTEN KW_HINT LP word3_list RP word EXTENMARK statement {$$ = npval(PV_EXTENSION,@1.first_line,@4.last_line, @1.first_column, @8.last_column); $$->u1.str = $6; $$->u2.statements = $8; $$->u4.regexten=1;$$->u3.hints = $4;}
|
||||
|
||||
;
|
||||
|
||||
statements : statement {$$=$1;}
|
||||
| statements statement {if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
|
||||
else if ( $1 ) {$$=$1;}
|
||||
else if ( $2 ) {$$=$2;} }
|
||||
| statements error {$$=$1;}
|
||||
;
|
||||
|
||||
if_head : KW_IF LP { reset_parencount(parseio->scanner); } word_list RP { $$= npval(PV_IF,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $4; }
|
||||
;
|
||||
|
||||
random_head : KW_RANDOM LP { reset_parencount(parseio->scanner); } word_list RP { $$= npval(PV_RANDOM,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str=$4;}
|
||||
;
|
||||
|
||||
iftime_head : KW_IFTIME LP word3_list COLON word3_list COLON word3_list BAR word3_list BAR word3_list BAR word3_list RP { $$= npval(PV_IFTIME,@1.first_line,@5.last_line, @1.first_column, @5.last_column);
|
||||
$$->u1.list = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->u1.list->u1.str = (char*)malloc(strlen($3)+strlen($5)+strlen($7)+4);
|
||||
strcpy($$->u1.list->u1.str,$3);
|
||||
strcat($$->u1.list->u1.str,":");
|
||||
strcat($$->u1.list->u1.str,$5);
|
||||
strcat($$->u1.list->u1.str,":");
|
||||
strcat($$->u1.list->u1.str,$7);
|
||||
free($3);
|
||||
free($5);
|
||||
free($7);
|
||||
$$->u1.list->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column);
|
||||
$$->u1.list->next->u1.str = $9;
|
||||
$$->u1.list->next->next = npval(PV_WORD,@11.first_line,@11.last_line, @11.first_column, @11.last_column);
|
||||
$$->u1.list->next->next->u1.str = $11;
|
||||
$$->u1.list->next->next->next = npval(PV_WORD,@13.first_line,@13.last_line, @13.first_column, @13.last_column);
|
||||
$$->u1.list->next->next->next->u1.str = $13;
|
||||
prev_word = 0;
|
||||
}
|
||||
| KW_IFTIME LP word BAR word3_list BAR word3_list BAR word3_list RP { $$= npval(PV_IFTIME,@1.first_line,@5.last_line, @1.first_column, @5.last_column);
|
||||
$$->u1.list = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->u1.list->u1.str = $3;
|
||||
$$->u1.list->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->u1.list->next->u1.str = $5;
|
||||
$$->u1.list->next->next = npval(PV_WORD,@7.first_line,@7.last_line, @7.first_column, @7.last_column);
|
||||
$$->u1.list->next->next->u1.str = $7;
|
||||
$$->u1.list->next->next->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column);
|
||||
$$->u1.list->next->next->next->u1.str = $9;
|
||||
prev_word = 0;
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
/* word_list is a hack to fix a problem with context switching between bison and flex;
|
||||
by the time you register a new context with flex, you've already got a look-ahead token
|
||||
from the old context, with no way to put it back and start afresh. So, we kludge this
|
||||
and merge the words back together. */
|
||||
|
||||
word_list : word { $$ = $1;}
|
||||
| word word { $$ = (char*)malloc(strlen($1)+strlen($2)+1); strcpy($$, $1); strcat($$, $2); free($1); free($2);prev_word = $$;}
|
||||
;
|
||||
word3_list : word { $$ = $1;}
|
||||
| word word { $$ = (char*)malloc(strlen($1)+strlen($2)+1); strcpy($$, $1); strcat($$, $2); free($1); free($2);prev_word = $$;}
|
||||
| word word word { $$ = (char*)malloc(strlen($1)+strlen($2)+strlen($3)+1); strcpy($$, $1); strcat($$, $2); strcat($$, $3); free($1); free($2); free($3);prev_word=$$;}
|
||||
;
|
||||
|
||||
goto_word : word { $$ = $1;}
|
||||
| word word { $$ = (char*)malloc(strlen($1)+strlen($2)+1); strcpy($$, $1); strcat($$, $2); free($1); free($2);}
|
||||
| word COLON word { $$ = (char*)malloc(strlen($1)+strlen($3)+2); strcpy($$, $1); strcat($$,":"); strcat($$, $3); free($1); free($3);}
|
||||
;
|
||||
|
||||
switch_head : KW_SWITCH LP { reset_parencount(parseio->scanner); } word RP LC
|
||||
{$$=npval(PV_SWITCH,@1.first_line,@6.last_line, @1.first_column, @6.last_column);
|
||||
$$->u1.str = $4; }
|
||||
;
|
||||
|
||||
statement : LC statements RC {$$=npval(PV_STATEMENTBLOCK,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.list = $2; }
|
||||
| word EQ {reset_semicount(parseio->scanner);} word SEMI
|
||||
{$$=npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column);
|
||||
$$->u1.str = $1; $$->u2.val = $4; }
|
||||
| KW_GOTO target SEMI {$$=npval(PV_GOTO,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.list = $2;}
|
||||
| KW_JUMP jumptarget SEMI {$$=npval(PV_GOTO,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.list = $2;}
|
||||
| word COLON {$$=npval(PV_LABEL,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = $1; }
|
||||
| KW_FOR LP {reset_semicount(parseio->scanner);} word SEMI
|
||||
{reset_semicount(parseio->scanner);} word SEMI
|
||||
{reset_parencount(parseio->scanner);} word RP statement
|
||||
{ $$=npval(PV_FOR,@1.first_line,@12.last_line, @1.first_column, @12.last_column);
|
||||
$$->u1.for_init = $4; $$->u2.for_test=$7; $$->u3.for_inc = $10; $$->u4.for_statements = $12;}
|
||||
| KW_WHILE LP {reset_parencount(parseio->scanner);} word RP statement
|
||||
{$$=npval(PV_WHILE,@1.first_line,@6.last_line, @1.first_column, @6.last_column);
|
||||
$$->u1.str = $4; $$->u2.statements = $6; }
|
||||
| switch_head RC /* empty list OK */ {$$=$1;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
|
||||
| switch_head case_statements RC {$$=$1; $$->u2.statements = $2;$$->endline = @3.last_line; $$->endcol = @3.last_column;}
|
||||
| AMPER macro_call SEMI {$$ = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
|
||||
| application_call SEMI { $$ = $1;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
|
||||
| word SEMI { $$= npval(PV_APPLICATION_CALL,@1.first_line,@2.last_line, @1.first_column, @2.last_column);
|
||||
$$->u1.str = $1;}
|
||||
| application_call EQ {reset_semicount(parseio->scanner);} word SEMI {
|
||||
char *bufx;
|
||||
int tot=0;
|
||||
pval *pptr;
|
||||
|
||||
$$ = npval(PV_VARDEC,@1.first_line,@5.last_line, @1.first_column, @5.last_column);
|
||||
$$->u2.val=$4;
|
||||
/* rebuild the original string-- this is not an app call, it's an unwrapped vardec, with a func call on the LHS */
|
||||
/* string to big to fit in the buffer? */
|
||||
tot+=strlen($1->u1.str);
|
||||
for(pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
|
||||
tot+=strlen(pptr->u1.str);
|
||||
tot++; /* for a sep like a comma */
|
||||
}
|
||||
tot+=4; /* for safety */
|
||||
bufx = (char *)malloc(tot);
|
||||
strcpy(bufx,$1->u1.str);
|
||||
strcat(bufx,"(");
|
||||
for (pptr=$1->u2.arglist;pptr;pptr=pptr->next) {
|
||||
if ( pptr != $1->u2.arglist )
|
||||
strcat(bufx,",");
|
||||
strcat(bufx,pptr->u1.str);
|
||||
}
|
||||
strcat(bufx,")");
|
||||
#ifdef AAL_ARGCHECK
|
||||
if ( !ael_is_funcname($1->u1.str) )
|
||||
ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Function call? The name %s is not in my internal list of function names\n",
|
||||
my_file, @1.first_line, @1.first_column, @1.last_column, $1->u1.str);
|
||||
#endif
|
||||
$$->u1.str = bufx;
|
||||
destroy_pval($1); /* the app call it is not, get rid of that chain */
|
||||
prev_word = 0;
|
||||
}
|
||||
| KW_BREAK SEMI { $$ = npval(PV_BREAK,@1.first_line,@2.last_line, @1.first_column, @2.last_column);}
|
||||
| KW_RETURN SEMI {$$ = npval(PV_RETURN,@1.first_line,@2.last_line, @1.first_column, @2.last_column);}
|
||||
| KW_CONTINUE SEMI {$$ = npval(PV_CONTINUE,@1.first_line,@2.last_line, @1.first_column, @2.last_column);}
|
||||
| random_head statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
|
||||
| random_head statement KW_ELSE statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column; $$->u3.else_statements = $4;}
|
||||
| if_head statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
|
||||
| if_head statement KW_ELSE statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column; $$->u3.else_statements = $4;}
|
||||
| iftime_head statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
|
||||
| iftime_head statement KW_ELSE statement {$$=$1; $$->u2.statements = $2;$$->endline = @2.last_line; $$->endcol = @2.last_column; $$->u3.else_statements = $4;}
|
||||
| SEMI { $$=0; }
|
||||
;
|
||||
|
||||
target : goto_word { $$ = npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); $$->u1.str = $1;}
|
||||
| goto_word BAR goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $3;}
|
||||
| goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $3;}
|
||||
| goto_word BAR goto_word BAR goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $3;
|
||||
$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->next->next->u1.str = $5; }
|
||||
| goto_word COMMA goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $3;
|
||||
$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->next->next->u1.str = $5; }
|
||||
| KW_DEFAULT BAR goto_word BAR goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $3;
|
||||
$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->next->next->u1.str = $5; }
|
||||
| KW_DEFAULT COMMA goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $3;
|
||||
$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->next->next->u1.str = $5; }
|
||||
;
|
||||
|
||||
jumptarget : goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $1; $$->next = npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->next->u1.str = strdup("1");} /* jump extension[,priority][@context] */
|
||||
| goto_word COMMA goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $1; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $3;}
|
||||
| goto_word COMMA word AT word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $5; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $1;
|
||||
$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->next->next->u1.str = $3; }
|
||||
| goto_word AT goto_word {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = $3; $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $1;
|
||||
$$->next->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->next->u1.str = strdup("1"); }
|
||||
| goto_word COMMA word AT KW_DEFAULT {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $1;
|
||||
$$->next->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->next->next->u1.str = $3; }
|
||||
| goto_word AT KW_DEFAULT {$$=npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column);
|
||||
$$->u1.str = strdup("default"); $$->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->u1.str = $1;
|
||||
$$->next->next = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->next->next->u1.str = strdup("1"); }
|
||||
;
|
||||
|
||||
macro_call : word LP {reset_argcount(parseio->scanner);} eval_arglist RP
|
||||
{$$= npval(PV_MACRO_CALL,@1.first_line,@2.last_line, @1.first_column, @2.last_column);
|
||||
$$->u1.str = $1; $$->u2.arglist = $4;}
|
||||
| word LP RP {$$= npval(PV_MACRO_CALL,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $1; }
|
||||
;
|
||||
|
||||
application_call_head: word {reset_argcount(parseio->scanner);} LP {if (strcasecmp($1,"goto") == 0) {
|
||||
$$= npval(PV_GOTO,@1.first_line,@3.last_line, @1.first_column, @3.last_column);
|
||||
free($1); /* won't be using this */
|
||||
ast_log(LOG_WARNING, "==== File: %s, Line %d, Cols: %d-%d: Suggestion: Use the goto statement instead of the Goto() application call in AEL.\n", my_file, @1.first_line, @1.first_column, @1.last_column );
|
||||
} else
|
||||
$$= npval(PV_APPLICATION_CALL,@1.first_line,@3.last_line, @1.first_column, @3.last_column);
|
||||
$$->u1.str = $1; }
|
||||
;
|
||||
|
||||
application_call : application_call_head eval_arglist RP {$$ = $1;
|
||||
if( $$->type == PV_GOTO )
|
||||
$$->u1.list = $2;
|
||||
else
|
||||
$$->u2.arglist = $2;
|
||||
$$->endline = @3.last_line; $$->endcol = @3.last_column;}
|
||||
| application_call_head RP {$$=$1;$$->endline = @2.last_line; $$->endcol = @2.last_column;}
|
||||
;
|
||||
|
||||
eval_arglist : word_list { $$= npval(PV_WORD,@1.first_line,@1.last_line, @1.first_column, @1.last_column); $$->u1.str = $1;}
|
||||
| /*nothing! */ { $$= npval(PV_WORD,0/*@1.first_line*/,0/*@1.last_line*/,0/* @1.first_column*/, 0/*@1.last_column*/); $$->u1.str = strdup(""); }
|
||||
| eval_arglist COMMA word { pval *z = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column); $$ = $1; linku1($1,z); z->u1.str = $3;}
|
||||
| eval_arglist COMMA { pval *z = npval(PV_WORD,@2.first_line,@2.last_line, @2.first_column, @2.last_column); $$ = $1; linku1($1,z); z->u1.str = strdup("");}
|
||||
;
|
||||
|
||||
case_statements: case_statement {$$=$1;}
|
||||
| case_statements case_statement { if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
|
||||
else if ( $1 ) {$$=$1;}
|
||||
else if ( $2 ) {$$=$2;} }
|
||||
;
|
||||
|
||||
case_statement: KW_CASE word COLON statements {$$ = npval(PV_CASE,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2; $$->u2.statements = $4;}
|
||||
| KW_DEFAULT COLON statements {$$ = npval(PV_DEFAULT,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = 0; $$->u2.statements = $3;}
|
||||
| KW_PATTERN word COLON statements {$$ = npval(PV_PATTERN,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2; $$->u2.statements = $4;}
|
||||
| KW_CASE word COLON {$$ = npval(PV_CASE,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2;}
|
||||
| KW_DEFAULT COLON {$$ = npval(PV_DEFAULT,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = 0;}
|
||||
| KW_PATTERN word COLON {$$ = npval(PV_PATTERN,@1.first_line,@3.last_line, @1.first_column, @3.last_column); $$->u1.str = $2;}
|
||||
;
|
||||
|
||||
macro_statements: macro_statement {$$ = $1;}
|
||||
| macro_statements macro_statement { if ( $1 && $2 ) {$$=$1; linku1($$,$2);}
|
||||
else if ( $1 ) {$$=$1;}
|
||||
else if ( $2 ) {$$=$2;} }
|
||||
;
|
||||
|
||||
macro_statement : statement {$$=$1;}
|
||||
| KW_CATCH word LC statements RC {$$=npval(PV_CATCH,@1.first_line,@5.last_line, @1.first_column, @5.last_column); $$->u1.str = $2; $$->u2.statements = $4;}
|
||||
;
|
||||
|
||||
switches : KW_SWITCHES LC switchlist RC {$$= npval(PV_SWITCHES,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.list = $3; }
|
||||
| KW_SWITCHES LC RC /* empty switch list OK */ {$$= npval(PV_SWITCHES,@1.first_line,@3.last_line, @1.first_column, @3.last_column);}
|
||||
;
|
||||
|
||||
eswitches : KW_ESWITCHES LC switchlist RC {$$= npval(PV_ESWITCHES,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.list = $3; }
|
||||
| KW_ESWITCHES LC RC /* empty switch list OK */ {$$= npval(PV_ESWITCHES,@1.first_line,@3.last_line, @1.first_column, @3.last_column); } /* if there's nothing to declare, why include it? */
|
||||
;
|
||||
|
||||
switchlist : word SEMI {$$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = $1;}
|
||||
| switchlist word SEMI {pval *z = npval(PV_WORD,@2.first_line,@3.last_line, @2.first_column, @3.last_column); $$=$1; z->u1.str = $2; linku1($$,z); }
|
||||
| switchlist error {$$=$1;}
|
||||
;
|
||||
|
||||
includeslist : includedname SEMI {$$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column); $$->u1.str = $1;}
|
||||
| includedname BAR word3_list COLON word3_list COLON word3_list BAR word3_list BAR word3_list BAR word3_list SEMI {
|
||||
$$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column);
|
||||
$$->u1.str = $1;
|
||||
$$->u2.arglist = npval(PV_WORD,@3.first_line,@7.last_line, @3.first_column, @7.last_column);
|
||||
$$->u2.arglist->u1.str = (char*)malloc(strlen($3)+strlen($5)+strlen($7)+4);
|
||||
strcpy($$->u2.arglist->u1.str,$3);
|
||||
strcat($$->u2.arglist->u1.str,":");
|
||||
strcat($$->u2.arglist->u1.str,$5);
|
||||
strcat($$->u2.arglist->u1.str,":");
|
||||
strcat($$->u2.arglist->u1.str,$7);
|
||||
free($3);
|
||||
free($5);
|
||||
free($7);
|
||||
$$->u2.arglist->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column);
|
||||
$$->u2.arglist->next->u1.str = $9;
|
||||
$$->u2.arglist->next->next = npval(PV_WORD,@11.first_line,@11.last_line, @11.first_column, @11.last_column);
|
||||
$$->u2.arglist->next->next->u1.str = $11;
|
||||
$$->u2.arglist->next->next->next = npval(PV_WORD,@13.first_line,@13.last_line, @13.first_column, @13.last_column);
|
||||
$$->u2.arglist->next->next->next->u1.str = $13;
|
||||
prev_word=0;
|
||||
}
|
||||
| includedname BAR word BAR word3_list BAR word3_list BAR word3_list SEMI {
|
||||
$$=npval(PV_WORD,@1.first_line,@2.last_line, @1.first_column, @2.last_column);
|
||||
$$->u1.str = $1;
|
||||
$$->u2.arglist = npval(PV_WORD,@3.first_line,@3.last_line, @3.first_column, @3.last_column);
|
||||
$$->u2.arglist->u1.str = $3;
|
||||
$$->u2.arglist->next = npval(PV_WORD,@5.first_line,@5.last_line, @5.first_column, @5.last_column);
|
||||
$$->u2.arglist->next->u1.str = $5;
|
||||
$$->u2.arglist->next->next = npval(PV_WORD,@7.first_line,@7.last_line, @7.first_column, @7.last_column);
|
||||
$$->u2.arglist->next->next->u1.str = $7;
|
||||
$$->u2.arglist->next->next->next = npval(PV_WORD,@9.first_line,@9.last_line, @9.first_column, @9.last_column);
|
||||
$$->u2.arglist->next->next->next->u1.str = $9;
|
||||
prev_word=0;
|
||||
}
|
||||
| includeslist includedname SEMI {pval *z = npval(PV_WORD,@2.first_line,@3.last_line, @2.first_column, @3.last_column); $$=$1; z->u1.str = $2; linku1($$,z); }
|
||||
| includeslist includedname BAR word3_list COLON word3_list COLON word3_list BAR word3_list BAR word3_list BAR word3_list SEMI {pval *z = npval(PV_WORD,@2.first_line,@3.last_line, @2.first_column, @3.last_column);
|
||||
$$=$1; z->u1.str = $2; linku1($$,z);
|
||||
z->u2.arglist = npval(PV_WORD,@4.first_line,@4.last_line, @4.first_column, @4.last_column);
|
||||
$$->u2.arglist->u1.str = (char*)malloc(strlen($4)+strlen($6)+strlen($8)+4);
|
||||
strcpy($$->u2.arglist->u1.str,$4);
|
||||
strcat($$->u2.arglist->u1.str,":");
|
||||
strcat($$->u2.arglist->u1.str,$6);
|
||||
strcat($$->u2.arglist->u1.str,":");
|
||||
strcat($$->u2.arglist->u1.str,$8);
|
||||
free($4);
|
||||
free($6);
|
||||
free($8);
|
||||
z->u2.arglist->next = npval(PV_WORD,@10.first_line,@10.last_line, @10.first_column, @10.last_column);
|
||||
z->u2.arglist->next->u1.str = $10;
|
||||
z->u2.arglist->next->next = npval(PV_WORD,@12.first_line,@12.last_line, @12.first_column, @12.last_column);
|
||||
z->u2.arglist->next->next->u1.str = $12;
|
||||
z->u2.arglist->next->next->next = npval(PV_WORD,@14.first_line,@14.last_line, @14.first_column, @14.last_column);
|
||||
z->u2.arglist->next->next->next->u1.str = $14;
|
||||
prev_word=0;
|
||||
}
|
||||
| includeslist includedname BAR word BAR word3_list BAR word3_list BAR word3_list SEMI
|
||||
{pval *z = npval(PV_WORD,@2.first_line,@2.last_line, @2.first_column, @3.last_column);
|
||||
$$=$1; z->u1.str = $2; linku1($$,z);
|
||||
z->u2.arglist = npval(PV_WORD,@4.first_line,@4.last_line, @4.first_column, @4.last_column);
|
||||
$$->u2.arglist->u1.str = $4;
|
||||
z->u2.arglist->next = npval(PV_WORD,@6.first_line,@6.last_line, @6.first_column, @6.last_column);
|
||||
z->u2.arglist->next->u1.str = $6;
|
||||
z->u2.arglist->next->next = npval(PV_WORD,@8.first_line,@8.last_line, @8.first_column, @8.last_column);
|
||||
z->u2.arglist->next->next->u1.str = $8;
|
||||
z->u2.arglist->next->next->next = npval(PV_WORD,@10.first_line,@10.last_line, @10.first_column, @10.last_column);
|
||||
z->u2.arglist->next->next->next->u1.str = $10;
|
||||
prev_word=0;
|
||||
}
|
||||
| includeslist error {$$=$1;}
|
||||
;
|
||||
|
||||
includedname : word { $$ = $1;}
|
||||
| KW_DEFAULT {$$=strdup("default");}
|
||||
;
|
||||
|
||||
includes : KW_INCLUDES LC includeslist RC {$$= npval(PV_INCLUDES,@1.first_line,@4.last_line, @1.first_column, @4.last_column); $$->u1.list = $3;}
|
||||
| KW_INCLUDES LC RC {$$= npval(PV_INCLUDES,@1.first_line,@3.last_line, @1.first_column, @3.last_column);}
|
||||
;
|
||||
|
||||
|
||||
%%
|
||||
|
||||
static char *token_equivs1[] =
|
||||
{
|
||||
"AMPER",
|
||||
"AT",
|
||||
"BAR",
|
||||
"COLON",
|
||||
"COMMA",
|
||||
"EQ",
|
||||
"EXTENMARK",
|
||||
"KW_BREAK",
|
||||
"KW_CASE",
|
||||
"KW_CATCH",
|
||||
"KW_CONTEXT",
|
||||
"KW_CONTINUE",
|
||||
"KW_DEFAULT",
|
||||
"KW_ELSE",
|
||||
"KW_ESWITCHES",
|
||||
"KW_FOR",
|
||||
"KW_GLOBALS",
|
||||
"KW_GOTO",
|
||||
"KW_HINT",
|
||||
"KW_IFTIME",
|
||||
"KW_IF",
|
||||
"KW_IGNOREPAT",
|
||||
"KW_INCLUDES"
|
||||
"KW_JUMP",
|
||||
"KW_MACRO",
|
||||
"KW_PATTERN",
|
||||
"KW_REGEXTEN",
|
||||
"KW_RETURN",
|
||||
"KW_SWITCHES",
|
||||
"KW_SWITCH",
|
||||
"KW_WHILE",
|
||||
"LC",
|
||||
"LP",
|
||||
"RC",
|
||||
"RP",
|
||||
"SEMI",
|
||||
};
|
||||
|
||||
static char *token_equivs2[] =
|
||||
{
|
||||
"&",
|
||||
"@",
|
||||
"|",
|
||||
":",
|
||||
",",
|
||||
"=",
|
||||
"=>",
|
||||
"break",
|
||||
"case",
|
||||
"catch",
|
||||
"context",
|
||||
"continue",
|
||||
"default",
|
||||
"else",
|
||||
"eswitches",
|
||||
"for",
|
||||
"globals",
|
||||
"goto",
|
||||
"hint",
|
||||
"ifTime",
|
||||
"if",
|
||||
"ignorepat",
|
||||
"includes"
|
||||
"jump",
|
||||
"macro",
|
||||
"pattern",
|
||||
"regexten",
|
||||
"return",
|
||||
"switches",
|
||||
"switch",
|
||||
"while",
|
||||
"{",
|
||||
"(",
|
||||
"}",
|
||||
")",
|
||||
";",
|
||||
};
|
||||
|
||||
|
||||
static char *ael_token_subst(char *mess)
|
||||
{
|
||||
/* calc a length, malloc, fill, and return; yyerror had better free it! */
|
||||
int len=0,i;
|
||||
char *p;
|
||||
char *res, *s,*t;
|
||||
int token_equivs_entries = sizeof(token_equivs1)/sizeof(char*);
|
||||
|
||||
for (p=mess; *p; p++) {
|
||||
for (i=0; i<token_equivs_entries; i++) {
|
||||
if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 )
|
||||
{
|
||||
len+=strlen(token_equivs2[i])+2;
|
||||
p += strlen(token_equivs1[i])-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
len++;
|
||||
}
|
||||
res = (char*)malloc(len+1);
|
||||
res[0] = 0;
|
||||
s = res;
|
||||
for (p=mess; *p;) {
|
||||
int found = 0;
|
||||
for (i=0; i<token_equivs_entries; i++) {
|
||||
if ( strncmp(p,token_equivs1[i],strlen(token_equivs1[i])) == 0 ) {
|
||||
*s++ = '\'';
|
||||
for (t=token_equivs2[i]; *t;) {
|
||||
*s++ = *t++;
|
||||
}
|
||||
*s++ = '\'';
|
||||
p += strlen(token_equivs1[i]);
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
*s++ = *p++;
|
||||
}
|
||||
*s++ = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
void yyerror(YYLTYPE *locp, struct parse_io *parseio, char const *s)
|
||||
{
|
||||
char *s2 = ael_token_subst((char *)s);
|
||||
if (locp->first_line == locp->last_line) {
|
||||
ast_log(LOG_ERROR, "==== File: %s, Line %d, Cols: %d-%d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_column, s2);
|
||||
} else {
|
||||
ast_log(LOG_ERROR, "==== File: %s, Line %d Col %d to Line %d Col %d: Error: %s\n", my_file, locp->first_line, locp->first_column, locp->last_line, locp->last_column, s2);
|
||||
}
|
||||
free(s2);
|
||||
parseio->syntax_error_count++;
|
||||
}
|
||||
|
||||
struct pval *npval(pvaltype type,int first_line, int last_line, int first_column, int last_column)
|
||||
{
|
||||
extern char *my_file;
|
||||
pval *z = (pval *)calloc(sizeof(struct pval),1);
|
||||
z->type = type;
|
||||
z->startline = first_line;
|
||||
z->endline = last_line;
|
||||
z->startcol = first_column;
|
||||
z->endcol = last_column;
|
||||
z->filename = strdup(my_file);
|
||||
return z;
|
||||
}
|
||||
|
||||
void linku1(pval *head, pval *tail)
|
||||
{
|
||||
if (!head->next) {
|
||||
head->next = tail;
|
||||
head->u1_last = tail;
|
||||
} else {
|
||||
head->u1_last->next = tail;
|
||||
head->u1_last = tail;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
4754
pbx/pbx_ael.c
4754
pbx/pbx_ael.c
File diff suppressed because it is too large
Load Diff
|
@ -66,6 +66,22 @@ ast_expr2f.o: ../ast_expr2f.c
|
|||
check_expr: check_expr.c ast_expr2.o ast_expr2f.o
|
||||
$(CC) $(CFLAGS) -o $@ $^
|
||||
|
||||
aelparse : ../pbx/ael/aelflex.o ../pbx/ael/aelbison.o ../pbx/pbx_ael.o ael_main.o ../ast_expr2f.o ../ast_expr2.o
|
||||
$(CC) $(CFLAGS) -g -o aelparse ../pbx/ael/aelflex.o ../pbx/ael/aelbison.o ael_main.o ../pbx/pbx_ael.o ../ast_expr2f.o ../ast_expr2.o
|
||||
|
||||
ael_main.o : ael_main.c ../include/asterisk/ael_structs.h
|
||||
$(CC) $(CFLAGS) -c -g -o ael_main.o ael_main.c
|
||||
|
||||
ael_main1.o : ael_main.c ../include/asterisk/ael_structs.h
|
||||
$(CC) $(CFLAGS) -c -g -o ael_main1.o ael_main.c
|
||||
|
||||
testexpr2s: ../ast_expr2f.c ../ast_expr2.c ../ast_expr2.h
|
||||
gcc -g -c -I../include -DSTANDALONE ../ast_expr2f.c -o ast_expr2f.o
|
||||
gcc -g -c -I../include -DSTANDALONE ../ast_expr2.c -o ast_expr2.o
|
||||
gcc -g -o testexpr2s ast_expr2f.o ast_expr2.o
|
||||
rm ast_expr2.o ast_expr2f.o
|
||||
./testexpr2s expr2.testinput
|
||||
|
||||
smsq.o: smsq.c
|
||||
$(CC) $(CFLAGS) -include ../include/autoconfig.h -c -o $@ $<
|
||||
|
||||
|
|
|
@ -0,0 +1,264 @@
|
|||
#include <sys/types.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <locale.h>
|
||||
#include <ctype.h>
|
||||
#if !defined(SOLARIS) && !defined(__CYGWIN__)
|
||||
#include <err.h>
|
||||
#else
|
||||
#define quad_t int64_t
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <regex.h>
|
||||
#include <limits.h>
|
||||
#include <asterisk/ast_expr.h>
|
||||
#include <asterisk/logger.h>
|
||||
#include <asterisk/module.h>
|
||||
#include <asterisk/channel.h>
|
||||
#include <asterisk/app.h>
|
||||
#include "asterisk/ael_structs.h"
|
||||
#define AST_CONFIG_MAX_PATH 255
|
||||
|
||||
int conts=0, extens=0, priors=0;
|
||||
char last_exten[18000];
|
||||
char ast_config_AST_CONFIG_DIR[AST_CONFIG_MAX_PATH];
|
||||
char ast_config_AST_VAR_DIR[AST_CONFIG_MAX_PATH];
|
||||
|
||||
void ast_cli_register_multiple(void);
|
||||
void ast_register_file_version(void);
|
||||
void ast_unregister_file_version(void);
|
||||
int ast_add_extension2(void *con,
|
||||
int replace, const char *extension, int priority, const char *label, const char *callerid,
|
||||
const char *application, void *data, void (*datad)(void *),
|
||||
const char *registrar);
|
||||
void pbx_builtin_setvar(void *chan, void *data);
|
||||
void ast_context_create(void **extcontexts, const char *name, const char *registrar);
|
||||
void ast_context_add_ignorepat2(void *con, const char *value, const char *registrar);
|
||||
void ast_context_add_include2(void *con, const char *value, const char *registrar);
|
||||
void ast_context_add_switch2(void *con, const char *value, const char *data, int eval, const char *registrar);
|
||||
void ast_merge_contexts_and_delete(void);
|
||||
void ast_context_verify_includes(void);
|
||||
struct ast_context * ast_walk_contexts(void);
|
||||
void ast_cli_unregister_multiple(void);
|
||||
void ast_context_destroy(void);
|
||||
void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...);
|
||||
char *ast_process_quotes_and_slashes(char *start, char find, char replace_with);
|
||||
void ast_verbose(const char *fmt, ...);
|
||||
struct ast_app *pbx_findapp(const char *app);
|
||||
static int no_comp = 0;
|
||||
static int use_curr_dir = 0;
|
||||
|
||||
|
||||
struct ast_app *pbx_findapp(const char *app)
|
||||
{
|
||||
return (struct ast_app*)1; /* so as not to trigger an error */
|
||||
}
|
||||
|
||||
|
||||
void ast_copy_string(char *dst, const char *src, size_t size)
|
||||
{
|
||||
while (*src && size) {
|
||||
*dst++ = *src++;
|
||||
size--;
|
||||
}
|
||||
if (__builtin_expect(!size, 0))
|
||||
dst--;
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
void ast_cli_register_multiple(void)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_cli_register_multiple();\n");
|
||||
}
|
||||
|
||||
void ast_register_file_version(void)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_register_file_version();\n");
|
||||
}
|
||||
|
||||
void ast_unregister_file_version(void)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_unregister_file_version();\n");
|
||||
|
||||
}
|
||||
int ast_add_extension2(void *con,
|
||||
int replace, const char *extension, int priority, const char *label, const char *callerid,
|
||||
const char *application, void *data, void (*datad)(void *),
|
||||
const char *registrar)
|
||||
{
|
||||
priors++;
|
||||
if (strcmp(extension,last_exten) != 0) {
|
||||
extens++;
|
||||
strcpy(last_exten, extension);
|
||||
}
|
||||
if (!label) {
|
||||
label = "(null)";
|
||||
}
|
||||
if (!callerid) {
|
||||
callerid = "(null)";
|
||||
}
|
||||
if (!application) {
|
||||
application = "(null)";
|
||||
}
|
||||
if(!no_comp)
|
||||
printf("Executed ast_add_extension2(con, rep=%d, exten=%s, priority=%d, label=%s, callerid=%s, appl=%s, data=%s, FREE, registrar=%s);\n",
|
||||
replace, extension, priority, label, callerid, application, (data?(char*)data:"(null)"), registrar);
|
||||
|
||||
/* since add_extension2 is responsible for the malloc'd data stuff */
|
||||
if( data )
|
||||
free(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pbx_builtin_setvar(void *chan, void *data)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed pbx_builtin_setvar(chan, data=%s);\n", (char*)data);
|
||||
}
|
||||
|
||||
|
||||
void ast_context_create(void **extcontexts, const char *name, const char *registrar)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_context_create(conts, name=%s, registrar=%s);\n", name, registrar);
|
||||
conts++;
|
||||
}
|
||||
|
||||
void ast_context_add_ignorepat2(void *con, const char *value, const char *registrar)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_context_add_ignorepat2(con, value=%s, registrar=%s);\n", value, registrar);
|
||||
}
|
||||
|
||||
void ast_context_add_include2(void *con, const char *value, const char *registrar)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_context_add_include2(con, value=%s, registrar=%s);\n", value, registrar);
|
||||
}
|
||||
|
||||
void ast_context_add_switch2(void *con, const char *value, const char *data, int eval, const char *registrar)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_context_add_switch2(con, value=%s, data=%s, eval=%d, registrar=%s);\n", value, data, eval, registrar);
|
||||
}
|
||||
|
||||
void ast_merge_contexts_and_delete(void)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_merge_contexts_and_delete();\n");
|
||||
}
|
||||
|
||||
void ast_context_verify_includes(void)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_context_verify_includes();\n");
|
||||
}
|
||||
|
||||
struct ast_context * ast_walk_contexts(void)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_walk_contexts();\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ast_cli_unregister_multiple(void)
|
||||
{
|
||||
if(!no_comp)
|
||||
printf("Executed ast_cli_unregister_multiple();\n");
|
||||
}
|
||||
|
||||
void ast_context_destroy(void)
|
||||
{
|
||||
printf("Executed ast_context_destroy();\n");
|
||||
}
|
||||
|
||||
void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
|
||||
{
|
||||
va_list vars;
|
||||
va_start(vars,fmt);
|
||||
|
||||
printf("LOG: lev:%d file:%s line:%d func: %s ",
|
||||
level, file, line, function);
|
||||
vprintf(fmt, vars);
|
||||
fflush(stdout);
|
||||
va_end(vars);
|
||||
}
|
||||
|
||||
void ast_verbose(const char *fmt, ...)
|
||||
{
|
||||
va_list vars;
|
||||
va_start(vars,fmt);
|
||||
|
||||
printf("VERBOSE: ");
|
||||
vprintf(fmt, vars);
|
||||
fflush(stdout);
|
||||
va_end(vars);
|
||||
}
|
||||
|
||||
char *ast_process_quotes_and_slashes(char *start, char find, char replace_with)
|
||||
{
|
||||
char *dataPut = start;
|
||||
int inEscape = 0;
|
||||
int inQuotes = 0;
|
||||
|
||||
for (; *start; start++) {
|
||||
if (inEscape) {
|
||||
*dataPut++ = *start; /* Always goes verbatim */
|
||||
inEscape = 0;
|
||||
} else {
|
||||
if (*start == '\\') {
|
||||
inEscape = 1; /* Do not copy \ into the data */
|
||||
} else if (*start == '\'') {
|
||||
inQuotes = 1-inQuotes; /* Do not copy ' into the data */
|
||||
} else {
|
||||
/* Replace , with |, unless in quotes */
|
||||
*dataPut++ = inQuotes ? *start : ((*start==find) ? replace_with : *start);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start != dataPut)
|
||||
*dataPut = 0;
|
||||
return dataPut;
|
||||
}
|
||||
|
||||
extern struct module_symbols mod_data;
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=1;i<argc;i++)
|
||||
{
|
||||
if( argv[i][0] == '-' && argv[i][1] == 'n' )
|
||||
no_comp =1;
|
||||
if( argv[i][0] == '-' && argv[i][1] == 'd' )
|
||||
use_curr_dir =1;
|
||||
}
|
||||
|
||||
|
||||
if( !no_comp )
|
||||
printf("\n(You can use the -n option if you aren't interested in seeing all the instructions generated by the compiler)\n\n");
|
||||
if( !use_curr_dir )
|
||||
printf("\n(You can use the -d option if you want to use the current working directory as the CONFIG_DIR. I will look in this dir for extensions.ael* and its included files)\n\n");
|
||||
|
||||
if( use_curr_dir )
|
||||
{
|
||||
strcpy(ast_config_AST_CONFIG_DIR, ".");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy(ast_config_AST_CONFIG_DIR, "/etc/asterisk");
|
||||
}
|
||||
strcpy(ast_config_AST_VAR_DIR, "/var/lib/asterisk");
|
||||
|
||||
mod_data.load_module(0);
|
||||
|
||||
ast_log(4, "ael2_parse", __LINE__, "main", "%d contexts, %d extensions, %d priorities\n", conts, extens, priors);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
2 + 2
|
||||
2 + 2
|
||||
|
||||
2 - 4
|
||||
4 - 2
|
||||
-4 - -2
|
||||
4 + 2 * 8
|
||||
(4 + 2) * 8
|
||||
4 + (2 * 8)
|
||||
4 + (2 * 8) ? 3 :: 6
|
||||
4 + 8 / 2
|
||||
4 + 8 / 3
|
||||
(4+8) / 3
|
||||
4 + 8 % 3
|
||||
4 + 9 % 3
|
||||
(4+9) %3
|
||||
(4+8) %3
|
||||
(4+9) %3
|
||||
(4+8) %3
|
||||
(4+9) % 3
|
||||
(4+8) % 3
|
||||
(4+9) % 3
|
||||
(4+8) % 3
|
||||
(4+9)% 3
|
||||
(4+8)% 3
|
||||
(4+9)% 3
|
||||
(4+8)% 3
|
||||
4 & 4
|
||||
0 & 4
|
||||
0 & 0
|
||||
2 | 0
|
||||
2 | 4
|
||||
0 | 0
|
||||
!0 | 0
|
||||
!4 | 0
|
||||
4 | !0
|
||||
!4 | !0
|
||||
3 < 4
|
||||
4 < 3
|
||||
3 > 4
|
||||
4 > 3
|
||||
3 = 3
|
||||
3 = 4
|
||||
3 != 3
|
||||
3 != 4
|
||||
3 >= 4
|
||||
3 >= 3
|
||||
4 >= 3
|
||||
3 <= 4
|
||||
4 <= 3
|
||||
4 <= 4
|
||||
3 > 4 & 4 < 3
|
||||
4 > 3 & 3 < 4
|
||||
x = x
|
||||
y = x
|
||||
x != y
|
||||
x != x
|
||||
"Something interesting" =~ interesting
|
||||
"Something interesting" =~ Something
|
||||
"Something interesting" : Something
|
||||
"Something interesting" : interesting
|
||||
"Something interesting" =~ "interesting"
|
||||
"Something interesting" =~ "Something"
|
||||
"Something interesting" : "Something"
|
||||
"Something interesting" : "interesting"
|
||||
"Something interesting" =~ (interesting)
|
||||
"Something interesting" =~ (Something)
|
||||
"Something interesting" : (Something)
|
||||
"Something interesting" : (interesting)
|
||||
"Something interesting" =~ "\(interesting\)"
|
||||
"Something interesting" =~ "\(Something\)"
|
||||
"Something interesting" : "\(Something\)"
|
||||
"Something interesting" : "\(interesting\)"
|
||||
"011043567857575" : "011\(..\)"
|
||||
"9011043567857575" : "011\(..\)"
|
||||
"011043567857575" =~ "011\(..\)"
|
||||
"9011043567857575" =~ "011\(..\)"
|
||||
"Something interesting" =~ (interesting)
|
||||
"Something interesting" =~ (Something)
|
||||
"Something interesting" : (Something)
|
||||
"Something interesting" : (interesting)
|
||||
"Something interesting" =~ "(interesting)"
|
||||
"Something interesting" =~ "(Something)"
|
||||
"Something interesting" : "(Something)"
|
||||
"Something interesting" : "(interesting)"
|
||||
"011043567857575" : "011(..)"
|
||||
"9011043567857575" : "011(..)"
|
||||
"011043567857575" =~ "011(..)"
|
||||
"9011043567857575" =~ "011(..)"
|
||||
3
|
||||
something
|
||||
043
|
Reference in New Issue