30#define ASTMM_LIBC ASTMM_REDIRECT
54#include "asterisk/argdesc.h"
68static int extensions_dot_conf_loaded = 0;
120 for (i=0; i<depth; i++) {
126 fprintf(fin,
"%s;\n",
item->u1.str);
130 fprintf(fin,
"macro %s(",
item->u1.str);
131 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
132 if (lp !=
item->u2.arglist )
134 fprintf(fin,
"%s", lp->
u1.
str);
136 fprintf(fin,
") {\n");
138 for (i=0; i<depth; i++) {
141 fprintf(fin,
"};\n\n");
145 if (
item->u3.abstract )
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);
158 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
159 if ( lp !=
item->u2.arglist )
161 fprintf(fin,
"%s", lp->
u1.
str);
167 fprintf(fin,
"%s(",
item->u1.str);
168 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
169 if ( lp !=
item->u2.arglist )
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");
220 for (lp=
item->u1.list; lp; lp=lp->
next) {
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);
259 fprintf(fin,
"goto %s",
item->u1.list->u1.str);
260 if (
item->u1.list->next )
261 fprintf(fin,
",%s",
item->u1.list->next->u1.str);
262 if (
item->u1.list->next &&
item->u1.list->next->next )
263 fprintf(fin,
",%s",
item->u1.list->next->next->u1.str);
268 fprintf(fin,
"%s:\n",
item->u1.str);
272 fprintf(fin,
"for (%s; %s; %s)\n",
item->u1.for_init,
item->u2.for_test,
item->u3.for_inc);
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",
299 item->u1.list->u1.str,
300 item->u1.list->next->u1.str,
301 item->u1.list->next->next->u1.str,
302 item->u1.list->next->next->next->u1.str
305 fprintf(fin,
"random ( %s )\n",
item->u1.str );
307 fprintf(fin,
"if ( %s )\n",
item->u1.str);
308 if (
item->u2.statements &&
item->u2.statements->next ) {
309 for (i=0; i<depth; i++) {
314 for (i=0; i<depth; i++) {
317 if (
item->u3.else_statements )
321 }
else if (
item->u2.statements ) {
324 if (
item->u3.else_statements )
325 fprintf(fin,
" {} ");
327 fprintf(fin,
" {}; ");
329 if (
item->u3.else_statements ) {
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++) {
348 if (
item->u4.regexten )
349 fprintf(fin,
"regexten ");
350 if (
item->u3.hints )
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++) {
384 FILE *fin = fopen(fname,
"w");
418 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
438 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
448 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
518 if (
item->u1.list->next )
520 if (
item->u1.list->next &&
item->u1.list->next->next )
571 if (
item->u3.else_statements ) {
584 if (
item->u3.else_statements ) {
597 if (
item->u3.else_statements ) {
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",
959 DAY->filename,
DAY->startline,
DAY->endline, day);
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",
964 DAY->filename,
DAY->startline,
DAY->endline, day);
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",
971 DAY->filename,
DAY->startline,
DAY->endline,
c);
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",
976 DAY->filename,
DAY->startline,
DAY->endline, day);
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",
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",
1159 if (!
item->u1.list) {
1163 if (!
item->u1.list->next && !strstr((
item->u1.list)->u1.str,
"${")) {
1171 if (
item->u1.list->next && !
item->u1.list->next->next) {
1172 if (!strstr((
item->u1.list)->u1.str,
"${")
1173 && !strstr(
item->u1.list->next->u1.str,
"${") ) {
1180 if (
item->u1.list->next &&
item->u1.list->next->next) {
1183 pval *second =
item->u1.list->next;
1184 pval *third =
item->u1.list->next->next;
1186 if (!strstr((
item->u1.list)->u1.str,
"${")
1187 && !strstr(
item->u1.list->next->u1.str,
"${")
1188 && !strstr(
item->u1.list->next->next->u1.str,
"${")) {
1204 char *incl_context = p4->
u1.
str;
1207 if (that_other_context) {
1227 if (!
item->u1.list) {
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",
1239 if (!
item->u1.list->next && !strstr(
item->u1.list->u1.str,
"${")) {
1247 ast_log(
LOG_ERROR,
"Error: file %s, line %d-%d: goto: no label %s exists in the current extension!\n",
1256 if (
item->u1.list->next && !
item->u1.list->next->next) {
1260 if (!strstr((
item->u1.list)->u1.str,
"${")
1261 && !strstr(
item->u1.list->next->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",
1270 item->filename,
item->startline,
item->endline,
item->u1.list->u1.str,
item->u1.list->next->u1.str );
1279 if (
item->u1.list->next &&
item->u1.list->next->next) {
1282 pval *second =
item->u1.list->next;
1283 pval *third =
item->u1.list->next->next;
1287 if (!strstr((
item->u1.list)->u1.str,
"${")
1288 && !strstr(
item->u1.list->next->u1.str,
"${")
1289 && !strstr(
item->u1.list->next->next->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",
1321 item->filename,
item->startline,
item->endline,
item->u1.list->next->u1.str,
item->u1.list->next->next->u1.str,
item->u1.list->u1.str );
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",
1459 for (p4=
item->u1.list; p4; p4=p4->
next) {
1462 char *incl_context = p4->
u1.
str;
1517 if (
item->u3.else_statements) {
1751 if (
item->u3.else_statements) {
1783 if (
item->u2.statements) {
1784 struct pval *p5 =
item->u2.statements;
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')
1996int 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",
2058int 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;
2205 for (v=
a->setvars;v;v=v->
next) {
2206 if (strcmp(v->name,buff1) == 0) {
2220 for (t=
item->u2.statements; t; t=t->
next) {
2233 for (t=
item->u2.statements; t; t=t->
next) {
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) {
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",
2285 for (t=
item->u2.statements; t; t=t->
next) {
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);
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",
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;
2389 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
2402 if (
item->u3.abstract ) {
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",
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",
2480 for (lp=
item->u2.arglist; lp; lp=lp->
next) {
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",
2488 item->filename,
item->startline,
item->endline,
item->u1.str, hereargs, thereargs);
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",
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",
2605 for (lp=
item->u1.list; lp; lp=lp->
next){
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);
2698 strp = strchr(
item->u1.for_init,
'=');
2703 strp = strchr(
item->u3.for_inc,
'=');
2707 if ( strpbrk(
item->u2.for_test,
"~!-+<>=*/&^") && !strstr(
item->u2.for_test,
"${") ) {
2708 ast_log(
LOG_WARNING,
"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2712 if ( strpbrk(
item->u3.for_inc,
"~!-+<>=*/&^") && !strstr(
item->u3.for_inc,
"${") ) {
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",
2777 if (
item->u3.else_statements) {
2789 if (
item->u2.arglist ) {
2797 if (
item->u3.else_statements) {
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",
2820 if (
item->u3.else_statements) {
2900 apps = argdesc_parse(rfilename, &argapp_errs);
2909 argdesc_destroy(
apps);
2940 if (!exten->
plist) {
2941 exten->
plist = prio;
2948 prio->
exten = exten;
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) {
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 ==
'[') {
3260 if (
item->u3.else_statements ) {
3275 if (
item->u3.else_statements ) {
3290 if (
item->u3.else_statements ) {
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;
3382 if (!strcmp(mother_exten->
name,
"~~s~~") &&
first) {
3391 linkprio(exten, switch_set, mother_exten);
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);
3692 switch_end->
exten = 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);
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;
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;
4254 switch( pr->
type ) {
4271 strcpy(
app,
"GotoIf");
4276 strcpy(
app,
"GotoIf");
4284 strcpy(
app,
"Random");
4289 strcpy(
app,
"GotoIfTime");
4294 strcpy(
app,
"Return");
4302 label =
last->origin->u1.str;
4371 char *apparg_save = p->
appargs;
4388 printf(
"WHAT? The goto doesn't fall into one of three cases for GOTO????\n");
4405 for (exten = exten_list; exten; exten = exten->
next_exten) {
4424 for (p=root; p; p=p->
next ) {
4440 for (p=root; p; p=p->
next ) {
4458 snprintf(
buf,
sizeof(
buf),
"LOCAL(%s)=${ARG%d}", lp->
u1.
str, argc++);
4475 exten-> return_target = np2;
4500 if( (s3=strchr(
exten->
name,
'/') ) != 0 )
4519 exten-> return_target = np2;
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++) {
4647 for (exten = exten_list; exten; exten = exten->
next_exten) {
4651 if (!strcmp(exten->
name,
"~~s~~")) {
4687 if (
item->u2.arglist )
4829 if (
item->u1.for_init)
4831 if (
item->u2.for_test)
4833 if (
item->u3.for_inc)
4872 if (
item->u3.else_statements) {
4894 if (
item->u3.else_statements) {
4944 for (i=
item; i; i=nxt) {
4952static char *ael_funclist[] =
4977 "GROUP_MATCH_COUNT",
4989 "QUEUE_MEMBER_COUNT",
4990 "QUEUE_MEMBER_LIST",
5011int ael_is_funcname(
char *
name)
5014 t =
sizeof(ael_funclist)/
sizeof(
char*);
5016 while ((s < t) && strcasecmp(
name, ael_funclist[s]))
5035 ast_log(
LOG_ERROR,
"Func: %s the pval passed is not appropriate for this function!\n", funcname);
5112 *arg = (*arg)->
next;
5133 if (!(*next_statement))
5136 *next_statement = (*next_statement)->
next;
5138 return *next_statement;
5197 *statements = (*statements)->
next;
5241 *
args = (*args)->next;
5285 *
args = (*args)->next;
5316 *statement = (*statement)->
next;
5370 return (*next_item)->u1.str;
5392 return (*next_item)->u1.str;
5402 s->
u1.
str = (
char *)include;
5425 if (!hr || !dom || !dow || !mon || !s) {
5434 s->
u1.
str = (
char *)include;
5437 hr->
u1.
str = hour_range;
5438 dom->
u1.
str = dom_range;
5439 dow->
u1.
str = dow_range;
5440 mon->
u1.
str = month_range;
5476 return (*next_item)->u1.str;
5491 if (!(*next_statement))
5492 *next_statement = p->
u1.
list;
5494 *next_statement = (*next_statement)->
next;
5496 return *next_statement;
5539 ext->u1.str = exten;
5540 pri->
u1.
str = label;
5545 }
else if (exten && strlen(exten)) {
5549 ext->u1.str = exten;
5550 pri->
u1.
str = label;
5557 pri->
u1.
str = label;
5693 if (!hr || !dom || !dow || !mon) {
5726 p->
u1.
str = percent;
5789 *next_case = (*next_case)->
next;
5877 ast_log(
LOG_ERROR,
"pvalGlobalsAddStatement called where first arg is not a Globals!\n");
5891 if (!*next_statement) {
5892 *next_statement = p;
5895 *next_statement = (*next_statement)->
next;
5896 return (*next_statement)->
next;
5916 *next_obj = (*next_obj)->
next;
5917 return (*next_obj)->
next;
Structures for AEL - the Asterisk extension language.
struct sla_ringing_trunk * first
struct sla_ringing_trunk * last
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
Asterisk main include file. File version handling, generic pbx functions.
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
#define ast_strdupa(s)
duplicate a string in memory from the stack
void ast_free_ptr(void *ptr)
free() wrapper
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
General Asterisk PBX channel definitions.
#define AST_MAX_EXTENSION
Standard Command Line Interface.
static struct ast_threadstorage buf2
static struct ast_threadstorage buf1
Application convenience functions, designed to give consistent look and feel to Asterisk apps.
Configuration File Parser.
Support for logging to various files, console and syslog Configuration in file logger....
Asterisk module definitions.
const char * ast_config_AST_VAR_DIR
static struct ao2_container * hints
Core PBX routines and definitions.
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...
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, const char *registrar_file, int registrar_line)
Add an extension to an extension context, this time with an ast_context *.
int ast_context_add_include2(struct ast_context *con, const char *value, const char *registrar)
Add a context include.
int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
struct ast_custom_function * ast_custom_function_find(const char *name)
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.
const char * ast_get_context_name(struct ast_context *con)
int ast_context_ignorepats_count(const struct ast_context *con)
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)
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
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)
int ast_context_switches_count(const struct ast_context *con)
int ast_context_includes_count(const struct ast_context *con)
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
static struct ast_context * local_contexts
static struct ast_hashtab * local_table
int ast_compile_ael2(struct ast_context **local_contexts, struct ast_hashtab *local_table, struct pval *root)
static int check_continue(pval *item)
void check_switch_expr(pval *item, struct argapp *apps)
void pvalStatementBlockAddStatement(pval *p, pval *statement)
int pvalCheckType(pval *p, char *funcname, pvaltype type)
static void check_macro_returns(pval *macro)
char * pvalLabelGetName(pval *p)
void pvalExtenSetRegexten(pval *p)
static struct pval * find_label_in_current_context(char *exten, char *label, pval *curr_cont)
void ael2_semantic_check(pval *item, int *arg_errs, int *arg_warns, int *arg_notes)
static void attach_exten(struct ael_extension **list, struct ael_extension *newmem)
void pvalIncludesAddIncludeWithTimeConstraints(pval *p, const char *include, char *hour_range, char *dom_range, char *dow_range, char *month_range)
static pval * get_contxt(pval *p)
struct ael_priority * new_prio(void)
char * pvalESwitchesWalkNames(pval *p, pval **next_item)
char * pvalForGetTest(pval *p)
void pvalContextAddStatement(pval *p, pval *statement)
void pvalMacroSetArglist(pval *p, pval *arglist)
void pvalContextUnsetAbstract(pval *p)
void pvalIfSetCondition(pval *p, char *expr)
void pvalESwitchesAddSwitch(pval *p, char *name)
char * pvalSwitchesWalkNames(pval *p, pval **next_item)
void destroy_pval_item(pval *item)
void pvalExtenSetName(pval *p, char *name)
char * pvalIgnorePatGetPattern(pval *p)
void pvalMacroAddStatement(pval *p, pval *statement)
pval * pvalConditionalGetThenStatement(pval *p)
char * pvalForGetInit(pval *p)
pval * pvalCreateNode(pvaltype type)
char * pvalIncludesWalk(pval *p, pval **next_item)
static void check_day(pval *DAY)
static void gen_match_to_pattern(char *pattern, char *result)
void pvalGotoGetTarget(pval *p, char **context, char **exten, char **label)
void check_pval_item(pval *item, struct argapp *apps, int in_globals)
static struct pval * in_macro(pval *item)
char * pvalCatchGetExtName(pval *p)
static const char * match_context
static int context_used(struct ael_extension *exten_list, struct ast_context *context)
void pvalForSetInit(pval *p, char *init)
static struct pval * match_pval_item(pval *item)
char * pvalContextGetName(pval *p)
void pvalMacroCallSetMacroName(pval *p, char *name)
char * pvalIfGetCondition(pval *p)
static int label_inside_case(pval *label)
char * pvalMacroCallGetMacroName(pval *p)
char * pvalVarDecGetVarname(pval *p)
pval * pvalGlobalsWalkStatements(pval *p, pval **next_statement)
static struct pval * find_label_in_current_extension(const char *label, pval *curr_ext)
pval * pvalMacroWalkStatements(pval *p, pval **next_statement)
static pval * get_extension_or_contxt(pval *p)
struct pval * find_macro(char *name)
void pvalSwitchesAddSwitch(pval *p, char *name)
pval * pvalStatementBlockWalkStatements(pval *p, pval **next_statement)
static void check_label(pval *item)
void pvalCasePatDefAddStatement(pval *p, pval *statement)
void pvalMacroAddArg(pval *p, pval *arg)
void pvalIncludeGetTimeConstraints(pval *p, char **hour_range, char **dom_range, char **dow_range, char **month_range)
pval * pvalAppCallWalkArgs(pval *p, pval **args)
pval * pvalCatchGetStatement(pval *p)
static void find_pval_gotos(pval *item, int lev)
static void print_pval(FILE *fin, pval *item, int depth)
int check_app_args(pval *appcall, pval *arglist, struct argapp *app)
static void check_dow(pval *DOW)
get_dow: Get day of week
void traverse_pval_template(pval *item, int depth)
char * pvalForGetInc(pval *p)
struct pval * match_pval(pval *item)
void pvalAppCallAddArg(pval *p, pval *arg)
pval * linku1(pval *head, pval *tail)
static void print_pval_list(FILE *fin, pval *item, int depth)
pval * pvalConditionalGetElseStatement(pval *p)
void pvalRandomSetCondition(pval *p, char *percent)
static void check_goto(pval *item)
void pvalExtenSetStatement(pval *p, pval *statement)
static void remove_spaces_before_equals(char *str)
static void check_abstract_reference(pval *abstract_context)
static void check_timerange(pval *p)
static void check_includes(pval *includes)
void pvalExtenSetHints(pval *p, char *hints)
void set_priorities(struct ael_extension *exten)
char * pvalMacroGetName(pval *p)
pval * pvalContextWalkStatements(pval *p, pval **statements)
void pvalIgnorePatSetPattern(pval *p, char *pat)
void pvalVarDecSetValue(pval *p, char *value)
char * pvalExtenGetHints(pval *p)
pvaltype pvalObjectGetType(pval *p)
static void check_month(pval *MON)
void pvalForSetTest(pval *p, char *test)
static void linkexten(struct ael_extension *exten, struct ael_extension *add)
void traverse_pval_item_template(pval *item, int depth)
int contains_switch(pval *item)
void pvalConditionalSetThenStatement(pval *p, pval *statement)
void check_pval(pval *item, struct argapp *apps, int in_globals)
void pvalSwitchAddCase(pval *p, pval *Case)
struct ael_extension * new_exten(void)
static int in_abstract_context
static pval * current_context
struct pval * find_context(char *name)
void pvalLabelSetName(pval *p, char *name)
static int gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *this_context)
static pval * last_matched_label
void pvalCatchSetExtName(pval *p, char *name)
void pvalContextSetAbstract(pval *p)
static void find_pval_goto_item(pval *item, int lev)
static struct pval * in_context(pval *item)
pval * pvalTopLevWalkObjects(pval *p, pval **next_obj)
void destroy_pval(pval *item)
void destroy_extensions(struct ael_extension *exten)
void pvalIncludesAddInclude(pval *p, const char *include)
pval * pvalExtenGetStatement(pval *p)
void pvalGotoSetTarget(pval *p, char *context, char *exten, char *label)
static pval * get_goto_target(pval *item)
pval * pvalMacroWalkArgs(pval *p, pval **arg)
void pvalVarDecSetVarname(pval *p, char *name)
void pvalCatchSetStatement(pval *p, pval *statement)
void linkprio(struct ael_extension *exten, struct ael_priority *prio, struct ael_extension *mother_exten)
void pvalIfTimeSetCondition(pval *p, char *hour_range, char *dow_range, char *dom_range, char *mon_range)
int pvalExtenGetRegexten(pval *p)
int localized_pbx_load_module(void)
static pval * current_extension
static void check_expr2_input(pval *expr, char *str)
char * pvalWordGetString(pval *p)
void pvalForSetInc(pval *p, char *inc)
void pvalForSetStatement(pval *p, pval *statement)
char * pvalSwitchGetTestexpr(pval *p)
pval * pvalSwitchWalkCases(pval *p, pval **next_case)
void pvalIfTimeGetCondition(pval *p, char **hour_range, char **dow_range, char **dom_range, char **month_range)
void ael2_print(char *fname, pval *tree)
pval * pvalForGetStatement(pval *p)
void pvalMacroCallSetArglist(pval *p, pval *arglist)
static int check_break(pval *item)
char * pvalExtenGetName(pval *p)
void add_extensions(struct ael_extension *exten)
void pvalConditionalSetElseStatement(pval *p, pval *statement)
static void check_context_names(void)
int pvalContextGetAbstract(pval *p)
void pvalAppCallSetAppName(pval *p, char *name)
static int return_on_context_match
void pvalMacroSetName(pval *p, char *name)
char * pvalVarDecGetValue(pval *p)
static int control_statement_count
void pvalWordSetString(pval *p, char *str)
void pvalGlobalsAddStatement(pval *p, pval *statement)
void pvalContextSetName(pval *p, char *name)
static const char * match_label
static char expr_output[2096]
char * pvalAppCallGetAppName(pval *p)
void pvalCasePatSetVal(pval *p, char *val)
void pvalSwitchSetTestexpr(pval *p, char *expr)
static void fix_gotos_in_extensions(struct ael_extension *exten)
pval * pvalCasePatDefWalkStatements(pval *p, pval **statement)
char * pvalCasePatGetVal(pval *p)
static struct pval * find_first_label_in_current_context(char *label, pval *curr_cont)
static struct pval * find_label_in_current_db(const char *context, const char *exten, const char *label)
char * pvalRandomGetCondition(pval *p)
static const char * match_exten
void pvalTopLevAddObject(pval *p, pval *contextOrObj)
static int extension_matches(pval *here, const char *exten, const char *pattern)
void pvalAppCallSetArglist(pval *p, pval *arglist)
pval * pvalMacroCallWalkArgs(pval *p, pval **args)
int find_switch_item(pval *item)
void pvalExtenUnSetRegexten(pval *p)
void pvalMacroCallAddArg(pval *p, pval *arg)
int count_labels_in_current_context(char *label)
void ast_expr_clear_extra_error_info(void)
void ast_expr_register_extra_error_info(char *errmsg)
static char next_item(const char *format)
static force_inline int attribute_pure ast_strlen_zero(const char *s)
struct ael_priority * plist
struct ael_priority * loop_break
struct ast_context * context
struct ael_priority * plist_last
struct ael_priority * loop_continue
struct ael_extension * next_exten
struct ael_priority * goto_false
struct ael_priority * goto_true
struct ael_priority * next
struct ael_extension * exten
Registered applications container.
ast_context: An extension context
struct pval * goto_target
struct pval * for_statements
struct pval * else_statements
struct pval * macro_statements
struct ael_extension * compiled_label
static struct aco_type item
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.