#include "asterisk.h"
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <regex.h>
#include <sys/stat.h>
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pval.h"
#include "asterisk/ael_structs.h"
#include "asterisk/utils.h"
Go to the source code of this file.
Definition in file pval.c.
void add_extensions | ( | struct ael_extension * | exten | ) |
Definition at line 4241 of file pval.c.
References AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_LABEL, AEL_RAND_CONTROL, AEL_RETURN, ael_priority::app, app, ael_priority::appargs, ast_add_extension2(), ast_free_ptr, ast_log(), AST_MAX_EXTENSION, pval::else_statements, ael_priority::exten, exten, ael_priority::goto_false, ael_priority::goto_true, last, LOG_WARNING, ael_extension::name, ael_priority::next, ael_priority::origin, pbx_substitute_variables_helper(), PRIORITY_HINT, ael_priority::priority_num, PV_IFTIME, PV_SWITCH, strdup, pval::type, ael_priority::type, and pval::u3.
04242 { 04243 struct ael_priority *pr; 04244 char *label=0; 04245 char realext[AST_MAX_EXTENSION]; 04246 if (!exten) { 04247 ast_log(LOG_WARNING, "This file is Empty!\n" ); 04248 return; 04249 } 04250 do { 04251 struct ael_priority *last = 0; 04252 04253 pbx_substitute_variables_helper(NULL, exten->name, realext, sizeof(realext) - 1); 04254 if (exten->hints) { 04255 if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, PRIORITY_HINT, NULL, exten->cidmatch, 04256 exten->hints, NULL, ast_free_ptr, registrar)) { 04257 ast_log(LOG_WARNING, "Unable to add step at priority 'hint' of extension '%s'\n", 04258 exten->name); 04259 } 04260 } 04261 04262 for (pr=exten->plist; pr; pr=pr->next) { 04263 char app[2000]; 04264 char appargs[2000]; 04265 04266 /* before we can add the extension, we need to prep the app/appargs; 04267 the CONTROL types need to be done after the priority numbers are calculated. 04268 */ 04269 if (pr->type == AEL_LABEL) /* don't try to put labels in the dialplan! */ { 04270 last = pr; 04271 continue; 04272 } 04273 04274 if (pr->app) 04275 strcpy(app, pr->app); 04276 else 04277 app[0] = 0; 04278 if (pr->appargs ) 04279 strcpy(appargs, pr->appargs); 04280 else 04281 appargs[0] = 0; 04282 switch( pr->type ) { 04283 case AEL_APPCALL: 04284 /* easy case. Everything is all set up */ 04285 break; 04286 04287 case AEL_CONTROL1: /* FOR loop, WHILE loop, BREAK, CONTINUE, IF, IFTIME */ 04288 /* simple, unconditional goto. */ 04289 strcpy(app,"Goto"); 04290 if (pr->goto_true->origin && pr->goto_true->origin->type == PV_SWITCH ) { 04291 snprintf(appargs,sizeof(appargs),"%s,%d", pr->goto_true->exten->name, pr->goto_true->priority_num); 04292 } else if (pr->goto_true->origin && pr->goto_true->origin->type == PV_IFTIME && pr->goto_true->origin->u3.else_statements ) { 04293 snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num+1); 04294 } else 04295 snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num); 04296 break; 04297 04298 case AEL_FOR_CONTROL: /* WHILE loop test, FOR loop test */ 04299 strcpy(app,"GotoIf"); 04300 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num); 04301 break; 04302 04303 case AEL_IF_CONTROL: 04304 strcpy(app,"GotoIf"); 04305 if (pr->origin->u3.else_statements ) 04306 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num+1); 04307 else 04308 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num); 04309 break; 04310 04311 case AEL_RAND_CONTROL: 04312 strcpy(app,"Random"); 04313 snprintf(appargs,sizeof(appargs),"%s:%d", pr->appargs, pr->goto_true->priority_num+1); 04314 break; 04315 04316 case AEL_IFTIME_CONTROL: 04317 strcpy(app,"GotoIfTime"); 04318 snprintf(appargs,sizeof(appargs),"%s?%d", pr->appargs, pr->priority_num+2); 04319 break; 04320 04321 case AEL_RETURN: 04322 strcpy(app,"Return"); 04323 appargs[0] = 0; 04324 break; 04325 04326 default: 04327 break; 04328 } 04329 if (last && last->type == AEL_LABEL ) { 04330 label = last->origin->u1.str; 04331 } 04332 else 04333 label = 0; 04334 04335 if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, pr->priority_num, (label?label:NULL), exten->cidmatch, 04336 app, strdup(appargs), ast_free_ptr, registrar)) { 04337 ast_log(LOG_WARNING, "Unable to add step at priority '%d' of extension '%s'\n", pr->priority_num, 04338 exten->name); 04339 } 04340 last = pr; 04341 } 04342 exten = exten->next_exten; 04343 } while ( exten ); 04344 }
void ael2_print | ( | char * | fname, | |
pval * | tree | |||
) |
Definition at line 381 of file pval.c.
References ast_log(), LOG_ERROR, and print_pval_list().
00382 { 00383 FILE *fin = fopen(fname,"w"); 00384 if ( !fin ) { 00385 ast_log(LOG_ERROR, "Couldn't open %s for writing.\n", fname); 00386 return; 00387 } 00388 print_pval_list(fin, tree, 0); 00389 fclose(fin); 00390 }
void ael2_semantic_check | ( | pval * | item, | |
int * | arg_errs, | |||
int * | arg_warns, | |||
int * | arg_notes | |||
) |
Definition at line 2882 of file pval.c.
References ast_config_AST_VAR_DIR, check_context_names(), check_pval(), and current_db.
Referenced by pbx_load_module().
02883 { 02884 02885 #ifdef AAL_ARGCHECK 02886 int argapp_errs =0; 02887 char *rfilename; 02888 #endif 02889 struct argapp *apps=0; 02890 02891 if (!item) 02892 return; /* don't check an empty tree */ 02893 #ifdef AAL_ARGCHECK 02894 rfilename = alloca(10 + strlen(ast_config_AST_VAR_DIR)); 02895 sprintf(rfilename, "%s/applist", ast_config_AST_VAR_DIR); 02896 02897 apps = argdesc_parse(rfilename, &argapp_errs); /* giveth */ 02898 #endif 02899 current_db = item; 02900 errs = warns = notes = 0; 02901 02902 check_context_names(); 02903 check_pval(item, apps, 0); 02904 02905 #ifdef AAL_ARGCHECK 02906 argdesc_destroy(apps); /* taketh away */ 02907 #endif 02908 current_db = 0; 02909 02910 *arg_errs = errs; 02911 *arg_warns = warns; 02912 *arg_notes = notes; 02913 }
int ast_compile_ael2 | ( | struct ast_context ** | local_contexts, | |
struct ast_hashtab * | local_table, | |||
struct pval * | root | |||
) |
Definition at line 4427 of file pval.c.
References buf2, context, exten, pval::list, pval::next, pbx_builtin_setvar(), PV_GLOBALS, pval::str, pval::type, pval::u1, pval::u2, and pval::val.
04428 { 04429 pval *p,*p2; 04430 struct ast_context *context; 04431 char buf[2000]; 04432 struct ael_extension *exten; 04433 struct ael_extension *exten_list = 0; 04434 04435 for (p=root; p; p=p->next ) { /* do the globals first, so they'll be there 04436 when we try to eval them */ 04437 switch (p->type) { 04438 case PV_GLOBALS: 04439 /* just VARDEC elements */ 04440 for (p2=p->u1.list; p2; p2=p2->next) { 04441 char buf2[2000]; 04442 snprintf(buf2,sizeof(buf2),"%s=%s", p2->u1.str, p2->u2.val); 04443 pbx_builtin_setvar(NULL, buf2); 04444 } 04445 break; 04446 default: 04447 break; 04448 } 04449 } 04450 04451 for (p=root; p; p=p->next ) { 04452 pval *lp; 04453 int argc; 04454 04455 switch (p->type) { 04456 case PV_MACRO: 04457 04458 context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar); 04459 04460 exten = new_exten(); 04461 exten->context = context; 04462 exten->name = strdup("~~s~~"); 04463 argc = 1; 04464 for (lp=p->u2.arglist; lp; lp=lp->next) { 04465 /* for each arg, set up a "Set" command */ 04466 struct ael_priority *np2 = new_prio(); 04467 np2->type = AEL_APPCALL; 04468 if (!ast_compat_app_set) { 04469 np2->app = strdup("MSet"); 04470 } else { 04471 np2->app = strdup("Set"); 04472 } 04473 snprintf(buf,sizeof(buf),"LOCAL(%s)=${ARG%d}", lp->u1.str, argc++); 04474 remove_spaces_before_equals(buf); 04475 np2->appargs = strdup(buf); 04476 linkprio(exten, np2, NULL); 04477 } 04478 04479 /* CONTAINS APPCALLS, CATCH, just like extensions... */ 04480 if (gen_prios(exten, p->u1.str, p->u3.macro_statements, 0, context)) { 04481 return -1; 04482 } 04483 if (exten->return_needed) { /* most likely, this will go away */ 04484 struct ael_priority *np2 = new_prio(); 04485 np2->type = AEL_APPCALL; 04486 np2->app = strdup("NoOp"); 04487 snprintf(buf,sizeof(buf),"End of Macro %s-%s",p->u1.str, exten->name); 04488 np2->appargs = strdup(buf); 04489 linkprio(exten, np2, NULL); 04490 exten-> return_target = np2; 04491 } 04492 04493 set_priorities(exten); 04494 attach_exten(&exten_list, exten); 04495 break; 04496 04497 case PV_GLOBALS: 04498 /* already done */ 04499 break; 04500 04501 case PV_CONTEXT: 04502 context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar); 04503 04504 /* contexts contain: ignorepat, includes, switches, eswitches, extensions, */ 04505 for (p2=p->u2.statements; p2; p2=p2->next) { 04506 pval *p3; 04507 char *s3; 04508 04509 switch (p2->type) { 04510 case PV_EXTENSION: 04511 exten = new_exten(); 04512 exten->name = strdup(p2->u1.str); 04513 exten->context = context; 04514 04515 if( (s3=strchr(exten->name, '/') ) != 0 ) 04516 { 04517 *s3 = 0; 04518 exten->cidmatch = s3+1; 04519 } 04520 04521 if ( p2->u3.hints ) 04522 exten->hints = strdup(p2->u3.hints); 04523 exten->regexten = p2->u4.regexten; 04524 if (gen_prios(exten, p->u1.str, p2->u2.statements, 0, context)) { 04525 return -1; 04526 } 04527 if (exten->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 04528 struct ael_priority *np2 = new_prio(); 04529 np2->type = AEL_APPCALL; 04530 np2->app = strdup("NoOp"); 04531 snprintf(buf,sizeof(buf),"End of Extension %s", exten->name); 04532 np2->appargs = strdup(buf); 04533 linkprio(exten, np2, NULL); 04534 exten-> return_target = np2; 04535 } 04536 /* is the last priority in the extension a label? Then add a trailing no-op */ 04537 if ( exten->plist_last && exten->plist_last->type == AEL_LABEL ) { 04538 struct ael_priority *np2 = new_prio(); 04539 np2->type = AEL_APPCALL; 04540 np2->app = strdup("NoOp"); 04541 snprintf(buf,sizeof(buf),"A NoOp to follow a trailing label %s", exten->plist_last->origin->u1.str); 04542 np2->appargs = strdup(buf); 04543 linkprio(exten, np2, NULL); 04544 } 04545 04546 set_priorities(exten); 04547 attach_exten(&exten_list, exten); 04548 break; 04549 04550 case PV_IGNOREPAT: 04551 ast_context_add_ignorepat2(context, p2->u1.str, registrar); 04552 break; 04553 04554 case PV_INCLUDES: 04555 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04556 if ( p3->u2.arglist ) { 04557 snprintf(buf,sizeof(buf), "%s,%s,%s,%s,%s", 04558 p3->u1.str, 04559 p3->u2.arglist->u1.str, 04560 p3->u2.arglist->next->u1.str, 04561 p3->u2.arglist->next->next->u1.str, 04562 p3->u2.arglist->next->next->next->u1.str); 04563 ast_context_add_include2(context, buf, registrar); 04564 } else 04565 ast_context_add_include2(context, p3->u1.str, registrar); 04566 } 04567 break; 04568 04569 case PV_SWITCHES: 04570 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04571 char *c = strchr(p3->u1.str, '/'); 04572 if (c) { 04573 *c = '\0'; 04574 c++; 04575 } else 04576 c = ""; 04577 04578 ast_context_add_switch2(context, p3->u1.str, c, 0, registrar); 04579 } 04580 break; 04581 04582 case PV_ESWITCHES: 04583 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04584 char *c = strchr(p3->u1.str, '/'); 04585 if (c) { 04586 *c = '\0'; 04587 c++; 04588 } else 04589 c = ""; 04590 04591 ast_context_add_switch2(context, p3->u1.str, c, 1, registrar); 04592 } 04593 break; 04594 default: 04595 break; 04596 } 04597 } 04598 04599 break; 04600 04601 default: 04602 /* huh? what? */ 04603 break; 04604 04605 } 04606 } 04607 /* moved these from being done after a macro or extension were processed, 04608 to after all processing is done, for the sake of fixing gotos to labels inside cases... */ 04609 /* I guess this would be considered 2nd pass of compiler now... */ 04610 fix_gotos_in_extensions(exten_list); /* find and fix extension ref in gotos to labels that are in case statements */ 04611 add_extensions(exten_list); /* actually makes calls to create priorities in ast_contexts -- feeds dialplan to asterisk */ 04612 destroy_extensions(exten_list); /* all that remains is an empty husk, discard of it as is proper */ 04613 04614 return 0; 04615 }
static void attach_exten | ( | struct ael_extension ** | list, | |
struct ael_extension * | newmem | |||
) | [static] |
Definition at line 4346 of file pval.c.
References ael_extension::next_exten.
04347 { 04348 /* travel to the end of the list... */ 04349 struct ael_extension *lptr; 04350 if( !*list ) { 04351 *list = newmem; 04352 return; 04353 } 04354 lptr = *list; 04355 04356 while( lptr->next_exten ) { 04357 lptr = lptr->next_exten; 04358 } 04359 /* lptr should now pointing to the last element in the list; it has a null next_exten pointer */ 04360 lptr->next_exten = newmem; 04361 }
static void check_abstract_reference | ( | pval * | abstract_context | ) | [static] |
Definition at line 2326 of file pval.c.
References current_db, pval::list, pval::next, PV_CONTEXT, PV_INCLUDES, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by check_pval_item().
02327 { 02328 pval *i,*j; 02329 /* find some context includes that reference this context */ 02330 02331 02332 /* otherwise, print out a warning */ 02333 for (i=current_db; i; i=i->next) { 02334 if (i->type == PV_CONTEXT) { 02335 for (j=i->u2. statements; j; j=j->next) { 02336 if ( j->type == PV_INCLUDES ) { 02337 struct pval *p4; 02338 for (p4=j->u1.list; p4; p4=p4->next) { 02339 /* for each context pointed to, find it, then find a context/label that matches the 02340 target here! */ 02341 if ( !strcmp(p4->u1.str, abstract_context->u1.str) ) 02342 return; /* found a match! */ 02343 } 02344 } 02345 } 02346 } 02347 } 02348 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", 02349 abstract_context->filename, abstract_context->startline, abstract_context->endline, abstract_context->u1.str); 02350 warns++; 02351 }
Definition at line 2127 of file pval.c.
References app, ast_log(), pval::endline, pval::filename, LOG_WARNING, pval::next, pval::startline, pval::str, and pval::u1.
02128 { 02129 #ifdef AAL_ARGCHECK 02130 struct argdesc *ad = app->args; 02131 pval *pa; 02132 int z; 02133 02134 for (pa = arglist; pa; pa=pa->next) { 02135 if (!ad) { 02136 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n", 02137 arglist->filename, arglist->startline, arglist->endline, pa->u1.str, app->name); 02138 warns++; 02139 return 1; 02140 } else { 02141 /* find the first entry in the ad list that will match */ 02142 do { 02143 if ( ad->dtype == ARGD_VARARG ) /* once we hit the VARARG, all bets are off. Discontinue the comparisons */ 02144 break; 02145 02146 z= option_matches( ad, pa, app); 02147 if (!z) { 02148 if ( !arglist ) 02149 arglist=appcall; 02150 02151 if (ad->type == ARGD_REQUIRED) { 02152 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n", 02153 arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name); 02154 warns++; 02155 return 1; 02156 } 02157 } else if (z && ad->dtype == ARGD_OPTIONSET) { 02158 option_matches_j( ad, pa, app); 02159 } 02160 ad = ad->next; 02161 } while (ad && !z); 02162 } 02163 } 02164 /* any app nodes left, that are not optional? */ 02165 for ( ; ad; ad=ad->next) { 02166 if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) { 02167 if ( !arglist ) 02168 arglist=appcall; 02169 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n", 02170 arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name); 02171 warns++; 02172 return 1; 02173 } 02174 } 02175 return 0; 02176 #else 02177 return 0; 02178 #endif 02179 }
static int check_break | ( | pval * | item | ) | [static] |
Definition at line 1042 of file pval.c.
References ast_log(), pval::dad, pval::endline, pval::filename, LOG_ERROR, PV_CASE, PV_CONTEXT, PV_DEFAULT, PV_FOR, PV_MACRO, PV_PATTERN, PV_WHILE, pval::startline, and pval::type.
Referenced by check_pval_item().
01043 { 01044 pval *p = item; 01045 01046 while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ { 01047 /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make 01048 no sense */ 01049 if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN 01050 || p->type == PV_WHILE || p->type == PV_FOR ) { 01051 return 1; 01052 } 01053 p = p->dad; 01054 } 01055 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'break' not in switch, for, or while statement!\n", 01056 item->filename, item->startline, item->endline); 01057 errs++; 01058 01059 return 0; 01060 }
static void check_context_names | ( | void | ) | [static] |
Definition at line 2307 of file pval.c.
References pval::abstract, ast_log(), current_db, pval::endline, pval::filename, LOG_WARNING, pval::next, PV_CONTEXT, PV_MACRO, pval::startline, pval::str, pval::type, pval::u1, and pval::u3.
Referenced by ael2_semantic_check().
02308 { 02309 pval *i,*j; 02310 for (i=current_db; i; i=i->next) { 02311 if (i->type == PV_CONTEXT || i->type == PV_MACRO) { 02312 for (j=i->next; j; j=j->next) { 02313 if ( j->type == PV_CONTEXT || j->type == PV_MACRO ) { 02314 if ( !strcmp(i->u1.str, j->u1.str) && !(i->u3.abstract&2) && !(j->u3.abstract&2) ) 02315 { 02316 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", 02317 i->filename, i->startline, i->endline, i->u1.str, j->filename, j->startline, j->endline); 02318 warns++; 02319 } 02320 } 02321 } 02322 } 02323 } 02324 }
static int check_continue | ( | pval * | item | ) | [static] |
Definition at line 1062 of file pval.c.
References ast_log(), pval::dad, pval::endline, pval::filename, LOG_ERROR, PV_CONTEXT, PV_FOR, PV_MACRO, PV_WHILE, pval::startline, and pval::type.
Referenced by check_pval_item().
01063 { 01064 pval *p = item; 01065 01066 while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ { 01067 /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make 01068 no sense */ 01069 if( p->type == PV_WHILE || p->type == PV_FOR ) { 01070 return 1; 01071 } 01072 p = p->dad; 01073 } 01074 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'continue' not in 'for' or 'while' statement!\n", 01075 item->filename, item->startline, item->endline); 01076 errs++; 01077 01078 return 0; 01079 }
static void check_day | ( | pval * | DAY | ) | [static] |
Definition at line 941 of file pval.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
00942 { 00943 char *day; 00944 char *c; 00945 /* The following line is coincidence, really! */ 00946 int s, e; 00947 00948 day = ast_strdupa(DAY->u1.str); 00949 00950 /* Check for all days */ 00951 if (ast_strlen_zero(day) || !strcmp(day, "*")) { 00952 return; 00953 } 00954 /* Get start and ending days */ 00955 c = strchr(day, '-'); 00956 if (c) { 00957 *c = '\0'; 00958 c++; 00959 } 00960 /* Find the start */ 00961 if (sscanf(day, "%2d", &s) != 1) { 00962 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n", 00963 DAY->filename, DAY->startline, DAY->endline, day); 00964 warns++; 00965 } 00966 else if ((s < 1) || (s > 31)) { 00967 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", 00968 DAY->filename, DAY->startline, DAY->endline, day); 00969 warns++; 00970 } 00971 s--; 00972 if (c) { 00973 if (sscanf(c, "%2d", &e) != 1) { 00974 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n", 00975 DAY->filename, DAY->startline, DAY->endline, c); 00976 warns++; 00977 } 00978 else if ((e < 1) || (e > 31)) { 00979 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", 00980 DAY->filename, DAY->startline, DAY->endline, day); 00981 warns++; 00982 } 00983 e--; 00984 } else 00985 e = s; 00986 }
static void check_dow | ( | pval * | DOW | ) | [static] |
get_dow: Get day of week
Definition at line 902 of file pval.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
00903 { 00904 char *dow; 00905 char *c; 00906 /* The following line is coincidence, really! */ 00907 int s, e; 00908 00909 dow = ast_strdupa(DOW->u1.str); 00910 00911 /* Check for all days */ 00912 if (ast_strlen_zero(dow) || !strcmp(dow, "*")) 00913 return; 00914 /* Get start and ending days */ 00915 c = strchr(dow, '-'); 00916 if (c) { 00917 *c = '\0'; 00918 c++; 00919 } else 00920 c = NULL; 00921 /* Find the start */ 00922 s = 0; 00923 while ((s < 7) && strcasecmp(dow, days[s])) s++; 00924 if (s >= 7) { 00925 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", 00926 DOW->filename, DOW->startline, DOW->endline, dow); 00927 warns++; 00928 } 00929 if (c) { 00930 e = 0; 00931 while ((e < 7) && strcasecmp(c, days[e])) e++; 00932 if (e >= 7) { 00933 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", 00934 DOW->filename, DOW->startline, DOW->endline, c); 00935 warns++; 00936 } 00937 } else 00938 e = s; 00939 }
static void check_expr2_input | ( | pval * | expr, | |
char * | str | |||
) | [static] |
Definition at line 805 of file pval.c.
References ast_log(), pval::endline, pval::filename, LOG_WARNING, and pval::startline.
Referenced by check_pval_item().
00806 { 00807 int spaces = strspn(str,"\t \n"); 00808 if ( !strncmp(str+spaces,"$[",2) ) { 00809 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n", 00810 expr->filename, expr->startline, expr->endline, str); 00811 warns++; 00812 } 00813 }
static void check_goto | ( | pval * | item | ) | [static] |
Definition at line 1225 of file pval.c.
References ast_log(), E_FINDLABEL, E_MATCH, pval::endline, pval::filename, find_context(), find_label_in_current_context(), find_label_in_current_db(), find_label_in_current_extension(), first, get_contxt(), get_extension_or_contxt(), in_context(), in_macro(), pval::list, localized_pbx_load_module(), LOG_ERROR, LOG_WARNING, pval::next, pbx_find_extension(), PV_INCLUDES, pbx_find_info::stacklen, pval::startline, pval::statements, pbx_find_info::status, STATUS_SUCCESS, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by check_pval_item(), and find_pval_goto_item().
01226 { 01227 /* check for the target of the goto-- does it exist? */ 01228 if ( !(item->u1.list)->next && !(item->u1.list)->u1.str ) { 01229 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: empty label reference found!\n", 01230 item->filename, item->startline, item->endline); 01231 errs++; 01232 } 01233 01234 /* just one item-- the label should be in the current extension */ 01235 01236 if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) { 01237 struct pval *z = get_extension_or_contxt(item); 01238 struct pval *x = 0; 01239 if (z) 01240 x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), z); /* if in macro, use current context instead */ 01241 /* printf("Called find_label_in_current_extension with arg %s; current_extension is %x: %d\n", 01242 (char*)((item->u1.list)->u1.str), current_extension?current_extension:current_context, current_extension?current_extension->type:current_context->type); */ 01243 if (!x) { 01244 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s exists in the current extension!\n", 01245 item->filename, item->startline, item->endline, item->u1.list->u1.str); 01246 errs++; 01247 } 01248 else 01249 return; 01250 } 01251 01252 /* TWO items */ 01253 if (item->u1.list->next && !item->u1.list->next->next) { 01254 /* two items */ 01255 /* printf("Calling find_label_in_current_context with args %s, %s\n", 01256 (char*)((item->u1.list)->u1.str), (char *)item->u1.list->next->u1.str); */ 01257 if (!strstr((item->u1.list)->u1.str,"${") 01258 && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ { 01259 struct pval *z = get_contxt(item); 01260 struct pval *x = 0; 01261 01262 if (z) 01263 x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, z); 01264 01265 if (!x) { 01266 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", 01267 item->filename, item->startline, item->endline, item->u1.list->u1.str, item->u1.list->next->u1.str ); 01268 errs++; 01269 } 01270 else 01271 return; 01272 } 01273 } 01274 01275 /* All 3 items! */ 01276 if (item->u1.list->next && item->u1.list->next->next) { 01277 /* all three */ 01278 pval *first = item->u1.list; 01279 pval *second = item->u1.list->next; 01280 pval *third = item->u1.list->next->next; 01281 01282 /* printf("Calling find_label_in_current_db with args %s, %s, %s\n", 01283 (char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); */ 01284 if (!strstr((item->u1.list)->u1.str,"${") 01285 && !strstr(item->u1.list->next->u1.str,"${") 01286 && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ { 01287 struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); 01288 if (!x) { 01289 struct pval *p3; 01290 struct pval *found = 0; 01291 struct pval *that_context = find_context(item->u1.list->u1.str); 01292 01293 /* the target of the goto could be in an included context!! Fancy that!! */ 01294 /* look for includes in the current context */ 01295 if (that_context) { 01296 for (p3=that_context->u2.statements; p3; p3=p3->next) { 01297 if (p3->type == PV_INCLUDES) { 01298 struct pval *p4; 01299 for (p4=p3->u1.list; p4; p4=p4->next) { 01300 /* for each context pointed to, find it, then find a context/label that matches the 01301 target here! */ 01302 char *incl_context = p4->u1.str; 01303 /* find a matching context name */ 01304 struct pval *that_other_context = find_context(incl_context); 01305 if (that_other_context) { 01306 struct pval *x3; 01307 x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context); 01308 if (x3) { 01309 found = x3; 01310 break; 01311 } 01312 } 01313 } 01314 } 01315 } 01316 if (!found) { 01317 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s|%s exists in the context %s or its inclusions!\n", 01318 item->filename, item->startline, item->endline, item->u1.list->next->u1.str, item->u1.list->next->next->u1.str, item->u1.list->u1.str ); 01319 errs++; 01320 } else { 01321 struct pval *mac = in_macro(item); /* is this goto inside a macro? */ 01322 if( mac ) { /* yes! */ 01323 struct pval *targ = in_context(found); 01324 if( mac != targ ) 01325 { 01326 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", 01327 item->filename, item->startline, item->endline); 01328 warns++; 01329 } 01330 } 01331 } 01332 } else { 01333 /* here is where code would go to check for target existence in extensions.conf files */ 01334 #ifdef STANDALONE 01335 struct pbx_find_info pfiq = {.stacklen = 0 }; 01336 extern int localized_pbx_load_module(void); 01337 /* if this is a standalone, we will need to make sure the 01338 localized load of extensions.conf is done */ 01339 if (!extensions_dot_conf_loaded) { 01340 localized_pbx_load_module(); 01341 extensions_dot_conf_loaded++; 01342 } 01343 01344 pbx_find_extension(NULL, NULL, &pfiq, first->u1.str, second->u1.str, atoi(third->u1.str), 01345 atoi(third->u1.str) ? NULL : third->u1.str, NULL, 01346 atoi(third->u1.str) ? E_MATCH : E_FINDLABEL); 01347 01348 if (pfiq.status != STATUS_SUCCESS) { 01349 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", 01350 item->filename, item->startline, item->endline, first->u1.str, second->u1.str, third->u1.str); 01351 warns++; 01352 } 01353 #else 01354 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: goto: Couldn't find goto target %s|%s|%s in the AEL code!\n", 01355 item->filename, item->startline, item->endline, first->u1.str, second->u1.str, third->u1.str); 01356 warns++; 01357 #endif 01358 } 01359 } else { 01360 struct pval *mac = in_macro(item); /* is this goto inside a macro? */ 01361 if( mac ) { /* yes! */ 01362 struct pval *targ = in_context(x); 01363 if( mac != targ ) 01364 { 01365 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", 01366 item->filename, item->startline, item->endline); 01367 warns++; 01368 } 01369 } 01370 } 01371 } 01372 } 01373 }
static void check_includes | ( | pval * | includes | ) | [static] |
Definition at line 815 of file pval.c.
References ast_log(), pval::endline, pval::filename, find_context(), pval::list, LOG_WARNING, pval::next, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
00816 { 00817 struct pval *p4; 00818 for (p4=includes->u1.list; p4; p4=p4->next) { 00819 /* for each context pointed to, find it, then find a context/label that matches the 00820 target here! */ 00821 char *incl_context = p4->u1.str; 00822 /* find a matching context name */ 00823 struct pval *that_other_context = find_context(incl_context); 00824 if (!that_other_context && strcmp(incl_context, "parkedcalls") != 0) { 00825 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\ 00826 (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n", 00827 includes->filename, includes->startline, includes->endline, incl_context, incl_context); 00828 warns++; 00829 } 00830 } 00831 }
static void check_label | ( | pval * | item | ) | [static] |
Definition at line 1110 of file pval.c.
References ast_log(), current_context, current_extension, pval::dad, pval::endline, pval::filename, find_first_label_in_current_context(), LOG_ERROR, PV_EXTENSION, PV_MACRO, pval::startline, pval::str, pval::type, and pval::u1.
Referenced by check_pval_item().
01111 { 01112 struct pval *curr; 01113 struct pval *x; 01114 int alright = 0; 01115 01116 /* A label outside an extension just plain does not make sense! */ 01117 01118 curr = item; 01119 01120 while( curr ) { 01121 if( curr->type == PV_MACRO || curr->type == PV_EXTENSION ) { 01122 alright = 1; 01123 break; 01124 } 01125 curr = curr->dad; 01126 } 01127 if( !alright ) 01128 { 01129 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Label %s is not within an extension or macro!\n", 01130 item->filename, item->startline, item->endline, item->u1.str); 01131 errs++; 01132 } 01133 01134 01135 /* basically, ensure that a label is not repeated in a context. Period. 01136 The method: well, for each label, find the first label in the context 01137 with the same name. If it's not the current label, then throw an error. */ 01138 01139 01140 /* printf("==== check_label: ====\n"); */ 01141 if( !current_extension ) 01142 curr = current_context; 01143 else 01144 curr = current_extension; 01145 01146 x = find_first_label_in_current_context((char *)item->u1.str, curr); 01147 /* printf("Hey, check_label found with item = %x, and x is %x, and currcont is %x, label name is %s\n", item,x, current_context, (char *)item->u1.str); */ 01148 if( x && x != item ) 01149 { 01150 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Duplicate label %s! Previously defined at file %s, line %d.\n", 01151 item->filename, item->startline, item->endline, item->u1.str, x->filename, x->startline); 01152 errs++; 01153 } 01154 /* printf("<<<<< check_label: ====\n"); */ 01155 }
static void check_macro_returns | ( | pval * | macro | ) | [static] |
Definition at line 649 of file pval.c.
References ast_log(), calloc, pval::endcol, pval::endline, pval::filename, LOG_WARNING, pval::macro_statements, pval::next, PV_RETURN, pval::startcol, pval::startline, pval::str, strdup, pval::type, pval::u1, and pval::u3.
Referenced by check_pval_item().
00650 { 00651 pval *i; 00652 if (!macro->u3.macro_statements) 00653 { 00654 pval *z = calloc(1, sizeof(struct pval)); 00655 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s is empty! I will insert a return.\n", 00656 macro->filename, macro->startline, macro->endline, macro->u1.str); 00657 00658 z->type = PV_RETURN; 00659 z->startline = macro->startline; 00660 z->endline = macro->endline; 00661 z->startcol = macro->startcol; 00662 z->endcol = macro->endcol; 00663 z->filename = strdup(macro->filename); 00664 00665 macro->u3.macro_statements = z; 00666 return; 00667 } 00668 for (i=macro->u3.macro_statements; i; i=i->next) { 00669 /* if the last statement in the list is not return, then insert a return there */ 00670 if (i->next == NULL) { 00671 if (i->type != PV_RETURN) { 00672 pval *z = calloc(1, sizeof(struct pval)); 00673 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s does not end with a return; I will insert one.\n", 00674 macro->filename, macro->startline, macro->endline, macro->u1.str); 00675 00676 z->type = PV_RETURN; 00677 z->startline = macro->startline; 00678 z->endline = macro->endline; 00679 z->startcol = macro->startcol; 00680 z->endcol = macro->endcol; 00681 z->filename = strdup(macro->filename); 00682 00683 i->next = z; 00684 return; 00685 } 00686 } 00687 } 00688 return; 00689 }
static void check_month | ( | pval * | MON | ) | [static] |
Definition at line 1004 of file pval.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
01005 { 01006 char *mon; 01007 char *c; 01008 /* The following line is coincidence, really! */ 01009 int s, e; 01010 01011 mon = ast_strdupa(MON->u1.str); 01012 01013 /* Check for all days */ 01014 if (ast_strlen_zero(mon) || !strcmp(mon, "*")) 01015 return ; 01016 /* Get start and ending days */ 01017 c = strchr(mon, '-'); 01018 if (c) { 01019 *c = '\0'; 01020 c++; 01021 } 01022 /* Find the start */ 01023 s = 0; 01024 while ((s < 12) && strcasecmp(mon, months[s])) s++; 01025 if (s >= 12) { 01026 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n", 01027 MON->filename, MON->startline, MON->endline, mon); 01028 warns++; 01029 } 01030 if (c) { 01031 e = 0; 01032 while ((e < 12) && strcasecmp(mon, months[e])) e++; 01033 if (e >= 12) { 01034 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n", 01035 MON->filename, MON->startline, MON->endline, c); 01036 warns++; 01037 } 01038 } else 01039 e = s; 01040 }
Definition at line 2862 of file pval.c.
References check_pval_item(), and pval::next.
02863 { 02864 pval *i; 02865 02866 /* checks to do: 02867 1. Do goto's point to actual labels? 02868 2. Do macro calls reference a macro? 02869 3. Does the number of macro args match the definition? 02870 4. Is a macro call missing its & at the front? 02871 5. Application calls-- we could check syntax for existing applications, 02872 but I need some some sort of universal description bnf for a general 02873 sort of method for checking arguments, in number, maybe even type, at least. 02874 Don't want to hand code checks for hundreds of applications. 02875 */ 02876 02877 for (i=item; i; i=i->next) { 02878 check_pval_item(i,apps,in_globals); 02879 } 02880 }
Definition at line 2354 of file pval.c.
References pval::abstract, app, pval::arglist, ast_expr(), ast_expr_clear_extra_error_info(), ast_expr_register_extra_error_info(), ast_log(), check_abstract_reference(), check_app_args(), check_break(), check_continue(), check_day(), check_dow(), check_expr2_input(), check_goto(), check_includes(), check_label(), check_macro_returns(), check_month(), check_pval(), check_switch_expr(), check_timerange(), current_context, current_extension, E_MATCH, pval::else_statements, pval::endcol, pval::endline, pval::filename, find_context(), find_macro(), find_pval_gotos(), pval::for_inc, pval::for_init, pval::for_statements, pval::for_test, free, pval::list, localized_pbx_load_module(), LOG_ERROR, LOG_WARNING, pval::macro_statements, pval::next, pbx_find_extension(), PV_APPLICATION_CALL, PV_BREAK, PV_CASE, PV_CATCH, PV_CONTEXT, PV_CONTINUE, PV_DEFAULT, PV_ESWITCHES, PV_EXTENSION, PV_FOR, PV_GLOBALS, PV_GOTO, PV_IF, PV_IFTIME, PV_IGNOREPAT, PV_INCLUDES, PV_LABEL, PV_LOCALVARDEC, PV_MACRO, PV_MACRO_CALL, PV_PATTERN, PV_RANDOM, PV_RETURN, PV_STATEMENTBLOCK, PV_SWITCH, PV_SWITCHES, PV_VARDEC, PV_WHILE, PV_WORD, pbx_find_info::stacklen, pval::startcol, pval::startline, pval::statements, pbx_find_info::status, STATUS_SUCCESS, pval::str, pval::type, pval::u1, pval::u2, pval::u3, pval::u4, and pval::val.
02355 { 02356 pval *lp; 02357 #ifdef AAL_ARGCHECK 02358 struct argapp *app, *found; 02359 #endif 02360 struct pval *macro_def; 02361 struct pval *app_def; 02362 02363 char errmsg[4096]; 02364 char *strp; 02365 02366 switch (item->type) { 02367 case PV_WORD: 02368 /* fields: item->u1.str == string associated with this (word). 02369 item->u2.arglist == pval list of 4 PV_WORD elements for time values (only in PV_INCLUDES) */ 02370 break; 02371 02372 case PV_MACRO: 02373 /* fields: item->u1.str == name of macro 02374 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 02375 item->u2.arglist->u1.str == argument 02376 item->u2.arglist->next == next arg 02377 02378 item->u3.macro_statements == pval list of statements in macro body. 02379 */ 02380 in_abstract_context = 0; 02381 current_context = item; 02382 current_extension = 0; 02383 02384 check_macro_returns(item); 02385 02386 for (lp=item->u2.arglist; lp; lp=lp->next) { 02387 02388 } 02389 check_pval(item->u3.macro_statements, apps,in_globals); 02390 break; 02391 02392 case PV_CONTEXT: 02393 /* fields: item->u1.str == name of context 02394 item->u2.statements == pval list of statements in context body 02395 item->u3.abstract == int 1 if an abstract keyword were present 02396 */ 02397 current_context = item; 02398 current_extension = 0; 02399 if ( item->u3.abstract ) { 02400 in_abstract_context = 1; 02401 check_abstract_reference(item); 02402 } else 02403 in_abstract_context = 0; 02404 check_pval(item->u2.statements, apps,in_globals); 02405 break; 02406 02407 case PV_MACRO_CALL: 02408 /* fields: item->u1.str == name of macro to call 02409 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 02410 item->u2.arglist->u1.str == argument 02411 item->u2.arglist->next == next arg 02412 */ 02413 #ifdef STANDALONE 02414 /* if this is a standalone, we will need to make sure the 02415 localized load of extensions.conf is done */ 02416 if (!extensions_dot_conf_loaded) { 02417 localized_pbx_load_module(); 02418 extensions_dot_conf_loaded++; 02419 } 02420 #endif 02421 macro_def = find_macro(item->u1.str); 02422 if (!macro_def) { 02423 #ifdef STANDALONE 02424 struct pbx_find_info pfiq = {.stacklen = 0 }; 02425 struct pbx_find_info pfiq2 = {.stacklen = 0 }; 02426 02427 /* look for the macro in the extensions.conf world */ 02428 pbx_find_extension(NULL, NULL, &pfiq, item->u1.str, "s", 1, NULL, NULL, E_MATCH); 02429 02430 if (pfiq.status != STATUS_SUCCESS) { 02431 char namebuf2[256]; 02432 snprintf(namebuf2, 256, "macro-%s", item->u1.str); 02433 02434 /* look for the macro in the extensions.conf world */ 02435 pbx_find_extension(NULL, NULL, &pfiq2, namebuf2, "s", 1, NULL, NULL, E_MATCH); 02436 02437 if (pfiq2.status == STATUS_SUCCESS) { 02438 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", 02439 item->filename, item->startline, item->endline, item->u1.str, item->u1.str); 02440 warns++; 02441 } else { 02442 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to non-existent %s! (Not even in the extensions.conf stuff!)\n", 02443 item->filename, item->startline, item->endline, item->u1.str); 02444 warns++; 02445 } 02446 } 02447 #else 02448 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to %s cannot be found in the AEL code!\n", 02449 item->filename, item->startline, item->endline, item->u1.str); 02450 warns++; 02451 02452 #endif 02453 #ifdef THIS_IS_1DOT4 02454 char namebuf2[256]; 02455 snprintf(namebuf2, 256, "macro-%s", item->u1.str); 02456 02457 /* look for the macro in the extensions.conf world */ 02458 pbx_find_extension(NULL, NULL, &pfiq, namebuf2, "s", 1, NULL, NULL, E_MATCH); 02459 02460 if (pfiq.status != STATUS_SUCCESS) { 02461 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", 02462 item->filename, item->startline, item->endline, item->u1.str); 02463 warns++; 02464 } 02465 02466 #endif 02467 02468 } else if (macro_def->type != PV_MACRO) { 02469 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: macro call to %s references a context, not a macro!\n", 02470 item->filename, item->startline, item->endline, item->u1.str); 02471 errs++; 02472 } else { 02473 /* macro_def is a MACRO, so do the args match in number? */ 02474 int hereargs = 0; 02475 int thereargs = 0; 02476 02477 for (lp=item->u2.arglist; lp; lp=lp->next) { 02478 hereargs++; 02479 } 02480 for (lp=macro_def->u2.arglist; lp; lp=lp->next) { 02481 thereargs++; 02482 } 02483 if (hereargs != thereargs ) { 02484 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", 02485 item->filename, item->startline, item->endline, item->u1.str, hereargs, thereargs); 02486 errs++; 02487 } 02488 } 02489 break; 02490 02491 case PV_APPLICATION_CALL: 02492 /* fields: item->u1.str == name of application to call 02493 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 02494 item->u2.arglist->u1.str == argument 02495 item->u2.arglist->next == next arg 02496 */ 02497 /* Need to check to see if the application is available! */ 02498 app_def = find_context(item->u1.str); 02499 if (app_def && app_def->type == PV_MACRO) { 02500 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: application call to %s references an existing macro, but had no & preceding it!\n", 02501 item->filename, item->startline, item->endline, item->u1.str); 02502 errs++; 02503 } 02504 if (strcasecmp(item->u1.str,"GotoIf") == 0 02505 || strcasecmp(item->u1.str,"GotoIfTime") == 0 02506 || strcasecmp(item->u1.str,"while") == 0 02507 || strcasecmp(item->u1.str,"endwhile") == 0 02508 || strcasecmp(item->u1.str,"random") == 0 02509 || strcasecmp(item->u1.str,"gosub") == 0 02510 || strcasecmp(item->u1.str,"gosubif") == 0 02511 || strcasecmp(item->u1.str,"continuewhile") == 0 02512 || strcasecmp(item->u1.str,"endwhile") == 0 02513 || strcasecmp(item->u1.str,"execif") == 0 02514 || strcasecmp(item->u1.str,"execiftime") == 0 02515 || strcasecmp(item->u1.str,"exitwhile") == 0 02516 || strcasecmp(item->u1.str,"goto") == 0 02517 || strcasecmp(item->u1.str,"macro") == 0 02518 || strcasecmp(item->u1.str,"macroexclusive") == 0 02519 || strcasecmp(item->u1.str,"macroif") == 0 02520 || strcasecmp(item->u1.str,"stackpop") == 0 02521 || strcasecmp(item->u1.str,"execIf") == 0 ) { 02522 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", 02523 item->filename, item->startline, item->endline, item->u1.str); 02524 warns++; 02525 } 02526 if (strcasecmp(item->u1.str,"macroexit") == 0) { 02527 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: I am converting the MacroExit call here to a return statement.\n", 02528 item->filename, item->startline, item->endline); 02529 item->type = PV_RETURN; 02530 free(item->u1.str); 02531 item->u1.str = 0; 02532 } 02533 02534 #ifdef AAL_ARGCHECK 02535 found = 0; 02536 for (app=apps; app; app=app->next) { 02537 if (strcasecmp(app->name, item->u1.str) == 0) { 02538 found =app; 02539 break; 02540 } 02541 } 02542 if (!found) { 02543 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: application call to %s not listed in applist database!\n", 02544 item->filename, item->startline, item->endline, item->u1.str); 02545 warns++; 02546 } else 02547 check_app_args(item, item->u2.arglist, app); 02548 #endif 02549 break; 02550 02551 case PV_CASE: 02552 /* fields: item->u1.str == value of case 02553 item->u2.statements == pval list of statements under the case 02554 */ 02555 /* Make sure sequence of statements under case is terminated with goto, return, or break */ 02556 /* find the last statement */ 02557 check_pval(item->u2.statements, apps,in_globals); 02558 break; 02559 02560 case PV_PATTERN: 02561 /* fields: item->u1.str == value of case 02562 item->u2.statements == pval list of statements under the case 02563 */ 02564 /* Make sure sequence of statements under case is terminated with goto, return, or break */ 02565 /* find the last statement */ 02566 02567 check_pval(item->u2.statements, apps,in_globals); 02568 break; 02569 02570 case PV_DEFAULT: 02571 /* fields: 02572 item->u2.statements == pval list of statements under the case 02573 */ 02574 02575 check_pval(item->u2.statements, apps,in_globals); 02576 break; 02577 02578 case PV_CATCH: 02579 /* fields: item->u1.str == name of extension to catch 02580 item->u2.statements == pval list of statements in context body 02581 */ 02582 check_pval(item->u2.statements, apps,in_globals); 02583 break; 02584 02585 case PV_SWITCHES: 02586 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 02587 */ 02588 check_pval(item->u1.list, apps,in_globals); 02589 break; 02590 02591 case PV_ESWITCHES: 02592 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 02593 */ 02594 check_pval(item->u1.list, apps,in_globals); 02595 break; 02596 02597 case PV_INCLUDES: 02598 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 02599 */ 02600 check_pval(item->u1.list, apps,in_globals); 02601 check_includes(item); 02602 for (lp=item->u1.list; lp; lp=lp->next){ 02603 char *incl_context = lp->u1.str; 02604 struct pval *that_context = find_context(incl_context); 02605 02606 if ( lp->u2.arglist ) { 02607 check_timerange(lp->u2.arglist); 02608 check_dow(lp->u2.arglist->next); 02609 check_day(lp->u2.arglist->next->next); 02610 check_month(lp->u2.arglist->next->next->next); 02611 } 02612 02613 if (that_context) { 02614 find_pval_gotos(that_context->u2.statements,0); 02615 02616 } 02617 } 02618 break; 02619 02620 case PV_STATEMENTBLOCK: 02621 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 02622 */ 02623 check_pval(item->u1.list, apps,in_globals); 02624 break; 02625 02626 case PV_VARDEC: 02627 /* fields: item->u1.str == variable name 02628 item->u2.val == variable value to assign 02629 */ 02630 /* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */ 02631 if( !in_globals ) { /* don't check stuff inside the globals context; no wrapping in $[ ] there... */ 02632 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); 02633 ast_expr_register_extra_error_info(errmsg); 02634 ast_expr(item->u2.val, expr_output, sizeof(expr_output),NULL); 02635 ast_expr_clear_extra_error_info(); 02636 if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) { 02637 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", 02638 item->filename, item->startline, item->endline, item->u2.val); 02639 warns++; 02640 } 02641 check_expr2_input(item,item->u2.val); 02642 } 02643 break; 02644 02645 case PV_LOCALVARDEC: 02646 /* fields: item->u1.str == variable name 02647 item->u2.val == variable value to assign 02648 */ 02649 /* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */ 02650 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); 02651 ast_expr_register_extra_error_info(errmsg); 02652 ast_expr(item->u2.val, expr_output, sizeof(expr_output),NULL); 02653 ast_expr_clear_extra_error_info(); 02654 if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) { 02655 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", 02656 item->filename, item->startline, item->endline, item->u2.val); 02657 warns++; 02658 } 02659 check_expr2_input(item,item->u2.val); 02660 break; 02661 02662 case PV_GOTO: 02663 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 02664 item->u1.list->u1.str == where the data on a PV_WORD will always be. 02665 */ 02666 /* don't check goto's in abstract contexts */ 02667 if ( in_abstract_context ) 02668 break; 02669 02670 check_goto(item); 02671 break; 02672 02673 case PV_LABEL: 02674 /* fields: item->u1.str == label name 02675 */ 02676 if ( strspn(item->u1.str, "0123456789") == strlen(item->u1.str) ) { 02677 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: label '%s' is numeric, this is bad practice!\n", 02678 item->filename, item->startline, item->endline, item->u1.str); 02679 warns++; 02680 } 02681 02682 check_label(item); 02683 break; 02684 02685 case PV_FOR: 02686 /* fields: item->u1.for_init == a string containing the initalizer 02687 item->u2.for_test == a string containing the loop test 02688 item->u3.for_inc == a string containing the loop increment 02689 02690 item->u4.for_statements == a pval list of statements in the for () 02691 */ 02692 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); 02693 ast_expr_register_extra_error_info(errmsg); 02694 02695 strp = strchr(item->u1.for_init, '='); 02696 if (strp) { 02697 ast_expr(strp+1, expr_output, sizeof(expr_output),NULL); 02698 } 02699 ast_expr(item->u2.for_test, expr_output, sizeof(expr_output),NULL); 02700 strp = strchr(item->u3.for_inc, '='); 02701 if (strp) { 02702 ast_expr(strp+1, expr_output, sizeof(expr_output),NULL); 02703 } 02704 if ( strpbrk(item->u2.for_test,"~!-+<>=*/&^") && !strstr(item->u2.for_test,"${") ) { 02705 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", 02706 item->filename, item->startline, item->endline, item->u2.for_test); 02707 warns++; 02708 } 02709 if ( strpbrk(item->u3.for_inc,"~!-+<>=*/&^") && !strstr(item->u3.for_inc,"${") ) { 02710 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", 02711 item->filename, item->startline, item->endline, item->u3.for_inc); 02712 warns++; 02713 } 02714 check_expr2_input(item,item->u2.for_test); 02715 check_expr2_input(item,item->u3.for_inc); 02716 02717 ast_expr_clear_extra_error_info(); 02718 check_pval(item->u4.for_statements, apps,in_globals); 02719 break; 02720 02721 case PV_WHILE: 02722 /* fields: item->u1.str == the while conditional, as supplied by user 02723 02724 item->u2.statements == a pval list of statements in the while () 02725 */ 02726 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); 02727 ast_expr_register_extra_error_info(errmsg); 02728 ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL); 02729 ast_expr_clear_extra_error_info(); 02730 if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { 02731 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n", 02732 item->filename, item->startline, item->endline, item->u1.str); 02733 warns++; 02734 } 02735 check_expr2_input(item,item->u1.str); 02736 check_pval(item->u2.statements, apps,in_globals); 02737 break; 02738 02739 case PV_BREAK: 02740 /* fields: none 02741 */ 02742 check_break(item); 02743 break; 02744 02745 case PV_RETURN: 02746 /* fields: none 02747 */ 02748 break; 02749 02750 case PV_CONTINUE: 02751 /* fields: none 02752 */ 02753 check_continue(item); 02754 break; 02755 02756 case PV_RANDOM: 02757 /* fields: item->u1.str == the random number expression, as supplied by user 02758 02759 item->u2.statements == a pval list of statements in the if () 02760 item->u3.else_statements == a pval list of statements in the else 02761 (could be zero) 02762 */ 02763 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); 02764 ast_expr_register_extra_error_info(errmsg); 02765 ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL); 02766 ast_expr_clear_extra_error_info(); 02767 if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { 02768 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n", 02769 item->filename, item->startline, item->endline, item->u1.str); 02770 warns++; 02771 } 02772 check_expr2_input(item,item->u1.str); 02773 check_pval(item->u2.statements, apps,in_globals); 02774 if (item->u3.else_statements) { 02775 check_pval(item->u3.else_statements, apps,in_globals); 02776 } 02777 break; 02778 02779 case PV_IFTIME: 02780 /* fields: item->u1.list == the if time values, 4 of them, each in PV_WORD, linked list 02781 02782 item->u2.statements == a pval list of statements in the if () 02783 item->u3.else_statements == a pval list of statements in the else 02784 (could be zero) 02785 */ 02786 if ( item->u2.arglist ) { 02787 check_timerange(item->u1.list); 02788 check_dow(item->u1.list->next); 02789 check_day(item->u1.list->next->next); 02790 check_month(item->u1.list->next->next->next); 02791 } 02792 02793 check_pval(item->u2.statements, apps,in_globals); 02794 if (item->u3.else_statements) { 02795 check_pval(item->u3.else_statements, apps,in_globals); 02796 } 02797 break; 02798 02799 case PV_IF: 02800 /* fields: item->u1.str == the if conditional, as supplied by user 02801 02802 item->u2.statements == a pval list of statements in the if () 02803 item->u3.else_statements == a pval list of statements in the else 02804 (could be zero) 02805 */ 02806 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); 02807 ast_expr_register_extra_error_info(errmsg); 02808 ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL); 02809 ast_expr_clear_extra_error_info(); 02810 if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) { 02811 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n", 02812 item->filename, item->startline, item->endline, item->u1.str); 02813 warns++; 02814 } 02815 check_expr2_input(item,item->u1.str); 02816 check_pval(item->u2.statements, apps,in_globals); 02817 if (item->u3.else_statements) { 02818 check_pval(item->u3.else_statements, apps,in_globals); 02819 } 02820 break; 02821 02822 case PV_SWITCH: 02823 /* fields: item->u1.str == the switch expression 02824 02825 item->u2.statements == a pval list of statements in the switch, 02826 (will be case statements, most likely!) 02827 */ 02828 /* we can check the switch expression, see if it matches any of the app variables... 02829 if it does, then, are all the possible cases accounted for? */ 02830 check_switch_expr(item, apps); 02831 check_pval(item->u2.statements, apps,in_globals); 02832 break; 02833 02834 case PV_EXTENSION: 02835 /* fields: item->u1.str == the extension name, label, whatever it's called 02836 02837 item->u2.statements == a pval list of statements in the extension 02838 item->u3.hints == a char * hint argument 02839 item->u4.regexten == an int boolean. non-zero says that regexten was specified 02840 */ 02841 current_extension = item ; 02842 02843 check_pval(item->u2.statements, apps,in_globals); 02844 break; 02845 02846 case PV_IGNOREPAT: 02847 /* fields: item->u1.str == the ignorepat data 02848 */ 02849 break; 02850 02851 case PV_GLOBALS: 02852 /* fields: item->u1.statements == pval list of statements, usually vardecs 02853 */ 02854 in_abstract_context = 0; 02855 check_pval(item->u1.statements, apps, 1); 02856 break; 02857 default: 02858 break; 02859 } 02860 }
Definition at line 2181 of file pval.c.
References ast_strdupa, argapp::next, pval::str, and pval::u1.
02182 { 02183 #ifdef AAL_ARGCHECK 02184 /* get and clean the variable name */ 02185 char *buff1, *p; 02186 struct argapp *a,*a2; 02187 struct appsetvar *v,*v2; 02188 struct argchoice *c; 02189 pval *t; 02190 02191 p = item->u1.str; 02192 while (p && *p && (*p == ' ' || *p == '\t' || *p == '$' || *p == '{' ) ) 02193 p++; 02194 02195 buff1 = ast_strdupa(p); 02196 02197 while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] == '}' || buff1[strlen(buff1)-1] == ' ' || buff1[strlen(buff1)-1] == '\t')) 02198 buff1[strlen(buff1)-1] = 0; 02199 /* buff1 now contains the variable name */ 02200 v = 0; 02201 for (a=apps; a; a=a->next) { 02202 for (v=a->setvars;v;v=v->next) { 02203 if (strcmp(v->name,buff1) == 0) { 02204 break; 02205 } 02206 } 02207 if ( v ) 02208 break; 02209 } 02210 if (v && v->vals) { 02211 /* we have a match, to a variable that has a set of determined values */ 02212 int def= 0; 02213 int pat = 0; 02214 int f1 = 0; 02215 02216 /* first of all, does this switch have a default case ? */ 02217 for (t=item->u2.statements; t; t=t->next) { 02218 if (t->type == PV_DEFAULT) { 02219 def =1; 02220 break; 02221 } 02222 if (t->type == PV_PATTERN) { 02223 pat++; 02224 } 02225 } 02226 if (def || pat) /* nothing to check. All cases accounted for! */ 02227 return; 02228 for (c=v->vals; c; c=c->next) { 02229 f1 = 0; 02230 for (t=item->u2.statements; t; t=t->next) { 02231 if (t->type == PV_CASE || t->type == PV_PATTERN) { 02232 if (!strcmp(t->u1.str,c->name)) { 02233 f1 = 1; 02234 break; 02235 } 02236 } 02237 } 02238 if (!f1) { 02239 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n", 02240 item->filename, item->startline, item->endline, item->u1.str, c->name); 02241 warns++; 02242 } 02243 } 02244 /* next, is there an app call in the current exten, that would set this var? */ 02245 f1 = 0; 02246 t = current_extension->u2.statements; 02247 if ( t && t->type == PV_STATEMENTBLOCK ) 02248 t = t->u1.statements; 02249 for (; t && t != item; t=t->next) { 02250 if (t->type == PV_APPLICATION_CALL) { 02251 /* find the application that matches the u1.str */ 02252 for (a2=apps; a2; a2=a2->next) { 02253 if (strcasecmp(a2->name, t->u1.str)==0) { 02254 for (v2=a2->setvars; v2; v2=v2->next) { 02255 if (strcmp(v2->name, buff1) == 0) { 02256 /* found an app that sets the var */ 02257 f1 = 1; 02258 break; 02259 } 02260 } 02261 } 02262 if (f1) 02263 break; 02264 } 02265 } 02266 if (f1) 02267 break; 02268 } 02269 02270 /* see if it sets the var */ 02271 if (!f1) { 02272 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", 02273 item->filename, item->startline, item->endline, item->u1.str); 02274 warns++; 02275 } 02276 } 02277 #else 02278 pval *t,*tl=0,*p2; 02279 int def= 0; 02280 02281 /* first of all, does this switch have a default case ? */ 02282 for (t=item->u2.statements; t; t=t->next) { 02283 if (t->type == PV_DEFAULT) { 02284 def =1; 02285 break; 02286 } 02287 tl = t; 02288 } 02289 if (def) /* nothing to check. All cases accounted for! */ 02290 return; 02291 /* if no default, warn and insert a default case at the end */ 02292 p2 = tl->next = calloc(1, sizeof(struct pval)); 02293 02294 p2->type = PV_DEFAULT; 02295 p2->startline = tl->startline; 02296 p2->endline = tl->endline; 02297 p2->startcol = tl->startcol; 02298 p2->endcol = tl->endcol; 02299 p2->filename = strdup(tl->filename); 02300 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: A default case was automatically added to the switch.\n", 02301 p2->filename, p2->startline, p2->endline); 02302 warns++; 02303 02304 #endif 02305 }
static void check_timerange | ( | pval * | p | ) | [static] |
Definition at line 834 of file pval.c.
References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
00835 { 00836 char *times; 00837 char *e; 00838 int s1, s2; 00839 int e1, e2; 00840 00841 times = ast_strdupa(p->u1.str); 00842 00843 /* Star is all times */ 00844 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 00845 return; 00846 } 00847 /* Otherwise expect a range */ 00848 e = strchr(times, '-'); 00849 if (!e) { 00850 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", 00851 p->filename, p->startline, p->endline, times); 00852 warns++; 00853 return; 00854 } 00855 *e = '\0'; 00856 e++; 00857 while (*e && !isdigit(*e)) 00858 e++; 00859 if (!*e) { 00860 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n", 00861 p->filename, p->startline, p->endline, p->u1.str); 00862 warns++; 00863 } 00864 if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) { 00865 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n", 00866 p->filename, p->startline, p->endline, times); 00867 warns++; 00868 } 00869 if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) { 00870 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n", 00871 p->filename, p->startline, p->endline, times); 00872 warns++; 00873 } 00874 00875 s1 = s1 * 30 + s2/2; 00876 if ((s1 < 0) || (s1 >= 24*30)) { 00877 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) is out of range!\n", 00878 p->filename, p->startline, p->endline, times); 00879 warns++; 00880 } 00881 e1 = e1 * 30 + e2/2; 00882 if ((e1 < 0) || (e1 >= 24*30)) { 00883 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) is out of range!\n", 00884 p->filename, p->startline, p->endline, e); 00885 warns++; 00886 } 00887 return; 00888 }
int contains_switch | ( | pval * | item | ) |
Definition at line 3326 of file pval.c.
References find_switch_item(), and pval::next.
Referenced by find_switch_item(), and gen_prios().
03327 { 03328 pval *i; 03329 03330 for (i=item; i; i=i->next) { 03331 if (find_switch_item(i)) 03332 return 1; 03333 } 03334 return 0; 03335 }
void destroy_extensions | ( | struct ael_extension * | exten | ) |
Definition at line 2975 of file pval.c.
References ael_priority::app, ael_priority::appargs, exten, free, ael_priority::goto_false, ael_priority::goto_true, ael_extension::hints, ael_extension::loop_break, ael_extension::loop_continue, ael_extension::name, ael_priority::next, ael_extension::next_exten, ael_priority::origin, ael_extension::plist, and ael_extension::plist_last.
02976 { 02977 struct ael_extension *ne, *nen; 02978 for (ne=exten; ne; ne=nen) { 02979 struct ael_priority *pe, *pen; 02980 02981 if (ne->name) 02982 free(ne->name); 02983 02984 /* cidmatch fields are allocated with name, and freed when 02985 the name field is freed. Don't do a free for this field, 02986 unless you LIKE to see a crash! */ 02987 02988 if (ne->hints) 02989 free(ne->hints); 02990 02991 for (pe=ne->plist; pe; pe=pen) { 02992 pen = pe->next; 02993 if (pe->app) 02994 free(pe->app); 02995 pe->app = 0; 02996 if (pe->appargs) 02997 free(pe->appargs); 02998 pe->appargs = 0; 02999 pe->origin = 0; 03000 pe->goto_true = 0; 03001 pe->goto_false = 0; 03002 free(pe); 03003 } 03004 nen = ne->next_exten; 03005 ne->next_exten = 0; 03006 ne->plist =0; 03007 ne->plist_last = 0; 03008 ne->next_exten = 0; 03009 ne->loop_break = 0; 03010 ne->loop_continue = 0; 03011 free(ne); 03012 } 03013 }
void destroy_pval | ( | pval * | item | ) |
Definition at line 4890 of file pval.c.
References destroy_pval_item(), and pval::next.
04891 { 04892 pval *i,*nxt; 04893 04894 for (i=item; i; i=nxt) { 04895 nxt = i->next; 04896 04897 destroy_pval_item(i); 04898 } 04899 }
void destroy_pval_item | ( | pval * | item | ) |
Definition at line 4622 of file pval.c.
References pval::arglist, ast_log(), destroy_pval(), pval::else_statements, pval::filename, pval::for_inc, pval::for_init, pval::for_statements, pval::for_test, free, pval::hints, pval::list, LOG_WARNING, pval::macro_statements, PV_APPLICATION_CALL, PV_BREAK, PV_CASE, PV_CATCH, PV_CONTEXT, PV_CONTINUE, PV_DEFAULT, PV_ESWITCHES, PV_EXTENSION, PV_FOR, PV_GLOBALS, PV_GOTO, PV_IF, PV_IFTIME, PV_IGNOREPAT, PV_INCLUDES, PV_LABEL, PV_LOCALVARDEC, PV_MACRO, PV_MACRO_CALL, PV_PATTERN, PV_RANDOM, PV_RETURN, PV_STATEMENTBLOCK, PV_SWITCH, PV_SWITCHES, PV_VARDEC, PV_WHILE, PV_WORD, pval::statements, pval::str, pval::type, pval::u1, pval::u2, pval::u3, pval::u4, and pval::val.
04623 { 04624 if (item == NULL) { 04625 ast_log(LOG_WARNING, "null item\n"); 04626 return; 04627 } 04628 04629 if (item->filename) 04630 free(item->filename); 04631 04632 switch (item->type) { 04633 case PV_WORD: 04634 /* fields: item->u1.str == string associated with this (word). */ 04635 if (item->u1.str ) 04636 free(item->u1.str); 04637 if ( item->u2.arglist ) 04638 destroy_pval(item->u2.arglist); 04639 break; 04640 04641 case PV_MACRO: 04642 /* fields: item->u1.str == name of macro 04643 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 04644 item->u2.arglist->u1.str == argument 04645 item->u2.arglist->next == next arg 04646 04647 item->u3.macro_statements == pval list of statements in macro body. 04648 */ 04649 destroy_pval(item->u2.arglist); 04650 if (item->u1.str ) 04651 free(item->u1.str); 04652 destroy_pval(item->u3.macro_statements); 04653 break; 04654 04655 case PV_CONTEXT: 04656 /* fields: item->u1.str == name of context 04657 item->u2.statements == pval list of statements in context body 04658 item->u3.abstract == int 1 if an abstract keyword were present 04659 */ 04660 if (item->u1.str) 04661 free(item->u1.str); 04662 destroy_pval(item->u2.statements); 04663 break; 04664 04665 case PV_MACRO_CALL: 04666 /* fields: item->u1.str == name of macro to call 04667 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 04668 item->u2.arglist->u1.str == argument 04669 item->u2.arglist->next == next arg 04670 */ 04671 if (item->u1.str) 04672 free(item->u1.str); 04673 destroy_pval(item->u2.arglist); 04674 break; 04675 04676 case PV_APPLICATION_CALL: 04677 /* fields: item->u1.str == name of application to call 04678 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 04679 item->u2.arglist->u1.str == argument 04680 item->u2.arglist->next == next arg 04681 */ 04682 if (item->u1.str) 04683 free(item->u1.str); 04684 destroy_pval(item->u2.arglist); 04685 break; 04686 04687 case PV_CASE: 04688 /* fields: item->u1.str == value of case 04689 item->u2.statements == pval list of statements under the case 04690 */ 04691 if (item->u1.str) 04692 free(item->u1.str); 04693 destroy_pval(item->u2.statements); 04694 break; 04695 04696 case PV_PATTERN: 04697 /* fields: item->u1.str == value of case 04698 item->u2.statements == pval list of statements under the case 04699 */ 04700 if (item->u1.str) 04701 free(item->u1.str); 04702 destroy_pval(item->u2.statements); 04703 break; 04704 04705 case PV_DEFAULT: 04706 /* fields: 04707 item->u2.statements == pval list of statements under the case 04708 */ 04709 destroy_pval(item->u2.statements); 04710 break; 04711 04712 case PV_CATCH: 04713 /* fields: item->u1.str == name of extension to catch 04714 item->u2.statements == pval list of statements in context body 04715 */ 04716 if (item->u1.str) 04717 free(item->u1.str); 04718 destroy_pval(item->u2.statements); 04719 break; 04720 04721 case PV_SWITCHES: 04722 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 04723 */ 04724 destroy_pval(item->u1.list); 04725 break; 04726 04727 case PV_ESWITCHES: 04728 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 04729 */ 04730 destroy_pval(item->u1.list); 04731 break; 04732 04733 case PV_INCLUDES: 04734 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 04735 item->u2.arglist == pval list of 4 PV_WORD elements for time values 04736 */ 04737 destroy_pval(item->u1.list); 04738 break; 04739 04740 case PV_STATEMENTBLOCK: 04741 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 04742 */ 04743 destroy_pval(item->u1.list); 04744 break; 04745 04746 case PV_LOCALVARDEC: 04747 case PV_VARDEC: 04748 /* fields: item->u1.str == variable name 04749 item->u2.val == variable value to assign 04750 */ 04751 if (item->u1.str) 04752 free(item->u1.str); 04753 if (item->u2.val) 04754 free(item->u2.val); 04755 break; 04756 04757 case PV_GOTO: 04758 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 04759 item->u1.list->u1.str == where the data on a PV_WORD will always be. 04760 */ 04761 04762 destroy_pval(item->u1.list); 04763 break; 04764 04765 case PV_LABEL: 04766 /* fields: item->u1.str == label name 04767 */ 04768 if (item->u1.str) 04769 free(item->u1.str); 04770 break; 04771 04772 case PV_FOR: 04773 /* fields: item->u1.for_init == a string containing the initalizer 04774 item->u2.for_test == a string containing the loop test 04775 item->u3.for_inc == a string containing the loop increment 04776 04777 item->u4.for_statements == a pval list of statements in the for () 04778 */ 04779 if (item->u1.for_init) 04780 free(item->u1.for_init); 04781 if (item->u2.for_test) 04782 free(item->u2.for_test); 04783 if (item->u3.for_inc) 04784 free(item->u3.for_inc); 04785 destroy_pval(item->u4.for_statements); 04786 break; 04787 04788 case PV_WHILE: 04789 /* fields: item->u1.str == the while conditional, as supplied by user 04790 04791 item->u2.statements == a pval list of statements in the while () 04792 */ 04793 if (item->u1.str) 04794 free(item->u1.str); 04795 destroy_pval(item->u2.statements); 04796 break; 04797 04798 case PV_BREAK: 04799 /* fields: none 04800 */ 04801 break; 04802 04803 case PV_RETURN: 04804 /* fields: none 04805 */ 04806 break; 04807 04808 case PV_CONTINUE: 04809 /* fields: none 04810 */ 04811 break; 04812 04813 case PV_IFTIME: 04814 /* fields: item->u1.list == the 4 time values, in PV_WORD structs, linked list 04815 04816 item->u2.statements == a pval list of statements in the if () 04817 item->u3.else_statements == a pval list of statements in the else 04818 (could be zero) 04819 */ 04820 destroy_pval(item->u1.list); 04821 destroy_pval(item->u2.statements); 04822 if (item->u3.else_statements) { 04823 destroy_pval(item->u3.else_statements); 04824 } 04825 break; 04826 04827 case PV_RANDOM: 04828 /* fields: item->u1.str == the random percentage, as supplied by user 04829 04830 item->u2.statements == a pval list of statements in the true part () 04831 item->u3.else_statements == a pval list of statements in the else 04832 (could be zero) 04833 fall thru to If */ 04834 case PV_IF: 04835 /* fields: item->u1.str == the if conditional, as supplied by user 04836 04837 item->u2.statements == a pval list of statements in the if () 04838 item->u3.else_statements == a pval list of statements in the else 04839 (could be zero) 04840 */ 04841 if (item->u1.str) 04842 free(item->u1.str); 04843 destroy_pval(item->u2.statements); 04844 if (item->u3.else_statements) { 04845 destroy_pval(item->u3.else_statements); 04846 } 04847 break; 04848 04849 case PV_SWITCH: 04850 /* fields: item->u1.str == the switch expression 04851 04852 item->u2.statements == a pval list of statements in the switch, 04853 (will be case statements, most likely!) 04854 */ 04855 if (item->u1.str) 04856 free(item->u1.str); 04857 destroy_pval(item->u2.statements); 04858 break; 04859 04860 case PV_EXTENSION: 04861 /* fields: item->u1.str == the extension name, label, whatever it's called 04862 04863 item->u2.statements == a pval list of statements in the extension 04864 item->u3.hints == a char * hint argument 04865 item->u4.regexten == an int boolean. non-zero says that regexten was specified 04866 */ 04867 if (item->u1.str) 04868 free(item->u1.str); 04869 if (item->u3.hints) 04870 free(item->u3.hints); 04871 destroy_pval(item->u2.statements); 04872 break; 04873 04874 case PV_IGNOREPAT: 04875 /* fields: item->u1.str == the ignorepat data 04876 */ 04877 if (item->u1.str) 04878 free(item->u1.str); 04879 break; 04880 04881 case PV_GLOBALS: 04882 /* fields: item->u1.statements == pval list of statements, usually vardecs 04883 */ 04884 destroy_pval(item->u1.statements); 04885 break; 04886 } 04887 free(item); 04888 }
static int extension_matches | ( | pval * | here, | |
const char * | exten, | |||
const char * | pattern | |||
) | [static] |
Definition at line 693 of file pval.c.
References ast_log(), pval::endline, pval::filename, LOG_ERROR, LOG_WARNING, and pval::startline.
Referenced by match_pval_item().
00694 { 00695 int err1; 00696 regex_t preg; 00697 00698 /* simple case, they match exactly, the pattern and exten name */ 00699 if (strcmp(pattern,exten) == 0) 00700 return 1; 00701 00702 if (pattern[0] == '_') { 00703 char reg1[2000]; 00704 const char *p; 00705 char *r = reg1; 00706 00707 if ( strlen(pattern)*5 >= 2000 ) /* safety valve */ { 00708 ast_log(LOG_ERROR,"Error: The pattern %s is way too big. Pattern matching cancelled.\n", 00709 pattern); 00710 return 0; 00711 } 00712 /* form a regular expression from the pattern, and then match it against exten */ 00713 *r++ = '^'; /* what if the extension is a pattern ?? */ 00714 *r++ = '_'; /* what if the extension is a pattern ?? */ 00715 *r++ = '?'; 00716 for (p=pattern+1; *p; p++) { 00717 switch ( *p ) { 00718 case 'X': 00719 *r++ = '['; 00720 *r++ = '0'; 00721 *r++ = '-'; 00722 *r++ = '9'; 00723 *r++ = 'X'; 00724 *r++ = ']'; 00725 break; 00726 00727 case 'Z': 00728 *r++ = '['; 00729 *r++ = '1'; 00730 *r++ = '-'; 00731 *r++ = '9'; 00732 *r++ = 'Z'; 00733 *r++ = ']'; 00734 break; 00735 00736 case 'N': 00737 *r++ = '['; 00738 *r++ = '2'; 00739 *r++ = '-'; 00740 *r++ = '9'; 00741 *r++ = 'N'; 00742 *r++ = ']'; 00743 break; 00744 00745 case '[': 00746 while ( *p && *p != ']' ) { 00747 *r++ = *p++; 00748 } 00749 *r++ = ']'; 00750 if ( *p != ']') { 00751 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n", 00752 here->filename, here->startline, here->endline, pattern); 00753 } 00754 break; 00755 00756 case '.': 00757 case '!': 00758 *r++ = '.'; 00759 *r++ = '*'; 00760 break; 00761 case '*': 00762 *r++ = '\\'; 00763 *r++ = '*'; 00764 break; 00765 default: 00766 *r++ = *p; 00767 break; 00768 00769 } 00770 } 00771 *r++ = '$'; /* what if the extension is a pattern ?? */ 00772 *r++ = *p++; /* put in the closing null */ 00773 err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED); 00774 if ( err1 ) { 00775 char errmess[500]; 00776 regerror(err1,&preg,errmess,sizeof(errmess)); 00777 regfree(&preg); 00778 ast_log(LOG_WARNING, "Regcomp of %s failed, error code %d\n", 00779 reg1, err1); 00780 return 0; 00781 } 00782 err1 = regexec(&preg, exten, 0, 0, 0); 00783 regfree(&preg); 00784 00785 if ( err1 ) { 00786 /* ast_log(LOG_NOTICE,"*****************************[%d]Extension %s did not match %s(%s)\n", 00787 err1,exten, pattern, reg1); */ 00788 return 0; /* no match */ 00789 } else { 00790 /* ast_log(LOG_NOTICE,"*****************************Extension %s matched %s\n", 00791 exten, pattern); */ 00792 return 1; 00793 } 00794 00795 00796 } else { 00797 if ( strcmp(exten,pattern) == 0 ) { 00798 return 1; 00799 } else 00800 return 0; 00801 } 00802 }
struct pval* find_context | ( | char * | name | ) |
Definition at line 1950 of file pval.c.
References current_db, and match_pval().
01951 { 01952 return_on_context_match = 1; 01953 count_labels = 0; 01954 match_context = name; 01955 match_exten = "*"; /* don't really need to set these, shouldn't be reached */ 01956 match_label = "*"; 01957 return match_pval(current_db); 01958 }
Definition at line 1836 of file pval.c.
References find_context(), pval::list, match_pval(), pval::next, PV_INCLUDES, pval::statements, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by check_label().
01837 { 01838 /* printf(" --- Got args %s, %s\n", exten, label); */ 01839 struct pval *ret; 01840 struct pval *p3; 01841 01842 count_labels = 0; 01843 return_on_context_match = 0; 01844 match_context = "*"; 01845 match_exten = "*"; 01846 match_label = label; 01847 01848 ret = match_pval(curr_cont); 01849 if (ret) 01850 return ret; 01851 01852 /* the target of the goto could be in an included context!! Fancy that!! */ 01853 /* look for includes in the current context */ 01854 for (p3=curr_cont->u2.statements; p3; p3=p3->next) { 01855 if (p3->type == PV_INCLUDES) { 01856 struct pval *p4; 01857 for (p4=p3->u1.list; p4; p4=p4->next) { 01858 /* for each context pointed to, find it, then find a context/label that matches the 01859 target here! */ 01860 char *incl_context = p4->u1.str; 01861 /* find a matching context name */ 01862 struct pval *that_context = find_context(incl_context); 01863 if (that_context) { 01864 struct pval *x3; 01865 x3 = find_first_label_in_current_context(label, that_context); 01866 if (x3) { 01867 return x3; 01868 } 01869 } 01870 } 01871 } 01872 } 01873 return 0; 01874 }
struct pval * find_label_in_current_context | ( | char * | exten, | |
char * | label, | |||
pval * | curr_cont | |||
) | [static] |
Definition at line 1876 of file pval.c.
References find_context(), pval::list, match_pval(), pval::next, PV_INCLUDES, pval::statements, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by check_goto(), and get_goto_target().
01877 { 01878 /* printf(" --- Got args %s, %s\n", exten, label); */ 01879 struct pval *ret; 01880 struct pval *p3; 01881 01882 count_labels = 0; 01883 return_on_context_match = 0; 01884 match_context = "*"; 01885 match_exten = exten; 01886 match_label = label; 01887 ret = match_pval(curr_cont->u2.statements); 01888 if (ret) 01889 return ret; 01890 01891 /* the target of the goto could be in an included context!! Fancy that!! */ 01892 /* look for includes in the current context */ 01893 for (p3=curr_cont->u2.statements; p3; p3=p3->next) { 01894 if (p3->type == PV_INCLUDES) { 01895 struct pval *p4; 01896 for (p4=p3->u1.list; p4; p4=p4->next) { 01897 /* for each context pointed to, find it, then find a context/label that matches the 01898 target here! */ 01899 char *incl_context = p4->u1.str; 01900 /* find a matching context name */ 01901 struct pval *that_context = find_context(incl_context); 01902 if (that_context) { 01903 struct pval *x3; 01904 x3 = find_label_in_current_context(exten, label, that_context); 01905 if (x3) { 01906 return x3; 01907 } 01908 } 01909 } 01910 } 01911 } 01912 return 0; 01913 }
static struct pval * find_label_in_current_db | ( | const char * | context, | |
const char * | exten, | |||
const char * | label | |||
) | [static] |
Definition at line 1926 of file pval.c.
References current_db, and match_pval().
Referenced by check_goto(), and get_goto_target().
01927 { 01928 /* printf(" --- Got args %s, %s, %s\n", context, exten, label); */ 01929 count_labels = 0; 01930 return_on_context_match = 0; 01931 01932 match_context = context; 01933 match_exten = exten; 01934 match_label = label; 01935 01936 return match_pval(current_db); 01937 }
static struct pval * find_label_in_current_extension | ( | const char * | label, | |
pval * | curr_ext | |||
) | [static] |
Definition at line 1915 of file pval.c.
References match_pval().
Referenced by check_goto(), and get_goto_target().
01916 { 01917 /* printf(" --- Got args %s\n", label); */ 01918 count_labels = 0; 01919 return_on_context_match = 0; 01920 match_context = "*"; 01921 match_exten = "*"; 01922 match_label = label; 01923 return match_pval(curr_ext); 01924 }
struct pval* find_macro | ( | char * | name | ) |
Definition at line 1940 of file pval.c.
References current_db, and match_pval().
01941 { 01942 return_on_context_match = 1; 01943 count_labels = 0; 01944 match_context = name; 01945 match_exten = "*"; /* don't really need to set these, shouldn't be reached */ 01946 match_label = "*"; 01947 return match_pval(current_db); 01948 }
static void find_pval_goto_item | ( | pval * | item, | |
int | lev | |||
) | [static] |
Definition at line 1376 of file pval.c.
References ast_log(), check_goto(), pval::else_statements, find_context(), find_pval_gotos(), pval::for_statements, pval::list, LOG_ERROR, pval::macro_statements, pval::next, PV_CASE, PV_CATCH, PV_CONTEXT, PV_DEFAULT, PV_EXTENSION, PV_FOR, PV_GOTO, PV_IF, PV_IFTIME, PV_INCLUDES, PV_MACRO, PV_PATTERN, PV_RANDOM, PV_STATEMENTBLOCK, PV_SWITCH, PV_WHILE, pval::statements, pval::str, pval::type, pval::u1, pval::u2, pval::u3, and pval::u4.
Referenced by find_pval_gotos().
01377 { 01378 struct pval *p4; 01379 01380 if (lev>100) { 01381 ast_log(LOG_ERROR,"find_pval_goto in infinite loop! item_type: %d\n\n", item->type); 01382 return; 01383 } 01384 01385 switch ( item->type ) { 01386 case PV_MACRO: 01387 /* fields: item->u1.str == name of macro 01388 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 01389 item->u2.arglist->u1.str == argument 01390 item->u2.arglist->next == next arg 01391 01392 item->u3.macro_statements == pval list of statements in macro body. 01393 */ 01394 01395 /* printf("Descending into macro %s at line %d\n", item->u1.str, item->startline); */ 01396 find_pval_gotos(item->u3.macro_statements,lev+1); /* if we're just searching for a context, don't bother descending into them */ 01397 01398 break; 01399 01400 case PV_CONTEXT: 01401 /* fields: item->u1.str == name of context 01402 item->u2.statements == pval list of statements in context body 01403 item->u3.abstract == int 1 if an abstract keyword were present 01404 */ 01405 break; 01406 01407 case PV_CASE: 01408 /* fields: item->u1.str == value of case 01409 item->u2.statements == pval list of statements under the case 01410 */ 01411 /* printf("Descending into Case of %s\n", item->u1.str); */ 01412 find_pval_gotos(item->u2.statements,lev+1); 01413 break; 01414 01415 case PV_PATTERN: 01416 /* fields: item->u1.str == value of case 01417 item->u2.statements == pval list of statements under the case 01418 */ 01419 /* printf("Descending into Pattern of %s\n", item->u1.str); */ 01420 find_pval_gotos(item->u2.statements,lev+1); 01421 break; 01422 01423 case PV_DEFAULT: 01424 /* fields: 01425 item->u2.statements == pval list of statements under the case 01426 */ 01427 /* printf("Descending into default\n"); */ 01428 find_pval_gotos(item->u2.statements,lev+1); 01429 break; 01430 01431 case PV_CATCH: 01432 /* fields: item->u1.str == name of extension to catch 01433 item->u2.statements == pval list of statements in context body 01434 */ 01435 /* printf("Descending into catch of %s\n", item->u1.str); */ 01436 find_pval_gotos(item->u2.statements,lev+1); 01437 break; 01438 01439 case PV_STATEMENTBLOCK: 01440 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 01441 */ 01442 /* printf("Descending into statement block\n"); */ 01443 find_pval_gotos(item->u1.list,lev+1); 01444 break; 01445 01446 case PV_GOTO: 01447 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 01448 item->u1.list->u1.str == where the data on a PV_WORD will always be. 01449 */ 01450 check_goto(item); /* THE WHOLE FUNCTION OF THIS ENTIRE ROUTINE!!!! */ 01451 break; 01452 01453 case PV_INCLUDES: 01454 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 01455 */ 01456 for (p4=item->u1.list; p4; p4=p4->next) { 01457 /* for each context pointed to, find it, then find a context/label that matches the 01458 target here! */ 01459 char *incl_context = p4->u1.str; 01460 /* find a matching context name */ 01461 struct pval *that_context = find_context(incl_context); 01462 if (that_context && that_context->u2.statements) { 01463 /* printf("Descending into include of '%s' at line %d; that_context=%s, that_context type=%d\n", incl_context, item->startline, that_context->u1.str, that_context->type); */ 01464 find_pval_gotos(that_context->u2.statements,lev+1); /* keep working up the includes */ 01465 } 01466 } 01467 break; 01468 01469 case PV_FOR: 01470 /* fields: item->u1.for_init == a string containing the initalizer 01471 item->u2.for_test == a string containing the loop test 01472 item->u3.for_inc == a string containing the loop increment 01473 01474 item->u4.for_statements == a pval list of statements in the for () 01475 */ 01476 /* printf("Descending into for at line %d\n", item->startline); */ 01477 find_pval_gotos(item->u4.for_statements,lev+1); 01478 break; 01479 01480 case PV_WHILE: 01481 /* fields: item->u1.str == the while conditional, as supplied by user 01482 01483 item->u2.statements == a pval list of statements in the while () 01484 */ 01485 /* printf("Descending into while at line %d\n", item->startline); */ 01486 find_pval_gotos(item->u2.statements,lev+1); 01487 break; 01488 01489 case PV_RANDOM: 01490 /* fields: item->u1.str == the random number expression, as supplied by user 01491 01492 item->u2.statements == a pval list of statements in the if () 01493 item->u3.else_statements == a pval list of statements in the else 01494 (could be zero) 01495 fall thru to PV_IF */ 01496 01497 case PV_IFTIME: 01498 /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list 01499 01500 item->u2.statements == a pval list of statements in the if () 01501 item->u3.else_statements == a pval list of statements in the else 01502 (could be zero) 01503 fall thru to PV_IF*/ 01504 case PV_IF: 01505 /* fields: item->u1.str == the if conditional, as supplied by user 01506 01507 item->u2.statements == a pval list of statements in the if () 01508 item->u3.else_statements == a pval list of statements in the else 01509 (could be zero) 01510 */ 01511 /* printf("Descending into random/iftime/if at line %d\n", item->startline); */ 01512 find_pval_gotos(item->u2.statements,lev+1); 01513 01514 if (item->u3.else_statements) { 01515 /* printf("Descending into random/iftime/if's ELSE at line %d\n", item->startline); */ 01516 find_pval_gotos(item->u3.else_statements,lev+1); 01517 } 01518 break; 01519 01520 case PV_SWITCH: 01521 /* fields: item->u1.str == the switch expression 01522 01523 item->u2.statements == a pval list of statements in the switch, 01524 (will be case statements, most likely!) 01525 */ 01526 /* printf("Descending into switch at line %d\n", item->startline); */ 01527 find_pval_gotos(item->u3.else_statements,lev+1); 01528 break; 01529 01530 case PV_EXTENSION: 01531 /* fields: item->u1.str == the extension name, label, whatever it's called 01532 01533 item->u2.statements == a pval list of statements in the extension 01534 item->u3.hints == a char * hint argument 01535 item->u4.regexten == an int boolean. non-zero says that regexten was specified 01536 */ 01537 01538 /* printf("Descending into extension %s at line %d\n", item->u1.str, item->startline); */ 01539 find_pval_gotos(item->u2.statements,lev+1); 01540 break; 01541 01542 default: 01543 break; 01544 } 01545 }
static void find_pval_gotos | ( | pval * | item, | |
int | lev | |||
) | [static] |
Definition at line 1547 of file pval.c.
References find_pval_goto_item(), and pval::next.
Referenced by check_pval_item(), and find_pval_goto_item().
01548 { 01549 pval *i; 01550 01551 for (i=item; i; i=i->next) { 01552 /* printf("About to call pval_goto_item, itemcount=%d, itemtype=%d\n", item_count, i->type); */ 01553 find_pval_goto_item(i, lev); 01554 } 01555 }
int find_switch_item | ( | pval * | item | ) |
Definition at line 3087 of file pval.c.
References contains_switch(), pval::else_statements, pval::for_statements, pval::list, pval::macro_statements, PV_APPLICATION_CALL, PV_BREAK, PV_CASE, PV_CATCH, PV_CONTEXT, PV_CONTINUE, PV_DEFAULT, PV_ESWITCHES, PV_EXTENSION, PV_FOR, PV_GLOBALS, PV_GOTO, PV_IF, PV_IFTIME, PV_IGNOREPAT, PV_INCLUDES, PV_LABEL, PV_LOCALVARDEC, PV_MACRO, PV_MACRO_CALL, PV_PATTERN, PV_RANDOM, PV_RETURN, PV_STATEMENTBLOCK, PV_SWITCH, PV_SWITCHES, PV_VARDEC, PV_WHILE, PV_WORD, pval::statements, pval::type, pval::u1, pval::u2, pval::u3, and pval::u4.
Referenced by contains_switch().
03088 { 03089 switch ( item->type ) { 03090 case PV_LOCALVARDEC: 03091 /* fields: item->u1.str == string associated with this (word). */ 03092 break; 03093 03094 case PV_WORD: 03095 /* fields: item->u1.str == string associated with this (word). */ 03096 break; 03097 03098 case PV_MACRO: 03099 /* fields: item->u1.str == name of macro 03100 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 03101 item->u2.arglist->u1.str == argument 03102 item->u2.arglist->next == next arg 03103 03104 item->u3.macro_statements == pval list of statements in macro body. 03105 */ 03106 /* had better not see this */ 03107 if (contains_switch(item->u3.macro_statements)) 03108 return 1; 03109 break; 03110 03111 case PV_CONTEXT: 03112 /* fields: item->u1.str == name of context 03113 item->u2.statements == pval list of statements in context body 03114 item->u3.abstract == int 1 if an abstract keyword were present 03115 */ 03116 /* had better not see this */ 03117 if (contains_switch(item->u2.statements)) 03118 return 1; 03119 break; 03120 03121 case PV_MACRO_CALL: 03122 /* fields: item->u1.str == name of macro to call 03123 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 03124 item->u2.arglist->u1.str == argument 03125 item->u2.arglist->next == next arg 03126 */ 03127 break; 03128 03129 case PV_APPLICATION_CALL: 03130 /* fields: item->u1.str == name of application to call 03131 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 03132 item->u2.arglist->u1.str == argument 03133 item->u2.arglist->next == next arg 03134 */ 03135 break; 03136 03137 case PV_CASE: 03138 /* fields: item->u1.str == value of case 03139 item->u2.statements == pval list of statements under the case 03140 */ 03141 /* had better not see this */ 03142 if (contains_switch(item->u2.statements)) 03143 return 1; 03144 break; 03145 03146 case PV_PATTERN: 03147 /* fields: item->u1.str == value of case 03148 item->u2.statements == pval list of statements under the case 03149 */ 03150 /* had better not see this */ 03151 if (contains_switch(item->u2.statements)) 03152 return 1; 03153 break; 03154 03155 case PV_DEFAULT: 03156 /* fields: 03157 item->u2.statements == pval list of statements under the case 03158 */ 03159 /* had better not see this */ 03160 if (contains_switch(item->u2.statements)) 03161 return 1; 03162 break; 03163 03164 case PV_CATCH: 03165 /* fields: item->u1.str == name of extension to catch 03166 item->u2.statements == pval list of statements in context body 03167 */ 03168 /* had better not see this */ 03169 if (contains_switch(item->u2.statements)) 03170 return 1; 03171 break; 03172 03173 case PV_SWITCHES: 03174 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 03175 */ 03176 break; 03177 03178 case PV_ESWITCHES: 03179 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 03180 */ 03181 break; 03182 03183 case PV_INCLUDES: 03184 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 03185 item->u2.arglist == pval list of 4 PV_WORD elements for time values 03186 */ 03187 break; 03188 03189 case PV_STATEMENTBLOCK: 03190 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 03191 */ 03192 if (contains_switch(item->u1.list) ) 03193 return 1; 03194 break; 03195 03196 case PV_VARDEC: 03197 /* fields: item->u1.str == variable name 03198 item->u2.val == variable value to assign 03199 */ 03200 break; 03201 03202 case PV_GOTO: 03203 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 03204 item->u1.list->u1.str == where the data on a PV_WORD will always be. 03205 */ 03206 break; 03207 03208 case PV_LABEL: 03209 /* fields: item->u1.str == label name 03210 */ 03211 break; 03212 03213 case PV_FOR: 03214 /* fields: item->u1.for_init == a string containing the initalizer 03215 item->u2.for_test == a string containing the loop test 03216 item->u3.for_inc == a string containing the loop increment 03217 03218 item->u4.for_statements == a pval list of statements in the for () 03219 */ 03220 if (contains_switch(item->u4.for_statements)) 03221 return 1; 03222 break; 03223 03224 case PV_WHILE: 03225 /* fields: item->u1.str == the while conditional, as supplied by user 03226 03227 item->u2.statements == a pval list of statements in the while () 03228 */ 03229 if (contains_switch(item->u2.statements)) 03230 return 1; 03231 break; 03232 03233 case PV_BREAK: 03234 /* fields: none 03235 */ 03236 break; 03237 03238 case PV_RETURN: 03239 /* fields: none 03240 */ 03241 break; 03242 03243 case PV_CONTINUE: 03244 /* fields: none 03245 */ 03246 break; 03247 03248 case PV_IFTIME: 03249 /* fields: item->u1.list == there are 4 linked PV_WORDs here. 03250 03251 item->u2.statements == a pval list of statements in the if () 03252 item->u3.else_statements == a pval list of statements in the else 03253 (could be zero) 03254 */ 03255 if (contains_switch(item->u2.statements)) 03256 return 1; 03257 if ( item->u3.else_statements ) { 03258 if (contains_switch(item->u3.else_statements)) 03259 return 1; 03260 } 03261 break; 03262 03263 case PV_RANDOM: 03264 /* fields: item->u1.str == the random number expression, as supplied by user 03265 03266 item->u2.statements == a pval list of statements in the if () 03267 item->u3.else_statements == a pval list of statements in the else 03268 (could be zero) 03269 */ 03270 if (contains_switch(item->u2.statements)) 03271 return 1; 03272 if ( item->u3.else_statements ) { 03273 if (contains_switch(item->u3.else_statements)) 03274 return 1; 03275 } 03276 break; 03277 03278 case PV_IF: 03279 /* fields: item->u1.str == the if conditional, as supplied by user 03280 03281 item->u2.statements == a pval list of statements in the if () 03282 item->u3.else_statements == a pval list of statements in the else 03283 (could be zero) 03284 */ 03285 if (contains_switch(item->u2.statements)) 03286 return 1; 03287 if ( item->u3.else_statements ) { 03288 if (contains_switch(item->u3.else_statements)) 03289 return 1; 03290 } 03291 break; 03292 03293 case PV_SWITCH: 03294 /* fields: item->u1.str == the switch expression 03295 03296 item->u2.statements == a pval list of statements in the switch, 03297 (will be case statements, most likely!) 03298 */ 03299 return 1; /* JACKPOT */ 03300 break; 03301 03302 case PV_EXTENSION: 03303 /* fields: item->u1.str == the extension name, label, whatever it's called 03304 03305 item->u2.statements == a pval list of statements in the extension 03306 item->u3.hints == a char * hint argument 03307 item->u4.regexten == an int boolean. non-zero says that regexten was specified 03308 */ 03309 if (contains_switch(item->u2.statements)) 03310 return 1; 03311 break; 03312 03313 case PV_IGNOREPAT: 03314 /* fields: item->u1.str == the ignorepat data 03315 */ 03316 break; 03317 03318 case PV_GLOBALS: 03319 /* fields: item->u1.statements == pval list of statements, usually vardecs 03320 */ 03321 break; 03322 } 03323 return 0; 03324 }
static void fix_gotos_in_extensions | ( | struct ael_extension * | exten | ) | [static] |
Definition at line 4383 of file pval.c.
References buf1, exten, ael_priority::next, ael_extension::next_exten, ael_extension::plist, PV_GOTO, and strdup.
04384 { 04385 struct ael_extension *e; 04386 for(e=exten;e;e=e->next_exten) { 04387 04388 struct ael_priority *p; 04389 for(p=e->plist;p;p=p->next) { 04390 04391 if( p->origin && p->origin->type == PV_GOTO && p->origin->u3.goto_target_in_case ) { 04392 04393 /* fix the extension of the goto target to the actual extension in the post-compiled dialplan */ 04394 04395 pval *target = p->origin->u2.goto_target; 04396 struct ael_extension *z = target->u3.compiled_label; 04397 pval *pv2 = p->origin; 04398 char buf1[500]; 04399 char *apparg_save = p->appargs; 04400 04401 p->appargs = 0; 04402 if (!pv2->u1.list->next) /* just one -- it won't hurt to repeat the extension */ { 04403 snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->u1.str); 04404 p->appargs = strdup(buf1); 04405 04406 } else if (pv2->u1.list->next && !pv2->u1.list->next->next) /* two */ { 04407 snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->next->u1.str); 04408 p->appargs = strdup(buf1); 04409 } else if (pv2->u1.list->next && pv2->u1.list->next->next) { 04410 snprintf(buf1,sizeof(buf1),"%s,%s,%s", pv2->u1.list->u1.str, 04411 z->name, 04412 pv2->u1.list->next->next->u1.str); 04413 p->appargs = strdup(buf1); 04414 } 04415 else 04416 printf("WHAT? The goto doesn't fall into one of three cases for GOTO????\n"); 04417 04418 if( apparg_save ) { 04419 free(apparg_save); 04420 } 04421 } 04422 } 04423 } 04424 }
static void gen_match_to_pattern | ( | char * | pattern, | |
char * | result | |||
) | [static] |
Definition at line 3058 of file pval.c.
Referenced by gen_prios().
03059 { 03060 /* the result will be a string that will be matched by pattern */ 03061 char *p=pattern, *t=result; 03062 while (*p) { 03063 if (*p == 'x' || *p == 'n' || *p == 'z' || *p == 'X' || *p == 'N' || *p == 'Z') 03064 *t++ = '9'; 03065 else if (*p == '[') { 03066 char *z = p+1; 03067 while (*z != ']') 03068 z++; 03069 if (*(z+1)== ']') 03070 z++; 03071 *t++=*(p+1); /* use the first char in the set */ 03072 p = z; 03073 } else { 03074 *t++ = *p; 03075 } 03076 p++; 03077 } 03078 *t++ = 0; /* cap it off */ 03079 }
static int gen_prios | ( | struct ael_extension * | exten, | |
char * | label, | |||
pval * | statement, | |||
struct ael_extension * | mother_exten, | |||
struct ast_context * | this_context | |||
) | [static] |
Definition at line 3338 of file pval.c.
References AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_LABEL, AEL_RETURN, ael_priority::app, ael_priority::appargs, pval::arglist, ast_compat_app_set, buf1, buf2, BUF_SIZE, ael_extension::checked_switch, pval::compiled_label, contains_switch(), ael_extension::context, control_statement_count, pval::else_statements, ael_priority::exten, exten, first, pval::for_inc, pval::for_init, pval::for_statements, pval::for_test, free, gen_match_to_pattern(), get_goto_target(), ael_priority::goto_false, pval::goto_target, pval::goto_target_in_case, ael_priority::goto_true, ael_extension::has_switch, ael_extension::is_switch, label_inside_case(), linkexten(), linkprio(), pval::list, ael_extension::loop_break, ael_extension::loop_continue, malloc, ael_extension::name, new_exten(), new_prio(), pval::next, ael_priority::origin, PV_APPLICATION_CALL, PV_BREAK, PV_CASE, PV_CATCH, PV_CONTINUE, PV_DEFAULT, PV_FOR, PV_GOTO, PV_IF, PV_IFTIME, PV_LABEL, PV_LOCALVARDEC, PV_MACRO_CALL, PV_PATTERN, PV_RANDOM, PV_RETURN, PV_STATEMENTBLOCK, PV_SWITCH, PV_VARDEC, PV_WHILE, remove_spaces_before_equals(), ael_extension::return_needed, pval::statements, pval::str, strdup, pval::type, ael_priority::type, pval::u1, pval::u2, pval::u3, pval::u4, and pval::val.
03339 { 03340 pval *p,*p2,*p3; 03341 struct ael_priority *pr; 03342 struct ael_priority *for_init, *for_test, *for_inc, *for_loop, *for_end; 03343 struct ael_priority *while_test, *while_loop, *while_end; 03344 struct ael_priority *switch_set, *switch_test, *switch_end, *fall_thru, *switch_empty; 03345 struct ael_priority *if_test, *if_end, *if_skip, *if_false; 03346 #ifdef OLD_RAND_ACTION 03347 struct ael_priority *rand_test, *rand_end, *rand_skip; 03348 #endif 03349 char *buf1; 03350 char *buf2; 03351 char *new_label; 03352 char *strp, *strp2; 03353 int default_exists; 03354 int local_control_statement_count; 03355 int first; 03356 struct ael_priority *loop_break_save; 03357 struct ael_priority *loop_continue_save; 03358 struct ael_extension *switch_case,*switch_null; 03359 03360 if (!(buf1 = malloc(BUF_SIZE))) { 03361 return -1; 03362 } 03363 if (!(buf2 = malloc(BUF_SIZE))) { 03364 return -1; 03365 } 03366 if (!(new_label = malloc(BUF_SIZE))) { 03367 return -1; 03368 } 03369 03370 if ((mother_exten && !mother_exten->checked_switch) || (exten && !exten->checked_switch)) { 03371 if (contains_switch(statement)) { /* only run contains_switch if you haven't checked before */ 03372 if (mother_exten) { 03373 if (!mother_exten->has_switch) { 03374 for (first = 1; first >= 0; first--) { 03375 switch_set = new_prio(); 03376 switch_set->type = AEL_APPCALL; 03377 if (!ast_compat_app_set) { 03378 switch_set->app = strdup("MSet"); 03379 } else { 03380 switch_set->app = strdup("Set"); 03381 } 03382 /* Are we likely inside a gosub subroutine? */ 03383 if (!strcmp(mother_exten->name, "~~s~~") && first) { 03384 /* If we're not actually within a gosub, this will fail, but the 03385 * second time through, it will get set. If we are within gosub, 03386 * the second time through is redundant, but acceptable. */ 03387 switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}"); 03388 } else { 03389 switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}"); 03390 first = 0; 03391 } 03392 linkprio(exten, switch_set, mother_exten); 03393 mother_exten->has_switch = 1; 03394 mother_exten->checked_switch = 1; 03395 if (exten) { 03396 exten->has_switch = 1; 03397 exten->checked_switch = 1; 03398 } 03399 } 03400 } 03401 } else if (exten) { 03402 if (!exten->has_switch) { 03403 for (first = 1; first >= 0; first--) { 03404 switch_set = new_prio(); 03405 switch_set->type = AEL_APPCALL; 03406 if (!ast_compat_app_set) { 03407 switch_set->app = strdup("MSet"); 03408 } else { 03409 switch_set->app = strdup("Set"); 03410 } 03411 /* Are we likely inside a gosub subroutine? */ 03412 if (!strcmp(exten->name, "~~s~~")) { 03413 /* If we're not actually within a gosub, this will fail, but the 03414 * second time through, it will get set. If we are within gosub, 03415 * the second time through is redundant, but acceptable. */ 03416 switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}"); 03417 } else { 03418 switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}"); 03419 first = 0; 03420 } 03421 linkprio(exten, switch_set, mother_exten); 03422 exten->has_switch = 1; 03423 exten->checked_switch = 1; 03424 if (mother_exten) { 03425 mother_exten->has_switch = 1; 03426 mother_exten->checked_switch = 1; 03427 } 03428 } 03429 } 03430 } 03431 } else { 03432 if (mother_exten) { 03433 mother_exten->checked_switch = 1; 03434 } 03435 if (exten) { 03436 exten->checked_switch = 1; 03437 } 03438 } 03439 } 03440 for (p=statement; p; p=p->next) { 03441 switch (p->type) { 03442 case PV_VARDEC: 03443 pr = new_prio(); 03444 pr->type = AEL_APPCALL; 03445 snprintf(buf1, BUF_SIZE, "%s=$[%s]", p->u1.str, p->u2.val); 03446 if (!ast_compat_app_set) { 03447 pr->app = strdup("MSet"); 03448 } else { 03449 pr->app = strdup("Set"); 03450 } 03451 remove_spaces_before_equals(buf1); 03452 pr->appargs = strdup(buf1); 03453 pr->origin = p; 03454 linkprio(exten, pr, mother_exten); 03455 break; 03456 03457 case PV_LOCALVARDEC: 03458 pr = new_prio(); 03459 pr->type = AEL_APPCALL; 03460 snprintf(buf1, BUF_SIZE, "LOCAL(%s)=$[%s]", p->u1.str, p->u2.val); 03461 if (!ast_compat_app_set) { 03462 pr->app = strdup("MSet"); 03463 } else { 03464 pr->app = strdup("Set"); 03465 } 03466 remove_spaces_before_equals(buf1); 03467 pr->appargs = strdup(buf1); 03468 pr->origin = p; 03469 linkprio(exten, pr, mother_exten); 03470 break; 03471 03472 case PV_GOTO: 03473 pr = new_prio(); 03474 pr->type = AEL_APPCALL; 03475 p->u2.goto_target = get_goto_target(p); 03476 if( p->u2.goto_target ) { 03477 p->u3.goto_target_in_case = label_inside_case(p->u2.goto_target); 03478 } 03479 03480 if (!p->u1.list->next) /* just one */ { 03481 pr->app = strdup("Goto"); 03482 if (!mother_exten) 03483 pr->appargs = strdup(p->u1.list->u1.str); 03484 else { /* for the case of simple within-extension gotos in case/pattern/default statement blocks: */ 03485 snprintf(buf1, BUF_SIZE, "%s,%s", mother_exten->name, p->u1.list->u1.str); 03486 pr->appargs = strdup(buf1); 03487 } 03488 03489 } else if (p->u1.list->next && !p->u1.list->next->next) /* two */ { 03490 snprintf(buf1, BUF_SIZE, "%s,%s", p->u1.list->u1.str, p->u1.list->next->u1.str); 03491 pr->app = strdup("Goto"); 03492 pr->appargs = strdup(buf1); 03493 } else if (p->u1.list->next && p->u1.list->next->next) { 03494 snprintf(buf1, BUF_SIZE, "%s,%s,%s", p->u1.list->u1.str, 03495 p->u1.list->next->u1.str, 03496 p->u1.list->next->next->u1.str); 03497 pr->app = strdup("Goto"); 03498 pr->appargs = strdup(buf1); 03499 } 03500 pr->origin = p; 03501 linkprio(exten, pr, mother_exten); 03502 break; 03503 03504 case PV_LABEL: 03505 pr = new_prio(); 03506 pr->type = AEL_LABEL; 03507 pr->origin = p; 03508 p->u3.compiled_label = exten; 03509 linkprio(exten, pr, mother_exten); 03510 break; 03511 03512 case PV_FOR: 03513 control_statement_count++; 03514 loop_break_save = exten->loop_break; /* save them, then restore before leaving */ 03515 loop_continue_save = exten->loop_continue; 03516 snprintf(new_label, BUF_SIZE, "for_%s_%d", label, control_statement_count); 03517 for_init = new_prio(); 03518 for_inc = new_prio(); 03519 for_test = new_prio(); 03520 for_loop = new_prio(); 03521 for_end = new_prio(); 03522 for_init->type = AEL_APPCALL; 03523 for_inc->type = AEL_APPCALL; 03524 for_test->type = AEL_FOR_CONTROL; 03525 for_test->goto_false = for_end; 03526 for_loop->type = AEL_CONTROL1; /* simple goto */ 03527 for_end->type = AEL_APPCALL; 03528 if (!ast_compat_app_set) { 03529 for_init->app = strdup("MSet"); 03530 } else { 03531 for_init->app = strdup("Set"); 03532 } 03533 03534 strcpy(buf2,p->u1.for_init); 03535 remove_spaces_before_equals(buf2); 03536 strp = strchr(buf2, '='); 03537 if (strp) { 03538 strp2 = strchr(p->u1.for_init, '='); 03539 *(strp+1) = 0; 03540 strcat(buf2,"$["); 03541 strncat(buf2,strp2+1, BUF_SIZE-strlen(strp2+1)-2); 03542 strcat(buf2,"]"); 03543 for_init->appargs = strdup(buf2); 03544 } else { 03545 strp2 = p->u1.for_init; 03546 while (*strp2 && isspace(*strp2)) 03547 strp2++; 03548 if (*strp2 == '&') { /* itsa macro call */ 03549 char *strp3 = strp2+1; 03550 while (*strp3 && isspace(*strp3)) 03551 strp3++; 03552 strcpy(buf2, strp3); 03553 strp3 = strchr(buf2,'('); 03554 if (strp3) { 03555 *strp3 = '|'; 03556 } 03557 while ((strp3=strchr(buf2,','))) { 03558 *strp3 = '|'; 03559 } 03560 strp3 = strrchr(buf2, ')'); 03561 if (strp3) 03562 *strp3 = 0; /* remove the closing paren */ 03563 03564 for_init->appargs = strdup(buf2); 03565 free(for_init->app); 03566 for_init->app = strdup("Macro"); 03567 } else { /* must be a regular app call */ 03568 char *strp3; 03569 strcpy(buf2, strp2); 03570 strp3 = strchr(buf2,'('); 03571 if (strp3) { 03572 *strp3 = 0; 03573 free(for_init->app); 03574 for_init->app = strdup(buf2); 03575 for_init->appargs = strdup(strp3+1); 03576 strp3 = strrchr(for_init->appargs, ')'); 03577 if (strp3) 03578 *strp3 = 0; /* remove the closing paren */ 03579 } 03580 } 03581 } 03582 03583 strcpy(buf2,p->u3.for_inc); 03584 remove_spaces_before_equals(buf2); 03585 strp = strchr(buf2, '='); 03586 if (strp) { /* there's an = in this part; that means an assignment. set it up */ 03587 strp2 = strchr(p->u3.for_inc, '='); 03588 *(strp+1) = 0; 03589 strcat(buf2,"$["); 03590 strncat(buf2,strp2+1, BUF_SIZE-strlen(strp2+1)-2); 03591 strcat(buf2,"]"); 03592 for_inc->appargs = strdup(buf2); 03593 if (!ast_compat_app_set) { 03594 for_inc->app = strdup("MSet"); 03595 } else { 03596 for_inc->app = strdup("Set"); 03597 } 03598 } else { 03599 strp2 = p->u3.for_inc; 03600 while (*strp2 && isspace(*strp2)) 03601 strp2++; 03602 if (*strp2 == '&') { /* itsa macro call */ 03603 char *strp3 = strp2+1; 03604 while (*strp3 && isspace(*strp3)) 03605 strp3++; 03606 strcpy(buf2, strp3); 03607 strp3 = strchr(buf2,'('); 03608 if (strp3) { 03609 *strp3 = ','; 03610 } 03611 strp3 = strrchr(buf2, ')'); 03612 if (strp3) 03613 *strp3 = 0; /* remove the closing paren */ 03614 03615 for_inc->appargs = strdup(buf2); 03616 03617 for_inc->app = strdup("Macro"); 03618 } else { /* must be a regular app call */ 03619 char *strp3; 03620 strcpy(buf2, strp2); 03621 strp3 = strchr(buf2,'('); 03622 if (strp3) { 03623 *strp3 = 0; 03624 for_inc->app = strdup(buf2); 03625 for_inc->appargs = strdup(strp3+1); 03626 strp3 = strrchr(for_inc->appargs, ')'); 03627 if (strp3) 03628 *strp3 = 0; /* remove the closing paren */ 03629 } 03630 } 03631 } 03632 snprintf(buf1, BUF_SIZE, "$[%s]",p->u2.for_test); 03633 for_test->app = 0; 03634 for_test->appargs = strdup(buf1); 03635 for_loop->goto_true = for_test; 03636 snprintf(buf1, BUF_SIZE, "Finish for_%s_%d", label, control_statement_count); 03637 for_end->app = strdup("NoOp"); 03638 for_end->appargs = strdup(buf1); 03639 /* link & load! */ 03640 linkprio(exten, for_init, mother_exten); 03641 linkprio(exten, for_test, mother_exten); 03642 03643 /* now, put the body of the for loop here */ 03644 exten->loop_break = for_end; 03645 exten->loop_continue = for_inc; 03646 03647 if (gen_prios(exten, new_label, p->u4.for_statements, mother_exten, this_context)) { /* this will link in all the statements here */ 03648 return -1; 03649 } 03650 03651 linkprio(exten, for_inc, mother_exten); 03652 linkprio(exten, for_loop, mother_exten); 03653 linkprio(exten, for_end, mother_exten); 03654 03655 03656 exten->loop_break = loop_break_save; 03657 exten->loop_continue = loop_continue_save; 03658 for_loop->origin = p; 03659 break; 03660 03661 case PV_WHILE: 03662 control_statement_count++; 03663 loop_break_save = exten->loop_break; /* save them, then restore before leaving */ 03664 loop_continue_save = exten->loop_continue; 03665 snprintf(new_label, BUF_SIZE, "while_%s_%d", label, control_statement_count); 03666 while_test = new_prio(); 03667 while_loop = new_prio(); 03668 while_end = new_prio(); 03669 while_test->type = AEL_FOR_CONTROL; 03670 while_test->goto_false = while_end; 03671 while_loop->type = AEL_CONTROL1; /* simple goto */ 03672 while_end->type = AEL_APPCALL; 03673 snprintf(buf1, BUF_SIZE, "$[%s]",p->u1.str); 03674 while_test->app = 0; 03675 while_test->appargs = strdup(buf1); 03676 while_loop->goto_true = while_test; 03677 snprintf(buf1, BUF_SIZE, "Finish while_%s_%d", label, control_statement_count); 03678 while_end->app = strdup("NoOp"); 03679 while_end->appargs = strdup(buf1); 03680 03681 linkprio(exten, while_test, mother_exten); 03682 03683 /* now, put the body of the for loop here */ 03684 exten->loop_break = while_end; 03685 exten->loop_continue = while_test; 03686 03687 if (gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context)) { /* this will link in all the while body statements here */ 03688 return -1; 03689 } 03690 03691 linkprio(exten, while_loop, mother_exten); 03692 linkprio(exten, while_end, mother_exten); 03693 03694 03695 exten->loop_break = loop_break_save; 03696 exten->loop_continue = loop_continue_save; 03697 while_loop->origin = p; 03698 break; 03699 03700 case PV_SWITCH: 03701 control_statement_count++; 03702 local_control_statement_count = control_statement_count; 03703 loop_break_save = exten->loop_break; /* save them, then restore before leaving */ 03704 loop_continue_save = exten->loop_continue; 03705 snprintf(new_label, BUF_SIZE, "sw_%s_%d", label, control_statement_count); 03706 switch_test = new_prio(); 03707 switch_end = new_prio(); 03708 switch_test->type = AEL_APPCALL; 03709 switch_end->type = AEL_APPCALL; 03710 snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", control_statement_count, p->u1.str); 03711 switch_test->app = strdup("Goto"); 03712 switch_test->appargs = strdup(buf1); 03713 snprintf(buf1, BUF_SIZE, "Finish switch_%s_%d", label, control_statement_count); 03714 switch_end->app = strdup("NoOp"); 03715 switch_end->appargs = strdup(buf1); 03716 switch_end->origin = p; 03717 switch_end->exten = exten; 03718 03719 linkprio(exten, switch_test, mother_exten); 03720 linkprio(exten, switch_end, mother_exten); 03721 03722 exten->loop_break = switch_end; 03723 exten->loop_continue = 0; 03724 default_exists = 0; 03725 03726 for (p2=p->u2.statements; p2; p2=p2->next) { 03727 /* now, for each case/default put the body of the for loop here */ 03728 if (p2->type == PV_CASE) { 03729 /* ok, generate a extension and link it in */ 03730 switch_case = new_exten(); 03731 if (mother_exten && mother_exten->checked_switch) { 03732 switch_case->has_switch = mother_exten->has_switch; 03733 switch_case->checked_switch = mother_exten->checked_switch; 03734 } 03735 if (exten && exten->checked_switch) { 03736 switch_case->has_switch = exten->has_switch; 03737 switch_case->checked_switch = exten->checked_switch; 03738 } 03739 switch_case->context = this_context; 03740 switch_case->is_switch = 1; 03741 /* the break/continue locations are inherited from parent */ 03742 switch_case->loop_break = exten->loop_break; 03743 switch_case->loop_continue = exten->loop_continue; 03744 03745 linkexten(exten,switch_case); 03746 snprintf(buf1, BUF_SIZE, "sw_%d_%s", local_control_statement_count, p2->u1.str); 03747 switch_case->name = strdup(buf1); 03748 snprintf(new_label, BUF_SIZE, "sw_%s_%s_%d", label, p2->u1.str, local_control_statement_count); 03749 03750 if (gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context)) { /* this will link in all the case body statements here */ 03751 return -1; 03752 } 03753 03754 /* here is where we write code to "fall thru" to the next case... if there is one... */ 03755 for (p3=p2->u2.statements; p3; p3=p3->next) { 03756 if (!p3->next) 03757 break; 03758 } 03759 /* p3 now points the last statement... */ 03760 if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN) ) { 03761 /* is there a following CASE/PATTERN/DEFAULT? */ 03762 if (p2->next && p2->next->type == PV_CASE) { 03763 fall_thru = new_prio(); 03764 fall_thru->type = AEL_APPCALL; 03765 fall_thru->app = strdup("Goto"); 03766 snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, p2->next->u1.str); 03767 fall_thru->appargs = strdup(buf1); 03768 linkprio(switch_case, fall_thru, mother_exten); 03769 } else if (p2->next && p2->next->type == PV_PATTERN) { 03770 fall_thru = new_prio(); 03771 fall_thru->type = AEL_APPCALL; 03772 fall_thru->app = strdup("Goto"); 03773 gen_match_to_pattern(p2->next->u1.str, buf2); 03774 snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, buf2); 03775 fall_thru->appargs = strdup(buf1); 03776 linkprio(switch_case, fall_thru, mother_exten); 03777 } else if (p2->next && p2->next->type == PV_DEFAULT) { 03778 fall_thru = new_prio(); 03779 fall_thru->type = AEL_APPCALL; 03780 fall_thru->app = strdup("Goto"); 03781 snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count); 03782 fall_thru->appargs = strdup(buf1); 03783 linkprio(switch_case, fall_thru, mother_exten); 03784 } else if (!p2->next) { 03785 fall_thru = new_prio(); 03786 fall_thru->type = AEL_CONTROL1; 03787 fall_thru->goto_true = switch_end; 03788 fall_thru->app = strdup("Goto"); 03789 linkprio(switch_case, fall_thru, mother_exten); 03790 } 03791 } 03792 if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 03793 char buf[2000]; 03794 struct ael_priority *np2 = new_prio(); 03795 np2->type = AEL_APPCALL; 03796 np2->app = strdup("NoOp"); 03797 snprintf(buf, BUF_SIZE, "End of Extension %s", switch_case->name); 03798 np2->appargs = strdup(buf); 03799 linkprio(switch_case, np2, mother_exten); 03800 switch_case-> return_target = np2; 03801 } 03802 } else if (p2->type == PV_PATTERN) { 03803 /* ok, generate a extension and link it in */ 03804 switch_case = new_exten(); 03805 if (mother_exten && mother_exten->checked_switch) { 03806 switch_case->has_switch = mother_exten->has_switch; 03807 switch_case->checked_switch = mother_exten->checked_switch; 03808 } 03809 if (exten && exten->checked_switch) { 03810 switch_case->has_switch = exten->has_switch; 03811 switch_case->checked_switch = exten->checked_switch; 03812 } 03813 switch_case->context = this_context; 03814 switch_case->is_switch = 1; 03815 /* the break/continue locations are inherited from parent */ 03816 switch_case->loop_break = exten->loop_break; 03817 switch_case->loop_continue = exten->loop_continue; 03818 03819 linkexten(exten,switch_case); 03820 snprintf(buf1, BUF_SIZE, "_sw_%d_%s", local_control_statement_count, p2->u1.str); 03821 switch_case->name = strdup(buf1); 03822 snprintf(new_label, BUF_SIZE, "sw_%s_%s_%d", label, p2->u1.str, local_control_statement_count); 03823 03824 if (gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context)) { /* this will link in all the while body statements here */ 03825 return -1; 03826 } 03827 /* here is where we write code to "fall thru" to the next case... if there is one... */ 03828 for (p3=p2->u2.statements; p3; p3=p3->next) { 03829 if (!p3->next) 03830 break; 03831 } 03832 /* p3 now points the last statement... */ 03833 if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) { 03834 /* is there a following CASE/PATTERN/DEFAULT? */ 03835 if (p2->next && p2->next->type == PV_CASE) { 03836 fall_thru = new_prio(); 03837 fall_thru->type = AEL_APPCALL; 03838 fall_thru->app = strdup("Goto"); 03839 snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, p2->next->u1.str); 03840 fall_thru->appargs = strdup(buf1); 03841 linkprio(switch_case, fall_thru, mother_exten); 03842 } else if (p2->next && p2->next->type == PV_PATTERN) { 03843 fall_thru = new_prio(); 03844 fall_thru->type = AEL_APPCALL; 03845 fall_thru->app = strdup("Goto"); 03846 gen_match_to_pattern(p2->next->u1.str, buf2); 03847 snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, buf2); 03848 fall_thru->appargs = strdup(buf1); 03849 linkprio(switch_case, fall_thru, mother_exten); 03850 } else if (p2->next && p2->next->type == PV_DEFAULT) { 03851 fall_thru = new_prio(); 03852 fall_thru->type = AEL_APPCALL; 03853 fall_thru->app = strdup("Goto"); 03854 snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count); 03855 fall_thru->appargs = strdup(buf1); 03856 linkprio(switch_case, fall_thru, mother_exten); 03857 } else if (!p2->next) { 03858 fall_thru = new_prio(); 03859 fall_thru->type = AEL_CONTROL1; 03860 fall_thru->goto_true = switch_end; 03861 fall_thru->app = strdup("Goto"); 03862 linkprio(switch_case, fall_thru, mother_exten); 03863 } 03864 } 03865 if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 03866 char buf[2000]; 03867 struct ael_priority *np2 = new_prio(); 03868 np2->type = AEL_APPCALL; 03869 np2->app = strdup("NoOp"); 03870 snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); 03871 np2->appargs = strdup(buf); 03872 linkprio(switch_case, np2, mother_exten); 03873 switch_case-> return_target = np2; 03874 } 03875 } else if (p2->type == PV_DEFAULT) { 03876 /* ok, generate a extension and link it in */ 03877 switch_case = new_exten(); 03878 if (mother_exten && mother_exten->checked_switch) { 03879 switch_case->has_switch = mother_exten->has_switch; 03880 switch_case->checked_switch = mother_exten->checked_switch; 03881 } 03882 if (exten && exten->checked_switch) { 03883 switch_case->has_switch = exten->has_switch; 03884 switch_case->checked_switch = exten->checked_switch; 03885 } 03886 switch_case->context = this_context; 03887 switch_case->is_switch = 1; 03888 03889 /* new: the default case intros a pattern with ., which covers ALMOST everything. 03890 but it doesn't cover a NULL pattern. So, we'll define a null extension to match 03891 that goto's the default extension. */ 03892 03893 default_exists++; 03894 switch_null = new_exten(); 03895 if (mother_exten && mother_exten->checked_switch) { 03896 switch_null->has_switch = mother_exten->has_switch; 03897 switch_null->checked_switch = mother_exten->checked_switch; 03898 } 03899 if (exten && exten->checked_switch) { 03900 switch_null->has_switch = exten->has_switch; 03901 switch_null->checked_switch = exten->checked_switch; 03902 } 03903 switch_null->context = this_context; 03904 switch_null->is_switch = 1; 03905 switch_empty = new_prio(); 03906 snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count); 03907 switch_empty->app = strdup("Goto"); 03908 switch_empty->appargs = strdup(buf1); 03909 linkprio(switch_null, switch_empty, mother_exten); 03910 snprintf(buf1, BUF_SIZE, "sw_%d_", local_control_statement_count); 03911 switch_null->name = strdup(buf1); 03912 switch_null->loop_break = exten->loop_break; 03913 switch_null->loop_continue = exten->loop_continue; 03914 linkexten(exten,switch_null); 03915 03916 /* the break/continue locations are inherited from parent */ 03917 switch_case->loop_break = exten->loop_break; 03918 switch_case->loop_continue = exten->loop_continue; 03919 linkexten(exten,switch_case); 03920 snprintf(buf1, BUF_SIZE, "_sw_%d_.", local_control_statement_count); 03921 switch_case->name = strdup(buf1); 03922 03923 snprintf(new_label, BUF_SIZE, "sw_%s_default_%d", label, local_control_statement_count); 03924 03925 if (gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context)) { /* this will link in all the default: body statements here */ 03926 return -1; 03927 } 03928 03929 /* here is where we write code to "fall thru" to the next case... if there is one... */ 03930 for (p3=p2->u2.statements; p3; p3=p3->next) { 03931 if (!p3->next) 03932 break; 03933 } 03934 /* p3 now points the last statement... */ 03935 if (!p3 || (p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) { 03936 /* is there a following CASE/PATTERN/DEFAULT? */ 03937 if (p2->next && p2->next->type == PV_CASE) { 03938 fall_thru = new_prio(); 03939 fall_thru->type = AEL_APPCALL; 03940 fall_thru->app = strdup("Goto"); 03941 snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, p2->next->u1.str); 03942 fall_thru->appargs = strdup(buf1); 03943 linkprio(switch_case, fall_thru, mother_exten); 03944 } else if (p2->next && p2->next->type == PV_PATTERN) { 03945 fall_thru = new_prio(); 03946 fall_thru->type = AEL_APPCALL; 03947 fall_thru->app = strdup("Goto"); 03948 gen_match_to_pattern(p2->next->u1.str, buf2); 03949 snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, buf2); 03950 fall_thru->appargs = strdup(buf1); 03951 linkprio(switch_case, fall_thru, mother_exten); 03952 } else if (p2->next && p2->next->type == PV_DEFAULT) { 03953 fall_thru = new_prio(); 03954 fall_thru->type = AEL_APPCALL; 03955 fall_thru->app = strdup("Goto"); 03956 snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count); 03957 fall_thru->appargs = strdup(buf1); 03958 linkprio(switch_case, fall_thru, mother_exten); 03959 } else if (!p2->next) { 03960 fall_thru = new_prio(); 03961 fall_thru->type = AEL_CONTROL1; 03962 fall_thru->goto_true = switch_end; 03963 fall_thru->app = strdup("Goto"); 03964 linkprio(switch_case, fall_thru, mother_exten); 03965 } 03966 } 03967 if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 03968 char buf[2000]; 03969 struct ael_priority *np2 = new_prio(); 03970 np2->type = AEL_APPCALL; 03971 np2->app = strdup("NoOp"); 03972 snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); 03973 np2->appargs = strdup(buf); 03974 linkprio(switch_case, np2, mother_exten); 03975 switch_case-> return_target = np2; 03976 } 03977 } else { 03978 /* what could it be??? */ 03979 } 03980 } 03981 03982 exten->loop_break = loop_break_save; 03983 exten->loop_continue = loop_continue_save; 03984 switch_test->origin = p; 03985 switch_end->origin = p; 03986 break; 03987 03988 case PV_MACRO_CALL: 03989 pr = new_prio(); 03990 pr->type = AEL_APPCALL; 03991 snprintf(buf1, BUF_SIZE, "%s,~~s~~,1", p->u1.str); 03992 first = 1; 03993 for (p2 = p->u2.arglist; p2; p2 = p2->next) { 03994 if (first) 03995 { 03996 strcat(buf1,"("); 03997 first = 0; 03998 } 03999 else 04000 strcat(buf1,","); 04001 strcat(buf1,p2->u1.str); 04002 } 04003 if (!first) 04004 strcat(buf1,")"); 04005 04006 pr->app = strdup("Gosub"); 04007 pr->appargs = strdup(buf1); 04008 pr->origin = p; 04009 linkprio(exten, pr, mother_exten); 04010 break; 04011 04012 case PV_APPLICATION_CALL: 04013 pr = new_prio(); 04014 pr->type = AEL_APPCALL; 04015 buf1[0] = 0; 04016 for (p2 = p->u2.arglist; p2; p2 = p2->next) { 04017 if (p2 != p->u2.arglist ) 04018 strcat(buf1,","); 04019 strcat(buf1,p2->u1.str); 04020 } 04021 pr->app = strdup(p->u1.str); 04022 pr->appargs = strdup(buf1); 04023 pr->origin = p; 04024 linkprio(exten, pr, mother_exten); 04025 break; 04026 04027 case PV_BREAK: 04028 pr = new_prio(); 04029 pr->type = AEL_CONTROL1; /* simple goto */ 04030 pr->goto_true = exten->loop_break; 04031 pr->origin = p; 04032 linkprio(exten, pr, mother_exten); 04033 break; 04034 04035 case PV_RETURN: /* hmmmm */ 04036 pr = new_prio(); 04037 pr->type = AEL_RETURN; /* simple Return */ 04038 /* exten->return_needed++; */ 04039 pr->app = strdup("Return"); 04040 pr->appargs = strdup(""); 04041 pr->origin = p; 04042 linkprio(exten, pr, mother_exten); 04043 break; 04044 04045 case PV_CONTINUE: 04046 pr = new_prio(); 04047 pr->type = AEL_CONTROL1; /* simple goto */ 04048 pr->goto_true = exten->loop_continue; 04049 pr->origin = p; 04050 linkprio(exten, pr, mother_exten); 04051 break; 04052 04053 case PV_IFTIME: 04054 control_statement_count++; 04055 snprintf(new_label, BUF_SIZE, "iftime_%s_%d", label, control_statement_count); 04056 04057 if_test = new_prio(); 04058 if_test->type = AEL_IFTIME_CONTROL; 04059 snprintf(buf1, BUF_SIZE, "%s,%s,%s,%s", 04060 p->u1.list->u1.str, 04061 p->u1.list->next->u1.str, 04062 p->u1.list->next->next->u1.str, 04063 p->u1.list->next->next->next->u1.str); 04064 if_test->app = 0; 04065 if_test->appargs = strdup(buf1); 04066 if_test->origin = p; 04067 04068 if_end = new_prio(); 04069 if_end->type = AEL_APPCALL; 04070 snprintf(buf1, BUF_SIZE, "Finish iftime_%s_%d", label, control_statement_count); 04071 if_end->app = strdup("NoOp"); 04072 if_end->appargs = strdup(buf1); 04073 04074 if (p->u3.else_statements) { 04075 if_skip = new_prio(); 04076 if_skip->type = AEL_CONTROL1; /* simple goto */ 04077 if_skip->goto_true = if_end; 04078 if_skip->origin = p; 04079 04080 } else { 04081 if_skip = 0; 04082 04083 if_test->goto_false = if_end; 04084 } 04085 04086 if_false = new_prio(); 04087 if_false->type = AEL_CONTROL1; 04088 if (p->u3.else_statements) { 04089 if_false->goto_true = if_skip; /* +1 */ 04090 } else { 04091 if_false->goto_true = if_end; 04092 } 04093 04094 /* link & load! */ 04095 linkprio(exten, if_test, mother_exten); 04096 linkprio(exten, if_false, mother_exten); 04097 04098 /* now, put the body of the if here */ 04099 04100 if (gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context)) { /* this will link in all the statements here */ 04101 return -1; 04102 } 04103 04104 if (p->u3.else_statements) { 04105 linkprio(exten, if_skip, mother_exten); 04106 if (gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context)) { /* this will link in all the statements here */ 04107 return -1; 04108 } 04109 } 04110 04111 linkprio(exten, if_end, mother_exten); 04112 04113 break; 04114 04115 case PV_RANDOM: 04116 case PV_IF: 04117 control_statement_count++; 04118 snprintf(new_label, BUF_SIZE, "if_%s_%d", label, control_statement_count); 04119 04120 if_test = new_prio(); 04121 if_end = new_prio(); 04122 if_test->type = AEL_IF_CONTROL; 04123 if_end->type = AEL_APPCALL; 04124 if ( p->type == PV_RANDOM ) 04125 snprintf(buf1, BUF_SIZE, "$[${RAND(0,99)} < (%s)]", p->u1.str); 04126 else 04127 snprintf(buf1, BUF_SIZE, "$[%s]", p->u1.str); 04128 if_test->app = 0; 04129 if_test->appargs = strdup(buf1); 04130 snprintf(buf1, BUF_SIZE, "Finish if_%s_%d", label, control_statement_count); 04131 if_end->app = strdup("NoOp"); 04132 if_end->appargs = strdup(buf1); 04133 if_test->origin = p; 04134 04135 if (p->u3.else_statements) { 04136 if_skip = new_prio(); 04137 if_skip->type = AEL_CONTROL1; /* simple goto */ 04138 if_skip->goto_true = if_end; 04139 if_test->goto_false = if_skip;; 04140 } else { 04141 if_skip = 0; 04142 if_test->goto_false = if_end;; 04143 } 04144 04145 /* link & load! */ 04146 linkprio(exten, if_test, mother_exten); 04147 04148 /* now, put the body of the if here */ 04149 04150 if (gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context)) { /* this will link in all the statements here */ 04151 return -1; 04152 } 04153 04154 if (p->u3.else_statements) { 04155 linkprio(exten, if_skip, mother_exten); 04156 if (gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context)) { /* this will link in all the statements here */ 04157 return -1; 04158 } 04159 } 04160 04161 linkprio(exten, if_end, mother_exten); 04162 04163 break; 04164 04165 case PV_STATEMENTBLOCK: 04166 if (gen_prios(exten, label, p->u1.list, mother_exten, this_context)) { /* recurse into the block */ 04167 return -1; 04168 } 04169 break; 04170 04171 case PV_CATCH: 04172 control_statement_count++; 04173 /* generate an extension with name of catch, put all catch stats 04174 into this exten! */ 04175 switch_case = new_exten(); 04176 if (mother_exten && mother_exten->checked_switch) { 04177 switch_case->has_switch = mother_exten->has_switch; 04178 switch_case->checked_switch = mother_exten->checked_switch; 04179 } 04180 if (exten && exten->checked_switch) { 04181 switch_case->has_switch = exten->has_switch; 04182 switch_case->checked_switch = exten->checked_switch; 04183 } 04184 04185 switch_case->context = this_context; 04186 linkexten(exten,switch_case); 04187 switch_case->name = strdup(p->u1.str); 04188 snprintf(new_label, BUF_SIZE, "catch_%s_%d",p->u1.str, control_statement_count); 04189 04190 if (gen_prios(switch_case, new_label, p->u2.statements, mother_exten,this_context)) { /* this will link in all the catch body statements here */ 04191 return -1; 04192 } 04193 if (switch_case->return_needed) { /* returns now generate a Return() app call, no longer a goto to the end of the exten */ 04194 char buf[2000]; 04195 struct ael_priority *np2 = new_prio(); 04196 np2->type = AEL_APPCALL; 04197 np2->app = strdup("NoOp"); 04198 snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); 04199 np2->appargs = strdup(buf); 04200 linkprio(switch_case, np2, mother_exten); 04201 switch_case-> return_target = np2; 04202 } 04203 04204 break; 04205 default: 04206 break; 04207 } 04208 } 04209 free(buf1); 04210 free(buf2); 04211 free(new_label); 04212 return 0; 04213 }
Definition at line 4373 of file pval.c.
References pval::dad, PV_CONTEXT, PV_MACRO, and pval::type.
Referenced by check_goto(), and get_goto_target().
04374 { 04375 while( p && p->type != PV_CONTEXT && p->type != PV_MACRO ) { 04376 04377 p = p->dad; 04378 } 04379 04380 return p; 04381 }
Definition at line 4363 of file pval.c.
References pval::dad, PV_CONTEXT, PV_EXTENSION, PV_MACRO, and pval::type.
Referenced by check_goto(), and get_goto_target().
04364 { 04365 while( p && p->type != PV_EXTENSION && p->type != PV_CONTEXT && p->type != PV_MACRO ) { 04366 04367 p = p->dad; 04368 } 04369 04370 return p; 04371 }
Definition at line 1157 of file pval.c.
References find_context(), find_label_in_current_context(), find_label_in_current_db(), find_label_in_current_extension(), first, get_contxt(), get_extension_or_contxt(), pval::list, pval::next, PV_INCLUDES, pval::statements, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by gen_prios().
01158 { 01159 /* just one item-- the label should be in the current extension */ 01160 pval *curr_ext = get_extension_or_contxt(item); /* containing exten, or macro */ 01161 pval *curr_cont; 01162 01163 if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) { 01164 struct pval *x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), curr_ext); 01165 return x; 01166 } 01167 01168 curr_cont = get_contxt(item); 01169 01170 /* TWO items */ 01171 if (item->u1.list->next && !item->u1.list->next->next) { 01172 if (!strstr((item->u1.list)->u1.str,"${") 01173 && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ { 01174 struct pval *x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, curr_cont); 01175 return x; 01176 } 01177 } 01178 01179 /* All 3 items! */ 01180 if (item->u1.list->next && item->u1.list->next->next) { 01181 /* all three */ 01182 pval *first = item->u1.list; 01183 pval *second = item->u1.list->next; 01184 pval *third = item->u1.list->next->next; 01185 01186 if (!strstr((item->u1.list)->u1.str,"${") 01187 && !strstr(item->u1.list->next->u1.str,"${") 01188 && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ { 01189 struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); 01190 if (!x) { 01191 01192 struct pval *p3; 01193 struct pval *that_context = find_context(item->u1.list->u1.str); 01194 01195 /* the target of the goto could be in an included context!! Fancy that!! */ 01196 /* look for includes in the current context */ 01197 if (that_context) { 01198 for (p3=that_context->u2.statements; p3; p3=p3->next) { 01199 if (p3->type == PV_INCLUDES) { 01200 struct pval *p4; 01201 for (p4=p3->u1.list; p4; p4=p4->next) { 01202 /* for each context pointed to, find it, then find a context/label that matches the 01203 target here! */ 01204 char *incl_context = p4->u1.str; 01205 /* find a matching context name */ 01206 struct pval *that_other_context = find_context(incl_context); 01207 if (that_other_context) { 01208 struct pval *x3; 01209 x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context); 01210 if (x3) { 01211 return x3; 01212 } 01213 } 01214 } 01215 } 01216 } 01217 } 01218 } 01219 return x; 01220 } 01221 } 01222 return 0; 01223 }
Definition at line 1094 of file pval.c.
References pval::dad, PV_CONTEXT, PV_MACRO, and pval::type.
Referenced by check_goto().
01095 { 01096 struct pval *curr; 01097 curr = item; 01098 while( curr ) { 01099 if( curr->type == PV_MACRO || curr->type == PV_CONTEXT ) { 01100 return curr; 01101 } 01102 curr = curr->dad; 01103 } 01104 return 0; 01105 }
Definition at line 1081 of file pval.c.
References pval::dad, PV_MACRO, and pval::type.
Referenced by check_goto().
01082 { 01083 struct pval *curr; 01084 curr = item; 01085 while( curr ) { 01086 if( curr->type == PV_MACRO ) { 01087 return curr; 01088 } 01089 curr = curr->dad; 01090 } 01091 return 0; 01092 }
int is_empty | ( | char * | arg | ) |
int is_float | ( | char * | arg | ) |
int is_int | ( | char * | arg | ) |
static int label_inside_case | ( | pval * | label | ) | [static] |
Definition at line 3015 of file pval.c.
References pval::dad, PV_CASE, PV_CONTEXT, PV_DEFAULT, PV_MACRO, PV_PATTERN, and pval::type.
Referenced by gen_prios().
03016 { 03017 pval *p = label; 03018 03019 while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ { 03020 if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN ) { 03021 return 1; 03022 } 03023 03024 p = p->dad; 03025 } 03026 return 0; 03027 }
static void linkexten | ( | struct ael_extension * | exten, | |
struct ael_extension * | add | |||
) | [static] |
Definition at line 3029 of file pval.c.
References exten, and ael_extension::next_exten.
Referenced by gen_prios().
03030 { 03031 add->next_exten = exten->next_exten; /* this will reverse the order. Big deal. */ 03032 exten->next_exten = add; 03033 }
void linkprio | ( | struct ael_extension * | exten, | |
struct ael_priority * | prio, | |||
struct ael_extension * | mother_exten | |||
) |
Definition at line 2933 of file pval.c.
References ael_priority::appargs, ael_priority::exten, exten, free, ael_extension::has_switch, and malloc.
Referenced by gen_prios().
02934 { 02935 char *p1, *p2; 02936 02937 if (!exten->plist) { 02938 exten->plist = prio; 02939 exten->plist_last = prio; 02940 } else { 02941 exten->plist_last->next = prio; 02942 exten->plist_last = prio; 02943 } 02944 if( !prio->exten ) 02945 prio->exten = exten; /* don't override the switch value */ 02946 /* The following code will cause all priorities within an extension 02947 to have ${EXTEN} or ${EXTEN: replaced with ~~EXTEN~~, which is 02948 set just before the first switch in an exten. The switches 02949 will muck up the original ${EXTEN} value, so we save it away 02950 and the user accesses this copy instead. */ 02951 if (prio->appargs && ((mother_exten && mother_exten->has_switch) || exten->has_switch) ) { 02952 while ((p1 = strstr(prio->appargs, "${EXTEN}"))) { 02953 p2 = malloc(strlen(prio->appargs)+5); 02954 *p1 = 0; 02955 strcpy(p2, prio->appargs); 02956 strcat(p2, "${~~EXTEN~~}"); 02957 if (*(p1+8)) 02958 strcat(p2, p1+8); 02959 free(prio->appargs); 02960 prio->appargs = p2; 02961 } 02962 while ((p1 = strstr(prio->appargs, "${EXTEN:"))) { 02963 p2 = malloc(strlen(prio->appargs)+5); 02964 *p1 = 0; 02965 strcpy(p2, prio->appargs); 02966 strcat(p2, "${~~EXTEN~~:"); 02967 if (*(p1+8)) 02968 strcat(p2, p1+8); 02969 free(prio->appargs); 02970 prio->appargs = p2; 02971 } 02972 } 02973 }
Definition at line 5837 of file pval.c.
References pval::next, pval::prev, and pval::u1_last.
05838 { 05839 if (!head) 05840 return tail; 05841 if (tail) { 05842 if (!head->next) { 05843 head->next = tail; 05844 } else { 05845 head->u1_last->next = tail; 05846 } 05847 head->u1_last = tail; 05848 tail->prev = head; /* the dad link only points to containers */ 05849 } 05850 return head; 05851 }
int localized_pbx_load_module | ( | void | ) |
Definition at line 1808 of file pval.c.
References match_pval_item(), and pval::next.
Referenced by find_context(), find_first_label_in_current_context(), find_label_in_current_context(), find_label_in_current_db(), find_label_in_current_extension(), find_macro(), and match_pval_item().
01809 { 01810 pval *i; 01811 01812 for (i=item; i; i=i->next) { 01813 pval *x; 01814 /* printf(" -- match pval: item %d\n", i->type); */ 01815 01816 if ((x = match_pval_item(i))) { 01817 /* printf("match_pval: returning x=%x\n", (int)x); */ 01818 return x; /* cut the search short */ 01819 } 01820 } 01821 return 0; 01822 }
Definition at line 1560 of file pval.c.
References pval::else_statements, extension_matches(), pval::for_statements, last_matched_label, pval::list, pval::macro_statements, match_pval(), pval::next, PV_CASE, PV_CATCH, PV_CONTEXT, PV_DEFAULT, PV_EXTENSION, PV_FOR, PV_IF, PV_IFTIME, PV_LABEL, PV_MACRO, PV_PATTERN, PV_RANDOM, PV_STATEMENTBLOCK, PV_SWITCH, PV_WHILE, pval::statements, pval::str, pval::type, pval::u1, pval::u2, pval::u3, and pval::u4.
Referenced by match_pval().
01561 { 01562 pval *x; 01563 01564 switch ( item->type ) { 01565 case PV_MACRO: 01566 /* fields: item->u1.str == name of macro 01567 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 01568 item->u2.arglist->u1.str == argument 01569 item->u2.arglist->next == next arg 01570 01571 item->u3.macro_statements == pval list of statements in macro body. 01572 */ 01573 /* printf(" matching in MACRO %s, match_context=%s; retoncontmtch=%d; \n", item->u1.str, match_context, return_on_context_match); */ 01574 if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) { 01575 01576 /* printf("MACRO: match context is: %s\n", match_context); */ 01577 01578 if (return_on_context_match && !strcmp(item->u1.str, match_context)) /* if we're just searching for a context, don't bother descending into them */ { 01579 /* printf("Returning on matching macro %s\n", match_context); */ 01580 return item; 01581 } 01582 01583 01584 if (!return_on_context_match) { 01585 /* printf("Descending into matching macro %s/%s\n", match_context, item->u1.str); */ 01586 if ((x=match_pval(item->u3.macro_statements))) { 01587 /* printf("Responded with pval match %x\n", x); */ 01588 return x; 01589 } 01590 } 01591 } else { 01592 /* printf("Skipping context/macro %s\n", item->u1.str); */ 01593 } 01594 01595 break; 01596 01597 case PV_CONTEXT: 01598 /* fields: item->u1.str == name of context 01599 item->u2.statements == pval list of statements in context body 01600 item->u3.abstract == int 1 if an abstract keyword were present 01601 */ 01602 /* printf(" matching in CONTEXT\n"); */ 01603 if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) { 01604 if (return_on_context_match && !strcmp(item->u1.str, match_context)) { 01605 /* printf("Returning on matching context %s\n", match_context); */ 01606 /* printf("non-CONTEXT: Responded with pval match %x\n", x); */ 01607 return item; 01608 } 01609 01610 if (!return_on_context_match ) { 01611 /* printf("Descending into matching context %s\n", match_context); */ 01612 if ((x=match_pval(item->u2.statements))) /* if we're just searching for a context, don't bother descending into them */ { 01613 /* printf("CONTEXT: Responded with pval match %x\n", x); */ 01614 return x; 01615 } 01616 } 01617 } else { 01618 /* printf("Skipping context/macro %s\n", item->u1.str); */ 01619 } 01620 break; 01621 01622 case PV_CASE: 01623 /* fields: item->u1.str == value of case 01624 item->u2.statements == pval list of statements under the case 01625 */ 01626 /* printf(" matching in CASE\n"); */ 01627 if ((x=match_pval(item->u2.statements))) { 01628 /* printf("CASE: Responded with pval match %x\n", x); */ 01629 return x; 01630 } 01631 break; 01632 01633 case PV_PATTERN: 01634 /* fields: item->u1.str == value of case 01635 item->u2.statements == pval list of statements under the case 01636 */ 01637 /* printf(" matching in PATTERN\n"); */ 01638 if ((x=match_pval(item->u2.statements))) { 01639 /* printf("PATTERN: Responded with pval match %x\n", x); */ 01640 return x; 01641 } 01642 break; 01643 01644 case PV_DEFAULT: 01645 /* fields: 01646 item->u2.statements == pval list of statements under the case 01647 */ 01648 /* printf(" matching in DEFAULT\n"); */ 01649 if ((x=match_pval(item->u2.statements))) { 01650 /* printf("DEFAULT: Responded with pval match %x\n", x); */ 01651 return x; 01652 } 01653 break; 01654 01655 case PV_CATCH: 01656 /* fields: item->u1.str == name of extension to catch 01657 item->u2.statements == pval list of statements in context body 01658 */ 01659 /* printf(" matching in CATCH\n"); */ 01660 if ((x=match_pval(item->u2.statements))) { 01661 /* printf("CATCH: Responded with pval match %x\n", x); */ 01662 return x; 01663 } 01664 break; 01665 01666 case PV_STATEMENTBLOCK: 01667 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 01668 */ 01669 /* printf(" matching in STATEMENTBLOCK\n"); */ 01670 if ((x=match_pval(item->u1.list))) { 01671 /* printf("STATEMENTBLOCK: Responded with pval match %x\n", x); */ 01672 return x; 01673 } 01674 break; 01675 01676 case PV_LABEL: 01677 /* fields: item->u1.str == label name 01678 */ 01679 /* printf("PV_LABEL %s (cont=%s, exten=%s\n", 01680 item->u1.str, current_context->u1.str, (current_extension?current_extension->u1.str:"<macro>"));*/ 01681 01682 if (count_labels) { 01683 if (!strcmp(match_label, item->u1.str)) { 01684 label_count++; 01685 last_matched_label = item; 01686 } 01687 01688 } else { 01689 if (!strcmp(match_label, item->u1.str)) { 01690 /* printf("LABEL: Responded with pval match %x\n", x); */ 01691 return item; 01692 } 01693 } 01694 break; 01695 01696 case PV_FOR: 01697 /* fields: item->u1.for_init == a string containing the initalizer 01698 item->u2.for_test == a string containing the loop test 01699 item->u3.for_inc == a string containing the loop increment 01700 01701 item->u4.for_statements == a pval list of statements in the for () 01702 */ 01703 /* printf(" matching in FOR\n"); */ 01704 if ((x=match_pval(item->u4.for_statements))) { 01705 /* printf("FOR: Responded with pval match %x\n", x);*/ 01706 return x; 01707 } 01708 break; 01709 01710 case PV_WHILE: 01711 /* fields: item->u1.str == the while conditional, as supplied by user 01712 01713 item->u2.statements == a pval list of statements in the while () 01714 */ 01715 /* printf(" matching in WHILE\n"); */ 01716 if ((x=match_pval(item->u2.statements))) { 01717 /* printf("WHILE: Responded with pval match %x\n", x); */ 01718 return x; 01719 } 01720 break; 01721 01722 case PV_RANDOM: 01723 /* fields: item->u1.str == the random number expression, as supplied by user 01724 01725 item->u2.statements == a pval list of statements in the if () 01726 item->u3.else_statements == a pval list of statements in the else 01727 (could be zero) 01728 fall thru to PV_IF */ 01729 01730 case PV_IFTIME: 01731 /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list 01732 01733 item->u2.statements == a pval list of statements in the if () 01734 item->u3.else_statements == a pval list of statements in the else 01735 (could be zero) 01736 fall thru to PV_IF*/ 01737 case PV_IF: 01738 /* fields: item->u1.str == the if conditional, as supplied by user 01739 01740 item->u2.statements == a pval list of statements in the if () 01741 item->u3.else_statements == a pval list of statements in the else 01742 (could be zero) 01743 */ 01744 /* printf(" matching in IF/IFTIME/RANDOM\n"); */ 01745 if ((x=match_pval(item->u2.statements))) { 01746 return x; 01747 } 01748 if (item->u3.else_statements) { 01749 if ((x=match_pval(item->u3.else_statements))) { 01750 /* printf("IF/IFTIME/RANDOM: Responded with pval match %x\n", x); */ 01751 return x; 01752 } 01753 } 01754 break; 01755 01756 case PV_SWITCH: 01757 /* fields: item->u1.str == the switch expression 01758 01759 item->u2.statements == a pval list of statements in the switch, 01760 (will be case statements, most likely!) 01761 */ 01762 /* printf(" matching in SWITCH\n"); */ 01763 if ((x=match_pval(item->u2.statements))) { 01764 /* printf("SWITCH: Responded with pval match %x\n", x); */ 01765 return x; 01766 } 01767 break; 01768 01769 case PV_EXTENSION: 01770 /* fields: item->u1.str == the extension name, label, whatever it's called 01771 01772 item->u2.statements == a pval list of statements in the extension 01773 item->u3.hints == a char * hint argument 01774 item->u4.regexten == an int boolean. non-zero says that regexten was specified 01775 */ 01776 /* printf(" matching in EXTENSION\n"); */ 01777 if (!strcmp(match_exten,"*") || extension_matches(item, match_exten, item->u1.str) ) { 01778 /* printf("Descending into matching exten %s => %s\n", match_exten, item->u1.str); */ 01779 if (strcmp(match_label,"1") == 0) { 01780 if (item->u2.statements) { 01781 struct pval *p5 = item->u2.statements; 01782 while (p5 && p5->type == PV_LABEL) /* find the first non-label statement in this context. If it exists, there's a "1" */ 01783 p5 = p5->next; 01784 if (p5) 01785 return p5; 01786 else 01787 return 0; 01788 } 01789 else 01790 return 0; 01791 } 01792 01793 if ((x=match_pval(item->u2.statements))) { 01794 /* printf("EXTENSION: Responded with pval match %x\n", x); */ 01795 return x; 01796 } 01797 } else { 01798 /* printf("Skipping exten %s\n", item->u1.str); */ 01799 } 01800 break; 01801 default: 01802 /* printf(" matching in default = %d\n", item->type); */ 01803 break; 01804 } 01805 return 0; 01806 }
struct ael_extension* new_exten | ( | void | ) |
Definition at line 2927 of file pval.c.
References calloc.
02928 { 02929 struct ael_extension *x = (struct ael_extension *)calloc(sizeof(struct ael_extension),1); 02930 return x; 02931 }
struct ael_priority* new_prio | ( | void | ) |
Definition at line 2921 of file pval.c.
References calloc.
02922 { 02923 struct ael_priority *x = (struct ael_priority *)calloc(sizeof(struct ael_priority),1); 02924 return x; 02925 }
static void print_pval | ( | FILE * | fin, | |
pval * | item, | |||
int | depth | |||
) | [static] |
Definition at line 114 of file pval.c.
References pval::arglist, pval::next, PV_MACRO, PV_WORD, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by print_pval_list().
00115 { 00116 int i; 00117 pval *lp; 00118 00119 for (i=0; i<depth; i++) { 00120 fprintf(fin, "\t"); /* depth == indentation */ 00121 } 00122 00123 switch ( item->type ) { 00124 case PV_WORD: 00125 fprintf(fin,"%s;\n", item->u1.str); /* usually, words are encapsulated in something else */ 00126 break; 00127 00128 case PV_MACRO: 00129 fprintf(fin,"macro %s(", item->u1.str); 00130 for (lp=item->u2.arglist; lp; lp=lp->next) { 00131 if (lp != item->u2.arglist ) 00132 fprintf(fin,", "); 00133 fprintf(fin,"%s", lp->u1.str); 00134 } 00135 fprintf(fin,") {\n"); 00136 print_pval_list(fin,item->u3.macro_statements,depth+1); 00137 for (i=0; i<depth; i++) { 00138 fprintf(fin,"\t"); /* depth == indentation */ 00139 } 00140 fprintf(fin,"};\n\n"); 00141 break; 00142 00143 case PV_CONTEXT: 00144 if ( item->u3.abstract ) 00145 fprintf(fin,"abstract context %s {\n", item->u1.str); 00146 else 00147 fprintf(fin,"context %s {\n", item->u1.str); 00148 print_pval_list(fin,item->u2.statements,depth+1); 00149 for (i=0; i<depth; i++) { 00150 fprintf(fin,"\t"); /* depth == indentation */ 00151 } 00152 fprintf(fin,"};\n\n"); 00153 break; 00154 00155 case PV_MACRO_CALL: 00156 fprintf(fin,"&%s(", item->u1.str); 00157 for (lp=item->u2.arglist; lp; lp=lp->next) { 00158 if ( lp != item->u2.arglist ) 00159 fprintf(fin,", "); 00160 fprintf(fin,"%s", lp->u1.str); 00161 } 00162 fprintf(fin,");\n"); 00163 break; 00164 00165 case PV_APPLICATION_CALL: 00166 fprintf(fin,"%s(", item->u1.str); 00167 for (lp=item->u2.arglist; lp; lp=lp->next) { 00168 if ( lp != item->u2.arglist ) 00169 fprintf(fin,","); 00170 fprintf(fin,"%s", lp->u1.str); 00171 } 00172 fprintf(fin,");\n"); 00173 break; 00174 00175 case PV_CASE: 00176 fprintf(fin,"case %s:\n", item->u1.str); 00177 print_pval_list(fin,item->u2.statements, depth+1); 00178 break; 00179 00180 case PV_PATTERN: 00181 fprintf(fin,"pattern %s:\n", item->u1.str); 00182 print_pval_list(fin,item->u2.statements, depth+1); 00183 break; 00184 00185 case PV_DEFAULT: 00186 fprintf(fin,"default:\n"); 00187 print_pval_list(fin,item->u2.statements, depth+1); 00188 break; 00189 00190 case PV_CATCH: 00191 fprintf(fin,"catch %s {\n", item->u1.str); 00192 print_pval_list(fin,item->u2.statements, depth+1); 00193 for (i=0; i<depth; i++) { 00194 fprintf(fin,"\t"); /* depth == indentation */ 00195 } 00196 fprintf(fin,"};\n"); 00197 break; 00198 00199 case PV_SWITCHES: 00200 fprintf(fin,"switches {\n"); 00201 print_pval_list(fin,item->u1.list,depth+1); 00202 for (i=0; i<depth; i++) { 00203 fprintf(fin,"\t"); /* depth == indentation */ 00204 } 00205 fprintf(fin,"};\n"); 00206 break; 00207 00208 case PV_ESWITCHES: 00209 fprintf(fin,"eswitches {\n"); 00210 print_pval_list(fin,item->u1.list,depth+1); 00211 for (i=0; i<depth; i++) { 00212 fprintf(fin,"\t"); /* depth == indentation */ 00213 } 00214 fprintf(fin,"};\n"); 00215 break; 00216 00217 case PV_INCLUDES: 00218 fprintf(fin,"includes {\n"); 00219 for (lp=item->u1.list; lp; lp=lp->next) { 00220 for (i=0; i<depth+1; i++) { 00221 fprintf(fin,"\t"); /* depth == indentation */ 00222 } 00223 fprintf(fin,"%s", lp->u1.str); /* usually, words are encapsulated in something else */ 00224 if (lp->u2.arglist) 00225 fprintf(fin,"|%s|%s|%s|%s", 00226 lp->u2.arglist->u1.str, 00227 lp->u2.arglist->next->u1.str, 00228 lp->u2.arglist->next->next->u1.str, 00229 lp->u2.arglist->next->next->next->u1.str 00230 ); 00231 fprintf(fin,";\n"); /* usually, words are encapsulated in something else */ 00232 } 00233 00234 for (i=0; i<depth; i++) { 00235 fprintf(fin,"\t"); /* depth == indentation */ 00236 } 00237 fprintf(fin,"};\n"); 00238 break; 00239 00240 case PV_STATEMENTBLOCK: 00241 fprintf(fin,"{\n"); 00242 print_pval_list(fin,item->u1.list, depth+1); 00243 for (i=0; i<depth; i++) { 00244 fprintf(fin,"\t"); /* depth == indentation */ 00245 } 00246 fprintf(fin,"}\n"); 00247 break; 00248 00249 case PV_VARDEC: 00250 fprintf(fin,"%s=%s;\n", item->u1.str, item->u2.val); 00251 break; 00252 00253 case PV_LOCALVARDEC: 00254 fprintf(fin,"local %s=%s;\n", item->u1.str, item->u2.val); 00255 break; 00256 00257 case PV_GOTO: 00258 fprintf(fin,"goto %s", item->u1.list->u1.str); 00259 if ( item->u1.list->next ) 00260 fprintf(fin,",%s", item->u1.list->next->u1.str); 00261 if ( item->u1.list->next && item->u1.list->next->next ) 00262 fprintf(fin,",%s", item->u1.list->next->next->u1.str); 00263 fprintf(fin,"\n"); 00264 break; 00265 00266 case PV_LABEL: 00267 fprintf(fin,"%s:\n", item->u1.str); 00268 break; 00269 00270 case PV_FOR: 00271 fprintf(fin,"for (%s; %s; %s)\n", item->u1.for_init, item->u2.for_test, item->u3.for_inc); 00272 print_pval_list(fin,item->u4.for_statements,depth+1); 00273 break; 00274 00275 case PV_WHILE: 00276 fprintf(fin,"while (%s)\n", item->u1.str); 00277 print_pval_list(fin,item->u2.statements,depth+1); 00278 break; 00279 00280 case PV_BREAK: 00281 fprintf(fin,"break;\n"); 00282 break; 00283 00284 case PV_RETURN: 00285 fprintf(fin,"return;\n"); 00286 break; 00287 00288 case PV_CONTINUE: 00289 fprintf(fin,"continue;\n"); 00290 break; 00291 00292 case PV_RANDOM: 00293 case PV_IFTIME: 00294 case PV_IF: 00295 if ( item->type == PV_IFTIME ) { 00296 00297 fprintf(fin,"ifTime ( %s|%s|%s|%s )\n", 00298 item->u1.list->u1.str, 00299 item->u1.list->next->u1.str, 00300 item->u1.list->next->next->u1.str, 00301 item->u1.list->next->next->next->u1.str 00302 ); 00303 } else if ( item->type == PV_RANDOM ) { 00304 fprintf(fin,"random ( %s )\n", item->u1.str ); 00305 } else 00306 fprintf(fin,"if ( %s )\n", item->u1.str); 00307 if ( item->u2.statements && item->u2.statements->next ) { 00308 for (i=0; i<depth; i++) { 00309 fprintf(fin,"\t"); /* depth == indentation */ 00310 } 00311 fprintf(fin,"{\n"); 00312 print_pval_list(fin,item->u2.statements,depth+1); 00313 for (i=0; i<depth; i++) { 00314 fprintf(fin,"\t"); /* depth == indentation */ 00315 } 00316 if ( item->u3.else_statements ) 00317 fprintf(fin,"}\n"); 00318 else 00319 fprintf(fin,"};\n"); 00320 } else if (item->u2.statements ) { 00321 print_pval_list(fin,item->u2.statements,depth+1); 00322 } else { 00323 if (item->u3.else_statements ) 00324 fprintf(fin, " {} "); 00325 else 00326 fprintf(fin, " {}; "); 00327 } 00328 if ( item->u3.else_statements ) { 00329 for (i=0; i<depth; i++) { 00330 fprintf(fin,"\t"); /* depth == indentation */ 00331 } 00332 fprintf(fin,"else\n"); 00333 print_pval_list(fin,item->u3.else_statements, depth); 00334 } 00335 break; 00336 00337 case PV_SWITCH: 00338 fprintf(fin,"switch( %s ) {\n", item->u1.str); 00339 print_pval_list(fin,item->u2.statements,depth+1); 00340 for (i=0; i<depth; i++) { 00341 fprintf(fin,"\t"); /* depth == indentation */ 00342 } 00343 fprintf(fin,"}\n"); 00344 break; 00345 00346 case PV_EXTENSION: 00347 if ( item->u4.regexten ) 00348 fprintf(fin, "regexten "); 00349 if ( item->u3.hints ) 00350 fprintf(fin,"hints(%s) ", item->u3.hints); 00351 00352 fprintf(fin,"%s => ", item->u1.str); 00353 print_pval_list(fin,item->u2.statements,depth+1); 00354 fprintf(fin,"\n"); 00355 break; 00356 00357 case PV_IGNOREPAT: 00358 fprintf(fin,"ignorepat => %s;\n", item->u1.str); 00359 break; 00360 00361 case PV_GLOBALS: 00362 fprintf(fin,"globals {\n"); 00363 print_pval_list(fin,item->u1.statements,depth+1); 00364 for (i=0; i<depth; i++) { 00365 fprintf(fin,"\t"); /* depth == indentation */ 00366 } 00367 fprintf(fin,"}\n"); 00368 break; 00369 } 00370 }
static void print_pval_list | ( | FILE * | fin, | |
pval * | item, | |||
int | depth | |||
) | [static] |
Definition at line 372 of file pval.c.
References pval::next, and print_pval().
Referenced by ael2_print().
00373 { 00374 pval *i; 00375 00376 for (i=item; i; i=i->next) { 00377 print_pval(fin, i, depth); 00378 } 00379 }
Definition at line 5215 of file pval.c.
References pval::arglist, linku1(), PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.
05216 { 05217 if (!pvalCheckType(p, "pvalAppCallAddArg", PV_APPLICATION_CALL)) 05218 return; 05219 if (!p->u2.arglist) 05220 p->u2.arglist = arg; 05221 else 05222 linku1(p->u2.arglist, arg); 05223 }
char* pvalAppCallGetAppName | ( | pval * | p | ) |
Definition at line 5201 of file pval.c.
References PV_APPLICATION_CALL, pvalCheckType(), pval::str, and pval::u1.
05202 { 05203 if (!pvalCheckType(p, "pvalAppCallGetAppName", PV_APPLICATION_CALL)) 05204 return 0; 05205 return p->u1.str; 05206 }
void pvalAppCallSetAppName | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5194 of file pval.c.
References PV_APPLICATION_CALL, pvalCheckType(), pval::str, and pval::u1.
05195 { 05196 if (!pvalCheckType(p, "pvalAppCallSetAppName", PV_APPLICATION_CALL)) 05197 return; 05198 p->u1.str = name; 05199 }
Definition at line 5208 of file pval.c.
References pval::arglist, PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.
05209 { 05210 if (!pvalCheckType(p, "pvalAppCallSetArglist", PV_APPLICATION_CALL)) 05211 return; 05212 p->u2.arglist = arglist; 05213 }
Definition at line 5225 of file pval.c.
References pval::arglist, args, PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.
05226 { 05227 if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL)) 05228 return 0; 05229 if (!(*args)) 05230 *args = p->u2.arglist; 05231 else { 05232 *args = (*args)->next; 05233 } 05234 return *args; 05235 }
Definition at line 5250 of file pval.c.
References pval::arglist, linku1(), pval::statements, and pval::u2.
05251 { 05252 if (!p->u2.arglist) 05253 p->u2.statements = statement; 05254 else 05255 linku1(p->u2.statements, statement); 05256 }
Definition at line 5258 of file pval.c.
References pval::next, pval::statements, and pval::u2.
05259 { 05260 if (!(*statement)) 05261 *statement = p->u2.statements; 05262 else { 05263 *statement = (*statement)->next; 05264 } 05265 return *statement; 05266 }
char* pvalCasePatGetVal | ( | pval * | p | ) |
void pvalCasePatSetVal | ( | pval * | p, | |
char * | val | |||
) |
Definition at line 5238 of file pval.c.
References PV_APPLICATION_CALL, pvalCheckType(), pval::str, and pval::u1.
05239 { 05240 if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL)) 05241 return; 05242 p->u1.str = val; 05243 }
char* pvalCatchGetExtName | ( | pval * | p | ) |
Definition at line 5276 of file pval.c.
References PV_CATCH, pvalCheckType(), pval::str, and pval::u1.
05277 { 05278 if (!pvalCheckType(p, "pvalCatchGetExtName", PV_CATCH)) 05279 return 0; 05280 return p->u1.str; 05281 }
Definition at line 5290 of file pval.c.
References PV_CATCH, pvalCheckType(), pval::statements, and pval::u2.
05291 { 05292 if (!pvalCheckType(p, "pvalCatchGetStatement", PV_CATCH)) 05293 return 0; 05294 return p->u2.statements; 05295 }
void pvalCatchSetExtName | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5283 of file pval.c.
References PV_CATCH, pvalCheckType(), pval::statements, and pval::u2.
05284 { 05285 if (!pvalCheckType(p, "pvalCatchSetStatement", PV_CATCH)) 05286 return; 05287 p->u2.statements = statement; 05288 }
Definition at line 4981 of file pval.c.
References ast_log(), LOG_ERROR, and pval::type.
Referenced by pvalAppCallAddArg(), pvalAppCallGetAppName(), pvalAppCallSetAppName(), pvalAppCallSetArglist(), pvalAppCallWalkArgs(), pvalCasePatSetVal(), pvalCatchGetExtName(), pvalCatchGetStatement(), pvalCatchSetExtName(), pvalCatchSetStatement(), pvalContextAddStatement(), pvalContextGetAbstract(), pvalContextGetName(), pvalContextSetAbstract(), pvalContextSetName(), pvalContextUnsetAbstract(), pvalContextWalkStatements(), pvalESwitchesAddSwitch(), pvalESwitchesWalkNames(), pvalExtenGetHints(), pvalExtenGetName(), pvalExtenGetRegexten(), pvalExtenGetStatement(), pvalExtenSetHints(), pvalExtenSetName(), pvalExtenSetRegexten(), pvalExtenSetStatement(), pvalExtenUnSetRegexten(), pvalForGetInc(), pvalForGetInit(), pvalForGetStatement(), pvalForGetTest(), pvalForSetInc(), pvalForSetInit(), pvalForSetStatement(), pvalForSetTest(), pvalGlobalsWalkStatements(), pvalGotoGetTarget(), pvalGotoSetTarget(), pvalIfGetCondition(), pvalIfSetCondition(), pvalIfTimeGetCondition(), pvalIfTimeSetCondition(), pvalIgnorePatGetPattern(), pvalIgnorePatSetPattern(), pvalIncludeGetTimeConstraints(), pvalIncludesAddInclude(), pvalIncludesAddIncludeWithTimeConstraints(), pvalIncludesWalk(), pvalLabelGetName(), pvalLabelSetName(), pvalMacroAddArg(), pvalMacroAddStatement(), pvalMacroCallAddArg(), pvalMacroCallGetMacroName(), pvalMacroCallSetArglist(), pvalMacroCallSetMacroName(), pvalMacroCallWalkArgs(), pvalMacroGetName(), pvalMacroSetArglist(), pvalMacroSetName(), pvalMacroWalkArgs(), pvalMacroWalkStatements(), pvalRandomGetCondition(), pvalRandomSetCondition(), pvalStatementBlockAddStatement(), pvalStatementBlockWalkStatements(), pvalSwitchAddCase(), pvalSwitchesAddSwitch(), pvalSwitchesWalkNames(), pvalSwitchGetTestexpr(), pvalSwitchSetTestexpr(), pvalSwitchWalkCases(), pvalVarDecGetValue(), pvalVarDecGetVarname(), pvalVarDecSetValue(), pvalVarDecSetVarname(), pvalWordGetString(), and pvalWordSetString().
04982 { 04983 if (p->type != type) 04984 { 04985 ast_log(LOG_ERROR, "Func: %s the pval passed is not appropriate for this function!\n", funcname); 04986 return 0; 04987 } 04988 return 1; 04989 }
Definition at line 5666 of file pval.c.
References pval::else_statements, and pval::u3.
05667 { 05668 return p->u3.else_statements; 05669 }
Definition at line 5661 of file pval.c.
References pval::statements, and pval::u2.
05662 { 05663 return p->u2.statements; 05664 }
Definition at line 5656 of file pval.c.
References pval::else_statements, and pval::u3.
05657 { 05658 p->u3.else_statements = statement; 05659 }
Definition at line 5651 of file pval.c.
References pval::statements, and pval::u2.
05652 { 05653 p->u2.statements = statement; 05654 }
Definition at line 5127 of file pval.c.
References linku1(), PV_CONTEXT, pvalCheckType(), pval::statements, and pval::u2.
05128 { 05129 if (!pvalCheckType(p, "pvalContextAddStatement", PV_CONTEXT)) 05130 return; 05131 if (!p->u2.statements) 05132 p->u2.statements = statement; 05133 else 05134 linku1(p->u2.statements, statement); 05135 }
int pvalContextGetAbstract | ( | pval * | p | ) |
Definition at line 5118 of file pval.c.
References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.
05119 { 05120 if (!pvalCheckType(p, "pvalContextGetAbstract", PV_CONTEXT)) 05121 return 0; 05122 return p->u3.abstract; 05123 }
char* pvalContextGetName | ( | pval * | p | ) |
Definition at line 5097 of file pval.c.
References PV_CONTEXT, pvalCheckType(), pval::str, and pval::u1.
05098 { 05099 if (!pvalCheckType(p, "pvalContextGetName", PV_CONTEXT)) 05100 return 0; 05101 return p->u1.str; 05102 }
void pvalContextSetAbstract | ( | pval * | p | ) |
Definition at line 5104 of file pval.c.
References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.
05105 { 05106 if (!pvalCheckType(p, "pvalContextSetAbstract", PV_CONTEXT)) 05107 return; 05108 p->u3.abstract = 1; 05109 }
void pvalContextSetName | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5090 of file pval.c.
References PV_CONTEXT, pvalCheckType(), pval::str, and pval::u1.
05091 { 05092 if (!pvalCheckType(p, "pvalContextSetName", PV_CONTEXT)) 05093 return; 05094 p->u1.str = name; 05095 }
void pvalContextUnsetAbstract | ( | pval * | p | ) |
Definition at line 5111 of file pval.c.
References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.
05112 { 05113 if (!pvalCheckType(p, "pvalContextUnsetAbstract", PV_CONTEXT)) 05114 return; 05115 p->u3.abstract = 0; 05116 }
Definition at line 5137 of file pval.c.
References pval::next, PV_CONTEXT, pvalCheckType(), pval::statements, and pval::u2.
05138 { 05139 if (!pvalCheckType(p, "pvalContextWalkStatements", PV_CONTEXT)) 05140 return 0; 05141 if (!(*statements)) 05142 *statements = p->u2.statements; 05143 else { 05144 *statements = (*statements)->next; 05145 } 05146 return *statements; 05147 }
Definition at line 4992 of file pval.c.
References calloc, and pval::type.
Referenced by pvalESwitchesAddSwitch(), pvalGotoSetTarget(), pvalIfTimeSetCondition(), pvalIncludesAddInclude(), pvalIncludesAddIncludeWithTimeConstraints(), and pvalSwitchesAddSwitch().
04993 { 04994 pval *p = calloc(1,sizeof(pval)); /* why, oh why, don't I use ast_calloc? Way, way, way too messy if I do! */ 04995 p->type = type; /* remember, this can be used externally or internally to asterisk */ 04996 return p; 04997 }
void pvalESwitchesAddSwitch | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5320 of file pval.c.
References linku1(), pval::list, PV_ESWITCHES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05321 { 05322 pval *s; 05323 if (!pvalCheckType(p, "pvalESwitchesAddSwitch", PV_ESWITCHES)) 05324 return; 05325 s = pvalCreateNode(PV_WORD); 05326 s->u1.str = name; 05327 p->u1.list = linku1(p->u1.list, s); 05328 }
Definition at line 5330 of file pval.c.
References pval::list, next_item(), PV_ESWITCHES, pvalCheckType(), and pval::u1.
05331 { 05332 if (!pvalCheckType(p, "pvalESwitchesWalkNames", PV_ESWITCHES)) 05333 return 0; 05334 if (!(*next_item)) 05335 *next_item = p->u1.list; 05336 else { 05337 *next_item = (*next_item)->next; 05338 } 05339 return (*next_item)->u1.str; 05340 }
char* pvalExtenGetHints | ( | pval * | p | ) |
Definition at line 5752 of file pval.c.
References pval::hints, PV_EXTENSION, pvalCheckType(), and pval::u3.
05753 { 05754 if (!pvalCheckType(p, "pvalExtenGetHints", PV_EXTENSION)) 05755 return 0; 05756 return p->u3.hints; 05757 }
char* pvalExtenGetName | ( | pval * | p | ) |
Definition at line 5717 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::str, and pval::u1.
05718 { 05719 if (!pvalCheckType(p, "pvalExtenGetName", PV_EXTENSION)) 05720 return 0; 05721 return p->u1.str; 05722 }
int pvalExtenGetRegexten | ( | pval * | p | ) |
Definition at line 5738 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.
05739 { 05740 if (!pvalCheckType(p, "pvalExtenGetRegexten", PV_EXTENSION)) 05741 return 0; 05742 return p->u4.regexten; 05743 }
Definition at line 5766 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::statements, and pval::u2.
05767 { 05768 if (!pvalCheckType(p, "pvalExtenGetStatement", PV_EXTENSION)) 05769 return 0; 05770 return p->u2.statements; 05771 }
void pvalExtenSetHints | ( | pval * | p, | |
char * | hints | |||
) |
Definition at line 5745 of file pval.c.
References pval::hints, PV_EXTENSION, pvalCheckType(), and pval::u3.
05746 { 05747 if (!pvalCheckType(p, "pvalExtenSetHints", PV_EXTENSION)) 05748 return; 05749 p->u3.hints = hints; 05750 }
void pvalExtenSetName | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5710 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::str, and pval::u1.
05711 { 05712 if (!pvalCheckType(p, "pvalExtenSetName", PV_EXTENSION)) 05713 return; 05714 p->u1.str = name; 05715 }
void pvalExtenSetRegexten | ( | pval * | p | ) |
Definition at line 5724 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.
05725 { 05726 if (!pvalCheckType(p, "pvalExtenSetRegexten", PV_EXTENSION)) 05727 return; 05728 p->u4.regexten = 1; 05729 }
Definition at line 5759 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::statements, and pval::u2.
05760 { 05761 if (!pvalCheckType(p, "pvalExtenSetStatement", PV_EXTENSION)) 05762 return; 05763 p->u2.statements = statement; 05764 }
void pvalExtenUnSetRegexten | ( | pval * | p | ) |
Definition at line 5731 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.
05732 { 05733 if (!pvalCheckType(p, "pvalExtenUnSetRegexten", PV_EXTENSION)) 05734 return; 05735 p->u4.regexten = 0; 05736 }
char* pvalForGetInc | ( | pval * | p | ) |
Definition at line 5578 of file pval.c.
References pval::for_inc, PV_FOR, pvalCheckType(), and pval::u3.
05579 { 05580 if (!pvalCheckType(p, "pvalForGetInc", PV_FOR)) 05581 return 0; 05582 return p->u3.for_inc; 05583 }
char* pvalForGetInit | ( | pval * | p | ) |
Definition at line 5564 of file pval.c.
References pval::for_init, PV_FOR, pvalCheckType(), and pval::u1.
05565 { 05566 if (!pvalCheckType(p, "pvalForGetInit", PV_FOR)) 05567 return 0; 05568 return p->u1.for_init; 05569 }
Definition at line 5585 of file pval.c.
References pval::for_statements, PV_FOR, pvalCheckType(), and pval::u4.
05586 { 05587 if (!pvalCheckType(p, "pvalForGetStatement", PV_FOR)) 05588 return 0; 05589 return p->u4.for_statements; 05590 }
char* pvalForGetTest | ( | pval * | p | ) |
Definition at line 5571 of file pval.c.
References pval::for_test, PV_FOR, pvalCheckType(), and pval::u2.
05572 { 05573 if (!pvalCheckType(p, "pvalForGetTest", PV_FOR)) 05574 return 0; 05575 return p->u2.for_test; 05576 }
void pvalForSetInc | ( | pval * | p, | |
char * | inc | |||
) |
Definition at line 5550 of file pval.c.
References pval::for_inc, PV_FOR, pvalCheckType(), and pval::u3.
05551 { 05552 if (!pvalCheckType(p, "pvalForSetInc", PV_FOR)) 05553 return; 05554 p->u3.for_inc = inc; 05555 }
void pvalForSetInit | ( | pval * | p, | |
char * | init | |||
) |
Definition at line 5536 of file pval.c.
References pval::for_init, PV_FOR, pvalCheckType(), and pval::u1.
05537 { 05538 if (!pvalCheckType(p, "pvalForSetInit", PV_FOR)) 05539 return; 05540 p->u1.for_init = init; 05541 }
Definition at line 5557 of file pval.c.
References pval::for_statements, PV_FOR, pvalCheckType(), and pval::u4.
05558 { 05559 if (!pvalCheckType(p, "pvalForSetStatement", PV_FOR)) 05560 return; 05561 p->u4.for_statements = statement; 05562 }
void pvalForSetTest | ( | pval * | p, | |
char * | test | |||
) |
Definition at line 5543 of file pval.c.
References pval::for_test, PV_FOR, pvalCheckType(), and pval::u2.
05544 { 05545 if (!pvalCheckType(p, "pvalForSetTest", PV_FOR)) 05546 return; 05547 p->u2.for_test = test; 05548 }
Definition at line 5789 of file pval.c.
References ast_log(), linku1(), LOG_ERROR, PV_GLOBALS, pval::statements, pval::type, and pval::u1.
05790 { 05791 if (p->type != PV_GLOBALS) { 05792 ast_log(LOG_ERROR, "pvalGlobalsAddStatement called where first arg is not a Globals!\n"); 05793 } else { 05794 if (!p->u1.statements) { 05795 p->u1.statements = statement; 05796 } else { 05797 p->u1.statements = linku1(p->u1.statements,statement); 05798 } 05799 } 05800 }
Definition at line 5802 of file pval.c.
References pval::next, PV_GLOBALS, and pvalCheckType().
05803 { 05804 if (!pvalCheckType(p, "pvalGlobalsWalkStatements", PV_GLOBALS)) 05805 return 0; 05806 if (!next_statement) { 05807 *next_statement = p; 05808 return p; 05809 } else { 05810 *next_statement = (*next_statement)->next; 05811 return (*next_statement)->next; 05812 } 05813 }
void pvalGotoGetTarget | ( | pval * | p, | |
char ** | context, | |||
char ** | exten, | |||
char ** | label | |||
) |
Definition at line 5494 of file pval.c.
References pval::list, pval::next, PV_GOTO, pvalCheckType(), pval::str, and pval::u1.
05495 { 05496 if (!pvalCheckType(p, "pvalGotoGetTarget", PV_GOTO)) 05497 return; 05498 if (p->u1.list && p->u1.list->next && p->u1.list->next->next) { 05499 *context = p->u1.list->u1.str; 05500 *exten = p->u1.list->next->u1.str; 05501 *label = p->u1.list->next->next->u1.str; 05502 05503 } else if (p->u1.list && p->u1.list->next ) { 05504 *exten = p->u1.list->u1.str; 05505 *label = p->u1.list->next->u1.str; 05506 *context = 0; 05507 05508 } else if (p->u1.list) { 05509 *label = p->u1.list->u1.str; 05510 *context = 0; 05511 *exten = 0; 05512 05513 } else { 05514 *context = 0; 05515 *exten = 0; 05516 *label = 0; 05517 } 05518 }
void pvalGotoSetTarget | ( | pval * | p, | |
char * | context, | |||
char * | exten, | |||
char * | label | |||
) |
Definition at line 5458 of file pval.c.
References ext, pval::list, pval::next, PV_GOTO, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05459 { 05460 pval *con, *ext, *pri; 05461 05462 if (!pvalCheckType(p, "pvalGotoSetTarget", PV_GOTO)) 05463 return; 05464 if (context && strlen(context)) { 05465 con = pvalCreateNode(PV_WORD); 05466 ext = pvalCreateNode(PV_WORD); 05467 pri = pvalCreateNode(PV_WORD); 05468 05469 con->u1.str = context; 05470 ext->u1.str = exten; 05471 pri->u1.str = label; 05472 05473 con->next = ext; 05474 ext->next = pri; 05475 p->u1.list = con; 05476 } else if (exten && strlen(exten)) { 05477 ext = pvalCreateNode(PV_WORD); 05478 pri = pvalCreateNode(PV_WORD); 05479 05480 ext->u1.str = exten; 05481 pri->u1.str = label; 05482 05483 ext->next = pri; 05484 p->u1.list = ext; 05485 } else { 05486 pri = pvalCreateNode(PV_WORD); 05487 05488 pri->u1.str = label; 05489 05490 p->u1.list = pri; 05491 } 05492 }
char* pvalIfGetCondition | ( | pval * | p | ) |
Definition at line 5601 of file pval.c.
References PV_IFTIME, pvalCheckType(), pval::str, and pval::u1.
05602 { 05603 if (!pvalCheckType(p, "pvalIfGetCondition", PV_IFTIME)) 05604 return 0; 05605 return p->u1.str; 05606 }
void pvalIfSetCondition | ( | pval * | p, | |
char * | expr | |||
) |
Definition at line 5594 of file pval.c.
References PV_IF, pvalCheckType(), pval::str, and pval::u1.
05595 { 05596 if (!pvalCheckType(p, "pvalIfSetCondition", PV_IF)) 05597 return; 05598 p->u1.str = expr; 05599 }
void pvalIfTimeGetCondition | ( | pval * | p, | |
char ** | hour_range, | |||
char ** | dow_range, | |||
char ** | dom_range, | |||
char ** | month_range | |||
) |
Definition at line 5627 of file pval.c.
References pval::list, pval::next, PV_IFTIME, pvalCheckType(), pval::str, and pval::u1.
05628 { 05629 if (!pvalCheckType(p, "pvalIfTimeGetCondition", PV_IFTIME)) 05630 return; 05631 *hour_range = p->u1.list->u1.str; 05632 *dow_range = p->u1.list->next->u1.str; 05633 *dom_range = p->u1.list->next->next->u1.str; 05634 *month_range = p->u1.list->next->next->next->u1.str; 05635 }
void pvalIfTimeSetCondition | ( | pval * | p, | |
char * | hour_range, | |||
char * | dow_range, | |||
char * | dom_range, | |||
char * | mon_range | |||
) |
Definition at line 5608 of file pval.c.
References pval::list, pval::next, PV_IFTIME, PV_WORD, pvalCheckType(), pvalCreateNode(), pvalWordSetString(), and pval::u1.
05608 : 24-hour format begin-end|dow range|dom range|month range */ 05609 { 05610 pval *hr = pvalCreateNode(PV_WORD); 05611 pval *dow = pvalCreateNode(PV_WORD); 05612 pval *dom = pvalCreateNode(PV_WORD); 05613 pval *mon = pvalCreateNode(PV_WORD); 05614 if (!pvalCheckType(p, "pvalIfTimeSetCondition", PV_IFTIME)) 05615 return; 05616 pvalWordSetString(hr, hour_range); 05617 pvalWordSetString(dow, dow_range); 05618 pvalWordSetString(dom, dom_range); 05619 pvalWordSetString(mon, mon_range); 05620 dom->next = mon; 05621 dow->next = dom; 05622 hr->next = dow; 05623 p->u1.list = hr; 05624 }
char* pvalIgnorePatGetPattern | ( | pval * | p | ) |
Definition at line 5781 of file pval.c.
References PV_IGNOREPAT, pvalCheckType(), pval::str, and pval::u1.
05782 { 05783 if (!pvalCheckType(p, "pvalIgnorePatGetPattern", PV_IGNOREPAT)) 05784 return 0; 05785 return p->u1.str; 05786 }
void pvalIgnorePatSetPattern | ( | pval * | p, | |
char * | pat | |||
) |
Definition at line 5774 of file pval.c.
References PV_IGNOREPAT, pvalCheckType(), pval::str, and pval::u1.
05775 { 05776 if (!pvalCheckType(p, "pvalIgnorePatSetPattern", PV_IGNOREPAT)) 05777 return; 05778 p->u1.str = pat; 05779 }
void pvalIncludeGetTimeConstraints | ( | pval * | p, | |
char ** | hour_range, | |||
char ** | dom_range, | |||
char ** | dow_range, | |||
char ** | month_range | |||
) |
Definition at line 5381 of file pval.c.
References pval::arglist, pval::next, PV_WORD, pvalCheckType(), pval::str, pval::u1, and pval::u2.
05382 { 05383 if (!pvalCheckType(p, "pvalIncludeGetTimeConstraints", PV_WORD)) 05384 return; 05385 if (p->u2.arglist) { 05386 *hour_range = p->u2.arglist->u1.str; 05387 *dom_range = p->u2.arglist->next->u1.str; 05388 *dow_range = p->u2.arglist->next->next->u1.str; 05389 *month_range = p->u2.arglist->next->next->next->u1.str; 05390 } else { 05391 *hour_range = 0; 05392 *dom_range = 0; 05393 *dow_range = 0; 05394 *month_range = 0; 05395 } 05396 }
void pvalIncludesAddInclude | ( | pval * | p, | |
const char * | include | |||
) |
Definition at line 5343 of file pval.c.
References linku1(), pval::list, PV_INCLUDES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05344 { 05345 pval *s; 05346 if (!pvalCheckType(p, "pvalIncludesAddSwitch", PV_INCLUDES)) 05347 return; 05348 s = pvalCreateNode(PV_WORD); 05349 s->u1.str = (char *)include; 05350 p->u1.list = linku1(p->u1.list, s); 05351 }
void pvalIncludesAddIncludeWithTimeConstraints | ( | pval * | p, | |
const char * | include, | |||
char * | hour_range, | |||
char * | dom_range, | |||
char * | dow_range, | |||
char * | month_range | |||
) |
Definition at line 5354 of file pval.c.
References pval::arglist, linku1(), pval::list, pval::next, PV_INCLUDES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, pval::u1, and pval::u2.
05355 { 05356 pval *hr = pvalCreateNode(PV_WORD); 05357 pval *dom = pvalCreateNode(PV_WORD); 05358 pval *dow = pvalCreateNode(PV_WORD); 05359 pval *mon = pvalCreateNode(PV_WORD); 05360 pval *s = pvalCreateNode(PV_WORD); 05361 05362 if (!pvalCheckType(p, "pvalIncludeAddIncludeWithTimeConstraints", PV_INCLUDES)) 05363 return; 05364 05365 s->u1.str = (char *)include; 05366 p->u1.list = linku1(p->u1.list, s); 05367 05368 hr->u1.str = hour_range; 05369 dom->u1.str = dom_range; 05370 dow->u1.str = dow_range; 05371 mon->u1.str = month_range; 05372 05373 s->u2.arglist = hr; 05374 05375 hr->next = dom; 05376 dom->next = dow; 05377 dow->next = mon; 05378 mon->next = 0; 05379 }
Definition at line 5398 of file pval.c.
References pval::list, next_item(), PV_INCLUDES, pvalCheckType(), and pval::u1.
05399 { 05400 if (!pvalCheckType(p, "pvalIncludesWalk", PV_INCLUDES)) 05401 return 0; 05402 if (!(*next_item)) 05403 *next_item = p->u1.list; 05404 else { 05405 *next_item = (*next_item)->next; 05406 } 05407 return (*next_item)->u1.str; 05408 }
char* pvalLabelGetName | ( | pval * | p | ) |
Definition at line 5528 of file pval.c.
References PV_LABEL, pvalCheckType(), pval::str, and pval::u1.
05529 { 05530 if (!pvalCheckType(p, "pvalLabelGetName", PV_LABEL)) 05531 return 0; 05532 return p->u1.str; 05533 }
void pvalLabelSetName | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5041 of file pval.c.
References pval::arglist, linku1(), PV_MACRO, pvalCheckType(), and pval::u2.
05042 { 05043 if (!pvalCheckType(p, "pvalMacroAddArg", PV_MACRO)) 05044 return; 05045 if (!p->u2.arglist) 05046 p->u2.arglist = arg; 05047 else 05048 linku1(p->u2.arglist, arg); 05049 05050 }
Definition at line 5064 of file pval.c.
References linku1(), pval::macro_statements, PV_MACRO, pvalCheckType(), and pval::u3.
05065 { 05066 if (!pvalCheckType(p, "pvalMacroAddStatement", PV_MACRO)) 05067 return; 05068 if (!p->u3.macro_statements) 05069 p->u3.macro_statements = statement; 05070 else 05071 linku1(p->u3.macro_statements, statement); 05072 05073 05074 }
Definition at line 5171 of file pval.c.
References pval::arglist, linku1(), PV_MACRO_CALL, pvalCheckType(), and pval::u2.
05172 { 05173 if (!pvalCheckType(p, "pvalMacroCallGetAddArg", PV_MACRO_CALL)) 05174 return; 05175 if (!p->u2.arglist) 05176 p->u2.arglist = arg; 05177 else 05178 linku1(p->u2.arglist, arg); 05179 }
char* pvalMacroCallGetMacroName | ( | pval * | p | ) |
Definition at line 5157 of file pval.c.
References PV_MACRO_CALL, pvalCheckType(), pval::str, and pval::u1.
05158 { 05159 if (!pvalCheckType(p, "pvalMacroCallGetMacroName", PV_MACRO_CALL)) 05160 return 0; 05161 return p->u1.str; 05162 }
Definition at line 5164 of file pval.c.
References pval::arglist, PV_MACRO_CALL, pvalCheckType(), and pval::u2.
05165 { 05166 if (!pvalCheckType(p, "pvalMacroCallSetArglist", PV_MACRO_CALL)) 05167 return; 05168 p->u2.arglist = arglist; 05169 }
void pvalMacroCallSetMacroName | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5150 of file pval.c.
References PV_MACRO_CALL, pvalCheckType(), pval::str, and pval::u1.
05151 { 05152 if (!pvalCheckType(p, "pvalMacroCallSetMacroName", PV_MACRO_CALL)) 05153 return; 05154 p->u1.str = name; 05155 }
Definition at line 5181 of file pval.c.
References pval::arglist, args, PV_MACRO_CALL, pvalCheckType(), and pval::u2.
05182 { 05183 if (!pvalCheckType(p, "pvalMacroCallWalkArgs", PV_MACRO_CALL)) 05184 return 0; 05185 if (!(*args)) 05186 *args = p->u2.arglist; 05187 else { 05188 *args = (*args)->next; 05189 } 05190 return *args; 05191 }
char* pvalMacroGetName | ( | pval * | p | ) |
Definition at line 5027 of file pval.c.
References PV_MACRO, pvalCheckType(), pval::str, and pval::u1.
05028 { 05029 if (!pvalCheckType(p, "pvalMacroGetName", PV_MACRO)) 05030 return 0; 05031 return p->u1.str; 05032 }
Definition at line 5034 of file pval.c.
References pval::arglist, PV_MACRO, pvalCheckType(), and pval::u2.
05035 { 05036 if (!pvalCheckType(p, "pvalMacroSetArglist", PV_MACRO)) 05037 return; 05038 p->u2.arglist = arglist; 05039 }
void pvalMacroSetName | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5052 of file pval.c.
References pval::arglist, pval::next, PV_MACRO, pvalCheckType(), and pval::u2.
05053 { 05054 if (!pvalCheckType(p, "pvalMacroWalkArgs", PV_MACRO)) 05055 return 0; 05056 if (!(*arg)) 05057 *arg = p->u2.arglist; 05058 else { 05059 *arg = (*arg)->next; 05060 } 05061 return *arg; 05062 }
Definition at line 5076 of file pval.c.
References pval::macro_statements, pval::next, PV_MACRO, pvalCheckType(), and pval::u3.
05077 { 05078 if (!pvalCheckType(p, "pvalMacroWalkStatements", PV_MACRO)) 05079 return 0; 05080 if (!(*next_statement)) 05081 *next_statement = p->u3.macro_statements; 05082 else { 05083 *next_statement = (*next_statement)->next; 05084 } 05085 return *next_statement; 05086 }
char* pvalRandomGetCondition | ( | pval * | p | ) |
Definition at line 5644 of file pval.c.
References PV_RANDOM, pvalCheckType(), pval::str, and pval::u1.
05645 { 05646 if (!pvalCheckType(p, "pvalRandomGetCondition", PV_RANDOM)) 05647 return 0; 05648 return p->u1.str; 05649 }
void pvalRandomSetCondition | ( | pval * | p, | |
char * | percent | |||
) |
Definition at line 5637 of file pval.c.
References PV_RANDOM, pvalCheckType(), pval::str, and pval::u1.
05638 { 05639 if (!pvalCheckType(p, "pvalRandomSetCondition", PV_RANDOM)) 05640 return; 05641 p->u1.str = percent; 05642 }
Definition at line 5411 of file pval.c.
References linku1(), pval::list, PV_STATEMENTBLOCK, pvalCheckType(), and pval::u1.
05412 { 05413 if (!pvalCheckType(p, "pvalStatementBlockAddStatement", PV_STATEMENTBLOCK)) 05414 return; 05415 p->u1.list = linku1(p->u1.list, statement); 05416 }
Definition at line 5418 of file pval.c.
References pval::list, pval::next, PV_STATEMENTBLOCK, pvalCheckType(), and pval::u1.
05419 { 05420 if (!pvalCheckType(p, "pvalStatementBlockWalkStatements", PV_STATEMENTBLOCK)) 05421 return 0; 05422 if (!(*next_statement)) 05423 *next_statement = p->u1.list; 05424 else { 05425 *next_statement = (*next_statement)->next; 05426 } 05427 return *next_statement; 05428 }
Definition at line 5685 of file pval.c.
References linku1(), PV_CASE, PV_SWITCH, pvalCheckType(), pval::statements, and pval::u2.
05686 { 05687 if (!pvalCheckType(p, "pvalSwitchAddCase", PV_SWITCH)) 05688 return; 05689 if (!pvalCheckType(Case, "pvalSwitchAddCase", PV_CASE)) 05690 return; 05691 if (!p->u2.statements) 05692 p->u2.statements = Case; 05693 else 05694 linku1(p->u2.statements, Case); 05695 }
void pvalSwitchesAddSwitch | ( | pval * | p, | |
char * | name | |||
) |
Definition at line 5298 of file pval.c.
References linku1(), pval::list, PV_SWITCHES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05299 { 05300 pval *s; 05301 if (!pvalCheckType(p, "pvalSwitchesAddSwitch", PV_SWITCHES)) 05302 return; 05303 s = pvalCreateNode(PV_WORD); 05304 s->u1.str = name; 05305 p->u1.list = linku1(p->u1.list, s); 05306 }
Definition at line 5308 of file pval.c.
References pval::list, next_item(), PV_SWITCHES, pvalCheckType(), and pval::u1.
05309 { 05310 if (!pvalCheckType(p, "pvalSwitchesWalkNames", PV_SWITCHES)) 05311 return 0; 05312 if (!(*next_item)) 05313 *next_item = p->u1.list; 05314 else { 05315 *next_item = (*next_item)->next; 05316 } 05317 return (*next_item)->u1.str; 05318 }
char* pvalSwitchGetTestexpr | ( | pval * | p | ) |
Definition at line 5678 of file pval.c.
References PV_SWITCH, pvalCheckType(), pval::str, and pval::u1.
05679 { 05680 if (!pvalCheckType(p, "pvalSwitchGetTestexpr", PV_SWITCH)) 05681 return 0; 05682 return p->u1.str; 05683 }
void pvalSwitchSetTestexpr | ( | pval * | p, | |
char * | expr | |||
) |
Definition at line 5671 of file pval.c.
References PV_SWITCH, pvalCheckType(), pval::str, and pval::u1.
05672 { 05673 if (!pvalCheckType(p, "pvalSwitchSetTestexpr", PV_SWITCH)) 05674 return; 05675 p->u1.str = expr; 05676 }
Definition at line 5697 of file pval.c.
References pval::next, PV_SWITCH, pvalCheckType(), pval::statements, and pval::u2.
05698 { 05699 if (!pvalCheckType(p, "pvalSwitchWalkCases", PV_SWITCH)) 05700 return 0; 05701 if (!(*next_case)) 05702 *next_case = p->u2.statements; 05703 else { 05704 *next_case = (*next_case)->next; 05705 } 05706 return *next_case; 05707 }
Definition at line 5825 of file pval.c.
References pval::next.
05826 { 05827 if (!next_obj) { 05828 *next_obj = p; 05829 return p; 05830 } else { 05831 *next_obj = (*next_obj)->next; 05832 return (*next_obj)->next; 05833 } 05834 }
char* pvalVarDecGetValue | ( | pval * | p | ) |
Definition at line 5451 of file pval.c.
References PV_VARDEC, pvalCheckType(), pval::u2, and pval::val.
05452 { 05453 if (!pvalCheckType(p, "pvalVarDecGetValue", PV_VARDEC)) 05454 return 0; 05455 return p->u2.val; 05456 }
char* pvalVarDecGetVarname | ( | pval * | p | ) |
Definition at line 5444 of file pval.c.
References PV_VARDEC, pvalCheckType(), pval::str, and pval::u1.
05445 { 05446 if (!pvalCheckType(p, "pvalVarDecGetVarname", PV_VARDEC)) 05447 return 0; 05448 return p->u1.str; 05449 }
void pvalVarDecSetValue | ( | pval * | p, | |
char * | value | |||
) |
void pvalVarDecSetVarname | ( | pval * | p, | |
char * | name | |||
) |
char* pvalWordGetString | ( | pval * | p | ) |
Definition at line 5012 of file pval.c.
References PV_WORD, pvalCheckType(), pval::str, and pval::u1.
05013 { 05014 if (!pvalCheckType(p, "pvalWordGetString", PV_WORD)) 05015 return 0; 05016 return p->u1.str; 05017 }
void pvalWordSetString | ( | pval * | p, | |
char * | str | |||
) |
Definition at line 5005 of file pval.c.
References PV_WORD, pvalCheckType(), pval::str, and pval::u1.
Referenced by pvalIfTimeSetCondition().
05006 { 05007 if (!pvalCheckType(p, "pvalWordSetString", PV_WORD)) 05008 return; 05009 p->u1.str = str; 05010 }
static void remove_spaces_before_equals | ( | char * | str | ) | [static] |
Definition at line 3035 of file pval.c.
Referenced by gen_prios().
03036 { 03037 char *p; 03038 while( str && *str && *str != '=' ) 03039 { 03040 if( *str == ' ' || *str == '\n' || *str == '\r' || *str == '\t' ) 03041 { 03042 p = str; 03043 while( *p ) 03044 { 03045 *p = *(p+1); 03046 p++; 03047 } 03048 } 03049 else 03050 str++; 03051 } 03052 }
void set_priorities | ( | struct ael_extension * | exten | ) |
Definition at line 4215 of file pval.c.
References exten, ael_priority::next, ael_priority::origin, ael_priority::priority_num, PV_LABEL, and pval::type.
04216 { 04217 int i; 04218 struct ael_priority *pr; 04219 do { 04220 if (exten->is_switch) 04221 i = 10; 04222 else if (exten->regexten) 04223 i=2; 04224 else 04225 i=1; 04226 04227 for (pr=exten->plist; pr; pr=pr->next) { 04228 pr->priority_num = i; 04229 04230 if (!pr->origin || (pr->origin && pr->origin->type != PV_LABEL) ) /* Labels don't show up in the dialplan, 04231 but we want them to point to the right 04232 priority, which would be the next line 04233 after the label; */ 04234 i++; 04235 } 04236 04237 exten = exten->next_exten; 04238 } while ( exten ); 04239 }
void traverse_pval_item_template | ( | pval * | item, | |
int | depth | |||
) |
Definition at line 399 of file pval.c.
References pval::arglist, pval::else_statements, pval::for_statements, pval::list, pval::macro_statements, pval::next, PV_APPLICATION_CALL, PV_BREAK, PV_CASE, PV_CATCH, PV_CONTEXT, PV_CONTINUE, PV_DEFAULT, PV_ESWITCHES, PV_EXTENSION, PV_FOR, PV_GLOBALS, PV_GOTO, PV_IF, PV_IFTIME, PV_IGNOREPAT, PV_INCLUDES, PV_LABEL, PV_LOCALVARDEC, PV_MACRO, PV_MACRO_CALL, PV_PATTERN, PV_RANDOM, PV_RETURN, PV_STATEMENTBLOCK, PV_SWITCH, PV_SWITCHES, PV_VARDEC, PV_WHILE, PV_WORD, pval::statements, pval::type, pval::u1, pval::u2, pval::u3, and pval::u4.
Referenced by traverse_pval_template().
00401 { 00402 pval *lp; 00403 00404 switch ( item->type ) { 00405 case PV_WORD: 00406 /* fields: item->u1.str == string associated with this (word). */ 00407 break; 00408 00409 case PV_MACRO: 00410 /* fields: item->u1.str == name of macro 00411 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 00412 item->u2.arglist->u1.str == argument 00413 item->u2.arglist->next == next arg 00414 00415 item->u3.macro_statements == pval list of statements in macro body. 00416 */ 00417 for (lp=item->u2.arglist; lp; lp=lp->next) { 00418 00419 } 00420 traverse_pval_item_template(item->u3.macro_statements,depth+1); 00421 break; 00422 00423 case PV_CONTEXT: 00424 /* fields: item->u1.str == name of context 00425 item->u2.statements == pval list of statements in context body 00426 item->u3.abstract == int 1 if an abstract keyword were present 00427 */ 00428 traverse_pval_item_template(item->u2.statements,depth+1); 00429 break; 00430 00431 case PV_MACRO_CALL: 00432 /* fields: item->u1.str == name of macro to call 00433 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 00434 item->u2.arglist->u1.str == argument 00435 item->u2.arglist->next == next arg 00436 */ 00437 for (lp=item->u2.arglist; lp; lp=lp->next) { 00438 } 00439 break; 00440 00441 case PV_APPLICATION_CALL: 00442 /* fields: item->u1.str == name of application to call 00443 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 00444 item->u2.arglist->u1.str == argument 00445 item->u2.arglist->next == next arg 00446 */ 00447 for (lp=item->u2.arglist; lp; lp=lp->next) { 00448 } 00449 break; 00450 00451 case PV_CASE: 00452 /* fields: item->u1.str == value of case 00453 item->u2.statements == pval list of statements under the case 00454 */ 00455 traverse_pval_item_template(item->u2.statements,depth+1); 00456 break; 00457 00458 case PV_PATTERN: 00459 /* fields: item->u1.str == value of case 00460 item->u2.statements == pval list of statements under the case 00461 */ 00462 traverse_pval_item_template(item->u2.statements,depth+1); 00463 break; 00464 00465 case PV_DEFAULT: 00466 /* fields: 00467 item->u2.statements == pval list of statements under the case 00468 */ 00469 traverse_pval_item_template(item->u2.statements,depth+1); 00470 break; 00471 00472 case PV_CATCH: 00473 /* fields: item->u1.str == name of extension to catch 00474 item->u2.statements == pval list of statements in context body 00475 */ 00476 traverse_pval_item_template(item->u2.statements,depth+1); 00477 break; 00478 00479 case PV_SWITCHES: 00480 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 00481 */ 00482 traverse_pval_item_template(item->u1.list,depth+1); 00483 break; 00484 00485 case PV_ESWITCHES: 00486 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 00487 */ 00488 traverse_pval_item_template(item->u1.list,depth+1); 00489 break; 00490 00491 case PV_INCLUDES: 00492 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 00493 item->u2.arglist == pval list of 4 PV_WORD elements for time values 00494 */ 00495 traverse_pval_item_template(item->u1.list,depth+1); 00496 traverse_pval_item_template(item->u2.arglist,depth+1); 00497 break; 00498 00499 case PV_STATEMENTBLOCK: 00500 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 00501 */ 00502 traverse_pval_item_template(item->u1.list,depth+1); 00503 break; 00504 00505 case PV_LOCALVARDEC: 00506 case PV_VARDEC: 00507 /* fields: item->u1.str == variable name 00508 item->u2.val == variable value to assign 00509 */ 00510 break; 00511 00512 case PV_GOTO: 00513 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 00514 item->u1.list->u1.str == where the data on a PV_WORD will always be. 00515 */ 00516 00517 if ( item->u1.list->next ) 00518 ; 00519 if ( item->u1.list->next && item->u1.list->next->next ) 00520 ; 00521 00522 break; 00523 00524 case PV_LABEL: 00525 /* fields: item->u1.str == label name 00526 */ 00527 break; 00528 00529 case PV_FOR: 00530 /* fields: item->u1.for_init == a string containing the initalizer 00531 item->u2.for_test == a string containing the loop test 00532 item->u3.for_inc == a string containing the loop increment 00533 00534 item->u4.for_statements == a pval list of statements in the for () 00535 */ 00536 traverse_pval_item_template(item->u4.for_statements,depth+1); 00537 break; 00538 00539 case PV_WHILE: 00540 /* fields: item->u1.str == the while conditional, as supplied by user 00541 00542 item->u2.statements == a pval list of statements in the while () 00543 */ 00544 traverse_pval_item_template(item->u2.statements,depth+1); 00545 break; 00546 00547 case PV_BREAK: 00548 /* fields: none 00549 */ 00550 break; 00551 00552 case PV_RETURN: 00553 /* fields: none 00554 */ 00555 break; 00556 00557 case PV_CONTINUE: 00558 /* fields: none 00559 */ 00560 break; 00561 00562 case PV_IFTIME: 00563 /* fields: item->u1.list == there are 4 linked PV_WORDs here. 00564 00565 item->u2.statements == a pval list of statements in the if () 00566 item->u3.else_statements == a pval list of statements in the else 00567 (could be zero) 00568 */ 00569 traverse_pval_item_template(item->u2.statements,depth+1); 00570 if ( item->u3.else_statements ) { 00571 traverse_pval_item_template(item->u3.else_statements,depth+1); 00572 } 00573 break; 00574 00575 case PV_RANDOM: 00576 /* fields: item->u1.str == the random number expression, as supplied by user 00577 00578 item->u2.statements == a pval list of statements in the if () 00579 item->u3.else_statements == a pval list of statements in the else 00580 (could be zero) 00581 */ 00582 traverse_pval_item_template(item->u2.statements,depth+1); 00583 if ( item->u3.else_statements ) { 00584 traverse_pval_item_template(item->u3.else_statements,depth+1); 00585 } 00586 break; 00587 00588 case PV_IF: 00589 /* fields: item->u1.str == the if conditional, as supplied by user 00590 00591 item->u2.statements == a pval list of statements in the if () 00592 item->u3.else_statements == a pval list of statements in the else 00593 (could be zero) 00594 */ 00595 traverse_pval_item_template(item->u2.statements,depth+1); 00596 if ( item->u3.else_statements ) { 00597 traverse_pval_item_template(item->u3.else_statements,depth+1); 00598 } 00599 break; 00600 00601 case PV_SWITCH: 00602 /* fields: item->u1.str == the switch expression 00603 00604 item->u2.statements == a pval list of statements in the switch, 00605 (will be case statements, most likely!) 00606 */ 00607 traverse_pval_item_template(item->u2.statements,depth+1); 00608 break; 00609 00610 case PV_EXTENSION: 00611 /* fields: item->u1.str == the extension name, label, whatever it's called 00612 00613 item->u2.statements == a pval list of statements in the extension 00614 item->u3.hints == a char * hint argument 00615 item->u4.regexten == an int boolean. non-zero says that regexten was specified 00616 */ 00617 traverse_pval_item_template(item->u2.statements,depth+1); 00618 break; 00619 00620 case PV_IGNOREPAT: 00621 /* fields: item->u1.str == the ignorepat data 00622 */ 00623 break; 00624 00625 case PV_GLOBALS: 00626 /* fields: item->u1.statements == pval list of statements, usually vardecs 00627 */ 00628 traverse_pval_item_template(item->u1.statements,depth+1); 00629 break; 00630 } 00631 }
void traverse_pval_template | ( | pval * | item, | |
int | depth | |||
) |
Definition at line 633 of file pval.c.
References pval::next, and traverse_pval_item_template().
00635 { 00636 pval *i; 00637 00638 for (i=item; i; i=i->next) { 00639 traverse_pval_item_template(i, depth); 00640 } 00641 }
int control_statement_count = 0 [static] |
int count_labels [static] |
pval* current_context [static] |
pval* current_db [static] |
Definition at line 71 of file pval.c.
Referenced by ael2_semantic_check(), check_abstract_reference(), check_context_names(), find_context(), find_label_in_current_db(), and find_macro().
pval* current_extension [static] |
int errs [static] |
char expr_output[2096] [static] |
int in_abstract_context [static] |
int label_count [static] |
pval* last_matched_label [static] |
const char* match_context [static] |
const char* match_exten [static] |
const char* match_label [static] |
int return_on_context_match [static] |