mirror of https://github.com/asterisk/asterisk
Merge Steve Murphy's (murf) complete re-implementation of AEL, which is now no longer considered experimental :-)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@22273 65c4cc65-6c06-0410-ace0-fbb531ad65f31.4
parent
bc50c527f8
commit
5f58cc8770
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
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
@ -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
File diff suppressed because it is too large
Load Diff
@ -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
|
Loading…
Reference in new issue