34 #include <sys/types.h>
55 #include "asterisk/argdesc.h"
70 static int extensions_dot_conf_loaded = 0;
122 for (i=0; i<depth; i++) {
126 switch ( item->
type ) {
128 fprintf(fin,
"%s;\n", item->
u1.
str);
132 fprintf(fin,
"macro %s(", item->
u1.
str);
136 fprintf(fin,
"%s", lp->
u1.
str);
138 fprintf(fin,
") {\n");
140 for (i=0; i<depth; i++) {
143 fprintf(fin,
"};\n\n");
148 fprintf(fin,
"abstract context %s {\n", item->
u1.
str);
150 fprintf(fin,
"context %s {\n", item->
u1.
str);
152 for (i=0; i<depth; i++) {
155 fprintf(fin,
"};\n\n");
159 fprintf(fin,
"&%s(", item->
u1.
str);
163 fprintf(fin,
"%s", lp->
u1.
str);
169 fprintf(fin,
"%s(", item->
u1.
str);
173 fprintf(fin,
"%s", lp->
u1.
str);
179 fprintf(fin,
"case %s:\n", item->
u1.
str);
184 fprintf(fin,
"pattern %s:\n", item->
u1.
str);
189 fprintf(fin,
"default:\n");
194 fprintf(fin,
"catch %s {\n", item->
u1.
str);
196 for (i=0; i<depth; i++) {
203 fprintf(fin,
"switches {\n");
205 for (i=0; i<depth; i++) {
212 fprintf(fin,
"eswitches {\n");
214 for (i=0; i<depth; i++) {
221 fprintf(fin,
"includes {\n");
223 for (i=0; i<depth+1; i++) {
226 fprintf(fin,
"%s", lp->
u1.
str);
228 fprintf(fin,
"|%s|%s|%s|%s",
237 for (i=0; i<depth; i++) {
246 for (i=0; i<depth; i++) {
253 fprintf(fin,
"%s=%s;\n", item->
u1.
str, item->
u2.
val);
257 fprintf(fin,
"local %s=%s;\n", item->
u1.
str, item->
u2.
val);
270 fprintf(fin,
"%s:\n", item->
u1.
str);
279 fprintf(fin,
"while (%s)\n", item->
u1.
str);
284 fprintf(fin,
"break;\n");
288 fprintf(fin,
"return;\n");
292 fprintf(fin,
"continue;\n");
300 fprintf(fin,
"ifTime ( %s|%s|%s|%s )\n",
307 fprintf(fin,
"random ( %s )\n", item->
u1.
str );
309 fprintf(fin,
"if ( %s )\n", item->
u1.
str);
311 for (i=0; i<depth; i++) {
316 for (i=0; i<depth; i++) {
327 fprintf(fin,
" {} ");
329 fprintf(fin,
" {}; ");
332 for (i=0; i<depth; i++) {
335 fprintf(fin,
"else\n");
341 fprintf(fin,
"switch( %s ) {\n", item->
u1.
str);
343 for (i=0; i<depth; i++) {
351 fprintf(fin,
"regexten ");
353 fprintf(fin,
"hints(%s) ", item->
u3.
hints);
355 fprintf(fin,
"%s => ", item->
u1.
str);
361 fprintf(fin,
"ignorepat => %s;\n", item->
u1.
str);
365 fprintf(fin,
"globals {\n");
367 for (i=0; i<depth; i++) {
379 for (i=item; i; i=i->
next) {
386 FILE *fin = fopen(fname,
"w");
407 switch ( item->
type ) {
641 for (i=item; i; i=i->
next) {
658 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The macro %s is empty! I will insert a return.\n",
673 if (i->
next == NULL) {
676 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The macro %s does not end with a return; I will insert one.\n",
702 if (strcmp(pattern,exten) == 0)
705 if (pattern[0] ==
'_') {
710 if ( strlen(pattern)*5 >= 2000 ) {
711 ast_log(
LOG_ERROR,
"Error: The pattern %s is way too big. Pattern matching cancelled.\n",
719 for (p=pattern+1; *p; p++) {
749 while ( *p && *p !=
']' ) {
754 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n",
776 err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED);
779 regerror(err1,&preg,errmess,
sizeof(errmess));
785 err1 = regexec(&preg, exten, 0, 0, 0);
800 if ( strcmp(exten,pattern) == 0 ) {
810 int spaces = strspn(str,
"\t \n");
811 if ( !strncmp(str+spaces,
"$[",2) ) {
812 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n",
824 char *incl_context = p4->
u1.
str;
827 if (!that_other_context && strcmp(incl_context,
"parkedcalls") != 0) {
828 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\
829 (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n",
851 e = strchr(times,
'-');
853 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The time range format (%s) requires a '-' surrounded by two 24-hour times of day!\n",
860 while (*e && !isdigit(*e))
863 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n",
867 if (sscanf(times,
"%2d:%2d", &s1, &s2) != 2) {
868 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n",
872 if (sscanf(e,
"%2d:%2d", &e1, &e2) != 2) {
873 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n",
879 if ((s1 < 0) || (s1 >= 24*30)) {
880 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start time (%s) is out of range!\n",
885 if ((e1 < 0) || (e1 >= 24*30)) {
886 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end time (%s) is out of range!\n",
918 c = strchr(dow,
'-');
926 while ((s < 7) && strcasecmp(dow, days[s])) s++;
928 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The day (%s) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!\n",
934 while ((e < 7) && strcasecmp(c, days[e])) e++;
936 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end day (%s) must be one of 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', or 'sat'!\n",
958 c = strchr(day,
'-');
964 if (sscanf(day,
"%2d", &s) != 1) {
965 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n",
969 else if ((s < 1) || (s > 31)) {
970 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start day of month (%s) must be a number in the range [1-31]!\n",
976 if (sscanf(c,
"%2d", &e) != 1) {
977 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n",
981 else if ((e < 1) || (e > 31)) {
982 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end day of month (%s) must be a number in the range [1-31]!\n",
1020 c = strchr(mon,
'-');
1027 while ((s < 12) && strcasecmp(mon, months[s])) s++;
1029 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1035 while ((e < 12) && strcasecmp(mon, months[e])) e++;
1037 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1058 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: 'break' not in switch, for, or while statement!\n",
1077 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: 'continue' not in 'for' or 'while' statement!\n",
1132 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: Label %s is not within an extension or macro!\n",
1144 if( !current_extension )
1151 if( x && x != item )
1153 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: Duplicate label %s! Previously defined at file %s, line %d.\n",
1179 if (!strstr((item->
u1.
list)->u1.str,
"${")
1193 if (!strstr((item->
u1.
list)->u1.str,
"${")
1211 char *incl_context = p4->
u1.
str;
1214 if (that_other_context) {
1239 if ( !(item->
u1.
list)->next && !(item->
u1.
list)->u1.str ) {
1240 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: empty label reference found!\n",
1254 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: no label %s exists in the current extension!\n",
1267 if (!strstr((item->
u1.
list)->u1.str,
"${")
1276 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: no label '%s,%s' exists in the current context, or any of its inclusions!\n",
1294 if (!strstr((item->
u1.
list)->u1.str,
"${")
1300 struct pval *found = 0;
1312 char *incl_context = p4->
u1.
str;
1315 if (that_other_context) {
1327 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: no label %s|%s exists in the context %s or its inclusions!\n",
1336 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: It's bad form to have a goto in a macro to a target outside the macro!\n",
1349 if (!extensions_dot_conf_loaded) {
1351 extensions_dot_conf_loaded++;
1355 atoi(third->
u1.
str) ? NULL : third->
u1.
str, NULL,
1359 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: goto: Couldn't find goto target %s|%s|%s, not even in extensions.conf!\n",
1364 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: goto: Couldn't find goto target %s|%s|%s in the AEL code!\n",
1375 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: It's bad form to have a goto in a macro to a target outside the macro!\n",
1395 switch ( item->
type ) {
1469 char *incl_context = p4->
u1.
str;
1561 for (i=item; i; i=i->
next) {
1574 switch ( item->
type ) {
1584 if (!strcmp(match_context,
"*") || !strcmp(item->
u1.
str, match_context)) {
1588 if (return_on_context_match && !strcmp(item->
u1.
str, match_context)) {
1594 if (!return_on_context_match) {
1613 if (!strcmp(match_context,
"*") || !strcmp(item->
u1.
str, match_context)) {
1614 if (return_on_context_match && !strcmp(item->
u1.
str, match_context)) {
1620 if (!return_on_context_match ) {
1693 if (!strcmp(match_label, item->
u1.
str)) {
1695 last_matched_label = item;
1699 if (!strcmp(match_label, item->
u1.
str)) {
1789 if (strcmp(match_label,
"1") == 0) {
1822 for (i=item; i; i=i->
next) {
1839 return_on_context_match = 0;
1853 return_on_context_match = 0;
1854 match_context =
"*";
1856 match_label = label;
1870 char *incl_context = p4->
u1.
str;
1893 return_on_context_match = 0;
1894 match_context =
"*";
1895 match_exten =
exten;
1896 match_label = label;
1909 char *incl_context = p4->
u1.
str;
1929 return_on_context_match = 0;
1930 match_context =
"*";
1932 match_label = label;
1940 return_on_context_match = 0;
1943 match_exten =
exten;
1944 match_label = label;
1952 return_on_context_match = 1;
1954 match_context =
name;
1962 return_on_context_match = 1;
1964 match_context =
name;
1973 for (s=arg; *s; s++) {
1974 if (*s !=
'.' && (*s < '0' || *s >
'9'))
1982 for (s=arg; *s; s++) {
1983 if (*s < '0' || *s >
'9')
1995 if (*arg !=
' ' && *arg !=
'\t')
2003 int option_matches_j(
struct argdesc *should,
pval *is,
struct argapp *
app)
2005 struct argchoice *ac;
2008 switch (should->dtype) {
2009 case ARGD_OPTIONSET:
2010 if ( strstr(is->
u1.
str,
"${") )
2015 for (q=opcop;*q;q++) {
2018 while (*p && *p !=
')' )
2024 for (ac=app->opts; ac; ac=ac->
next) {
2025 if (strlen(ac->name)>1 && strchr(ac->name,
'(') == 0 && strcmp(ac->name,is->
u1.
str) == 0)
2028 for (ac=app->opts; ac; ac=ac->
next) {
2029 if (strlen(ac->name)==1 || strchr(ac->name,
'(')) {
2030 char *p = strchr(opcop,ac->name[0]);
2032 if (p && *p ==
'j') {
2033 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: The j option in the %s application call is not appropriate for AEL!\n",
2040 if (ac->name[1] ==
'(') {
2041 if (*(p+1) !=
'(') {
2042 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The %c option in the %s application call should have an (argument), but doesn't!\n",
2050 for (q=opcop; *q; q++) {
2051 if ( *q !=
'+' && *q !=
'(' && *q !=
')') {
2052 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The %c option in the %s application call is not available as an option!\n",
2065 int option_matches(
struct argdesc *should,
pval *is,
struct argapp *app)
2067 struct argchoice *ac;
2070 switch (should->dtype) {
2095 for (ac=should->choices; ac; ac=ac->next) {
2096 if (strcmp(ac->name,is->
u1.
str) == 0)
2102 case ARGD_OPTIONSET:
2105 for (ac=app->opts; ac; ac=ac->
next) {
2106 if (strlen(ac->name)>1 && strchr(ac->name,
'(') == 0 && strcmp(ac->name,is->
u1.
str) == 0)
2109 for (ac=app->opts; ac; ac=ac->
next) {
2110 if (strlen(ac->name)==1 || strchr(ac->name,
'(')) {
2111 char *p = strchr(opcop,ac->name[0]);
2115 if (ac->name[1] ==
'(') {
2116 if (*(p+1) ==
'(') {
2118 while (*q && *q !=
')') {
2140 struct argdesc *ad = app->args;
2144 for (pa = arglist; pa; pa=pa->
next) {
2146 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n",
2153 if ( ad->dtype == ARGD_VARARG )
2156 z= option_matches( ad, pa, app);
2161 if (ad->type == ARGD_REQUIRED) {
2162 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2167 }
else if (z && ad->dtype == ARGD_OPTIONSET) {
2168 option_matches_j( ad, pa, app);
2175 for ( ; ad; ad=ad->next) {
2176 if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) {
2179 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2197 struct appsetvar *v,*v2;
2198 struct argchoice *c;
2202 while (p && *p && (*p ==
' ' || *p ==
'\t' || *p ==
'$' || *p ==
'{' ) )
2207 while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] ==
'}' || buff1[strlen(buff1)-1] ==
' ' || buff1[strlen(buff1)-1] ==
'\t'))
2208 buff1[strlen(buff1)-1] = 0;
2211 for (a=apps; a; a=a->
next) {
2212 for (v=a->setvars;v;v=v->
next) {
2213 if (strcmp(v->name,buff1) == 0) {
2238 for (c=v->vals; c; c=c->next) {
2242 if (!strcmp(t->
u1.
str,c->name)) {
2249 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n",
2259 for (; t && t != item; t=t->
next) {
2262 for (a2=apps; a2; a2=a2->
next) {
2263 if (strcasecmp(a2->name, t->
u1.
str)==0) {
2264 for (v2=a2->setvars; v2; v2=v2->
next) {
2265 if (strcmp(v2->name, buff1) == 0) {
2282 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Couldn't find an application call in this extension that sets the expression (%s) value!\n",
2310 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: A default case was automatically added to the switch.\n",
2311 p2->filename, p2->startline, p2->endline);
2320 for (i=current_db; i; i=i->
next) {
2326 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The context name (%s) is also declared in file %s, line %d-%d! (and neither is marked 'extend')\n",
2343 for (i=current_db; i; i=i->
next) {
2345 for (j=i->
u2. statements; j; j=j->
next) {
2351 if ( !strcmp(p4->
u1.
str, abstract_context->
u1.
str) )
2358 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Couldn't find a reference to this abstract context (%s) in any other context!\n",
2370 struct pval *macro_def;
2371 struct pval *app_def;
2376 switch (item->
type) {
2390 in_abstract_context = 0;
2391 current_context = item;
2392 current_extension = 0;
2407 current_context = item;
2408 current_extension = 0;
2410 in_abstract_context = 1;
2413 in_abstract_context = 0;
2426 if (!extensions_dot_conf_loaded) {
2428 extensions_dot_conf_loaded++;
2442 snprintf(namebuf2, 256,
"macro-%s", item->
u1.
str);
2448 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: macro call to non-existent %s! (macro-%s was found in the extensions.conf stuff, but we are using gosubs!)\n",
2452 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: macro call to non-existent %s! (Not even in the extensions.conf stuff!)\n",
2458 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: macro call to %s cannot be found in the AEL code!\n",
2463 #ifdef THIS_IS_1DOT4
2465 snprintf(namebuf2, 256,
"macro-%s", item->
u1.
str);
2471 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: macro call to %s was not found in the AEL, nor the extensions.conf !\n",
2479 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: macro call to %s references a context, not a macro!\n",
2493 if (hereargs != thereargs ) {
2494 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: The macro call to %s has %d arguments, but the macro definition has %d arguments\n",
2510 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: application call to %s references an existing macro, but had no & preceding it!\n",
2514 if (strcasecmp(item->
u1.
str,
"GotoIf") == 0
2515 || strcasecmp(item->
u1.
str,
"GotoIfTime") == 0
2516 || strcasecmp(item->
u1.
str,
"while") == 0
2517 || strcasecmp(item->
u1.
str,
"endwhile") == 0
2518 || strcasecmp(item->
u1.
str,
"random") == 0
2519 || strcasecmp(item->
u1.
str,
"gosub") == 0
2520 || strcasecmp(item->
u1.
str,
"gosubif") == 0
2521 || strcasecmp(item->
u1.
str,
"continuewhile") == 0
2522 || strcasecmp(item->
u1.
str,
"endwhile") == 0
2523 || strcasecmp(item->
u1.
str,
"execif") == 0
2524 || strcasecmp(item->
u1.
str,
"execiftime") == 0
2525 || strcasecmp(item->
u1.
str,
"exitwhile") == 0
2526 || strcasecmp(item->
u1.
str,
"goto") == 0
2527 || strcasecmp(item->
u1.
str,
"macro") == 0
2528 || strcasecmp(item->
u1.
str,
"macroexclusive") == 0
2529 || strcasecmp(item->
u1.
str,
"macroif") == 0
2530 || strcasecmp(item->
u1.
str,
"stackpop") == 0
2531 || strcasecmp(item->
u1.
str,
"execIf") == 0 ) {
2532 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: application call to %s affects flow of control, and needs to be re-written using AEL if, while, goto, etc. keywords instead!\n",
2536 if (strcasecmp(item->
u1.
str,
"macroexit") == 0) {
2537 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: I am converting the MacroExit call here to a return statement.\n",
2546 for (app=apps;
app; app=app->
next) {
2547 if (strcasecmp(app->name, item->
u1.
str) == 0) {
2553 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: application call to %s not listed in applist database!\n",
2613 char *incl_context = lp->
u1.
str;
2642 snprintf(errmsg,
sizeof(errmsg),
"file %s, line %d, columns %d-%d, variable declaration expr '%s':", item->
filename, item->
startline, item->
startcol, item->
endcol, item->
u2.
val);
2644 ast_expr(item->
u2.
val, expr_output,
sizeof(expr_output),NULL);
2646 if ( strpbrk(item->
u2.
val,
"~!-+<>=*/&^") && !strstr(item->
u2.
val,
"${") ) {
2647 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2660 snprintf(errmsg,
sizeof(errmsg),
"file %s, line %d, columns %d-%d, variable declaration expr '%s':", item->
filename, item->
startline, item->
startcol, item->
endcol, item->
u2.
val);
2662 ast_expr(item->
u2.
val, expr_output,
sizeof(expr_output),NULL);
2664 if ( strpbrk(item->
u2.
val,
"~!-+<>=*/&^") && !strstr(item->
u2.
val,
"${") ) {
2665 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2677 if ( in_abstract_context )
2686 if ( strspn(item->
u1.
str,
"0123456789") == strlen(item->
u1.
str) ) {
2687 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: label '%s' is numeric, this is bad practice!\n",
2702 snprintf(errmsg,
sizeof(errmsg),
"file %s, line %d, columns %d-%d, for test expr '%s':", item->
filename, item->
startline, item->
startcol, item->
endcol, item->
u2.
for_test);
2707 ast_expr(strp+1, expr_output,
sizeof(expr_output),NULL);
2712 ast_expr(strp+1, expr_output,
sizeof(expr_output),NULL);
2715 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2720 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2736 snprintf(errmsg,
sizeof(errmsg),
"file %s, line %d, columns %d-%d, while expr '%s':", item->
filename, item->
startline, item->
startcol, item->
endcol, item->
u1.
str);
2738 ast_expr(item->
u1.
str, expr_output,
sizeof(expr_output),NULL);
2740 if ( strpbrk(item->
u1.
str,
"~!-+<>=*/&^") && !strstr(item->
u1.
str,
"${") ) {
2741 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2773 snprintf(errmsg,
sizeof(errmsg),
"file %s, line %d, columns %d-%d, random expr '%s':", item->
filename, item->
startline, item->
startcol, item->
endcol, item->
u1.
str);
2775 ast_expr(item->
u1.
str, expr_output,
sizeof(expr_output),NULL);
2777 if ( strpbrk(item->
u1.
str,
"~!-+<>=*/&^") && !strstr(item->
u1.
str,
"${") ) {
2778 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n",
2816 snprintf(errmsg,
sizeof(errmsg),
"file %s, line %d, columns %d-%d, if expr '%s':", item->
filename, item->
startline, item->
startcol, item->
endcol, item->
u1.
str);
2818 ast_expr(item->
u1.
str, expr_output,
sizeof(expr_output),NULL);
2820 if ( strpbrk(item->
u1.
str,
"~!-+<>=*/&^") && !strstr(item->
u1.
str,
"${") ) {
2821 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n",
2851 current_extension = item ;
2864 in_abstract_context = 0;
2887 for (i=item; i; i=i->
next) {
2907 apps = argdesc_parse(rfilename, &argapp_errs);
2910 errs = warns = notes = 0;
2916 argdesc_destroy(apps);
2947 if (!exten->
plist) {
2948 exten->
plist = prio;
2962 while ((p1 = strstr(prio->
appargs,
"${EXTEN}"))) {
2966 strcat(p2,
"${~~EXTEN~~}");
2972 while ((p1 = strstr(prio->
appargs,
"${EXTEN:"))) {
2976 strcat(p2,
"${~~EXTEN~~:");
2988 for (ne=exten; ne; ne=nen) {
3001 for (pe=ne->
plist; pe; pe=pen) {
3048 while( str && *str && *str !=
'=' )
3050 if( *str ==
' ' || *str ==
'\n' || *str ==
'\r' || *str ==
'\t' )
3071 char *p=pattern, *t=result;
3073 if (*p ==
'x' || *p ==
'n' || *p ==
'z' || *p ==
'X' || *p ==
'N' || *p ==
'Z')
3075 else if (*p ==
'[') {
3099 switch ( item->
type ) {
3340 for (i=item; i; i=i->
next) {
3352 struct ael_priority *for_init, *for_test, *for_inc, *for_loop, *for_end;
3353 struct ael_priority *while_test, *while_loop, *while_end;
3354 struct ael_priority *switch_set, *switch_test, *switch_end, *fall_thru, *switch_empty;
3355 struct ael_priority *if_test, *if_end, *if_skip, *if_false;
3356 #ifdef OLD_RAND_ACTION
3364 int local_control_statement_count;
3384 for (first = 1; first >= 0; first--) {
3393 if (!strcmp(mother_exten->
name,
"~~s~~") && first) {
3402 linkprio(exten, switch_set, mother_exten);
3413 for (first = 1; first >= 0; first--) {
3422 if (!strcmp(exten->
name,
"~~s~~")) {
3431 linkprio(exten, switch_set, mother_exten);
3450 for (p=statement; p; p=p->
next) {
3523 control_statement_count++;
3526 snprintf(new_label,
BUF_SIZE,
"for_%s_%d", label, control_statement_count);
3546 strp = strchr(buf2,
'=');
3551 strncat(buf2,strp2+1,
BUF_SIZE-strlen(strp2+1)-2);
3556 while (*strp2 && isspace(*strp2))
3558 if (*strp2 ==
'&') {
3559 char *strp3 = strp2+1;
3560 while (*strp3 && isspace(*strp3))
3562 strcpy(buf2, strp3);
3563 strp3 = strchr(buf2,
'(');
3567 while ((strp3=strchr(buf2,
','))) {
3570 strp3 = strrchr(buf2,
')');
3579 strcpy(buf2, strp2);
3580 strp3 = strchr(buf2,
'(');
3586 strp3 = strrchr(for_init->
appargs,
')');
3595 strp = strchr(buf2,
'=');
3600 strncat(buf2,strp2+1,
BUF_SIZE-strlen(strp2+1)-2);
3610 while (*strp2 && isspace(*strp2))
3612 if (*strp2 ==
'&') {
3613 char *strp3 = strp2+1;
3614 while (*strp3 && isspace(*strp3))
3616 strcpy(buf2, strp3);
3617 strp3 = strchr(buf2,
'(');
3621 strp3 = strrchr(buf2,
')');
3630 strcpy(buf2, strp2);
3631 strp3 = strchr(buf2,
'(');
3636 strp3 = strrchr(for_inc->
appargs,
')');
3646 snprintf(buf1,
BUF_SIZE,
"Finish for_%s_%d", label, control_statement_count);
3650 linkprio(exten, for_init, mother_exten);
3651 linkprio(exten, for_test, mother_exten);
3661 linkprio(exten, for_inc, mother_exten);
3662 linkprio(exten, for_loop, mother_exten);
3663 linkprio(exten, for_end, mother_exten);
3672 control_statement_count++;
3675 snprintf(new_label,
BUF_SIZE,
"while_%s_%d", label, control_statement_count);
3684 while_test->
app = 0;
3687 snprintf(buf1,
BUF_SIZE,
"Finish while_%s_%d", label, control_statement_count);
3691 linkprio(exten, while_test, mother_exten);
3701 linkprio(exten, while_loop, mother_exten);
3702 linkprio(exten, while_end, mother_exten);
3711 control_statement_count++;
3715 snprintf(new_label,
BUF_SIZE,
"sw_%s_%d", label, control_statement_count);
3720 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s,10", control_statement_count, p->
u1.
str);
3723 snprintf(buf1,
BUF_SIZE,
"Finish switch_%s_%d", label, control_statement_count);
3729 linkprio(exten, switch_test, mother_exten);
3730 linkprio(exten, switch_end, mother_exten);
3749 switch_case->
context = this_context;
3756 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s", local_control_statement_count, p2->
u1.
str);
3758 snprintf(new_label,
BUF_SIZE,
"sw_%s_%s_%d", label, p2->
u1.
str, local_control_statement_count);
3776 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count, p2->
next->
u1.
str);
3778 linkprio(switch_case, fall_thru, mother_exten);
3784 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count, buf2);
3786 linkprio(switch_case, fall_thru, mother_exten);
3791 snprintf(buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3793 linkprio(switch_case, fall_thru, mother_exten);
3794 }
else if (!p2->
next) {
3799 linkprio(switch_case, fall_thru, mother_exten);
3807 snprintf(buf,
BUF_SIZE,
"End of Extension %s", switch_case->
name);
3809 linkprio(switch_case, np2, mother_exten);
3810 switch_case-> return_target = np2;
3823 switch_case->
context = this_context;
3830 snprintf(buf1,
BUF_SIZE,
"_sw_%d_%s", local_control_statement_count, p2->
u1.
str);
3832 snprintf(new_label,
BUF_SIZE,
"sw_%s_%s_%d", label, p2->
u1.
str, local_control_statement_count);
3849 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count, p2->
next->
u1.
str);
3851 linkprio(switch_case, fall_thru, mother_exten);
3857 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count, buf2);
3859 linkprio(switch_case, fall_thru, mother_exten);
3864 snprintf(buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3866 linkprio(switch_case, fall_thru, mother_exten);
3867 }
else if (!p2->
next) {
3872 linkprio(switch_case, fall_thru, mother_exten);
3880 snprintf(buf,
sizeof(buf),
"End of Extension %s", switch_case->
name);
3882 linkprio(switch_case, np2, mother_exten);
3883 switch_case-> return_target = np2;
3896 switch_case->
context = this_context;
3913 switch_null->
context = this_context;
3916 snprintf(buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3919 linkprio(switch_null, switch_empty, mother_exten);
3920 snprintf(buf1,
BUF_SIZE,
"sw_%d_", local_control_statement_count);
3930 snprintf(buf1,
BUF_SIZE,
"_sw_%d_.", local_control_statement_count);
3933 snprintf(new_label,
BUF_SIZE,
"sw_%s_default_%d", label, local_control_statement_count);
3951 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count, p2->
next->
u1.
str);
3953 linkprio(switch_case, fall_thru, mother_exten);
3959 snprintf(buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count, buf2);
3961 linkprio(switch_case, fall_thru, mother_exten);
3966 snprintf(buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3968 linkprio(switch_case, fall_thru, mother_exten);
3969 }
else if (!p2->
next) {
3974 linkprio(switch_case, fall_thru, mother_exten);
3982 snprintf(buf,
sizeof(buf),
"End of Extension %s", switch_case->
name);
3984 linkprio(switch_case, np2, mother_exten);
3985 switch_case-> return_target = np2;
4011 strcat(buf1,p2->
u1.
str);
4029 strcat(buf1,p2->
u1.
str);
4064 control_statement_count++;
4065 snprintf(new_label,
BUF_SIZE,
"iftime_%s_%d", label, control_statement_count);
4069 snprintf(buf1,
BUF_SIZE,
"%s,%s,%s,%s",
4080 snprintf(buf1,
BUF_SIZE,
"Finish iftime_%s_%d", label, control_statement_count);
4105 linkprio(exten, if_test, mother_exten);
4106 linkprio(exten, if_false, mother_exten);
4115 linkprio(exten, if_skip, mother_exten);
4121 linkprio(exten, if_end, mother_exten);
4127 control_statement_count++;
4128 snprintf(new_label,
BUF_SIZE,
"if_%s_%d", label, control_statement_count);
4135 snprintf(buf1,
BUF_SIZE,
"$[${RAND(0,99)} < (%s)]", p->
u1.
str);
4140 snprintf(buf1,
BUF_SIZE,
"Finish if_%s_%d", label, control_statement_count);
4156 linkprio(exten, if_test, mother_exten);
4165 linkprio(exten, if_skip, mother_exten);
4171 linkprio(exten, if_end, mother_exten);
4176 if (
gen_prios(exten, label, p->
u1.
list, mother_exten, this_context)) {
4182 control_statement_count++;
4195 switch_case->
context = this_context;
4198 snprintf(new_label,
BUF_SIZE,
"catch_%s_%d",p->
u1.
str, control_statement_count);
4208 snprintf(buf,
sizeof(buf),
"End of Extension %s", switch_case->
name);
4210 linkprio(switch_case, np2, mother_exten);
4211 switch_case-> return_target = np2;
4237 for (pr=exten->
plist; pr; pr=pr->
next) {
4272 for (pr=exten->
plist; pr; pr=pr->
next) {
4285 strcpy(app, pr->
app);
4292 switch( pr->
type ) {
4309 strcpy(app,
"GotoIf");
4314 strcpy(app,
"GotoIf");
4322 strcpy(app,
"Random");
4327 strcpy(app,
"GotoIfTime");
4332 strcpy(app,
"Return");
4409 char *apparg_save = p->
appargs;
4420 snprintf(buf1,
sizeof(buf1),
"%s,%s,%s", pv2->
u1.
list->
u1.
str,
4426 printf(
"WHAT? The goto doesn't fall into one of three cases for GOTO????\n");
4444 if (exten->
context == context) {
4459 for (p=root; p; p=p->
next ) {
4466 snprintf(buf2,
sizeof(buf2),
"%s=%s", p2->
u1.
str, p2->
u2.
val);
4475 for (p=root; p; p=p->
next ) {
4497 snprintf(buf,
sizeof(buf),
"LOCAL(%s)=${ARG%d}", lp->
u1.
str, argc++);
4511 snprintf(buf,
sizeof(buf),
"End of Macro %s-%s",p->
u1.
str, exten->
name);
4514 exten-> return_target = np2;
4539 if( (s3=strchr(exten->
name,
'/') ) != 0 )
4555 snprintf(buf,
sizeof(buf),
"End of Extension %s", exten->
name);
4558 exten-> return_target = np2;
4565 snprintf(buf,
sizeof(buf),
"A NoOp to follow a trailing label %s", exten->
plist_last->
origin->
u1.
str);
4581 snprintf(buf,
sizeof(buf),
"%s,%s,%s,%s,%s",
4595 char *c = strchr(p3->
u1.
str,
'/');
4608 char *c = strchr(p3->
u1.
str,
'/');
4635 const char *h_context =
"ael-builtin-h-bubble";
4643 { 1,
"Goto",
"9991" },
4645 { 9991,
"Set",
"~~parentcxt~~=${STACK_PEEK(1,c,1)}" },
4647 { 9992,
"GotoIf",
"$[\"${~~parentcxt~~}\"=\"\"]?9996" },
4649 { 9993,
"GotoIf",
"${DIALPLAN_EXISTS(${~~parentcxt~~},h,1)}?9994:9996" },
4651 { 9994,
"StackPop",
"" },
4653 { 9995,
"Goto",
"${~~parentcxt~~},h,1" },
4655 { 9996,
"NoOp",
"" }
4662 char h_context_template[] =
"/tmp/ael-builtin-h-bubble-XXXXXX";
4663 int fd = mkstemp(h_context_template);
4664 unlink(h_context_template);
4675 for (i = 0; i <
ARRAY_LEN(steps); i++) {
4690 if (!strcmp(exten->
name,
"~~s~~")) {
4721 switch (item->
type) {
4983 for (i=item; i; i=nxt) {
4991 static char *ael_funclist[] =
5016 "GROUP_MATCH_COUNT",
5028 "QUEUE_MEMBER_COUNT",
5029 "QUEUE_MEMBER_LIST",
5050 int ael_is_funcname(
char *
name)
5053 t =
sizeof(ael_funclist)/
sizeof(
char*);
5055 while ((s < t) && strcasecmp(name, ael_funclist[s]))
5072 if (p->
type != type)
5074 ast_log(
LOG_ERROR,
"Func: %s the pval passed is not appropriate for this function!\n", funcname);
5148 *arg = (*arg)->
next;
5169 if (!(*next_statement))
5172 *next_statement = (*next_statement)->
next;
5174 return *next_statement;
5233 *statements = (*statements)->
next;
5277 *args = (*args)->
next;
5321 *args = (*args)->
next;
5352 *statement = (*statement)->
next;
5404 *next_item = (*next_item)->
next;
5406 return (*next_item)->
u1.
str;
5426 *next_item = (*next_item)->
next;
5428 return (*next_item)->
u1.
str;
5438 s->
u1.
str = (
char *)include;
5454 s->
u1.
str = (
char *)include;
5457 hr->
u1.
str = hour_range;
5458 dom->
u1.
str = dom_range;
5459 dow->
u1.
str = dow_range;
5460 mon->
u1.
str = month_range;
5494 *next_item = (*next_item)->
next;
5496 return (*next_item)->
u1.
str;
5511 if (!(*next_statement))
5512 *next_statement = p->
u1.
list;
5514 *next_statement = (*next_statement)->
next;
5516 return *next_statement;
5553 if (context && strlen(context)) {
5560 pri->
u1.
str = label;
5565 }
else if (exten && strlen(exten)) {
5570 pri->
u1.
str = label;
5577 pri->
u1.
str = label;
5730 p->
u1.
str = percent;
5793 *next_case = (*next_case)->
next;
5881 ast_log(
LOG_ERROR,
"pvalGlobalsAddStatement called where first arg is not a Globals!\n");
5895 if (!*next_statement) {
5896 *next_statement = p;
5899 *next_statement = (*next_statement)->
next;
5900 return (*next_statement)->
next;
5920 *next_obj = (*next_obj)->
next;
5921 return (*next_obj)->
next;
pval * pvalCasePatDefWalkStatements(pval *p, pval **statement)
char * pvalSwitchGetTestexpr(pval *p)
void pvalContextUnsetAbstract(pval *p)
struct ast_include * ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
pval * pvalMacroWalkStatements(pval *p, pval **next_statement)
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
void pvalGotoSetTarget(pval *p, char *context, char *exten, char *label)
void pvalConditionalSetThenStatement(pval *p, pval *statement)
void pvalTopLevAddObject(pval *p, pval *contextOrObj)
char * pvalCasePatGetVal(pval *p)
void pvalForSetInit(pval *p, char *init)
static int context_used(struct ael_extension *exten_list, struct ast_context *context)
void check_pval_item(pval *item, struct argapp *apps, int in_globals)
static char exten[AST_MAX_EXTENSION]
static int control_statement_count
void destroy_pval_item(pval *item)
int ast_context_add_include2(struct ast_context *con, const char *include, const char *registrar)
Add a context include.
static void find_pval_gotos(pval *item, int lev)
void pvalAppCallAddArg(pval *p, pval *arg)
void check_switch_expr(pval *item, struct argapp *apps)
void pvalVarDecSetValue(pval *p, char *value)
void check_pval(pval *item, struct argapp *apps, int in_globals)
struct ael_priority * new_prio(void)
Asterisk main include file. File version handling, generic pbx functions.
static struct pval * in_macro(pval *item)
static int check_break(pval *item)
char * pvalMacroCallGetMacroName(pval *p)
static struct pval * find_label_in_current_extension(const char *label, pval *curr_ext)
void pvalExtenSetName(pval *p, char *name)
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
static void fix_gotos_in_extensions(struct ael_extension *exten)
void pvalESwitchesAddSwitch(pval *p, char *name)
void pvalMacroAddArg(pval *p, pval *arg)
void pvalExtenUnSetRegexten(pval *p)
void pvalCasePatSetVal(pval *p, char *val)
char * pvalMacroGetName(pval *p)
void pvalLabelSetName(pval *p, char *name)
void pvalIfSetCondition(pval *p, char *expr)
void pvalExtenSetRegexten(pval *p)
struct ael_priority * goto_true
void pvalMacroSetArglist(pval *p, pval *arglist)
void pvalContextSetName(pval *p, char *name)
char * pvalIncludesWalk(pval *p, pval **next_item)
int ast_add_extension2(struct ast_context *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)
Add an extension to an extension context, this time with an ast_context *.
static void linkexten(struct ael_extension *exten, struct ael_extension *add)
struct ael_priority * plist_last
static int label_inside_case(pval *label)
void pvalWordSetString(pval *p, char *str)
void add_extensions(struct ael_extension *exten)
#define ast_compat_app_set
Configuration File Parser.
char * pvalAppCallGetAppName(pval *p)
char * pvalExtenGetHints(pval *p)
void pvalIncludeGetTimeConstraints(pval *p, char **hour_range, char **dom_range, char **dow_range, char **month_range)
void pvalIgnorePatSetPattern(pval *p, char *pat)
static struct ast_threadstorage buf2
void pvalAppCallSetAppName(pval *p, char *name)
int pvalContextGetAbstract(pval *p)
char * pvalLabelGetName(pval *p)
struct ael_priority * plist
static void check_day(pval *DAY)
void pvalSwitchSetTestexpr(pval *p, char *expr)
struct ael_priority * goto_false
pval * pvalCreateNode(pvaltype type)
char * pvalVarDecGetValue(pval *p)
void pvalMacroCallAddArg(pval *p, pval *arg)
int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
Adds a switch (first param is a ast_context)
static struct ao2_container * hints
void ast_free_ptr(void *ptr)
char * pvalForGetInc(pval *p)
static void check_abstract_reference(pval *abstract_context)
int pvalExtenGetRegexten(pval *p)
static int gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *this_context)
struct ael_extension * next_exten
static struct pval * in_context(pval *item)
struct ast_context * context
struct ael_extension * new_exten(void)
void pvalGotoGetTarget(pval *p, char **context, char **exten, char **label)
static pval * get_contxt(pval *p)
void pvalForSetStatement(pval *p, pval *statement)
pval * pvalSwitchWalkCases(pval *p, pval **next_case)
char * pvalESwitchesWalkNames(pval *p, pval **next_item)
static int check_continue(pval *item)
pval * pvalTopLevWalkObjects(pval *p, pval **next_obj)
General Asterisk PBX channel definitions.
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
static int extension_matches(pval *here, const char *exten, const char *pattern)
static pval * current_extension
char * pvalVarDecGetVarname(pval *p)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
struct sla_ringing_trunk * last
static int in_abstract_context
char * pvalIfGetCondition(pval *p)
#define AST_MAX_EXTENSION
static void check_timerange(pval *p)
void pvalConditionalSetElseStatement(pval *p, pval *statement)
char * pvalWordGetString(pval *p)
void pvalForSetTest(pval *p, char *test)
static void check_macro_returns(pval *macro)
struct pval * goto_target
pval * pvalAppCallWalkArgs(pval *p, pval **args)
static void print_pval(FILE *fin, pval *item, int depth)
pvaltype pvalObjectGetType(pval *p)
struct ael_extension * exten
void ael2_print(char *fname, pval *tree)
static char next_item(const char *format)
void pvalVarDecSetVarname(pval *p, char *name)
pval * pvalConditionalGetElseStatement(pval *p)
struct ast_ignorepat * ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
pval * pvalConditionalGetThenStatement(pval *p)
void pvalIfTimeSetCondition(pval *p, char *hour_range, char *dow_range, char *dom_range, char *mon_range)
struct ael_priority * loop_break
int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
const char * ast_get_context_name(struct ast_context *con)
Core PBX routines and definitions.
void destroy_pval(pval *item)
struct ast_flags ast_compat
void pvalGlobalsAddStatement(pval *p, pval *statement)
void pvalSwitchesAddSwitch(pval *p, char *name)
int count_labels_in_current_context(char *label)
struct ael_extension * compiled_label
static struct pval * find_label_in_current_context(char *exten, char *label, pval *curr_cont)
#define ast_strdupa(s)
duplicate a string in memory from the stack
struct ast_custom_function * ast_custom_function_find(const char *name)
static char expr_output[2096]
void ast_expr_clear_extra_error_info(void)
static void gen_match_to_pattern(char *pattern, char *result)
char * pvalRandomGetCondition(pval *p)
struct pval * else_statements
int ast_compile_ael2(struct ast_context **local_contexts, struct ast_hashtab *local_table, struct pval *root)
static void check_goto(pval *item)
struct ael_priority * loop_continue
void pvalMacroSetName(pval *p, char *name)
struct sla_ringing_trunk * first
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
char * pvalCatchGetExtName(pval *p)
static struct ast_hashtab * local_table
void pvalExtenSetStatement(pval *p, pval *statement)
static struct pval * find_label_in_current_db(const char *context, const char *exten, const char *label)
char * pvalExtenGetName(pval *p)
static void check_label(pval *item)
static struct ast_threadstorage buf1
pval * linku1(pval *head, pval *tail)
static void check_includes(pval *includes)
pval * pvalMacroCallWalkArgs(pval *p, pval **args)
pval * pvalCatchGetStatement(pval *p)
void pvalIncludesAddIncludeWithTimeConstraints(pval *p, const char *include, char *hour_range, char *dom_range, char *dow_range, char *month_range)
void pvalContextSetAbstract(pval *p)
int contains_switch(pval *item)
struct ael_priority * next
Structures for AEL - the Asterisk extension language.
char * pvalIgnorePatGetPattern(pval *p)
void pvalRandomSetCondition(pval *p, char *percent)
static void attach_exten(struct ael_extension **list, struct ael_extension *newmem)
int localized_pbx_load_module(void)
int pbx_builtin_setvar(struct ast_channel *chan, const char *data)
Parse and set a single channel variable, where the name and value are separated with an '=' character...
char * pvalContextGetName(pval *p)
struct pval * find_context(char *name)
void pvalCatchSetStatement(pval *p, pval *statement)
Structure used to handle boolean flags.
void ast_expr_register_extra_error_info(char *errmsg)
pval * pvalGlobalsWalkStatements(pval *p, pval **next_statement)
Support for logging to various files, console and syslog Configuration in file logger.conf.
static void check_month(pval *MON)
char * pvalSwitchesWalkNames(pval *p, pval **next_item)
void destroy_extensions(struct ael_extension *exten)
struct ast_sw * ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
void pvalStatementBlockAddStatement(pval *p, pval *statement)
static pval * current_context
static void remove_spaces_before_equals(char *str)
void set_priorities(struct ael_extension *exten)
void pvalIncludesAddInclude(pval *p, const char *include)
Standard Command Line Interface.
int find_switch_item(pval *item)
int check_app_args(pval *appcall, pval *arglist, struct argapp *app)
pval * pvalMacroWalkArgs(pval *p, pval **arg)
static struct ast_context * local_contexts
void pvalCasePatDefAddStatement(pval *p, pval *statement)
void pvalMacroAddStatement(pval *p, pval *statement)
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
static struct pval * find_first_label_in_current_context(char *label, pval *curr_cont)
struct pval * find_macro(char *name)
pval * pvalStatementBlockWalkStatements(pval *p, pval **next_statement)
pval * pvalForGetStatement(pval *p)
void pvalSwitchAddCase(pval *p, pval *Case)
void pvalMacroCallSetArglist(pval *p, pval *arglist)
void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes)
static void check_expr2_input(pval *expr, char *str)
static const char * match_exten
void pvalExtenSetHints(pval *p, char *hints)
int pvalCheckType(pval *p, char *funcname, pvaltype type)
void pvalAppCallSetArglist(pval *p, pval *arglist)
static int return_on_context_match
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
static char context[AST_MAX_CONTEXT]
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
struct pval * for_statements
char * pvalForGetTest(pval *p)
void linkprio(struct ael_extension *exten, struct ael_priority *prio, struct ael_extension *mother_exten)
void pvalCatchSetExtName(pval *p, char *name)
pval * pvalExtenGetStatement(pval *p)
void pvalMacroCallSetMacroName(pval *p, char *name)
void traverse_pval_template(pval *item, int depth)
pval * pvalContextWalkStatements(pval *p, pval **statements)
static pval * get_goto_target(pval *item)
static pval * last_matched_label
Asterisk module definitions.
const char * ast_config_AST_VAR_DIR
static void print_pval_list(FILE *fin, pval *item, int depth)
void pvalForSetInc(pval *p, char *inc)
struct pval * match_pval(pval *item)
ast_context: An extension context
void traverse_pval_item_template(pval *item, int depth)
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
static const char * match_context
char * pvalForGetInit(pval *p)
static void check_dow(pval *DOW)
get_dow: Get day of week
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
struct pval * macro_statements
static const char * match_label
static void check_context_names(void)
static pval * get_extension_or_contxt(pval *p)
static struct pval * match_pval_item(pval *item)
static void find_pval_goto_item(pval *item, int lev)
void pvalContextAddStatement(pval *p, pval *statement)
void pvalIfTimeGetCondition(pval *p, char **hour_range, char **dow_range, char **dom_range, char **month_range)