30 #define ASTMM_LIBC ASTMM_REDIRECT 33 #include <sys/types.h> 54 #include "asterisk/argdesc.h" 68 static int extensions_dot_conf_loaded = 0;
120 for (i=0; i<depth; i++) {
124 switch ( item->
type ) {
126 fprintf(fin,
"%s;\n", item->
u1.
str);
130 fprintf(fin,
"macro %s(", item->
u1.
str);
134 fprintf(fin,
"%s", lp->
u1.
str);
136 fprintf(fin,
") {\n");
138 for (i=0; i<depth; i++) {
141 fprintf(fin,
"};\n\n");
146 fprintf(fin,
"abstract context %s {\n", item->
u1.
str);
148 fprintf(fin,
"context %s {\n", item->
u1.
str);
150 for (i=0; i<depth; i++) {
153 fprintf(fin,
"};\n\n");
157 fprintf(fin,
"&%s(", item->
u1.
str);
161 fprintf(fin,
"%s", lp->
u1.
str);
167 fprintf(fin,
"%s(", item->
u1.
str);
171 fprintf(fin,
"%s", lp->
u1.
str);
177 fprintf(fin,
"case %s:\n", item->
u1.
str);
182 fprintf(fin,
"pattern %s:\n", item->
u1.
str);
187 fprintf(fin,
"default:\n");
192 fprintf(fin,
"catch %s {\n", item->
u1.
str);
194 for (i=0; i<depth; i++) {
201 fprintf(fin,
"switches {\n");
203 for (i=0; i<depth; i++) {
210 fprintf(fin,
"eswitches {\n");
212 for (i=0; i<depth; i++) {
219 fprintf(fin,
"includes {\n");
221 for (i=0; i<depth+1; i++) {
224 fprintf(fin,
"%s", lp->
u1.
str);
226 fprintf(fin,
"|%s|%s|%s|%s",
235 for (i=0; i<depth; i++) {
244 for (i=0; i<depth; i++) {
251 fprintf(fin,
"%s=%s;\n", item->
u1.
str, item->
u2.
val);
255 fprintf(fin,
"local %s=%s;\n", item->
u1.
str, item->
u2.
val);
268 fprintf(fin,
"%s:\n", item->
u1.
str);
277 fprintf(fin,
"while (%s)\n", item->
u1.
str);
282 fprintf(fin,
"break;\n");
286 fprintf(fin,
"return;\n");
290 fprintf(fin,
"continue;\n");
298 fprintf(fin,
"ifTime ( %s|%s|%s|%s )\n",
305 fprintf(fin,
"random ( %s )\n", item->
u1.
str );
307 fprintf(fin,
"if ( %s )\n", item->
u1.
str);
309 for (i=0; i<depth; i++) {
314 for (i=0; i<depth; i++) {
325 fprintf(fin,
" {} ");
327 fprintf(fin,
" {}; ");
330 for (i=0; i<depth; i++) {
333 fprintf(fin,
"else\n");
339 fprintf(fin,
"switch( %s ) {\n", item->
u1.
str);
341 for (i=0; i<depth; i++) {
349 fprintf(fin,
"regexten ");
351 fprintf(fin,
"hints(%s) ", item->
u3.
hints);
353 fprintf(fin,
"%s => ", item->
u1.
str);
359 fprintf(fin,
"ignorepat => %s;\n", item->
u1.
str);
363 fprintf(fin,
"globals {\n");
365 for (i=0; i<depth; i++) {
377 for (i=item; i; i=i->
next) {
384 FILE *fin = fopen(fname,
"w");
405 switch ( item->
type ) {
639 for (i=item; i; i=i->
next) {
656 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The macro %s is empty! I will insert a return.\n",
674 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The macro %s does not end with a return; I will insert one.\n",
700 if (strcmp(pattern,exten) == 0)
703 if (pattern[0] ==
'_') {
708 if ( strlen(pattern)*5 >= 2000 ) {
709 ast_log(
LOG_ERROR,
"Error: The pattern %s is way too big. Pattern matching cancelled.\n",
717 for (p=pattern+1; *p; p++) {
747 while ( *p && *p !=
']' ) {
752 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n",
774 err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED);
777 regerror(err1,&preg,errmess,
sizeof(errmess));
783 err1 = regexec(&preg, exten, 0, 0, 0);
803 int spaces = strspn(str,
"\t \n");
804 if ( !strncmp(str+spaces,
"$[",2) ) {
805 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n",
817 char *incl_context = p4->
u1.
str;
820 if (!that_other_context && strcmp(incl_context,
"parkedcalls") != 0) {
821 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\ 822 (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n",
844 e = strchr(times,
'-');
846 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",
853 while (*e && !isdigit(*e))
856 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n",
860 if (sscanf(times,
"%2d:%2d", &s1, &s2) != 2) {
861 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n",
865 if (sscanf(e,
"%2d:%2d", &e1, &e2) != 2) {
866 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n",
872 if ((s1 < 0) || (s1 >= 24*30)) {
873 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start time (%s) is out of range!\n",
878 if ((e1 < 0) || (e1 >= 24*30)) {
879 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end time (%s) is out of range!\n",
911 c = strchr(dow,
'-');
919 while ((s < 7) && strcasecmp(dow,
days[s])) s++;
921 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",
927 while ((e < 7) && strcasecmp(c,
days[e])) e++;
929 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",
951 c = strchr(day,
'-');
957 if (sscanf(day,
"%2d", &s) != 1) {
958 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n",
962 else if ((s < 1) || (s > 31)) {
963 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",
969 if (sscanf(c,
"%2d", &e) != 1) {
970 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n",
974 else if ((e < 1) || (e > 31)) {
975 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",
1013 c = strchr(mon,
'-');
1020 while ((s < 12) && strcasecmp(mon,
months[s])) s++;
1022 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1028 while ((e < 12) && strcasecmp(mon,
months[e])) e++;
1030 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1051 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: 'break' not in switch, for, or while statement!\n",
1070 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: 'continue' not in 'for' or 'while' statement!\n",
1125 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: Label %s is not within an extension or macro!\n",
1137 if( !current_extension )
1144 if( x && x != item )
1146 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: Duplicate label %s! Previously defined at file %s, line %d.\n",
1172 if (!strstr((item->
u1.
list)->u1.str,
"${")
1186 if (!strstr((item->
u1.
list)->u1.str,
"${")
1204 char *incl_context = p4->
u1.
str;
1207 if (that_other_context) {
1232 if ( !(item->
u1.
list)->next && !(item->
u1.
list)->u1.str ) {
1233 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: empty label reference found!\n",
1247 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: no label %s exists in the current extension!\n",
1260 if (!strstr((item->
u1.
list)->u1.str,
"${")
1269 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",
1287 if (!strstr((item->
u1.
list)->u1.str,
"${")
1293 struct pval *found = 0;
1305 char *incl_context = p4->
u1.
str;
1308 if (that_other_context) {
1320 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: no label %s|%s exists in the context %s or its inclusions!\n",
1329 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",
1342 if (!extensions_dot_conf_loaded) {
1344 extensions_dot_conf_loaded++;
1352 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",
1357 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: goto: Couldn't find goto target %s|%s|%s in the AEL code!\n",
1368 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",
1388 switch ( item->
type ) {
1462 char *incl_context = p4->
u1.
str;
1554 for (i=item; i; i=i->
next) {
1567 switch ( item->
type ) {
1688 last_matched_label =
item;
1815 for (i=item; i; i=i->
next) {
1863 char *incl_context = p4->
u1.
str;
1902 char *incl_context = p4->
u1.
str;
1966 for (s=arg; *s; s++) {
1967 if (*s !=
'.' && (*s < '0' || *s >
'9'))
1975 for (s=arg; *s; s++) {
1976 if (*s < '0' || *s >
'9')
1988 if (*arg !=
' ' && *arg !=
'\t')
1996 int option_matches_j(
struct argdesc *should,
pval *is,
struct argapp *
app)
1998 struct argchoice *ac;
2001 switch (should->dtype) {
2002 case ARGD_OPTIONSET:
2003 if ( strstr(is->
u1.
str,
"${") )
2008 for (q=opcop;*q;q++) {
2011 while (*p && *p !=
')' )
2017 for (ac=app->opts; ac; ac=ac->
next) {
2018 if (strlen(ac->name)>1 && strchr(ac->name,
'(') == 0 && strcmp(ac->name,is->
u1.
str) == 0)
2021 for (ac=app->opts; ac; ac=ac->
next) {
2022 if (strlen(ac->name)==1 || strchr(ac->name,
'(')) {
2023 char *p = strchr(opcop,ac->name[0]);
2025 if (p && *p ==
'j') {
2026 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: The j option in the %s application call is not appropriate for AEL!\n",
2033 if (ac->name[1] ==
'(') {
2034 if (*(p+1) !=
'(') {
2035 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",
2043 for (q=opcop; *q; q++) {
2044 if ( *q !=
'+' && *q !=
'(' && *q !=
')') {
2045 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",
2058 int option_matches(
struct argdesc *should,
pval *is,
struct argapp *app)
2060 struct argchoice *ac;
2063 switch (should->dtype) {
2088 for (ac=should->choices; ac; ac=ac->next) {
2089 if (strcmp(ac->name,is->
u1.
str) == 0)
2095 case ARGD_OPTIONSET:
2098 for (ac=app->opts; ac; ac=ac->
next) {
2099 if (strlen(ac->name)>1 && strchr(ac->name,
'(') == 0 && strcmp(ac->name,is->
u1.
str) == 0)
2102 for (ac=app->opts; ac; ac=ac->
next) {
2103 if (strlen(ac->name)==1 || strchr(ac->name,
'(')) {
2104 char *p = strchr(opcop,ac->name[0]);
2108 if (ac->name[1] ==
'(') {
2109 if (*(p+1) ==
'(') {
2111 while (*q && *q !=
')') {
2133 struct argdesc *ad = app->args;
2137 for (pa = arglist; pa; pa=pa->
next) {
2139 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n",
2146 if ( ad->dtype == ARGD_VARARG )
2149 z= option_matches( ad, pa, app);
2154 if (ad->type == ARGD_REQUIRED) {
2155 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2160 }
else if (z && ad->dtype == ARGD_OPTIONSET) {
2161 option_matches_j( ad, pa, app);
2168 for ( ; ad; ad=ad->next) {
2169 if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) {
2172 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2190 struct appsetvar *v,*v2;
2191 struct argchoice *
c;
2195 while (p && *p && (*p ==
' ' || *p ==
'\t' || *p ==
'$' || *p ==
'{' ) )
2200 while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] ==
'}' || buff1[strlen(buff1)-1] ==
' ' || buff1[strlen(buff1)-1] ==
'\t'))
2201 buff1[strlen(buff1)-1] = 0;
2204 for (a=apps;
a; a=a->
next) {
2205 for (v=a->setvars;v;v=v->
next) {
2206 if (strcmp(v->name,buff1) == 0) {
2231 for (c=v->vals; c; c=c->next) {
2235 if (!strcmp(t->
u1.
str,c->name)) {
2242 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n",
2252 for (; t && t !=
item; t=t->
next) {
2255 for (a2=apps; a2; a2=a2->
next) {
2256 if (strcasecmp(a2->name, t->
u1.
str)==0) {
2257 for (v2=a2->setvars; v2; v2=v2->
next) {
2258 if (strcmp(v2->name, buff1) == 0) {
2275 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",
2303 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: A default case was automatically added to the switch.\n",
2304 p2->filename, p2->startline, p2->endline);
2313 for (i=current_db; i; i=i->
next) {
2319 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",
2336 for (i=current_db; i; i=i->
next) {
2338 for (j=i->
u2. statements; j; j=j->
next) {
2344 if ( !strcmp(p4->
u1.
str, abstract_context->
u1.
str) )
2351 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",
2363 struct pval *macro_def;
2364 struct pval *app_def;
2369 switch (item->
type) {
2384 current_context =
item;
2385 current_extension = 0;
2400 current_context =
item;
2401 current_extension = 0;
2419 if (!extensions_dot_conf_loaded) {
2421 extensions_dot_conf_loaded++;
2435 snprintf(namebuf2, 256,
"macro-%s", item->
u1.
str);
2441 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",
2445 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: macro call to non-existent %s! (Not even in the extensions.conf stuff!)\n",
2451 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: macro call to %s cannot be found in the AEL code!\n",
2456 #ifdef THIS_IS_1DOT4 2458 snprintf(namebuf2, 256,
"macro-%s", item->
u1.
str);
2464 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",
2472 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: macro call to %s references a context, not a macro!\n",
2486 if (hereargs != thereargs ) {
2487 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",
2503 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: application call to %s references an existing macro, but had no & preceding it!\n",
2507 if (strcasecmp(item->
u1.
str,
"GotoIf") == 0
2508 || strcasecmp(item->
u1.
str,
"GotoIfTime") == 0
2509 || strcasecmp(item->
u1.
str,
"while") == 0
2510 || strcasecmp(item->
u1.
str,
"endwhile") == 0
2511 || strcasecmp(item->
u1.
str,
"random") == 0
2512 || strcasecmp(item->
u1.
str,
"gosub") == 0
2513 || strcasecmp(item->
u1.
str,
"gosubif") == 0
2514 || strcasecmp(item->
u1.
str,
"continuewhile") == 0
2515 || strcasecmp(item->
u1.
str,
"endwhile") == 0
2516 || strcasecmp(item->
u1.
str,
"execif") == 0
2517 || strcasecmp(item->
u1.
str,
"execiftime") == 0
2518 || strcasecmp(item->
u1.
str,
"exitwhile") == 0
2519 || strcasecmp(item->
u1.
str,
"goto") == 0
2520 || strcasecmp(item->
u1.
str,
"macro") == 0
2521 || strcasecmp(item->
u1.
str,
"macroexclusive") == 0
2522 || strcasecmp(item->
u1.
str,
"macroif") == 0
2523 || strcasecmp(item->
u1.
str,
"stackpop") == 0
2524 || strcasecmp(item->
u1.
str,
"execIf") == 0 ) {
2525 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",
2529 if (strcasecmp(item->
u1.
str,
"macroexit") == 0) {
2530 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: I am converting the MacroExit call here to a return statement.\n",
2539 for (app=apps;
app; app=app->
next) {
2540 if (strcasecmp(app->name, item->
u1.
str) == 0) {
2546 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: application call to %s not listed in applist database!\n",
2606 char *incl_context = lp->
u1.
str;
2635 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);
2639 if ( strpbrk(item->
u2.
val,
"~!-+<>=*/&^") && !strstr(item->
u2.
val,
"${") ) {
2640 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2653 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);
2657 if ( strpbrk(item->
u2.
val,
"~!-+<>=*/&^") && !strstr(item->
u2.
val,
"${") ) {
2658 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2679 if ( strspn(item->
u1.
str,
"0123456789") == strlen(item->
u1.
str) ) {
2680 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: label '%s' is numeric, this is bad practice!\n",
2695 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);
2708 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2713 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2729 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);
2733 if ( strpbrk(item->
u1.
str,
"~!-+<>=*/&^") && !strstr(item->
u1.
str,
"${") ) {
2734 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2766 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);
2770 if ( strpbrk(item->
u1.
str,
"~!-+<>=*/&^") && !strstr(item->
u1.
str,
"${") ) {
2771 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n",
2809 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);
2813 if ( strpbrk(item->
u1.
str,
"~!-+<>=*/&^") && !strstr(item->
u1.
str,
"${") ) {
2814 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n",
2844 current_extension =
item ;
2880 for (i=item; i; i=i->
next) {
2900 apps = argdesc_parse(rfilename, &argapp_errs);
2909 argdesc_destroy(apps);
2940 if (!exten->
plist) {
2941 exten->
plist = prio;
2955 while ((p1 = strstr(prio->
appargs,
"${EXTEN}"))) {
2959 strcat(p2,
"${~~EXTEN~~}");
2965 while ((p1 = strstr(prio->
appargs,
"${EXTEN:"))) {
2969 strcat(p2,
"${~~EXTEN~~:");
2981 for (ne=exten; ne; ne=nen) {
2994 for (pe=ne->
plist; pe; pe=pen) {
3041 while( str && *str && *str !=
'=' )
3043 if( *str ==
' ' || *str ==
'\n' || *str ==
'\r' || *str ==
'\t' )
3064 char *p=pattern, *t=
result;
3066 if (*p ==
'x' || *p ==
'n' || *p ==
'z' || *p ==
'X' || *p ==
'N' || *p ==
'Z')
3068 else if (*p ==
'[') {
3092 switch ( item->
type ) {
3333 for (i=item; i; i=i->
next) {
3345 struct ael_priority *for_init, *for_test, *for_inc, *for_loop, *for_end;
3346 struct ael_priority *while_test, *while_loop, *while_end;
3347 struct ael_priority *switch_set, *switch_test, *switch_end, *fall_thru, *switch_empty;
3348 struct ael_priority *if_test, *if_end, *if_skip, *if_false;
3349 #ifdef OLD_RAND_ACTION 3357 int local_control_statement_count;
3377 for (first = 1; first >= 0; first--) {
3382 if (!strcmp(mother_exten->
name,
"~~s~~") && first) {
3391 linkprio(exten, switch_set, mother_exten);
3402 for (first = 1; first >= 0; first--) {
3407 if (!strcmp(exten->
name,
"~~s~~")) {
3416 linkprio(exten, switch_set, mother_exten);
3435 for (p=statement; p; p=p->
next) {
3519 strp = strchr(
buf2,
'=');
3529 while (*strp2 && isspace(*strp2))
3531 if (*strp2 ==
'&') {
3532 char *strp3 = strp2+1;
3533 while (*strp3 && isspace(*strp3))
3535 strcpy(
buf2, strp3);
3536 strp3 = strchr(
buf2,
'(');
3540 strp3 = strrchr(
buf2,
')');
3548 strcpy(
buf2, strp2);
3549 strp3 = strchr(
buf2,
'(');
3555 strp3 = strrchr(for_init->
appargs,
')');
3564 strp = strchr(
buf2,
'=');
3575 while (*strp2 && isspace(*strp2))
3577 if (*strp2 ==
'&') {
3578 char *strp3 = strp2+1;
3579 while (*strp3 && isspace(*strp3))
3581 strcpy(
buf2, strp3);
3582 strp3 = strchr(
buf2,
'(');
3586 strp3 = strrchr(
buf2,
')');
3595 strcpy(
buf2, strp2);
3596 strp3 = strchr(
buf2,
'(');
3601 strp3 = strrchr(for_inc->
appargs,
')');
3615 linkprio(exten, for_init, mother_exten);
3616 linkprio(exten, for_test, mother_exten);
3626 linkprio(exten, for_inc, mother_exten);
3627 linkprio(exten, for_loop, mother_exten);
3628 linkprio(exten, for_end, mother_exten);
3649 while_test->
app = 0;
3656 linkprio(exten, while_test, mother_exten);
3666 linkprio(exten, while_loop, mother_exten);
3667 linkprio(exten, while_end, mother_exten);
3694 linkprio(exten, switch_test, mother_exten);
3695 linkprio(exten, switch_end, mother_exten);
3714 switch_case->
context = this_context;
3721 snprintf(
buf1,
BUF_SIZE,
"sw_%d_%s", local_control_statement_count, p2->
u1.
str);
3723 snprintf(new_label,
BUF_SIZE,
"sw_%s_%s_%d", label, p2->
u1.
str, local_control_statement_count);
3743 linkprio(switch_case, fall_thru, mother_exten);
3749 snprintf(
buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count,
buf2);
3751 linkprio(switch_case, fall_thru, mother_exten);
3756 snprintf(
buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3758 linkprio(switch_case, fall_thru, mother_exten);
3759 }
else if (!p2->
next) {
3764 linkprio(switch_case, fall_thru, mother_exten);
3772 snprintf(buf,
BUF_SIZE,
"End of Extension %s", switch_case->
name);
3774 linkprio(switch_case, np2, mother_exten);
3775 switch_case-> return_target = np2;
3788 switch_case->
context = this_context;
3795 snprintf(
buf1,
BUF_SIZE,
"_sw_%d_%s", local_control_statement_count, p2->
u1.
str);
3797 snprintf(new_label,
BUF_SIZE,
"sw_%s_%s_%d", label, p2->
u1.
str, local_control_statement_count);
3816 linkprio(switch_case, fall_thru, mother_exten);
3822 snprintf(
buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count,
buf2);
3824 linkprio(switch_case, fall_thru, mother_exten);
3829 snprintf(
buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3831 linkprio(switch_case, fall_thru, mother_exten);
3832 }
else if (!p2->
next) {
3837 linkprio(switch_case, fall_thru, mother_exten);
3845 snprintf(buf,
sizeof(buf),
"End of Extension %s", switch_case->
name);
3847 linkprio(switch_case, np2, mother_exten);
3848 switch_case-> return_target = np2;
3861 switch_case->
context = this_context;
3878 switch_null->
context = this_context;
3881 snprintf(
buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3884 linkprio(switch_null, switch_empty, mother_exten);
3885 snprintf(
buf1,
BUF_SIZE,
"sw_%d_", local_control_statement_count);
3895 snprintf(
buf1,
BUF_SIZE,
"_sw_%d_.", local_control_statement_count);
3898 snprintf(new_label,
BUF_SIZE,
"sw_%s_default_%d", label, local_control_statement_count);
3918 linkprio(switch_case, fall_thru, mother_exten);
3924 snprintf(
buf1,
BUF_SIZE,
"sw_%d_%s,10", local_control_statement_count,
buf2);
3926 linkprio(switch_case, fall_thru, mother_exten);
3931 snprintf(
buf1,
BUF_SIZE,
"sw_%d_.,10", local_control_statement_count);
3933 linkprio(switch_case, fall_thru, mother_exten);
3934 }
else if (!p2->
next) {
3939 linkprio(switch_case, fall_thru, mother_exten);
3947 snprintf(buf,
sizeof(buf),
"End of Extension %s", switch_case->
name);
3949 linkprio(switch_case, np2, mother_exten);
3950 switch_case-> return_target = np2;
4070 linkprio(exten, if_test, mother_exten);
4071 linkprio(exten, if_false, mother_exten);
4080 linkprio(exten, if_skip, mother_exten);
4086 linkprio(exten, if_end, mother_exten);
4121 linkprio(exten, if_test, mother_exten);
4130 linkprio(exten, if_skip, mother_exten);
4136 linkprio(exten, if_end, mother_exten);
4141 if (
gen_prios(exten, label, p->
u1.
list, mother_exten, this_context)) {
4160 switch_case->
context = this_context;
4173 snprintf(buf,
sizeof(buf),
"End of Extension %s", switch_case->
name);
4175 linkprio(switch_case, np2, mother_exten);
4176 switch_case-> return_target = np2;
4199 for (pr=exten->
plist; pr; pr=pr->
next) {
4234 for (pr=exten->
plist; pr; pr=pr->
next) {
4247 strcpy(app, pr->
app);
4254 switch( pr->
type ) {
4271 strcpy(app,
"GotoIf");
4276 strcpy(app,
"GotoIf");
4284 strcpy(app,
"Random");
4289 strcpy(app,
"GotoIfTime");
4294 strcpy(app,
"Return");
4371 char *apparg_save = p->
appargs;
4382 snprintf(buf1,
sizeof(buf1),
"%s,%s,%s", pv2->
u1.
list->
u1.
str,
4388 printf(
"WHAT? The goto doesn't fall into one of three cases for GOTO????\n");
4406 if (exten->
context == context) {
4424 for (p=root; p; p=p->
next ) {
4431 snprintf(buf2,
sizeof(buf2),
"%s=%s", p2->
u1.
str, p2->
u2.
val);
4440 for (p=root; p; p=p->
next ) {
4458 snprintf(buf,
sizeof(buf),
"LOCAL(%s)=${ARG%d}", lp->
u1.
str, argc++);
4472 snprintf(buf,
sizeof(buf),
"End of Macro %s-%s",p->
u1.
str, exten->
name);
4475 exten-> return_target = np2;
4500 if( (s3=strchr(exten->
name,
'/') ) != 0 )
4516 snprintf(buf,
sizeof(buf),
"End of Extension %s", exten->
name);
4519 exten-> return_target = np2;
4526 snprintf(buf,
sizeof(buf),
"A NoOp to follow a trailing label %s", exten->
plist_last->
origin->
u1.
str);
4542 snprintf(buf,
sizeof(buf),
"%s,%s,%s,%s,%s",
4556 char *
c = strchr(p3->
u1.
str,
'/');
4569 char *
c = strchr(p3->
u1.
str,
'/');
4596 const char *h_context =
"ael-builtin-h-bubble";
4604 { 1,
"Goto",
"9991" },
4606 { 9991,
"Set",
"~~parentcxt~~=${STACK_PEEK(1,c,1)}" },
4608 { 9992,
"GotoIf",
"$[\"${~~parentcxt~~}\"=\"\"]?9996" },
4610 { 9993,
"GotoIf",
"${DIALPLAN_EXISTS(${~~parentcxt~~},h,1)}?9994:9996" },
4612 { 9994,
"StackPop",
"" },
4614 { 9995,
"Goto",
"${~~parentcxt~~},h,1" },
4616 { 9996,
"NoOp",
"" }
4623 char h_context_template[] =
"/tmp/ael-builtin-h-bubble-XXXXXX";
4624 int fd = mkstemp(h_context_template);
4625 unlink(h_context_template);
4636 for (i = 0; i <
ARRAY_LEN(steps); i++) {
4651 if (!strcmp(exten->
name,
"~~s~~")) {
4682 switch (item->
type) {