Compile symbolic Asterisk Extension Logic into Asterisk extensions, version 2. More...
#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.
Compile symbolic Asterisk Extension Logic into Asterisk extensions, version 2.
Definition in file pval.c.
| void add_extensions | ( | struct ael_extension * | exten | ) |
Definition at line 4207 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, ael_priority::appargs, ast_add_extension2(), ast_free_ptr(), ast_log(), AST_MAX_EXTENSION, ael_extension::cidmatch, ael_extension::context, pval::else_statements, ael_priority::exten, ael_priority::goto_false, ael_priority::goto_true, ael_extension::hints, last, LOG_WARNING, ael_extension::name, ael_priority::next, ael_extension::next_exten, ael_priority::origin, pbx_substitute_variables_helper(), ael_extension::plist, PRIORITY_HINT, ael_priority::priority_num, PV_IFTIME, PV_SWITCH, pval::str, strdup, pval::type, ael_priority::type, pval::u1, and pval::u3.
Referenced by ast_compile_ael2().
04208 { 04209 struct ael_priority *pr; 04210 char *label=0; 04211 char realext[AST_MAX_EXTENSION]; 04212 if (!exten) { 04213 ast_log(LOG_WARNING, "This file is Empty!\n" ); 04214 return; 04215 } 04216 do { 04217 struct ael_priority *last = 0; 04218 04219 pbx_substitute_variables_helper(NULL, exten->name, realext, sizeof(realext) - 1); 04220 if (exten->hints) { 04221 if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, PRIORITY_HINT, NULL, exten->cidmatch, 04222 exten->hints, NULL, ast_free_ptr, registrar)) { 04223 ast_log(LOG_WARNING, "Unable to add step at priority 'hint' of extension '%s'\n", 04224 exten->name); 04225 } 04226 } 04227 04228 for (pr=exten->plist; pr; pr=pr->next) { 04229 char app[2000]; 04230 char appargs[2000]; 04231 04232 /* before we can add the extension, we need to prep the app/appargs; 04233 the CONTROL types need to be done after the priority numbers are calculated. 04234 */ 04235 if (pr->type == AEL_LABEL) /* don't try to put labels in the dialplan! */ { 04236 last = pr; 04237 continue; 04238 } 04239 04240 if (pr->app) 04241 strcpy(app, pr->app); 04242 else 04243 app[0] = 0; 04244 if (pr->appargs ) 04245 strcpy(appargs, pr->appargs); 04246 else 04247 appargs[0] = 0; 04248 switch( pr->type ) { 04249 case AEL_APPCALL: 04250 /* easy case. Everything is all set up */ 04251 break; 04252 04253 case AEL_CONTROL1: /* FOR loop, WHILE loop, BREAK, CONTINUE, IF, IFTIME */ 04254 /* simple, unconditional goto. */ 04255 strcpy(app,"Goto"); 04256 if (pr->goto_true->origin && pr->goto_true->origin->type == PV_SWITCH ) { 04257 snprintf(appargs,sizeof(appargs),"%s,%d", pr->goto_true->exten->name, pr->goto_true->priority_num); 04258 } else if (pr->goto_true->origin && pr->goto_true->origin->type == PV_IFTIME && pr->goto_true->origin->u3.else_statements ) { 04259 snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num+1); 04260 } else 04261 snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num); 04262 break; 04263 04264 case AEL_FOR_CONTROL: /* WHILE loop test, FOR loop test */ 04265 strcpy(app,"GotoIf"); 04266 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num); 04267 break; 04268 04269 case AEL_IF_CONTROL: 04270 strcpy(app,"GotoIf"); 04271 if (pr->origin->u3.else_statements ) 04272 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num+1); 04273 else 04274 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num); 04275 break; 04276 04277 case AEL_RAND_CONTROL: 04278 strcpy(app,"Random"); 04279 snprintf(appargs,sizeof(appargs),"%s:%d", pr->appargs, pr->goto_true->priority_num+1); 04280 break; 04281 04282 case AEL_IFTIME_CONTROL: 04283 strcpy(app,"GotoIfTime"); 04284 snprintf(appargs,sizeof(appargs),"%s?%d", pr->appargs, pr->priority_num+2); 04285 break; 04286 04287 case AEL_RETURN: 04288 strcpy(app,"Return"); 04289 appargs[0] = 0; 04290 break; 04291 04292 default: 04293 break; 04294 } 04295 if (last && last->type == AEL_LABEL ) { 04296 label = last->origin->u1.str; 04297 } 04298 else 04299 label = 0; 04300 04301 if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, pr->priority_num, (label?label:NULL), exten->cidmatch, 04302 app, strdup(appargs), ast_free_ptr, registrar)) { 04303 ast_log(LOG_WARNING, "Unable to add step at priority '%d' of extension '%s'\n", pr->priority_num, 04304 exten->name); 04305 } 04306 last = pr; 04307 } 04308 exten = exten->next_exten; 04309 } while ( exten ); 04310 }
| void ael2_print | ( | char * | fname, | |
| pval * | tree | |||
| ) |
Definition at line 380 of file pval.c.
References ast_log(), LOG_ERROR, and print_pval_list().
00381 { 00382 FILE *fin = fopen(fname,"w"); 00383 if ( !fin ) { 00384 ast_log(LOG_ERROR, "Couldn't open %s for writing.\n", fname); 00385 return; 00386 } 00387 print_pval_list(fin, tree, 0); 00388 fclose(fin); 00389 }
| 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(), and check_pval().
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 }
| void ast_compile_ael2 | ( | struct ast_context ** | local_contexts, | |
| struct ast_hashtab * | local_table, | |||
| struct pval * | root | |||
| ) |
Definition at line 4393 of file pval.c.
References add_extensions(), AEL_APPCALL, AEL_LABEL, ael_priority::app, ael_priority::appargs, pval::arglist, ast_compat_app_set, ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), attach_exten(), buf, buf2, ael_extension::cidmatch, ael_extension::context, context, destroy_extensions(), exten, fix_gotos_in_extensions(), gen_prios(), ael_extension::hints, pval::hints, linkprio(), pval::list, pval::macro_statements, ael_extension::name, new_exten(), new_prio(), pval::next, ael_priority::origin, pbx_builtin_setvar(), ael_extension::plist_last, PV_CONTEXT, PV_ESWITCHES, PV_EXTENSION, PV_GLOBALS, PV_IGNOREPAT, PV_INCLUDES, PV_MACRO, PV_SWITCHES, pval::regexten, ael_extension::regexten, remove_spaces_before_equals(), ael_extension::return_needed, set_priorities(), pval::statements, pval::str, strdup, ael_priority::type, pval::type, pval::u1, pval::u2, pval::u3, pval::u4, and pval::val.
Referenced by pbx_load_module().
04394 { 04395 pval *p,*p2; 04396 struct ast_context *context; 04397 char buf[2000]; 04398 struct ael_extension *exten; 04399 struct ael_extension *exten_list = 0; 04400 04401 for (p=root; p; p=p->next ) { /* do the globals first, so they'll be there 04402 when we try to eval them */ 04403 switch (p->type) { 04404 case PV_GLOBALS: 04405 /* just VARDEC elements */ 04406 for (p2=p->u1.list; p2; p2=p2->next) { 04407 char buf2[2000]; 04408 snprintf(buf2,sizeof(buf2),"%s=%s", p2->u1.str, p2->u2.val); 04409 pbx_builtin_setvar(NULL, buf2); 04410 } 04411 break; 04412 default: 04413 break; 04414 } 04415 } 04416 04417 for (p=root; p; p=p->next ) { 04418 pval *lp; 04419 int argc; 04420 04421 switch (p->type) { 04422 case PV_MACRO: 04423 04424 context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar); 04425 04426 exten = new_exten(); 04427 exten->context = context; 04428 exten->name = strdup("s"); 04429 argc = 1; 04430 for (lp=p->u2.arglist; lp; lp=lp->next) { 04431 /* for each arg, set up a "Set" command */ 04432 struct ael_priority *np2 = new_prio(); 04433 np2->type = AEL_APPCALL; 04434 if (!ast_compat_app_set) { 04435 np2->app = strdup("MSet"); 04436 } else { 04437 np2->app = strdup("Set"); 04438 } 04439 snprintf(buf,sizeof(buf),"LOCAL(%s)=${ARG%d}", lp->u1.str, argc++); 04440 remove_spaces_before_equals(buf); 04441 np2->appargs = strdup(buf); 04442 linkprio(exten, np2, NULL); 04443 } 04444 04445 /* CONTAINS APPCALLS, CATCH, just like extensions... */ 04446 gen_prios(exten, p->u1.str, p->u3.macro_statements, 0, context ); 04447 if (exten->return_needed) { /* most likely, this will go away */ 04448 struct ael_priority *np2 = new_prio(); 04449 np2->type = AEL_APPCALL; 04450 np2->app = strdup("NoOp"); 04451 snprintf(buf,sizeof(buf),"End of Macro %s-%s",p->u1.str, exten->name); 04452 np2->appargs = strdup(buf); 04453 linkprio(exten, np2, NULL); 04454 exten-> return_target = np2; 04455 } 04456 04457 set_priorities(exten); 04458 attach_exten(&exten_list, exten); 04459 break; 04460 04461 case PV_GLOBALS: 04462 /* already done */ 04463 break; 04464 04465 case PV_CONTEXT: 04466 context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar); 04467 04468 /* contexts contain: ignorepat, includes, switches, eswitches, extensions, */ 04469 for (p2=p->u2.statements; p2; p2=p2->next) { 04470 pval *p3; 04471 char *s3; 04472 04473 switch (p2->type) { 04474 case PV_EXTENSION: 04475 exten = new_exten(); 04476 exten->name = strdup(p2->u1.str); 04477 exten->context = context; 04478 04479 if( (s3=strchr(exten->name, '/') ) != 0 ) 04480 { 04481 *s3 = 0; 04482 exten->cidmatch = s3+1; 04483 } 04484 04485 if ( p2->u3.hints ) 04486 exten->hints = strdup(p2->u3.hints); 04487 exten->regexten = p2->u4.regexten; 04488 gen_prios(exten, p->u1.str, p2->u2.statements, 0, context ); 04489 if (exten->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 04490 struct ael_priority *np2 = new_prio(); 04491 np2->type = AEL_APPCALL; 04492 np2->app = strdup("NoOp"); 04493 snprintf(buf,sizeof(buf),"End of Extension %s", exten->name); 04494 np2->appargs = strdup(buf); 04495 linkprio(exten, np2, NULL); 04496 exten-> return_target = np2; 04497 } 04498 /* is the last priority in the extension a label? Then add a trailing no-op */ 04499 if ( exten->plist_last && exten->plist_last->type == AEL_LABEL ) { 04500 struct ael_priority *np2 = new_prio(); 04501 np2->type = AEL_APPCALL; 04502 np2->app = strdup("NoOp"); 04503 snprintf(buf,sizeof(buf),"A NoOp to follow a trailing label %s", exten->plist_last->origin->u1.str); 04504 np2->appargs = strdup(buf); 04505 linkprio(exten, np2, NULL); 04506 } 04507 04508 set_priorities(exten); 04509 attach_exten(&exten_list, exten); 04510 break; 04511 04512 case PV_IGNOREPAT: 04513 ast_context_add_ignorepat2(context, p2->u1.str, registrar); 04514 break; 04515 04516 case PV_INCLUDES: 04517 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04518 if ( p3->u2.arglist ) { 04519 snprintf(buf,sizeof(buf), "%s,%s,%s,%s,%s", 04520 p3->u1.str, 04521 p3->u2.arglist->u1.str, 04522 p3->u2.arglist->next->u1.str, 04523 p3->u2.arglist->next->next->u1.str, 04524 p3->u2.arglist->next->next->next->u1.str); 04525 ast_context_add_include2(context, buf, registrar); 04526 } else 04527 ast_context_add_include2(context, p3->u1.str, registrar); 04528 } 04529 break; 04530 04531 case PV_SWITCHES: 04532 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04533 char *c = strchr(p3->u1.str, '/'); 04534 if (c) { 04535 *c = '\0'; 04536 c++; 04537 } else 04538 c = ""; 04539 04540 ast_context_add_switch2(context, p3->u1.str, c, 0, registrar); 04541 } 04542 break; 04543 04544 case PV_ESWITCHES: 04545 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04546 char *c = strchr(p3->u1.str, '/'); 04547 if (c) { 04548 *c = '\0'; 04549 c++; 04550 } else 04551 c = ""; 04552 04553 ast_context_add_switch2(context, p3->u1.str, c, 1, registrar); 04554 } 04555 break; 04556 default: 04557 break; 04558 } 04559 } 04560 04561 break; 04562 04563 default: 04564 /* huh? what? */ 04565 break; 04566 04567 } 04568 } 04569 /* moved these from being done after a macro or extension were processed, 04570 to after all processing is done, for the sake of fixing gotos to labels inside cases... */ 04571 /* I guess this would be considered 2nd pass of compiler now... */ 04572 fix_gotos_in_extensions(exten_list); /* find and fix extension ref in gotos to labels that are in case statements */ 04573 add_extensions(exten_list); /* actually makes calls to create priorities in ast_contexts -- feeds dialplan to asterisk */ 04574 destroy_extensions(exten_list); /* all that remains is an empty husk, discard of it as is proper */ 04575 04576 }
| static void attach_exten | ( | struct ael_extension ** | list, | |
| struct ael_extension * | newmem | |||
| ) | [static] |
Definition at line 4312 of file pval.c.
References ael_extension::next_exten.
Referenced by ast_compile_ael2().
04313 { 04314 /* travel to the end of the list... */ 04315 struct ael_extension *lptr; 04316 if( !*list ) { 04317 *list = newmem; 04318 return; 04319 } 04320 lptr = *list; 04321 04322 while( lptr->next_exten ) { 04323 lptr = lptr->next_exten; 04324 } 04325 /* lptr should now pointing to the last element in the list; it has a null next_exten pointer */ 04326 lptr->next_exten = newmem; 04327 }
| static void check_abstract_reference | ( | pval * | abstract_context | ) | [static] |
Definition at line 2325 of file pval.c.
References ast_log(), pval::endline, pval::filename, pval::list, LOG_WARNING, pval::next, PV_CONTEXT, PV_INCLUDES, pval::startline, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by check_pval_item().
02326 { 02327 pval *i,*j; 02328 /* find some context includes that reference this context */ 02329 02330 02331 /* otherwise, print out a warning */ 02332 for (i=current_db; i; i=i->next) { 02333 if (i->type == PV_CONTEXT) { 02334 for (j=i->u2. statements; j; j=j->next) { 02335 if ( j->type == PV_INCLUDES ) { 02336 struct pval *p4; 02337 for (p4=j->u1.list; p4; p4=p4->next) { 02338 /* for each context pointed to, find it, then find a context/label that matches the 02339 target here! */ 02340 if ( !strcmp(p4->u1.str, abstract_context->u1.str) ) 02341 return; /* found a match! */ 02342 } 02343 } 02344 } 02345 } 02346 } 02347 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", 02348 abstract_context->filename, abstract_context->startline, abstract_context->endline, abstract_context->u1.str); 02349 warns++; 02350 }
Definition at line 2126 of file pval.c.
References ast_log(), pval::endline, pval::filename, LOG_WARNING, pval::next, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
02127 { 02128 #ifdef AAL_ARGCHECK 02129 struct argdesc *ad = app->args; 02130 pval *pa; 02131 int z; 02132 02133 for (pa = arglist; pa; pa=pa->next) { 02134 if (!ad) { 02135 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n", 02136 arglist->filename, arglist->startline, arglist->endline, pa->u1.str, app->name); 02137 warns++; 02138 return 1; 02139 } else { 02140 /* find the first entry in the ad list that will match */ 02141 do { 02142 if ( ad->dtype == ARGD_VARARG ) /* once we hit the VARARG, all bets are off. Discontinue the comparisons */ 02143 break; 02144 02145 z= option_matches( ad, pa, app); 02146 if (!z) { 02147 if ( !arglist ) 02148 arglist=appcall; 02149 02150 if (ad->type == ARGD_REQUIRED) { 02151 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n", 02152 arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name); 02153 warns++; 02154 return 1; 02155 } 02156 } else if (z && ad->dtype == ARGD_OPTIONSET) { 02157 option_matches_j( ad, pa, app); 02158 } 02159 ad = ad->next; 02160 } while (ad && !z); 02161 } 02162 } 02163 /* any app nodes left, that are not optional? */ 02164 for ( ; ad; ad=ad->next) { 02165 if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) { 02166 if ( !arglist ) 02167 arglist=appcall; 02168 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n", 02169 arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name); 02170 warns++; 02171 return 1; 02172 } 02173 } 02174 return 0; 02175 #else 02176 return 0; 02177 #endif 02178 }
| static int check_break | ( | pval * | item | ) | [static] |
Definition at line 1041 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().
01042 { 01043 pval *p = item; 01044 01045 while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ { 01046 /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make 01047 no sense */ 01048 if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN 01049 || p->type == PV_WHILE || p->type == PV_FOR ) { 01050 return 1; 01051 } 01052 p = p->dad; 01053 } 01054 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'break' not in switch, for, or while statement!\n", 01055 item->filename, item->startline, item->endline); 01056 errs++; 01057 01058 return 0; 01059 }
| static void check_context_names | ( | void | ) | [static] |
Definition at line 2306 of file pval.c.
References pval::abstract, ast_log(), 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().
02307 { 02308 pval *i,*j; 02309 for (i=current_db; i; i=i->next) { 02310 if (i->type == PV_CONTEXT || i->type == PV_MACRO) { 02311 for (j=i->next; j; j=j->next) { 02312 if ( j->type == PV_CONTEXT || j->type == PV_MACRO ) { 02313 if ( !strcmp(i->u1.str, j->u1.str) && !(i->u3.abstract&2) && !(j->u3.abstract&2) ) 02314 { 02315 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", 02316 i->filename, i->startline, i->endline, i->u1.str, j->filename, j->startline, j->endline); 02317 warns++; 02318 } 02319 } 02320 } 02321 } 02322 } 02323 }
| static int check_continue | ( | pval * | item | ) | [static] |
Definition at line 1061 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().
01062 { 01063 pval *p = item; 01064 01065 while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ { 01066 /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make 01067 no sense */ 01068 if( p->type == PV_WHILE || p->type == PV_FOR ) { 01069 return 1; 01070 } 01071 p = p->dad; 01072 } 01073 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'continue' not in 'for' or 'while' statement!\n", 01074 item->filename, item->startline, item->endline); 01075 errs++; 01076 01077 return 0; 01078 }
| static void check_day | ( | pval * | DAY | ) | [static] |
Definition at line 940 of file pval.c.
References ast_log(), ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, s, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
00941 { 00942 char *day; 00943 char *c; 00944 /* The following line is coincidence, really! */ 00945 int s, e; 00946 00947 day = ast_strdupa(DAY->u1.str); 00948 00949 /* Check for all days */ 00950 if (ast_strlen_zero(day) || !strcmp(day, "*")) { 00951 return; 00952 } 00953 /* Get start and ending days */ 00954 c = strchr(day, '-'); 00955 if (c) { 00956 *c = '\0'; 00957 c++; 00958 } 00959 /* Find the start */ 00960 if (sscanf(day, "%2d", &s) != 1) { 00961 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n", 00962 DAY->filename, DAY->startline, DAY->endline, day); 00963 warns++; 00964 } 00965 else if ((s < 1) || (s > 31)) { 00966 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", 00967 DAY->filename, DAY->startline, DAY->endline, day); 00968 warns++; 00969 } 00970 s--; 00971 if (c) { 00972 if (sscanf(c, "%2d", &e) != 1) { 00973 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n", 00974 DAY->filename, DAY->startline, DAY->endline, c); 00975 warns++; 00976 } 00977 else if ((e < 1) || (e > 31)) { 00978 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", 00979 DAY->filename, DAY->startline, DAY->endline, day); 00980 warns++; 00981 } 00982 e--; 00983 } else 00984 e = s; 00985 }
| static void check_dow | ( | pval * | DOW | ) | [static] |
get_dow: Get day of week
Definition at line 901 of file pval.c.
References ast_log(), ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, s, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
00902 { 00903 char *dow; 00904 char *c; 00905 /* The following line is coincidence, really! */ 00906 int s, e; 00907 00908 dow = ast_strdupa(DOW->u1.str); 00909 00910 /* Check for all days */ 00911 if (ast_strlen_zero(dow) || !strcmp(dow, "*")) 00912 return; 00913 /* Get start and ending days */ 00914 c = strchr(dow, '-'); 00915 if (c) { 00916 *c = '\0'; 00917 c++; 00918 } else 00919 c = NULL; 00920 /* Find the start */ 00921 s = 0; 00922 while ((s < 7) && strcasecmp(dow, days[s])) s++; 00923 if (s >= 7) { 00924 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", 00925 DOW->filename, DOW->startline, DOW->endline, dow); 00926 warns++; 00927 } 00928 if (c) { 00929 e = 0; 00930 while ((e < 7) && strcasecmp(c, days[e])) e++; 00931 if (e >= 7) { 00932 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", 00933 DOW->filename, DOW->startline, DOW->endline, c); 00934 warns++; 00935 } 00936 } else 00937 e = s; 00938 }
| static void check_expr2_input | ( | pval * | expr, | |
| char * | str | |||
| ) | [static] |
Definition at line 804 of file pval.c.
References ast_log(), pval::endline, pval::filename, LOG_WARNING, and pval::startline.
Referenced by check_pval_item().
| static void check_goto | ( | pval * | item | ) | [static] |
Definition at line 1224 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().
01225 { 01226 /* check for the target of the goto-- does it exist? */ 01227 if ( !(item->u1.list)->next && !(item->u1.list)->u1.str ) { 01228 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: empty label reference found!\n", 01229 item->filename, item->startline, item->endline); 01230 errs++; 01231 } 01232 01233 /* just one item-- the label should be in the current extension */ 01234 01235 if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) { 01236 struct pval *z = get_extension_or_contxt(item); 01237 struct pval *x = 0; 01238 if (z) 01239 x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), z); /* if in macro, use current context instead */ 01240 /* printf("Called find_label_in_current_extension with arg %s; current_extension is %x: %d\n", 01241 (char*)((item->u1.list)->u1.str), current_extension?current_extension:current_context, current_extension?current_extension->type:current_context->type); */ 01242 if (!x) { 01243 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s exists in the current extension!\n", 01244 item->filename, item->startline, item->endline, item->u1.list->u1.str); 01245 errs++; 01246 } 01247 else 01248 return; 01249 } 01250 01251 /* TWO items */ 01252 if (item->u1.list->next && !item->u1.list->next->next) { 01253 /* two items */ 01254 /* printf("Calling find_label_in_current_context with args %s, %s\n", 01255 (char*)((item->u1.list)->u1.str), (char *)item->u1.list->next->u1.str); */ 01256 if (!strstr((item->u1.list)->u1.str,"${") 01257 && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ { 01258 struct pval *z = get_contxt(item); 01259 struct pval *x = 0; 01260 01261 if (z) 01262 x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, z); 01263 01264 if (!x) { 01265 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", 01266 item->filename, item->startline, item->endline, item->u1.list->u1.str, item->u1.list->next->u1.str ); 01267 errs++; 01268 } 01269 else 01270 return; 01271 } 01272 } 01273 01274 /* All 3 items! */ 01275 if (item->u1.list->next && item->u1.list->next->next) { 01276 /* all three */ 01277 pval *first = item->u1.list; 01278 pval *second = item->u1.list->next; 01279 pval *third = item->u1.list->next->next; 01280 01281 /* printf("Calling find_label_in_current_db with args %s, %s, %s\n", 01282 (char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); */ 01283 if (!strstr((item->u1.list)->u1.str,"${") 01284 && !strstr(item->u1.list->next->u1.str,"${") 01285 && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ { 01286 struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); 01287 if (!x) { 01288 struct pval *p3; 01289 struct pval *found = 0; 01290 struct pval *that_context = find_context(item->u1.list->u1.str); 01291 01292 /* the target of the goto could be in an included context!! Fancy that!! */ 01293 /* look for includes in the current context */ 01294 if (that_context) { 01295 for (p3=that_context->u2.statements; p3; p3=p3->next) { 01296 if (p3->type == PV_INCLUDES) { 01297 struct pval *p4; 01298 for (p4=p3->u1.list; p4; p4=p4->next) { 01299 /* for each context pointed to, find it, then find a context/label that matches the 01300 target here! */ 01301 char *incl_context = p4->u1.str; 01302 /* find a matching context name */ 01303 struct pval *that_other_context = find_context(incl_context); 01304 if (that_other_context) { 01305 struct pval *x3; 01306 x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context); 01307 if (x3) { 01308 found = x3; 01309 break; 01310 } 01311 } 01312 } 01313 } 01314 } 01315 if (!found) { 01316 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s|%s exists in the context %s or its inclusions!\n", 01317 item->filename, item->startline, item->endline, item->u1.list->next->u1.str, item->u1.list->next->next->u1.str, item->u1.list->u1.str ); 01318 errs++; 01319 } else { 01320 struct pval *mac = in_macro(item); /* is this goto inside a macro? */ 01321 if( mac ) { /* yes! */ 01322 struct pval *targ = in_context(found); 01323 if( mac != targ ) 01324 { 01325 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", 01326 item->filename, item->startline, item->endline); 01327 warns++; 01328 } 01329 } 01330 } 01331 } else { 01332 /* here is where code would go to check for target existence in extensions.conf files */ 01333 #ifdef STANDALONE 01334 struct pbx_find_info pfiq = {.stacklen = 0 }; 01335 extern int localized_pbx_load_module(void); 01336 /* if this is a standalone, we will need to make sure the 01337 localized load of extensions.conf is done */ 01338 if (!extensions_dot_conf_loaded) { 01339 localized_pbx_load_module(); 01340 extensions_dot_conf_loaded++; 01341 } 01342 01343 pbx_find_extension(NULL, NULL, &pfiq, first->u1.str, second->u1.str, atoi(third->u1.str), 01344 atoi(third->u1.str) ? NULL : third->u1.str, NULL, 01345 atoi(third->u1.str) ? E_MATCH : E_FINDLABEL); 01346 01347 if (pfiq.status != STATUS_SUCCESS) { 01348 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", 01349 item->filename, item->startline, item->endline, first->u1.str, second->u1.str, third->u1.str); 01350 warns++; 01351 } 01352 #else 01353 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: goto: Couldn't find goto target %s|%s|%s in the AEL code!\n", 01354 item->filename, item->startline, item->endline, first->u1.str, second->u1.str, third->u1.str); 01355 warns++; 01356 #endif 01357 } 01358 } else { 01359 struct pval *mac = in_macro(item); /* is this goto inside a macro? */ 01360 if( mac ) { /* yes! */ 01361 struct pval *targ = in_context(x); 01362 if( mac != targ ) 01363 { 01364 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", 01365 item->filename, item->startline, item->endline); 01366 warns++; 01367 } 01368 } 01369 } 01370 } 01371 } 01372 }
| static void check_includes | ( | pval * | includes | ) | [static] |
Definition at line 814 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().
00815 { 00816 struct pval *p4; 00817 for (p4=includes->u1.list; p4; p4=p4->next) { 00818 /* for each context pointed to, find it, then find a context/label that matches the 00819 target here! */ 00820 char *incl_context = p4->u1.str; 00821 /* find a matching context name */ 00822 struct pval *that_other_context = find_context(incl_context); 00823 if (!that_other_context && strcmp(incl_context, "parkedcalls") != 0) { 00824 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\ 00825 (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n", 00826 includes->filename, includes->startline, includes->endline, incl_context, incl_context); 00827 warns++; 00828 } 00829 } 00830 }
| static void check_label | ( | pval * | item | ) | [static] |
Definition at line 1109 of file pval.c.
References ast_log(), 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().
01110 { 01111 struct pval *curr; 01112 struct pval *x; 01113 int alright = 0; 01114 01115 /* A label outside an extension just plain does not make sense! */ 01116 01117 curr = item; 01118 01119 while( curr ) { 01120 if( curr->type == PV_MACRO || curr->type == PV_EXTENSION ) { 01121 alright = 1; 01122 break; 01123 } 01124 curr = curr->dad; 01125 } 01126 if( !alright ) 01127 { 01128 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Label %s is not within an extension or macro!\n", 01129 item->filename, item->startline, item->endline, item->u1.str); 01130 errs++; 01131 } 01132 01133 01134 /* basically, ensure that a label is not repeated in a context. Period. 01135 The method: well, for each label, find the first label in the context 01136 with the same name. If it's not the current label, then throw an error. */ 01137 01138 01139 /* printf("==== check_label: ====\n"); */ 01140 if( !current_extension ) 01141 curr = current_context; 01142 else 01143 curr = current_extension; 01144 01145 x = find_first_label_in_current_context((char *)item->u1.str, curr); 01146 /* 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); */ 01147 if( x && x != item ) 01148 { 01149 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Duplicate label %s! Previously defined at file %s, line %d.\n", 01150 item->filename, item->startline, item->endline, item->u1.str, x->filename, x->startline); 01151 errs++; 01152 } 01153 /* printf("<<<<< check_label: ====\n"); */ 01154 }
| static void check_macro_returns | ( | pval * | macro | ) | [static] |
Definition at line 648 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().
00649 { 00650 pval *i; 00651 if (!macro->u3.macro_statements) 00652 { 00653 pval *z = calloc(1, sizeof(struct pval)); 00654 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s is empty! I will insert a return.\n", 00655 macro->filename, macro->startline, macro->endline, macro->u1.str); 00656 00657 z->type = PV_RETURN; 00658 z->startline = macro->startline; 00659 z->endline = macro->endline; 00660 z->startcol = macro->startcol; 00661 z->endcol = macro->endcol; 00662 z->filename = strdup(macro->filename); 00663 00664 macro->u3.macro_statements = z; 00665 return; 00666 } 00667 for (i=macro->u3.macro_statements; i; i=i->next) { 00668 /* if the last statement in the list is not return, then insert a return there */ 00669 if (i->next == NULL) { 00670 if (i->type != PV_RETURN) { 00671 pval *z = calloc(1, sizeof(struct pval)); 00672 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s does not end with a return; I will insert one.\n", 00673 macro->filename, macro->startline, macro->endline, macro->u1.str); 00674 00675 z->type = PV_RETURN; 00676 z->startline = macro->startline; 00677 z->endline = macro->endline; 00678 z->startcol = macro->startcol; 00679 z->endcol = macro->endcol; 00680 z->filename = strdup(macro->filename); 00681 00682 i->next = z; 00683 return; 00684 } 00685 } 00686 } 00687 return; 00688 }
| static void check_month | ( | pval * | MON | ) | [static] |
Definition at line 1003 of file pval.c.
References ast_log(), ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, s, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
01004 { 01005 char *mon; 01006 char *c; 01007 /* The following line is coincidence, really! */ 01008 int s, e; 01009 01010 mon = ast_strdupa(MON->u1.str); 01011 01012 /* Check for all days */ 01013 if (ast_strlen_zero(mon) || !strcmp(mon, "*")) 01014 return ; 01015 /* Get start and ending days */ 01016 c = strchr(mon, '-'); 01017 if (c) { 01018 *c = '\0'; 01019 c++; 01020 } 01021 /* Find the start */ 01022 s = 0; 01023 while ((s < 12) && strcasecmp(mon, months[s])) s++; 01024 if (s >= 12) { 01025 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n", 01026 MON->filename, MON->startline, MON->endline, mon); 01027 warns++; 01028 } 01029 if (c) { 01030 e = 0; 01031 while ((e < 12) && strcasecmp(mon, months[e])) e++; 01032 if (e >= 12) { 01033 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n", 01034 MON->filename, MON->startline, MON->endline, c); 01035 warns++; 01036 } 01037 } else 01038 e = s; 01039 }
Definition at line 2862 of file pval.c.
References check_pval_item(), and pval::next.
Referenced by ael2_semantic_check(), and check_pval_item().
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 2353 of file pval.c.
References pval::abstract, 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(), 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, argapp::next, 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.
Referenced by check_pval().
02354 { 02355 pval *lp; 02356 #ifdef AAL_ARGCHECK 02357 struct argapp *app, *found; 02358 #endif 02359 struct pval *macro_def; 02360 struct pval *app_def; 02361 02362 char errmsg[4096]; 02363 char *strp; 02364 02365 switch (item->type) { 02366 case PV_WORD: 02367 /* fields: item->u1.str == string associated with this (word). 02368 item->u2.arglist == pval list of 4 PV_WORD elements for time values (only in PV_INCLUDES) */ 02369 break; 02370 02371 case PV_MACRO: 02372 /* fields: item->u1.str == name of macro 02373 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 02374 item->u2.arglist->u1.str == argument 02375 item->u2.arglist->next == next arg 02376 02377 item->u3.macro_statements == pval list of statements in macro body. 02378 */ 02379 in_abstract_context = 0; 02380 current_context = item; 02381 current_extension = 0; 02382 02383 check_macro_returns(item); 02384 02385 for (lp=item->u2.arglist; lp; lp=lp->next) { 02386 02387 } 02388 check_pval(item->u3.macro_statements, apps,in_globals); 02389 break; 02390 02391 case PV_CONTEXT: 02392 /* fields: item->u1.str == name of context 02393 item->u2.statements == pval list of statements in context body 02394 item->u3.abstract == int 1 if an abstract keyword were present 02395 */ 02396 current_context = item; 02397 current_extension = 0; 02398 if ( item->u3.abstract ) { 02399 in_abstract_context = 1; 02400 check_abstract_reference(item); 02401 } else 02402 in_abstract_context = 0; 02403 check_pval(item->u2.statements, apps,in_globals); 02404 break; 02405 02406 case PV_MACRO_CALL: 02407 /* fields: item->u1.str == name of macro to call 02408 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 02409 item->u2.arglist->u1.str == argument 02410 item->u2.arglist->next == next arg 02411 */ 02412 #ifdef STANDALONE 02413 /* if this is a standalone, we will need to make sure the 02414 localized load of extensions.conf is done */ 02415 if (!extensions_dot_conf_loaded) { 02416 localized_pbx_load_module(); 02417 extensions_dot_conf_loaded++; 02418 } 02419 #endif 02420 macro_def = find_macro(item->u1.str); 02421 if (!macro_def) { 02422 #ifdef STANDALONE 02423 struct pbx_find_info pfiq = {.stacklen = 0 }; 02424 struct pbx_find_info pfiq2 = {.stacklen = 0 }; 02425 02426 /* look for the macro in the extensions.conf world */ 02427 pbx_find_extension(NULL, NULL, &pfiq, item->u1.str, "s", 1, NULL, NULL, E_MATCH); 02428 02429 if (pfiq.status != STATUS_SUCCESS) { 02430 char namebuf2[256]; 02431 snprintf(namebuf2, 256, "macro-%s", item->u1.str); 02432 02433 /* look for the macro in the extensions.conf world */ 02434 pbx_find_extension(NULL, NULL, &pfiq2, namebuf2, "s", 1, NULL, NULL, E_MATCH); 02435 02436 if (pfiq2.status == STATUS_SUCCESS) { 02437 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", 02438 item->filename, item->startline, item->endline, item->u1.str, item->u1.str); 02439 warns++; 02440 } else { 02441 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to non-existent %s! (Not even in the extensions.conf stuff!)\n", 02442 item->filename, item->startline, item->endline, item->u1.str); 02443 warns++; 02444 } 02445 } 02446 #else 02447 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to %s cannot be found in the AEL code!\n", 02448 item->filename, item->startline, item->endline, item->u1.str); 02449 warns++; 02450 02451 #endif 02452 #ifdef THIS_IS_1DOT4 02453 char namebuf2[256]; 02454 snprintf(namebuf2, 256, "macro-%s", item->u1.str); 02455 02456 /* look for the macro in the extensions.conf world */ 02457 pbx_find_extension(NULL, NULL, &pfiq, namebuf2, "s", 1, NULL, NULL, E_MATCH); 02458 02459 if (pfiq.status != STATUS_SUCCESS) { 02460 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", 02461 item->filename, item->startline, item->endline, item->u1.str); 02462 warns++; 02463 } 02464 02465 #endif 02466 02467 } else if (macro_def->type != PV_MACRO) { 02468 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: macro call to %s references a context, not a macro!\n", 02469 item->filename, item->startline, item->endline, item->u1.str); 02470 errs++; 02471 } else { 02472 /* macro_def is a MACRO, so do the args match in number? */ 02473 int hereargs = 0; 02474 int thereargs = 0; 02475 02476 for (lp=item->u2.arglist; lp; lp=lp->next) { 02477 hereargs++; 02478 } 02479 for (lp=macro_def->u2.arglist; lp; lp=lp->next) { 02480 thereargs++; 02481 } 02482 if (hereargs != thereargs ) { 02483 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", 02484 item->filename, item->startline, item->endline, item->u1.str, hereargs, thereargs); 02485 errs++; 02486 } 02487 } 02488 break; 02489 02490 case PV_APPLICATION_CALL: 02491 /* fields: item->u1.str == name of application to call 02492 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 02493 item->u2.arglist->u1.str == argument 02494 item->u2.arglist->next == next arg 02495 */ 02496 /* Need to check to see if the application is available! */ 02497 app_def = find_context(item->u1.str); 02498 if (app_def && app_def->type == PV_MACRO) { 02499 ast_log(LOG_ERROR,"Error: file %s, line %d-%d: application call to %s references an existing macro, but had no & preceding it!\n", 02500 item->filename, item->startline, item->endline, item->u1.str); 02501 errs++; 02502 } 02503 if (strcasecmp(item->u1.str,"GotoIf") == 0 02504 || strcasecmp(item->u1.str,"GotoIfTime") == 0 02505 || strcasecmp(item->u1.str,"while") == 0 02506 || strcasecmp(item->u1.str,"endwhile") == 0 02507 || strcasecmp(item->u1.str,"random") == 0 02508 || strcasecmp(item->u1.str,"gosub") == 0 02509 || strcasecmp(item->u1.str,"return") == 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 2180 of file pval.c.
References ast_log(), calloc, pval::endcol, pval::endline, pval::filename, LOG_WARNING, pval::next, argapp::next, PV_APPLICATION_CALL, PV_CASE, PV_DEFAULT, PV_PATTERN, PV_STATEMENTBLOCK, pval::startcol, pval::startline, pval::statements, pval::str, strdup, pval::type, pval::u1, and pval::u2.
Referenced by check_pval_item().
02181 { 02182 #ifdef AAL_ARGCHECK 02183 /* get and clean the variable name */ 02184 char *buff1, *p; 02185 struct argapp *a,*a2; 02186 struct appsetvar *v,*v2; 02187 struct argchoice *c; 02188 pval *t; 02189 02190 p = item->u1.str; 02191 while (p && *p && (*p == ' ' || *p == '\t' || *p == '$' || *p == '{' ) ) 02192 p++; 02193 02194 buff1 = ast_strdupa(p); 02195 02196 while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] == '}' || buff1[strlen(buff1)-1] == ' ' || buff1[strlen(buff1)-1] == '\t')) 02197 buff1[strlen(buff1)-1] = 0; 02198 /* buff1 now contains the variable name */ 02199 v = 0; 02200 for (a=apps; a; a=a->next) { 02201 for (v=a->setvars;v;v=v->next) { 02202 if (strcmp(v->name,buff1) == 0) { 02203 break; 02204 } 02205 } 02206 if ( v ) 02207 break; 02208 } 02209 if (v && v->vals) { 02210 /* we have a match, to a variable that has a set of determined values */ 02211 int def= 0; 02212 int pat = 0; 02213 int f1 = 0; 02214 02215 /* first of all, does this switch have a default case ? */ 02216 for (t=item->u2.statements; t; t=t->next) { 02217 if (t->type == PV_DEFAULT) { 02218 def =1; 02219 break; 02220 } 02221 if (t->type == PV_PATTERN) { 02222 pat++; 02223 } 02224 } 02225 if (def || pat) /* nothing to check. All cases accounted for! */ 02226 return; 02227 for (c=v->vals; c; c=c->next) { 02228 f1 = 0; 02229 for (t=item->u2.statements; t; t=t->next) { 02230 if (t->type == PV_CASE || t->type == PV_PATTERN) { 02231 if (!strcmp(t->u1.str,c->name)) { 02232 f1 = 1; 02233 break; 02234 } 02235 } 02236 } 02237 if (!f1) { 02238 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n", 02239 item->filename, item->startline, item->endline, item->u1.str, c->name); 02240 warns++; 02241 } 02242 } 02243 /* next, is there an app call in the current exten, that would set this var? */ 02244 f1 = 0; 02245 t = current_extension->u2.statements; 02246 if ( t && t->type == PV_STATEMENTBLOCK ) 02247 t = t->u1.statements; 02248 for (; t && t != item; t=t->next) { 02249 if (t->type == PV_APPLICATION_CALL) { 02250 /* find the application that matches the u1.str */ 02251 for (a2=apps; a2; a2=a2->next) { 02252 if (strcasecmp(a2->name, t->u1.str)==0) { 02253 for (v2=a2->setvars; v2; v2=v2->next) { 02254 if (strcmp(v2->name, buff1) == 0) { 02255 /* found an app that sets the var */ 02256 f1 = 1; 02257 break; 02258 } 02259 } 02260 } 02261 if (f1) 02262 break; 02263 } 02264 } 02265 if (f1) 02266 break; 02267 } 02268 02269 /* see if it sets the var */ 02270 if (!f1) { 02271 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", 02272 item->filename, item->startline, item->endline, item->u1.str); 02273 warns++; 02274 } 02275 } 02276 #else 02277 pval *t,*tl=0,*p2; 02278 int def= 0; 02279 02280 /* first of all, does this switch have a default case ? */ 02281 for (t=item->u2.statements; t; t=t->next) { 02282 if (t->type == PV_DEFAULT) { 02283 def =1; 02284 break; 02285 } 02286 tl = t; 02287 } 02288 if (def) /* nothing to check. All cases accounted for! */ 02289 return; 02290 /* if no default, warn and insert a default case at the end */ 02291 p2 = tl->next = calloc(1, sizeof(struct pval)); 02292 02293 p2->type = PV_DEFAULT; 02294 p2->startline = tl->startline; 02295 p2->endline = tl->endline; 02296 p2->startcol = tl->startcol; 02297 p2->endcol = tl->endcol; 02298 p2->filename = strdup(tl->filename); 02299 ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: A default case was automatically added to the switch.\n", 02300 p2->filename, p2->startline, p2->endline); 02301 warns++; 02302 02303 #endif 02304 }
| static void check_timerange | ( | pval * | p | ) | [static] |
Definition at line 833 of file pval.c.
References ast_log(), ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.
Referenced by check_pval_item().
00834 { 00835 char *times; 00836 char *e; 00837 int s1, s2; 00838 int e1, e2; 00839 00840 times = ast_strdupa(p->u1.str); 00841 00842 /* Star is all times */ 00843 if (ast_strlen_zero(times) || !strcmp(times, "*")) { 00844 return; 00845 } 00846 /* Otherwise expect a range */ 00847 e = strchr(times, '-'); 00848 if (!e) { 00849 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", 00850 p->filename, p->startline, p->endline, times); 00851 warns++; 00852 return; 00853 } 00854 *e = '\0'; 00855 e++; 00856 while (*e && !isdigit(*e)) 00857 e++; 00858 if (!*e) { 00859 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n", 00860 p->filename, p->startline, p->endline, p->u1.str); 00861 warns++; 00862 } 00863 if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) { 00864 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n", 00865 p->filename, p->startline, p->endline, times); 00866 warns++; 00867 } 00868 if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) { 00869 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n", 00870 p->filename, p->startline, p->endline, times); 00871 warns++; 00872 } 00873 00874 s1 = s1 * 30 + s2/2; 00875 if ((s1 < 0) || (s1 >= 24*30)) { 00876 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) is out of range!\n", 00877 p->filename, p->startline, p->endline, times); 00878 warns++; 00879 } 00880 e1 = e1 * 30 + e2/2; 00881 if ((e1 < 0) || (e1 >= 24*30)) { 00882 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) is out of range!\n", 00883 p->filename, p->startline, p->endline, e); 00884 warns++; 00885 } 00886 return; 00887 }
| 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, 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.
Referenced by ast_compile_ael2().
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 4851 of file pval.c.
References destroy_pval_item(), and pval::next.
Referenced by destroy_pval_item(), pbx_load_module(), yydestruct(), and yyparse().
04852 { 04853 pval *i,*nxt; 04854 04855 for (i=item; i; i=nxt) { 04856 nxt = i->next; 04857 04858 destroy_pval_item(i); 04859 } 04860 }
| void destroy_pval_item | ( | pval * | item | ) |
Definition at line 4583 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.
Referenced by destroy_pval().
04584 { 04585 if (item == NULL) { 04586 ast_log(LOG_WARNING, "null item\n"); 04587 return; 04588 } 04589 04590 if (item->filename) 04591 free(item->filename); 04592 04593 switch (item->type) { 04594 case PV_WORD: 04595 /* fields: item->u1.str == string associated with this (word). */ 04596 if (item->u1.str ) 04597 free(item->u1.str); 04598 if ( item->u2.arglist ) 04599 destroy_pval(item->u2.arglist); 04600 break; 04601 04602 case PV_MACRO: 04603 /* fields: item->u1.str == name of macro 04604 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 04605 item->u2.arglist->u1.str == argument 04606 item->u2.arglist->next == next arg 04607 04608 item->u3.macro_statements == pval list of statements in macro body. 04609 */ 04610 destroy_pval(item->u2.arglist); 04611 if (item->u1.str ) 04612 free(item->u1.str); 04613 destroy_pval(item->u3.macro_statements); 04614 break; 04615 04616 case PV_CONTEXT: 04617 /* fields: item->u1.str == name of context 04618 item->u2.statements == pval list of statements in context body 04619 item->u3.abstract == int 1 if an abstract keyword were present 04620 */ 04621 if (item->u1.str) 04622 free(item->u1.str); 04623 destroy_pval(item->u2.statements); 04624 break; 04625 04626 case PV_MACRO_CALL: 04627 /* fields: item->u1.str == name of macro to call 04628 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 04629 item->u2.arglist->u1.str == argument 04630 item->u2.arglist->next == next arg 04631 */ 04632 if (item->u1.str) 04633 free(item->u1.str); 04634 destroy_pval(item->u2.arglist); 04635 break; 04636 04637 case PV_APPLICATION_CALL: 04638 /* fields: item->u1.str == name of application to call 04639 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 04640 item->u2.arglist->u1.str == argument 04641 item->u2.arglist->next == next arg 04642 */ 04643 if (item->u1.str) 04644 free(item->u1.str); 04645 destroy_pval(item->u2.arglist); 04646 break; 04647 04648 case PV_CASE: 04649 /* fields: item->u1.str == value of case 04650 item->u2.statements == pval list of statements under the case 04651 */ 04652 if (item->u1.str) 04653 free(item->u1.str); 04654 destroy_pval(item->u2.statements); 04655 break; 04656 04657 case PV_PATTERN: 04658 /* fields: item->u1.str == value of case 04659 item->u2.statements == pval list of statements under the case 04660 */ 04661 if (item->u1.str) 04662 free(item->u1.str); 04663 destroy_pval(item->u2.statements); 04664 break; 04665 04666 case PV_DEFAULT: 04667 /* fields: 04668 item->u2.statements == pval list of statements under the case 04669 */ 04670 destroy_pval(item->u2.statements); 04671 break; 04672 04673 case PV_CATCH: 04674 /* fields: item->u1.str == name of extension to catch 04675 item->u2.statements == pval list of statements in context body 04676 */ 04677 if (item->u1.str) 04678 free(item->u1.str); 04679 destroy_pval(item->u2.statements); 04680 break; 04681 04682 case PV_SWITCHES: 04683 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 04684 */ 04685 destroy_pval(item->u1.list); 04686 break; 04687 04688 case PV_ESWITCHES: 04689 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 04690 */ 04691 destroy_pval(item->u1.list); 04692 break; 04693 04694 case PV_INCLUDES: 04695 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 04696 item->u2.arglist == pval list of 4 PV_WORD elements for time values 04697 */ 04698 destroy_pval(item->u1.list); 04699 break; 04700 04701 case PV_STATEMENTBLOCK: 04702 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 04703 */ 04704 destroy_pval(item->u1.list); 04705 break; 04706 04707 case PV_LOCALVARDEC: 04708 case PV_VARDEC: 04709 /* fields: item->u1.str == variable name 04710 item->u2.val == variable value to assign 04711 */ 04712 if (item->u1.str) 04713 free(item->u1.str); 04714 if (item->u2.val) 04715 free(item->u2.val); 04716 break; 04717 04718 case PV_GOTO: 04719 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 04720 item->u1.list->u1.str == where the data on a PV_WORD will always be. 04721 */ 04722 04723 destroy_pval(item->u1.list); 04724 break; 04725 04726 case PV_LABEL: 04727 /* fields: item->u1.str == label name 04728 */ 04729 if (item->u1.str) 04730 free(item->u1.str); 04731 break; 04732 04733 case PV_FOR: 04734 /* fields: item->u1.for_init == a string containing the initalizer 04735 item->u2.for_test == a string containing the loop test 04736 item->u3.for_inc == a string containing the loop increment 04737 04738 item->u4.for_statements == a pval list of statements in the for () 04739 */ 04740 if (item->u1.for_init) 04741 free(item->u1.for_init); 04742 if (item->u2.for_test) 04743 free(item->u2.for_test); 04744 if (item->u3.for_inc) 04745 free(item->u3.for_inc); 04746 destroy_pval(item->u4.for_statements); 04747 break; 04748 04749 case PV_WHILE: 04750 /* fields: item->u1.str == the while conditional, as supplied by user 04751 04752 item->u2.statements == a pval list of statements in the while () 04753 */ 04754 if (item->u1.str) 04755 free(item->u1.str); 04756 destroy_pval(item->u2.statements); 04757 break; 04758 04759 case PV_BREAK: 04760 /* fields: none 04761 */ 04762 break; 04763 04764 case PV_RETURN: 04765 /* fields: none 04766 */ 04767 break; 04768 04769 case PV_CONTINUE: 04770 /* fields: none 04771 */ 04772 break; 04773 04774 case PV_IFTIME: 04775 /* fields: item->u1.list == the 4 time values, in PV_WORD structs, linked list 04776 04777 item->u2.statements == a pval list of statements in the if () 04778 item->u3.else_statements == a pval list of statements in the else 04779 (could be zero) 04780 */ 04781 destroy_pval(item->u1.list); 04782 destroy_pval(item->u2.statements); 04783 if (item->u3.else_statements) { 04784 destroy_pval(item->u3.else_statements); 04785 } 04786 break; 04787 04788 case PV_RANDOM: 04789 /* fields: item->u1.str == the random percentage, as supplied by user 04790 04791 item->u2.statements == a pval list of statements in the true part () 04792 item->u3.else_statements == a pval list of statements in the else 04793 (could be zero) 04794 fall thru to If */ 04795 case PV_IF: 04796 /* fields: item->u1.str == the if conditional, as supplied by user 04797 04798 item->u2.statements == a pval list of statements in the if () 04799 item->u3.else_statements == a pval list of statements in the else 04800 (could be zero) 04801 */ 04802 if (item->u1.str) 04803 free(item->u1.str); 04804 destroy_pval(item->u2.statements); 04805 if (item->u3.else_statements) { 04806 destroy_pval(item->u3.else_statements); 04807 } 04808 break; 04809 04810 case PV_SWITCH: 04811 /* fields: item->u1.str == the switch expression 04812 04813 item->u2.statements == a pval list of statements in the switch, 04814 (will be case statements, most likely!) 04815 */ 04816 if (item->u1.str) 04817 free(item->u1.str); 04818 destroy_pval(item->u2.statements); 04819 break; 04820 04821 case PV_EXTENSION: 04822 /* fields: item->u1.str == the extension name, label, whatever it's called 04823 04824 item->u2.statements == a pval list of statements in the extension 04825 item->u3.hints == a char * hint argument 04826 item->u4.regexten == an int boolean. non-zero says that regexten was specified 04827 */ 04828 if (item->u1.str) 04829 free(item->u1.str); 04830 if (item->u3.hints) 04831 free(item->u3.hints); 04832 destroy_pval(item->u2.statements); 04833 break; 04834 04835 case PV_IGNOREPAT: 04836 /* fields: item->u1.str == the ignorepat data 04837 */ 04838 if (item->u1.str) 04839 free(item->u1.str); 04840 break; 04841 04842 case PV_GLOBALS: 04843 /* fields: item->u1.statements == pval list of statements, usually vardecs 04844 */ 04845 destroy_pval(item->u1.statements); 04846 break; 04847 } 04848 free(item); 04849 }
| static int extension_matches | ( | pval * | here, | |
| const char * | exten, | |||
| const char * | pattern | |||
| ) | [static] |
Definition at line 692 of file pval.c.
References ast_log(), pval::endline, pval::filename, LOG_ERROR, LOG_WARNING, and pval::startline.
Referenced by match_pval_item().
00693 { 00694 int err1; 00695 regex_t preg; 00696 00697 /* simple case, they match exactly, the pattern and exten name */ 00698 if (strcmp(pattern,exten) == 0) 00699 return 1; 00700 00701 if (pattern[0] == '_') { 00702 char reg1[2000]; 00703 const char *p; 00704 char *r = reg1; 00705 00706 if ( strlen(pattern)*5 >= 2000 ) /* safety valve */ { 00707 ast_log(LOG_ERROR,"Error: The pattern %s is way too big. Pattern matching cancelled.\n", 00708 pattern); 00709 return 0; 00710 } 00711 /* form a regular expression from the pattern, and then match it against exten */ 00712 *r++ = '^'; /* what if the extension is a pattern ?? */ 00713 *r++ = '_'; /* what if the extension is a pattern ?? */ 00714 *r++ = '?'; 00715 for (p=pattern+1; *p; p++) { 00716 switch ( *p ) { 00717 case 'X': 00718 *r++ = '['; 00719 *r++ = '0'; 00720 *r++ = '-'; 00721 *r++ = '9'; 00722 *r++ = 'X'; 00723 *r++ = ']'; 00724 break; 00725 00726 case 'Z': 00727 *r++ = '['; 00728 *r++ = '1'; 00729 *r++ = '-'; 00730 *r++ = '9'; 00731 *r++ = 'Z'; 00732 *r++ = ']'; 00733 break; 00734 00735 case 'N': 00736 *r++ = '['; 00737 *r++ = '2'; 00738 *r++ = '-'; 00739 *r++ = '9'; 00740 *r++ = 'N'; 00741 *r++ = ']'; 00742 break; 00743 00744 case '[': 00745 while ( *p && *p != ']' ) { 00746 *r++ = *p++; 00747 } 00748 *r++ = ']'; 00749 if ( *p != ']') { 00750 ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n", 00751 here->filename, here->startline, here->endline, pattern); 00752 } 00753 break; 00754 00755 case '.': 00756 case '!': 00757 *r++ = '.'; 00758 *r++ = '*'; 00759 break; 00760 case '*': 00761 *r++ = '\\'; 00762 *r++ = '*'; 00763 break; 00764 default: 00765 *r++ = *p; 00766 break; 00767 00768 } 00769 } 00770 *r++ = '$'; /* what if the extension is a pattern ?? */ 00771 *r++ = *p++; /* put in the closing null */ 00772 err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED); 00773 if ( err1 ) { 00774 char errmess[500]; 00775 regerror(err1,&preg,errmess,sizeof(errmess)); 00776 regfree(&preg); 00777 ast_log(LOG_WARNING, "Regcomp of %s failed, error code %d\n", 00778 reg1, err1); 00779 return 0; 00780 } 00781 err1 = regexec(&preg, exten, 0, 0, 0); 00782 regfree(&preg); 00783 00784 if ( err1 ) { 00785 /* ast_log(LOG_NOTICE,"*****************************[%d]Extension %s did not match %s(%s)\n", 00786 err1,exten, pattern, reg1); */ 00787 return 0; /* no match */ 00788 } else { 00789 /* ast_log(LOG_NOTICE,"*****************************Extension %s matched %s\n", 00790 exten, pattern); */ 00791 return 1; 00792 } 00793 00794 00795 } else { 00796 if ( strcmp(exten,pattern) == 0 ) { 00797 return 1; 00798 } else 00799 return 0; 00800 } 00801 }
| struct pval* find_context | ( | char * | name | ) | [read] |
Definition at line 1949 of file pval.c.
References match_pval().
Referenced by ast_add_extension_nolock(), check_goto(), check_includes(), check_pval_item(), find_first_label_in_current_context(), find_label_in_current_context(), find_pval_goto_item(), and get_goto_target().
01950 { 01951 return_on_context_match = 1; 01952 count_labels = 0; 01953 match_context = name; 01954 match_exten = "*"; /* don't really need to set these, shouldn't be reached */ 01955 match_label = "*"; 01956 return match_pval(current_db); 01957 }
Definition at line 1835 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().
01836 { 01837 /* printf(" --- Got args %s, %s\n", exten, label); */ 01838 struct pval *ret; 01839 struct pval *p3; 01840 01841 count_labels = 0; 01842 return_on_context_match = 0; 01843 match_context = "*"; 01844 match_exten = "*"; 01845 match_label = label; 01846 01847 ret = match_pval(curr_cont); 01848 if (ret) 01849 return ret; 01850 01851 /* the target of the goto could be in an included context!! Fancy that!! */ 01852 /* look for includes in the current context */ 01853 for (p3=curr_cont->u2.statements; p3; p3=p3->next) { 01854 if (p3->type == PV_INCLUDES) { 01855 struct pval *p4; 01856 for (p4=p3->u1.list; p4; p4=p4->next) { 01857 /* for each context pointed to, find it, then find a context/label that matches the 01858 target here! */ 01859 char *incl_context = p4->u1.str; 01860 /* find a matching context name */ 01861 struct pval *that_context = find_context(incl_context); 01862 if (that_context) { 01863 struct pval *x3; 01864 x3 = find_first_label_in_current_context(label, that_context); 01865 if (x3) { 01866 return x3; 01867 } 01868 } 01869 } 01870 } 01871 } 01872 return 0; 01873 }
| struct pval * find_label_in_current_context | ( | char * | exten, | |
| char * | label, | |||
| pval * | curr_cont | |||
| ) | [static, read] |
Definition at line 1875 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().
01876 { 01877 /* printf(" --- Got args %s, %s\n", exten, label); */ 01878 struct pval *ret; 01879 struct pval *p3; 01880 01881 count_labels = 0; 01882 return_on_context_match = 0; 01883 match_context = "*"; 01884 match_exten = exten; 01885 match_label = label; 01886 ret = match_pval(curr_cont->u2.statements); 01887 if (ret) 01888 return ret; 01889 01890 /* the target of the goto could be in an included context!! Fancy that!! */ 01891 /* look for includes in the current context */ 01892 for (p3=curr_cont->u2.statements; p3; p3=p3->next) { 01893 if (p3->type == PV_INCLUDES) { 01894 struct pval *p4; 01895 for (p4=p3->u1.list; p4; p4=p4->next) { 01896 /* for each context pointed to, find it, then find a context/label that matches the 01897 target here! */ 01898 char *incl_context = p4->u1.str; 01899 /* find a matching context name */ 01900 struct pval *that_context = find_context(incl_context); 01901 if (that_context) { 01902 struct pval *x3; 01903 x3 = find_label_in_current_context(exten, label, that_context); 01904 if (x3) { 01905 return x3; 01906 } 01907 } 01908 } 01909 } 01910 } 01911 return 0; 01912 }
| static struct pval * find_label_in_current_db | ( | const char * | context, | |
| const char * | exten, | |||
| const char * | label | |||
| ) | [static, read] |
Definition at line 1925 of file pval.c.
References match_pval().
Referenced by check_goto(), and get_goto_target().
01926 { 01927 /* printf(" --- Got args %s, %s, %s\n", context, exten, label); */ 01928 count_labels = 0; 01929 return_on_context_match = 0; 01930 01931 match_context = context; 01932 match_exten = exten; 01933 match_label = label; 01934 01935 return match_pval(current_db); 01936 }
| static struct pval * find_label_in_current_extension | ( | const char * | label, | |
| pval * | curr_ext | |||
| ) | [static, read] |
Definition at line 1914 of file pval.c.
References match_pval().
Referenced by check_goto(), and get_goto_target().
01915 { 01916 /* printf(" --- Got args %s\n", label); */ 01917 count_labels = 0; 01918 return_on_context_match = 0; 01919 match_context = "*"; 01920 match_exten = "*"; 01921 match_label = label; 01922 return match_pval(curr_ext); 01923 }
| struct pval* find_macro | ( | char * | name | ) | [read] |
Definition at line 1939 of file pval.c.
References match_pval().
Referenced by check_pval_item().
01940 { 01941 return_on_context_match = 1; 01942 count_labels = 0; 01943 match_context = name; 01944 match_exten = "*"; /* don't really need to set these, shouldn't be reached */ 01945 match_label = "*"; 01946 return match_pval(current_db); 01947 }
| static void find_pval_goto_item | ( | pval * | item, | |
| int | lev | |||
| ) | [static] |
Definition at line 1375 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().
01376 { 01377 struct pval *p4; 01378 01379 if (lev>100) { 01380 ast_log(LOG_ERROR,"find_pval_goto in infinite loop! item_type: %d\n\n", item->type); 01381 return; 01382 } 01383 01384 switch ( item->type ) { 01385 case PV_MACRO: 01386 /* fields: item->u1.str == name of macro 01387 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 01388 item->u2.arglist->u1.str == argument 01389 item->u2.arglist->next == next arg 01390 01391 item->u3.macro_statements == pval list of statements in macro body. 01392 */ 01393 01394 /* printf("Descending into macro %s at line %d\n", item->u1.str, item->startline); */ 01395 find_pval_gotos(item->u3.macro_statements,lev+1); /* if we're just searching for a context, don't bother descending into them */ 01396 01397 break; 01398 01399 case PV_CONTEXT: 01400 /* fields: item->u1.str == name of context 01401 item->u2.statements == pval list of statements in context body 01402 item->u3.abstract == int 1 if an abstract keyword were present 01403 */ 01404 break; 01405 01406 case PV_CASE: 01407 /* fields: item->u1.str == value of case 01408 item->u2.statements == pval list of statements under the case 01409 */ 01410 /* printf("Descending into Case of %s\n", item->u1.str); */ 01411 find_pval_gotos(item->u2.statements,lev+1); 01412 break; 01413 01414 case PV_PATTERN: 01415 /* fields: item->u1.str == value of case 01416 item->u2.statements == pval list of statements under the case 01417 */ 01418 /* printf("Descending into Pattern of %s\n", item->u1.str); */ 01419 find_pval_gotos(item->u2.statements,lev+1); 01420 break; 01421 01422 case PV_DEFAULT: 01423 /* fields: 01424 item->u2.statements == pval list of statements under the case 01425 */ 01426 /* printf("Descending into default\n"); */ 01427 find_pval_gotos(item->u2.statements,lev+1); 01428 break; 01429 01430 case PV_CATCH: 01431 /* fields: item->u1.str == name of extension to catch 01432 item->u2.statements == pval list of statements in context body 01433 */ 01434 /* printf("Descending into catch of %s\n", item->u1.str); */ 01435 find_pval_gotos(item->u2.statements,lev+1); 01436 break; 01437 01438 case PV_STATEMENTBLOCK: 01439 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 01440 */ 01441 /* printf("Descending into statement block\n"); */ 01442 find_pval_gotos(item->u1.list,lev+1); 01443 break; 01444 01445 case PV_GOTO: 01446 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 01447 item->u1.list->u1.str == where the data on a PV_WORD will always be. 01448 */ 01449 check_goto(item); /* THE WHOLE FUNCTION OF THIS ENTIRE ROUTINE!!!! */ 01450 break; 01451 01452 case PV_INCLUDES: 01453 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 01454 */ 01455 for (p4=item->u1.list; p4; p4=p4->next) { 01456 /* for each context pointed to, find it, then find a context/label that matches the 01457 target here! */ 01458 char *incl_context = p4->u1.str; 01459 /* find a matching context name */ 01460 struct pval *that_context = find_context(incl_context); 01461 if (that_context && that_context->u2.statements) { 01462 /* 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); */ 01463 find_pval_gotos(that_context->u2.statements,lev+1); /* keep working up the includes */ 01464 } 01465 } 01466 break; 01467 01468 case PV_FOR: 01469 /* fields: item->u1.for_init == a string containing the initalizer 01470 item->u2.for_test == a string containing the loop test 01471 item->u3.for_inc == a string containing the loop increment 01472 01473 item->u4.for_statements == a pval list of statements in the for () 01474 */ 01475 /* printf("Descending into for at line %d\n", item->startline); */ 01476 find_pval_gotos(item->u4.for_statements,lev+1); 01477 break; 01478 01479 case PV_WHILE: 01480 /* fields: item->u1.str == the while conditional, as supplied by user 01481 01482 item->u2.statements == a pval list of statements in the while () 01483 */ 01484 /* printf("Descending into while at line %d\n", item->startline); */ 01485 find_pval_gotos(item->u2.statements,lev+1); 01486 break; 01487 01488 case PV_RANDOM: 01489 /* fields: item->u1.str == the random number expression, as supplied by user 01490 01491 item->u2.statements == a pval list of statements in the if () 01492 item->u3.else_statements == a pval list of statements in the else 01493 (could be zero) 01494 fall thru to PV_IF */ 01495 01496 case PV_IFTIME: 01497 /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list 01498 01499 item->u2.statements == a pval list of statements in the if () 01500 item->u3.else_statements == a pval list of statements in the else 01501 (could be zero) 01502 fall thru to PV_IF*/ 01503 case PV_IF: 01504 /* fields: item->u1.str == the if conditional, as supplied by user 01505 01506 item->u2.statements == a pval list of statements in the if () 01507 item->u3.else_statements == a pval list of statements in the else 01508 (could be zero) 01509 */ 01510 /* printf("Descending into random/iftime/if at line %d\n", item->startline); */ 01511 find_pval_gotos(item->u2.statements,lev+1); 01512 01513 if (item->u3.else_statements) { 01514 /* printf("Descending into random/iftime/if's ELSE at line %d\n", item->startline); */ 01515 find_pval_gotos(item->u3.else_statements,lev+1); 01516 } 01517 break; 01518 01519 case PV_SWITCH: 01520 /* fields: item->u1.str == the switch expression 01521 01522 item->u2.statements == a pval list of statements in the switch, 01523 (will be case statements, most likely!) 01524 */ 01525 /* printf("Descending into switch at line %d\n", item->startline); */ 01526 find_pval_gotos(item->u3.else_statements,lev+1); 01527 break; 01528 01529 case PV_EXTENSION: 01530 /* fields: item->u1.str == the extension name, label, whatever it's called 01531 01532 item->u2.statements == a pval list of statements in the extension 01533 item->u3.hints == a char * hint argument 01534 item->u4.regexten == an int boolean. non-zero says that regexten was specified 01535 */ 01536 01537 /* printf("Descending into extension %s at line %d\n", item->u1.str, item->startline); */ 01538 find_pval_gotos(item->u2.statements,lev+1); 01539 break; 01540 01541 default: 01542 break; 01543 } 01544 }
| static void find_pval_gotos | ( | pval * | item, | |
| int | lev | |||
| ) | [static] |
Definition at line 1546 of file pval.c.
References find_pval_goto_item(), and pval::next.
Referenced by check_pval_item(), and find_pval_goto_item().
01547 { 01548 pval *i; 01549 01550 for (i=item; i; i=i->next) { 01551 /* printf("About to call pval_goto_item, itemcount=%d, itemtype=%d\n", item_count, i->type); */ 01552 find_pval_goto_item(i, lev); 01553 } 01554 }
| 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 4349 of file pval.c.
References ael_priority::appargs, buf1, pval::compiled_label, free, pval::goto_target, pval::goto_target_in_case, pval::list, ael_extension::name, pval::next, ael_priority::next, ael_extension::next_exten, ael_priority::origin, ael_extension::plist, PV_GOTO, pval::str, strdup, pval::type, pval::u1, pval::u2, and pval::u3.
Referenced by ast_compile_ael2().
04350 { 04351 struct ael_extension *e; 04352 for(e=exten;e;e=e->next_exten) { 04353 04354 struct ael_priority *p; 04355 for(p=e->plist;p;p=p->next) { 04356 04357 if( p->origin && p->origin->type == PV_GOTO && p->origin->u3.goto_target_in_case ) { 04358 04359 /* fix the extension of the goto target to the actual extension in the post-compiled dialplan */ 04360 04361 pval *target = p->origin->u2.goto_target; 04362 struct ael_extension *z = target->u3.compiled_label; 04363 pval *pv2 = p->origin; 04364 char buf1[500]; 04365 char *apparg_save = p->appargs; 04366 04367 p->appargs = 0; 04368 if (!pv2->u1.list->next) /* just one -- it won't hurt to repeat the extension */ { 04369 snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->u1.str); 04370 p->appargs = strdup(buf1); 04371 04372 } else if (pv2->u1.list->next && !pv2->u1.list->next->next) /* two */ { 04373 snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->next->u1.str); 04374 p->appargs = strdup(buf1); 04375 } else if (pv2->u1.list->next && pv2->u1.list->next->next) { 04376 snprintf(buf1,sizeof(buf1),"%s,%s,%s", pv2->u1.list->u1.str, 04377 z->name, 04378 pv2->u1.list->next->next->u1.str); 04379 p->appargs = strdup(buf1); 04380 } 04381 else 04382 printf("WHAT? The goto doesn't fall into one of three cases for GOTO????\n"); 04383 04384 if( apparg_save ) { 04385 free(apparg_save); 04386 } 04387 } 04388 } 04389 } 04390 }
| 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 void 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, buf, buf1, buf2, ael_extension::checked_switch, pval::compiled_label, contains_switch(), ael_extension::context, pval::else_statements, ael_priority::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, 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.
Referenced by ast_compile_ael2().
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[2000]; 03350 char buf2[2000]; 03351 char *strp, *strp2; 03352 char new_label[2000]; 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 ((mother_exten && !mother_exten->checked_switch) || (exten && !exten->checked_switch)) { 03361 if (contains_switch(statement)) { /* only run contains_switch if you haven't checked before */ 03362 if (mother_exten) { 03363 if (!mother_exten->has_switch) { 03364 for (first = 1; first >= 0; first--) { 03365 switch_set = new_prio(); 03366 switch_set->type = AEL_APPCALL; 03367 if (!ast_compat_app_set) { 03368 switch_set->app = strdup("MSet"); 03369 } else { 03370 switch_set->app = strdup("Set"); 03371 } 03372 /* Are we likely inside a gosub subroutine? */ 03373 if (!strcmp(mother_exten->name, "s") && first) { 03374 /* If we're not actually within a gosub, this will fail, but the 03375 * second time through, it will get set. If we are within gosub, 03376 * the second time through is redundant, but acceptable. */ 03377 switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}"); 03378 } else { 03379 switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}"); 03380 first = 0; 03381 } 03382 linkprio(exten, switch_set, mother_exten); 03383 mother_exten->has_switch = 1; 03384 mother_exten->checked_switch = 1; 03385 if (exten) { 03386 exten->has_switch = 1; 03387 exten->checked_switch = 1; 03388 } 03389 } 03390 } 03391 } else if (exten) { 03392 if (!exten->has_switch) { 03393 for (first = 1; first >= 0; first--) { 03394 switch_set = new_prio(); 03395 switch_set->type = AEL_APPCALL; 03396 if (!ast_compat_app_set) { 03397 switch_set->app = strdup("MSet"); 03398 } else { 03399 switch_set->app = strdup("Set"); 03400 } 03401 /* Are we likely inside a gosub subroutine? */ 03402 if (!strcmp(exten->name, "s")) { 03403 /* If we're not actually within a gosub, this will fail, but the 03404 * second time through, it will get set. If we are within gosub, 03405 * the second time through is redundant, but acceptable. */ 03406 switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}"); 03407 } else { 03408 switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}"); 03409 first = 0; 03410 } 03411 linkprio(exten, switch_set, mother_exten); 03412 exten->has_switch = 1; 03413 exten->checked_switch = 1; 03414 if (mother_exten) { 03415 mother_exten->has_switch = 1; 03416 mother_exten->checked_switch = 1; 03417 } 03418 } 03419 } 03420 } 03421 } else { 03422 if (mother_exten) { 03423 mother_exten->checked_switch = 1; 03424 } 03425 if (exten) { 03426 exten->checked_switch = 1; 03427 } 03428 } 03429 } 03430 for (p=statement; p; p=p->next) { 03431 switch (p->type) { 03432 case PV_VARDEC: 03433 pr = new_prio(); 03434 pr->type = AEL_APPCALL; 03435 snprintf(buf1,sizeof(buf1),"%s=$[%s]", p->u1.str, p->u2.val); 03436 if (!ast_compat_app_set) { 03437 pr->app = strdup("MSet"); 03438 } else { 03439 pr->app = strdup("Set"); 03440 } 03441 remove_spaces_before_equals(buf1); 03442 pr->appargs = strdup(buf1); 03443 pr->origin = p; 03444 linkprio(exten, pr, mother_exten); 03445 break; 03446 03447 case PV_LOCALVARDEC: 03448 pr = new_prio(); 03449 pr->type = AEL_APPCALL; 03450 snprintf(buf1,sizeof(buf1),"LOCAL(%s)=$[%s]", p->u1.str, p->u2.val); 03451 if (!ast_compat_app_set) { 03452 pr->app = strdup("MSet"); 03453 } else { 03454 pr->app = strdup("Set"); 03455 } 03456 remove_spaces_before_equals(buf1); 03457 pr->appargs = strdup(buf1); 03458 pr->origin = p; 03459 linkprio(exten, pr, mother_exten); 03460 break; 03461 03462 case PV_GOTO: 03463 pr = new_prio(); 03464 pr->type = AEL_APPCALL; 03465 p->u2.goto_target = get_goto_target(p); 03466 if( p->u2.goto_target ) { 03467 p->u3.goto_target_in_case = label_inside_case(p->u2.goto_target); 03468 } 03469 03470 if (!p->u1.list->next) /* just one */ { 03471 pr->app = strdup("Goto"); 03472 if (!mother_exten) 03473 pr->appargs = strdup(p->u1.list->u1.str); 03474 else { /* for the case of simple within-extension gotos in case/pattern/default statement blocks: */ 03475 snprintf(buf1,sizeof(buf1),"%s,%s", mother_exten->name, p->u1.list->u1.str); 03476 pr->appargs = strdup(buf1); 03477 } 03478 03479 } else if (p->u1.list->next && !p->u1.list->next->next) /* two */ { 03480 snprintf(buf1,sizeof(buf1),"%s,%s", p->u1.list->u1.str, p->u1.list->next->u1.str); 03481 pr->app = strdup("Goto"); 03482 pr->appargs = strdup(buf1); 03483 } else if (p->u1.list->next && p->u1.list->next->next) { 03484 snprintf(buf1,sizeof(buf1),"%s,%s,%s", p->u1.list->u1.str, 03485 p->u1.list->next->u1.str, 03486 p->u1.list->next->next->u1.str); 03487 pr->app = strdup("Goto"); 03488 pr->appargs = strdup(buf1); 03489 } 03490 pr->origin = p; 03491 linkprio(exten, pr, mother_exten); 03492 break; 03493 03494 case PV_LABEL: 03495 pr = new_prio(); 03496 pr->type = AEL_LABEL; 03497 pr->origin = p; 03498 p->u3.compiled_label = exten; 03499 linkprio(exten, pr, mother_exten); 03500 break; 03501 03502 case PV_FOR: 03503 control_statement_count++; 03504 loop_break_save = exten->loop_break; /* save them, then restore before leaving */ 03505 loop_continue_save = exten->loop_continue; 03506 snprintf(new_label,sizeof(new_label),"for-%s-%d", label, control_statement_count); 03507 for_init = new_prio(); 03508 for_inc = new_prio(); 03509 for_test = new_prio(); 03510 for_loop = new_prio(); 03511 for_end = new_prio(); 03512 for_init->type = AEL_APPCALL; 03513 for_inc->type = AEL_APPCALL; 03514 for_test->type = AEL_FOR_CONTROL; 03515 for_test->goto_false = for_end; 03516 for_loop->type = AEL_CONTROL1; /* simple goto */ 03517 for_end->type = AEL_APPCALL; 03518 if (!ast_compat_app_set) { 03519 for_init->app = strdup("MSet"); 03520 } else { 03521 for_init->app = strdup("Set"); 03522 } 03523 03524 strcpy(buf2,p->u1.for_init); 03525 remove_spaces_before_equals(buf2); 03526 strp = strchr(buf2, '='); 03527 if (strp) { 03528 strp2 = strchr(p->u1.for_init, '='); 03529 *(strp+1) = 0; 03530 strcat(buf2,"$["); 03531 strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2); 03532 strcat(buf2,"]"); 03533 for_init->appargs = strdup(buf2); 03534 } else { 03535 strp2 = p->u1.for_init; 03536 while (*strp2 && isspace(*strp2)) 03537 strp2++; 03538 if (*strp2 == '&') { /* itsa macro call */ 03539 char *strp3 = strp2+1; 03540 while (*strp3 && isspace(*strp3)) 03541 strp3++; 03542 strcpy(buf2, strp3); 03543 strp3 = strchr(buf2,'('); 03544 if (strp3) { 03545 *strp3 = '|'; 03546 } 03547 while ((strp3=strchr(buf2,','))) { 03548 *strp3 = '|'; 03549 } 03550 strp3 = strrchr(buf2, ')'); 03551 if (strp3) 03552 *strp3 = 0; /* remove the closing paren */ 03553 03554 for_init->appargs = strdup(buf2); 03555 free(for_init->app); 03556 for_init->app = strdup("Macro"); 03557 } else { /* must be a regular app call */ 03558 char *strp3; 03559 strcpy(buf2, strp2); 03560 strp3 = strchr(buf2,'('); 03561 if (strp3) { 03562 *strp3 = 0; 03563 free(for_init->app); 03564 for_init->app = strdup(buf2); 03565 for_init->appargs = strdup(strp3+1); 03566 strp3 = strrchr(for_init->appargs, ')'); 03567 if (strp3) 03568 *strp3 = 0; /* remove the closing paren */ 03569 } 03570 } 03571 } 03572 03573 strcpy(buf2,p->u3.for_inc); 03574 remove_spaces_before_equals(buf2); 03575 strp = strchr(buf2, '='); 03576 if (strp) { /* there's an = in this part; that means an assignment. set it up */ 03577 strp2 = strchr(p->u3.for_inc, '='); 03578 *(strp+1) = 0; 03579 strcat(buf2,"$["); 03580 strncat(buf2,strp2+1, sizeof(buf2)-strlen(strp2+1)-2); 03581 strcat(buf2,"]"); 03582 for_inc->appargs = strdup(buf2); 03583 if (!ast_compat_app_set) { 03584 for_inc->app = strdup("MSet"); 03585 } else { 03586 for_inc->app = strdup("Set"); 03587 } 03588 } else { 03589 strp2 = p->u3.for_inc; 03590 while (*strp2 && isspace(*strp2)) 03591 strp2++; 03592 if (*strp2 == '&') { /* itsa macro call */ 03593 char *strp3 = strp2+1; 03594 while (*strp3 && isspace(*strp3)) 03595 strp3++; 03596 strcpy(buf2, strp3); 03597 strp3 = strchr(buf2,'('); 03598 if (strp3) { 03599 *strp3 = ','; 03600 } 03601 strp3 = strrchr(buf2, ')'); 03602 if (strp3) 03603 *strp3 = 0; /* remove the closing paren */ 03604 03605 for_inc->appargs = strdup(buf2); 03606 03607 for_inc->app = strdup("Macro"); 03608 } else { /* must be a regular app call */ 03609 char *strp3; 03610 strcpy(buf2, strp2); 03611 strp3 = strchr(buf2,'('); 03612 if (strp3) { 03613 *strp3 = 0; 03614 for_inc->app = strdup(buf2); 03615 for_inc->appargs = strdup(strp3+1); 03616 strp3 = strrchr(for_inc->appargs, ')'); 03617 if (strp3) 03618 *strp3 = 0; /* remove the closing paren */ 03619 } 03620 } 03621 } 03622 snprintf(buf1,sizeof(buf1),"$[%s]",p->u2.for_test); 03623 for_test->app = 0; 03624 for_test->appargs = strdup(buf1); 03625 for_loop->goto_true = for_test; 03626 snprintf(buf1,sizeof(buf1),"Finish for-%s-%d", label, control_statement_count); 03627 for_end->app = strdup("NoOp"); 03628 for_end->appargs = strdup(buf1); 03629 /* link & load! */ 03630 linkprio(exten, for_init, mother_exten); 03631 linkprio(exten, for_test, mother_exten); 03632 03633 /* now, put the body of the for loop here */ 03634 exten->loop_break = for_end; 03635 exten->loop_continue = for_inc; 03636 03637 gen_prios(exten, new_label, p->u4.for_statements, mother_exten, this_context); /* this will link in all the statements here */ 03638 03639 linkprio(exten, for_inc, mother_exten); 03640 linkprio(exten, for_loop, mother_exten); 03641 linkprio(exten, for_end, mother_exten); 03642 03643 03644 exten->loop_break = loop_break_save; 03645 exten->loop_continue = loop_continue_save; 03646 for_loop->origin = p; 03647 break; 03648 03649 case PV_WHILE: 03650 control_statement_count++; 03651 loop_break_save = exten->loop_break; /* save them, then restore before leaving */ 03652 loop_continue_save = exten->loop_continue; 03653 snprintf(new_label,sizeof(new_label),"while-%s-%d", label, control_statement_count); 03654 while_test = new_prio(); 03655 while_loop = new_prio(); 03656 while_end = new_prio(); 03657 while_test->type = AEL_FOR_CONTROL; 03658 while_test->goto_false = while_end; 03659 while_loop->type = AEL_CONTROL1; /* simple goto */ 03660 while_end->type = AEL_APPCALL; 03661 snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str); 03662 while_test->app = 0; 03663 while_test->appargs = strdup(buf1); 03664 while_loop->goto_true = while_test; 03665 snprintf(buf1,sizeof(buf1),"Finish while-%s-%d", label, control_statement_count); 03666 while_end->app = strdup("NoOp"); 03667 while_end->appargs = strdup(buf1); 03668 03669 linkprio(exten, while_test, mother_exten); 03670 03671 /* now, put the body of the for loop here */ 03672 exten->loop_break = while_end; 03673 exten->loop_continue = while_test; 03674 03675 gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the while body statements here */ 03676 03677 linkprio(exten, while_loop, mother_exten); 03678 linkprio(exten, while_end, mother_exten); 03679 03680 03681 exten->loop_break = loop_break_save; 03682 exten->loop_continue = loop_continue_save; 03683 while_loop->origin = p; 03684 break; 03685 03686 case PV_SWITCH: 03687 control_statement_count++; 03688 local_control_statement_count = control_statement_count; 03689 loop_break_save = exten->loop_break; /* save them, then restore before leaving */ 03690 loop_continue_save = exten->loop_continue; 03691 snprintf(new_label,sizeof(new_label),"sw-%s-%d", label, control_statement_count); 03692 switch_test = new_prio(); 03693 switch_end = new_prio(); 03694 switch_test->type = AEL_APPCALL; 03695 switch_end->type = AEL_APPCALL; 03696 snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",control_statement_count, p->u1.str); 03697 switch_test->app = strdup("Goto"); 03698 switch_test->appargs = strdup(buf1); 03699 snprintf(buf1,sizeof(buf1),"Finish switch-%s-%d", label, control_statement_count); 03700 switch_end->app = strdup("NoOp"); 03701 switch_end->appargs = strdup(buf1); 03702 switch_end->origin = p; 03703 switch_end->exten = exten; 03704 03705 linkprio(exten, switch_test, mother_exten); 03706 linkprio(exten, switch_end, mother_exten); 03707 03708 exten->loop_break = switch_end; 03709 exten->loop_continue = 0; 03710 default_exists = 0; 03711 03712 for (p2=p->u2.statements; p2; p2=p2->next) { 03713 /* now, for each case/default put the body of the for loop here */ 03714 if (p2->type == PV_CASE) { 03715 /* ok, generate a extension and link it in */ 03716 switch_case = new_exten(); 03717 if (mother_exten && mother_exten->checked_switch) { 03718 switch_case->has_switch = mother_exten->has_switch; 03719 switch_case->checked_switch = mother_exten->checked_switch; 03720 } 03721 if (exten && exten->checked_switch) { 03722 switch_case->has_switch = exten->has_switch; 03723 switch_case->checked_switch = exten->checked_switch; 03724 } 03725 switch_case->context = this_context; 03726 switch_case->is_switch = 1; 03727 /* the break/continue locations are inherited from parent */ 03728 switch_case->loop_break = exten->loop_break; 03729 switch_case->loop_continue = exten->loop_continue; 03730 03731 linkexten(exten,switch_case); 03732 snprintf(buf1,sizeof(buf1),"sw-%d-%s", local_control_statement_count, p2->u1.str); 03733 switch_case->name = strdup(buf1); 03734 snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, p2->u1.str, local_control_statement_count); 03735 03736 gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the case body statements here */ 03737 03738 /* here is where we write code to "fall thru" to the next case... if there is one... */ 03739 for (p3=p2->u2.statements; p3; p3=p3->next) { 03740 if (!p3->next) 03741 break; 03742 } 03743 /* p3 now points the last statement... */ 03744 if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN) ) { 03745 /* is there a following CASE/PATTERN/DEFAULT? */ 03746 if (p2->next && p2->next->type == PV_CASE) { 03747 fall_thru = new_prio(); 03748 fall_thru->type = AEL_APPCALL; 03749 fall_thru->app = strdup("Goto"); 03750 snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, p2->next->u1.str); 03751 fall_thru->appargs = strdup(buf1); 03752 linkprio(switch_case, fall_thru, mother_exten); 03753 } else if (p2->next && p2->next->type == PV_PATTERN) { 03754 fall_thru = new_prio(); 03755 fall_thru->type = AEL_APPCALL; 03756 fall_thru->app = strdup("Goto"); 03757 gen_match_to_pattern(p2->next->u1.str, buf2); 03758 snprintf(buf1,sizeof(buf1),"sw-%d-%s,10", local_control_statement_count, buf2); 03759 fall_thru->appargs = strdup(buf1); 03760 linkprio(switch_case, fall_thru, mother_exten); 03761 } else if (p2->next && p2->next->type == PV_DEFAULT) { 03762 fall_thru = new_prio(); 03763 fall_thru->type = AEL_APPCALL; 03764 fall_thru->app = strdup("Goto"); 03765 snprintf(buf1,sizeof(buf1),"sw-%d-.,10",local_control_statement_count); 03766 fall_thru->appargs = strdup(buf1); 03767 linkprio(switch_case, fall_thru, mother_exten); 03768 } else if (!p2->next) { 03769 fall_thru = new_prio(); 03770 fall_thru->type = AEL_CONTROL1; 03771 fall_thru->goto_true = switch_end; 03772 fall_thru->app = strdup("Goto"); 03773 linkprio(switch_case, fall_thru, mother_exten); 03774 } 03775 } 03776 if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 03777 char buf[2000]; 03778 struct ael_priority *np2 = new_prio(); 03779 np2->type = AEL_APPCALL; 03780 np2->app = strdup("NoOp"); 03781 snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); 03782 np2->appargs = strdup(buf); 03783 linkprio(switch_case, np2, mother_exten); 03784 switch_case-> return_target = np2; 03785 } 03786 } else if (p2->type == PV_PATTERN) { 03787 /* ok, generate a extension and link it in */ 03788 switch_case = new_exten(); 03789 if (mother_exten && mother_exten->checked_switch) { 03790 switch_case->has_switch = mother_exten->has_switch; 03791 switch_case->checked_switch = mother_exten->checked_switch; 03792 } 03793 if (exten && exten->checked_switch) { 03794 switch_case->has_switch = exten->has_switch; 03795 switch_case->checked_switch = exten->checked_switch; 03796 } 03797 switch_case->context = this_context; 03798 switch_case->is_switch = 1; 03799 /* the break/continue locations are inherited from parent */ 03800 switch_case->loop_break = exten->loop_break; 03801 switch_case->loop_continue = exten->loop_continue; 03802 03803 linkexten(exten,switch_case); 03804 snprintf(buf1,sizeof(buf1),"_sw-%d-%s", local_control_statement_count, p2->u1.str); 03805 switch_case->name = strdup(buf1); 03806 snprintf(new_label,sizeof(new_label),"sw-%s-%s-%d", label, p2->u1.str, local_control_statement_count); 03807 03808 gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the while body statements here */ 03809 /* here is where we write code to "fall thru" to the next case... if there is one... */ 03810 for (p3=p2->u2.statements; p3; p3=p3->next) { 03811 if (!p3->next) 03812 break; 03813 } 03814 /* p3 now points the last statement... */ 03815 if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) { 03816 /* is there a following CASE/PATTERN/DEFAULT? */ 03817 if (p2->next && p2->next->type == PV_CASE) { 03818 fall_thru = new_prio(); 03819 fall_thru->type = AEL_APPCALL; 03820 fall_thru->app = strdup("Goto"); 03821 snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, p2->next->u1.str); 03822 fall_thru->appargs = strdup(buf1); 03823 linkprio(switch_case, fall_thru, mother_exten); 03824 } else if (p2->next && p2->next->type == PV_PATTERN) { 03825 fall_thru = new_prio(); 03826 fall_thru->type = AEL_APPCALL; 03827 fall_thru->app = strdup("Goto"); 03828 gen_match_to_pattern(p2->next->u1.str, buf2); 03829 snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, buf2); 03830 fall_thru->appargs = strdup(buf1); 03831 linkprio(switch_case, fall_thru, mother_exten); 03832 } else if (p2->next && p2->next->type == PV_DEFAULT) { 03833 fall_thru = new_prio(); 03834 fall_thru->type = AEL_APPCALL; 03835 fall_thru->app = strdup("Goto"); 03836 snprintf(buf1,sizeof(buf1),"sw-%d-.,10",local_control_statement_count); 03837 fall_thru->appargs = strdup(buf1); 03838 linkprio(switch_case, fall_thru, mother_exten); 03839 } else if (!p2->next) { 03840 fall_thru = new_prio(); 03841 fall_thru->type = AEL_CONTROL1; 03842 fall_thru->goto_true = switch_end; 03843 fall_thru->app = strdup("Goto"); 03844 linkprio(switch_case, fall_thru, mother_exten); 03845 } 03846 } 03847 if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 03848 char buf[2000]; 03849 struct ael_priority *np2 = new_prio(); 03850 np2->type = AEL_APPCALL; 03851 np2->app = strdup("NoOp"); 03852 snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); 03853 np2->appargs = strdup(buf); 03854 linkprio(switch_case, np2, mother_exten); 03855 switch_case-> return_target = np2; 03856 } 03857 } else if (p2->type == PV_DEFAULT) { 03858 /* ok, generate a extension and link it in */ 03859 switch_case = new_exten(); 03860 if (mother_exten && mother_exten->checked_switch) { 03861 switch_case->has_switch = mother_exten->has_switch; 03862 switch_case->checked_switch = mother_exten->checked_switch; 03863 } 03864 if (exten && exten->checked_switch) { 03865 switch_case->has_switch = exten->has_switch; 03866 switch_case->checked_switch = exten->checked_switch; 03867 } 03868 switch_case->context = this_context; 03869 switch_case->is_switch = 1; 03870 03871 /* new: the default case intros a pattern with ., which covers ALMOST everything. 03872 but it doesn't cover a NULL pattern. So, we'll define a null extension to match 03873 that goto's the default extension. */ 03874 03875 default_exists++; 03876 switch_null = new_exten(); 03877 if (mother_exten && mother_exten->checked_switch) { 03878 switch_null->has_switch = mother_exten->has_switch; 03879 switch_null->checked_switch = mother_exten->checked_switch; 03880 } 03881 if (exten && exten->checked_switch) { 03882 switch_null->has_switch = exten->has_switch; 03883 switch_null->checked_switch = exten->checked_switch; 03884 } 03885 switch_null->context = this_context; 03886 switch_null->is_switch = 1; 03887 switch_empty = new_prio(); 03888 snprintf(buf1,sizeof(buf1),"sw-%d-.,10",local_control_statement_count); 03889 switch_empty->app = strdup("Goto"); 03890 switch_empty->appargs = strdup(buf1); 03891 linkprio(switch_null, switch_empty, mother_exten); 03892 snprintf(buf1,sizeof(buf1),"sw-%d-", local_control_statement_count); 03893 switch_null->name = strdup(buf1); 03894 switch_null->loop_break = exten->loop_break; 03895 switch_null->loop_continue = exten->loop_continue; 03896 linkexten(exten,switch_null); 03897 03898 /* the break/continue locations are inherited from parent */ 03899 switch_case->loop_break = exten->loop_break; 03900 switch_case->loop_continue = exten->loop_continue; 03901 linkexten(exten,switch_case); 03902 snprintf(buf1,sizeof(buf1),"_sw-%d-.", local_control_statement_count); 03903 switch_case->name = strdup(buf1); 03904 03905 snprintf(new_label,sizeof(new_label),"sw-%s-default-%d", label, local_control_statement_count); 03906 03907 gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context); /* this will link in all the default: body statements here */ 03908 03909 /* here is where we write code to "fall thru" to the next case... if there is one... */ 03910 for (p3=p2->u2.statements; p3; p3=p3->next) { 03911 if (!p3->next) 03912 break; 03913 } 03914 /* p3 now points the last statement... */ 03915 if (!p3 || (p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) { 03916 /* is there a following CASE/PATTERN/DEFAULT? */ 03917 if (p2->next && p2->next->type == PV_CASE) { 03918 fall_thru = new_prio(); 03919 fall_thru->type = AEL_APPCALL; 03920 fall_thru->app = strdup("Goto"); 03921 snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, p2->next->u1.str); 03922 fall_thru->appargs = strdup(buf1); 03923 linkprio(switch_case, fall_thru, mother_exten); 03924 } else if (p2->next && p2->next->type == PV_PATTERN) { 03925 fall_thru = new_prio(); 03926 fall_thru->type = AEL_APPCALL; 03927 fall_thru->app = strdup("Goto"); 03928 gen_match_to_pattern(p2->next->u1.str, buf2); 03929 snprintf(buf1,sizeof(buf1),"sw-%d-%s,10",local_control_statement_count, buf2); 03930 fall_thru->appargs = strdup(buf1); 03931 linkprio(switch_case, fall_thru, mother_exten); 03932 } else if (p2->next && p2->next->type == PV_DEFAULT) { 03933 fall_thru = new_prio(); 03934 fall_thru->type = AEL_APPCALL; 03935 fall_thru->app = strdup("Goto"); 03936 snprintf(buf1,sizeof(buf1),"sw-%d-.,10",local_control_statement_count); 03937 fall_thru->appargs = strdup(buf1); 03938 linkprio(switch_case, fall_thru, mother_exten); 03939 } else if (!p2->next) { 03940 fall_thru = new_prio(); 03941 fall_thru->type = AEL_CONTROL1; 03942 fall_thru->goto_true = switch_end; 03943 fall_thru->app = strdup("Goto"); 03944 linkprio(switch_case, fall_thru, mother_exten); 03945 } 03946 } 03947 if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */ 03948 char buf[2000]; 03949 struct ael_priority *np2 = new_prio(); 03950 np2->type = AEL_APPCALL; 03951 np2->app = strdup("NoOp"); 03952 snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); 03953 np2->appargs = strdup(buf); 03954 linkprio(switch_case, np2, mother_exten); 03955 switch_case-> return_target = np2; 03956 } 03957 } else { 03958 /* what could it be??? */ 03959 } 03960 } 03961 03962 exten->loop_break = loop_break_save; 03963 exten->loop_continue = loop_continue_save; 03964 switch_test->origin = p; 03965 switch_end->origin = p; 03966 break; 03967 03968 case PV_MACRO_CALL: 03969 pr = new_prio(); 03970 pr->type = AEL_APPCALL; 03971 snprintf(buf1,sizeof(buf1),"%s,s,1", p->u1.str); 03972 first = 1; 03973 for (p2 = p->u2.arglist; p2; p2 = p2->next) { 03974 if (first) 03975 { 03976 strcat(buf1,"("); 03977 first = 0; 03978 } 03979 else 03980 strcat(buf1,","); 03981 strcat(buf1,p2->u1.str); 03982 } 03983 if (!first) 03984 strcat(buf1,")"); 03985 03986 pr->app = strdup("Gosub"); 03987 pr->appargs = strdup(buf1); 03988 pr->origin = p; 03989 linkprio(exten, pr, mother_exten); 03990 break; 03991 03992 case PV_APPLICATION_CALL: 03993 pr = new_prio(); 03994 pr->type = AEL_APPCALL; 03995 buf1[0] = 0; 03996 for (p2 = p->u2.arglist; p2; p2 = p2->next) { 03997 if (p2 != p->u2.arglist ) 03998 strcat(buf1,","); 03999 strcat(buf1,p2->u1.str); 04000 } 04001 pr->app = strdup(p->u1.str); 04002 pr->appargs = strdup(buf1); 04003 pr->origin = p; 04004 linkprio(exten, pr, mother_exten); 04005 break; 04006 04007 case PV_BREAK: 04008 pr = new_prio(); 04009 pr->type = AEL_CONTROL1; /* simple goto */ 04010 pr->goto_true = exten->loop_break; 04011 pr->origin = p; 04012 linkprio(exten, pr, mother_exten); 04013 break; 04014 04015 case PV_RETURN: /* hmmmm */ 04016 pr = new_prio(); 04017 pr->type = AEL_RETURN; /* simple Return */ 04018 /* exten->return_needed++; */ 04019 pr->app = strdup("Return"); 04020 pr->appargs = strdup(""); 04021 pr->origin = p; 04022 linkprio(exten, pr, mother_exten); 04023 break; 04024 04025 case PV_CONTINUE: 04026 pr = new_prio(); 04027 pr->type = AEL_CONTROL1; /* simple goto */ 04028 pr->goto_true = exten->loop_continue; 04029 pr->origin = p; 04030 linkprio(exten, pr, mother_exten); 04031 break; 04032 04033 case PV_IFTIME: 04034 control_statement_count++; 04035 snprintf(new_label,sizeof(new_label),"iftime-%s-%d", label, control_statement_count); 04036 04037 if_test = new_prio(); 04038 if_test->type = AEL_IFTIME_CONTROL; 04039 snprintf(buf1,sizeof(buf1),"%s,%s,%s,%s", 04040 p->u1.list->u1.str, 04041 p->u1.list->next->u1.str, 04042 p->u1.list->next->next->u1.str, 04043 p->u1.list->next->next->next->u1.str); 04044 if_test->app = 0; 04045 if_test->appargs = strdup(buf1); 04046 if_test->origin = p; 04047 04048 if_end = new_prio(); 04049 if_end->type = AEL_APPCALL; 04050 snprintf(buf1,sizeof(buf1),"Finish iftime-%s-%d", label, control_statement_count); 04051 if_end->app = strdup("NoOp"); 04052 if_end->appargs = strdup(buf1); 04053 04054 if (p->u3.else_statements) { 04055 if_skip = new_prio(); 04056 if_skip->type = AEL_CONTROL1; /* simple goto */ 04057 if_skip->goto_true = if_end; 04058 if_skip->origin = p; 04059 04060 } else { 04061 if_skip = 0; 04062 04063 if_test->goto_false = if_end; 04064 } 04065 04066 if_false = new_prio(); 04067 if_false->type = AEL_CONTROL1; 04068 if (p->u3.else_statements) { 04069 if_false->goto_true = if_skip; /* +1 */ 04070 } else { 04071 if_false->goto_true = if_end; 04072 } 04073 04074 /* link & load! */ 04075 linkprio(exten, if_test, mother_exten); 04076 linkprio(exten, if_false, mother_exten); 04077 04078 /* now, put the body of the if here */ 04079 04080 gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the statements here */ 04081 04082 if (p->u3.else_statements) { 04083 linkprio(exten, if_skip, mother_exten); 04084 gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context); /* this will link in all the statements here */ 04085 04086 } 04087 04088 linkprio(exten, if_end, mother_exten); 04089 04090 break; 04091 04092 case PV_RANDOM: 04093 case PV_IF: 04094 control_statement_count++; 04095 snprintf(new_label,sizeof(new_label),"if-%s-%d", label, control_statement_count); 04096 04097 if_test = new_prio(); 04098 if_end = new_prio(); 04099 if_test->type = AEL_IF_CONTROL; 04100 if_end->type = AEL_APPCALL; 04101 if ( p->type == PV_RANDOM ) 04102 snprintf(buf1,sizeof(buf1),"$[${RAND(0,99)} < (%s)]",p->u1.str); 04103 else 04104 snprintf(buf1,sizeof(buf1),"$[%s]",p->u1.str); 04105 if_test->app = 0; 04106 if_test->appargs = strdup(buf1); 04107 snprintf(buf1,sizeof(buf1),"Finish if-%s-%d", label, control_statement_count); 04108 if_end->app = strdup("NoOp"); 04109 if_end->appargs = strdup(buf1); 04110 if_test->origin = p; 04111 04112 if (p->u3.else_statements) { 04113 if_skip = new_prio(); 04114 if_skip->type = AEL_CONTROL1; /* simple goto */ 04115 if_skip->goto_true = if_end; 04116 if_test->goto_false = if_skip;; 04117 } else { 04118 if_skip = 0; 04119 if_test->goto_false = if_end;; 04120 } 04121 04122 /* link & load! */ 04123 linkprio(exten, if_test, mother_exten); 04124 04125 /* now, put the body of the if here */ 04126 04127 gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context); /* this will link in all the statements here */ 04128 04129 if (p->u3.else_statements) { 04130 linkprio(exten, if_skip, mother_exten); 04131 gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context); /* this will link in all the statements here */ 04132 04133 } 04134 04135 linkprio(exten, if_end, mother_exten); 04136 04137 break; 04138 04139 case PV_STATEMENTBLOCK: 04140 gen_prios(exten, label, p->u1.list, mother_exten, this_context ); /* recurse into the block */ 04141 break; 04142 04143 case PV_CATCH: 04144 control_statement_count++; 04145 /* generate an extension with name of catch, put all catch stats 04146 into this exten! */ 04147 switch_case = new_exten(); 04148 if (mother_exten && mother_exten->checked_switch) { 04149 switch_case->has_switch = mother_exten->has_switch; 04150 switch_case->checked_switch = mother_exten->checked_switch; 04151 } 04152 if (exten && exten->checked_switch) { 04153 switch_case->has_switch = exten->has_switch; 04154 switch_case->checked_switch = exten->checked_switch; 04155 } 04156 04157 switch_case->context = this_context; 04158 linkexten(exten,switch_case); 04159 switch_case->name = strdup(p->u1.str); 04160 snprintf(new_label,sizeof(new_label),"catch-%s-%d",p->u1.str, control_statement_count); 04161 04162 gen_prios(switch_case, new_label, p->u2.statements,mother_exten,this_context); /* this will link in all the catch body statements here */ 04163 if (switch_case->return_needed) { /* returns now generate a Return() app call, no longer a goto to the end of the exten */ 04164 char buf[2000]; 04165 struct ael_priority *np2 = new_prio(); 04166 np2->type = AEL_APPCALL; 04167 np2->app = strdup("NoOp"); 04168 snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name); 04169 np2->appargs = strdup(buf); 04170 linkprio(switch_case, np2, mother_exten); 04171 switch_case-> return_target = np2; 04172 } 04173 04174 break; 04175 default: 04176 break; 04177 } 04178 } 04179 }
Definition at line 4339 of file pval.c.
References pval::dad, PV_CONTEXT, PV_MACRO, and pval::type.
Referenced by check_goto(), and get_goto_target().
04340 { 04341 while( p && p->type != PV_CONTEXT && p->type != PV_MACRO ) { 04342 04343 p = p->dad; 04344 } 04345 04346 return p; 04347 }
Definition at line 4329 of file pval.c.
References pval::dad, PV_CONTEXT, PV_EXTENSION, PV_MACRO, and pval::type.
Referenced by check_goto(), and get_goto_target().
04330 { 04331 while( p && p->type != PV_EXTENSION && p->type != PV_CONTEXT && p->type != PV_MACRO ) { 04332 04333 p = p->dad; 04334 } 04335 04336 return p; 04337 }
Definition at line 1156 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().
01157 { 01158 /* just one item-- the label should be in the current extension */ 01159 pval *curr_ext = get_extension_or_contxt(item); /* containing exten, or macro */ 01160 pval *curr_cont; 01161 01162 if (item->u1.list && !item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) { 01163 struct pval *x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), curr_ext); 01164 return x; 01165 } 01166 01167 curr_cont = get_contxt(item); 01168 01169 /* TWO items */ 01170 if (item->u1.list->next && !item->u1.list->next->next) { 01171 if (!strstr((item->u1.list)->u1.str,"${") 01172 && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ { 01173 struct pval *x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, curr_cont); 01174 return x; 01175 } 01176 } 01177 01178 /* All 3 items! */ 01179 if (item->u1.list->next && item->u1.list->next->next) { 01180 /* all three */ 01181 pval *first = item->u1.list; 01182 pval *second = item->u1.list->next; 01183 pval *third = item->u1.list->next->next; 01184 01185 if (!strstr((item->u1.list)->u1.str,"${") 01186 && !strstr(item->u1.list->next->u1.str,"${") 01187 && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ { 01188 struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); 01189 if (!x) { 01190 01191 struct pval *p3; 01192 struct pval *that_context = find_context(item->u1.list->u1.str); 01193 01194 /* the target of the goto could be in an included context!! Fancy that!! */ 01195 /* look for includes in the current context */ 01196 if (that_context) { 01197 for (p3=that_context->u2.statements; p3; p3=p3->next) { 01198 if (p3->type == PV_INCLUDES) { 01199 struct pval *p4; 01200 for (p4=p3->u1.list; p4; p4=p4->next) { 01201 /* for each context pointed to, find it, then find a context/label that matches the 01202 target here! */ 01203 char *incl_context = p4->u1.str; 01204 /* find a matching context name */ 01205 struct pval *that_other_context = find_context(incl_context); 01206 if (that_other_context) { 01207 struct pval *x3; 01208 x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context); 01209 if (x3) { 01210 return x3; 01211 } 01212 } 01213 } 01214 } 01215 } 01216 } 01217 } 01218 return x; 01219 } 01220 } 01221 return 0; 01222 }
Definition at line 1093 of file pval.c.
References pval::dad, PV_CONTEXT, PV_MACRO, and pval::type.
Referenced by check_goto().
Definition at line 1080 of file pval.c.
References pval::dad, PV_MACRO, and pval::type.
Referenced by check_goto().
| 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 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, free, ael_extension::has_switch, malloc, ael_priority::next, ael_extension::plist, and ael_extension::plist_last.
Referenced by ast_compile_ael2(), and 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 5798 of file pval.c.
References pval::next, pval::prev, and pval::u1_last.
Referenced by pvalAppCallAddArg(), pvalCasePatDefAddStatement(), pvalContextAddStatement(), pvalESwitchesAddSwitch(), pvalGlobalsAddStatement(), pvalIncludesAddInclude(), pvalIncludesAddIncludeWithTimeConstraints(), pvalMacroAddArg(), pvalMacroAddStatement(), pvalMacroCallAddArg(), pvalStatementBlockAddStatement(), pvalSwitchAddCase(), pvalSwitchesAddSwitch(), pvalTopLevAddObject(), and yyparse().
05799 { 05800 if (!head) 05801 return tail; 05802 if (tail) { 05803 if (!head->next) { 05804 head->next = tail; 05805 } else { 05806 head->u1_last->next = tail; 05807 } 05808 head->u1_last = tail; 05809 tail->prev = head; /* the dad link only points to containers */ 05810 } 05811 return head; 05812 }
| int localized_pbx_load_module | ( | void | ) |
Definition at line 1807 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().
01808 { 01809 pval *i; 01810 01811 for (i=item; i; i=i->next) { 01812 pval *x; 01813 /* printf(" -- match pval: item %d\n", i->type); */ 01814 01815 if ((x = match_pval_item(i))) { 01816 /* printf("match_pval: returning x=%x\n", (int)x); */ 01817 return x; /* cut the search short */ 01818 } 01819 } 01820 return 0; 01821 }
Definition at line 1559 of file pval.c.
References pval::else_statements, extension_matches(), pval::for_statements, 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().
01560 { 01561 pval *x; 01562 01563 switch ( item->type ) { 01564 case PV_MACRO: 01565 /* fields: item->u1.str == name of macro 01566 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 01567 item->u2.arglist->u1.str == argument 01568 item->u2.arglist->next == next arg 01569 01570 item->u3.macro_statements == pval list of statements in macro body. 01571 */ 01572 /* printf(" matching in MACRO %s, match_context=%s; retoncontmtch=%d; \n", item->u1.str, match_context, return_on_context_match); */ 01573 if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) { 01574 01575 /* printf("MACRO: match context is: %s\n", match_context); */ 01576 01577 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 */ { 01578 /* printf("Returning on matching macro %s\n", match_context); */ 01579 return item; 01580 } 01581 01582 01583 if (!return_on_context_match) { 01584 /* printf("Descending into matching macro %s/%s\n", match_context, item->u1.str); */ 01585 if ((x=match_pval(item->u3.macro_statements))) { 01586 /* printf("Responded with pval match %x\n", x); */ 01587 return x; 01588 } 01589 } 01590 } else { 01591 /* printf("Skipping context/macro %s\n", item->u1.str); */ 01592 } 01593 01594 break; 01595 01596 case PV_CONTEXT: 01597 /* fields: item->u1.str == name of context 01598 item->u2.statements == pval list of statements in context body 01599 item->u3.abstract == int 1 if an abstract keyword were present 01600 */ 01601 /* printf(" matching in CONTEXT\n"); */ 01602 if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) { 01603 if (return_on_context_match && !strcmp(item->u1.str, match_context)) { 01604 /* printf("Returning on matching context %s\n", match_context); */ 01605 /* printf("non-CONTEXT: Responded with pval match %x\n", x); */ 01606 return item; 01607 } 01608 01609 if (!return_on_context_match ) { 01610 /* printf("Descending into matching context %s\n", match_context); */ 01611 if ((x=match_pval(item->u2.statements))) /* if we're just searching for a context, don't bother descending into them */ { 01612 /* printf("CONTEXT: Responded with pval match %x\n", x); */ 01613 return x; 01614 } 01615 } 01616 } else { 01617 /* printf("Skipping context/macro %s\n", item->u1.str); */ 01618 } 01619 break; 01620 01621 case PV_CASE: 01622 /* fields: item->u1.str == value of case 01623 item->u2.statements == pval list of statements under the case 01624 */ 01625 /* printf(" matching in CASE\n"); */ 01626 if ((x=match_pval(item->u2.statements))) { 01627 /* printf("CASE: Responded with pval match %x\n", x); */ 01628 return x; 01629 } 01630 break; 01631 01632 case PV_PATTERN: 01633 /* fields: item->u1.str == value of case 01634 item->u2.statements == pval list of statements under the case 01635 */ 01636 /* printf(" matching in PATTERN\n"); */ 01637 if ((x=match_pval(item->u2.statements))) { 01638 /* printf("PATTERN: Responded with pval match %x\n", x); */ 01639 return x; 01640 } 01641 break; 01642 01643 case PV_DEFAULT: 01644 /* fields: 01645 item->u2.statements == pval list of statements under the case 01646 */ 01647 /* printf(" matching in DEFAULT\n"); */ 01648 if ((x=match_pval(item->u2.statements))) { 01649 /* printf("DEFAULT: Responded with pval match %x\n", x); */ 01650 return x; 01651 } 01652 break; 01653 01654 case PV_CATCH: 01655 /* fields: item->u1.str == name of extension to catch 01656 item->u2.statements == pval list of statements in context body 01657 */ 01658 /* printf(" matching in CATCH\n"); */ 01659 if ((x=match_pval(item->u2.statements))) { 01660 /* printf("CATCH: Responded with pval match %x\n", x); */ 01661 return x; 01662 } 01663 break; 01664 01665 case PV_STATEMENTBLOCK: 01666 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 01667 */ 01668 /* printf(" matching in STATEMENTBLOCK\n"); */ 01669 if ((x=match_pval(item->u1.list))) { 01670 /* printf("STATEMENTBLOCK: Responded with pval match %x\n", x); */ 01671 return x; 01672 } 01673 break; 01674 01675 case PV_LABEL: 01676 /* fields: item->u1.str == label name 01677 */ 01678 /* printf("PV_LABEL %s (cont=%s, exten=%s\n", 01679 item->u1.str, current_context->u1.str, (current_extension?current_extension->u1.str:"<macro>"));*/ 01680 01681 if (count_labels) { 01682 if (!strcmp(match_label, item->u1.str)) { 01683 label_count++; 01684 last_matched_label = item; 01685 } 01686 01687 } else { 01688 if (!strcmp(match_label, item->u1.str)) { 01689 /* printf("LABEL: Responded with pval match %x\n", x); */ 01690 return item; 01691 } 01692 } 01693 break; 01694 01695 case PV_FOR: 01696 /* fields: item->u1.for_init == a string containing the initalizer 01697 item->u2.for_test == a string containing the loop test 01698 item->u3.for_inc == a string containing the loop increment 01699 01700 item->u4.for_statements == a pval list of statements in the for () 01701 */ 01702 /* printf(" matching in FOR\n"); */ 01703 if ((x=match_pval(item->u4.for_statements))) { 01704 /* printf("FOR: Responded with pval match %x\n", x);*/ 01705 return x; 01706 } 01707 break; 01708 01709 case PV_WHILE: 01710 /* fields: item->u1.str == the while conditional, as supplied by user 01711 01712 item->u2.statements == a pval list of statements in the while () 01713 */ 01714 /* printf(" matching in WHILE\n"); */ 01715 if ((x=match_pval(item->u2.statements))) { 01716 /* printf("WHILE: Responded with pval match %x\n", x); */ 01717 return x; 01718 } 01719 break; 01720 01721 case PV_RANDOM: 01722 /* fields: item->u1.str == the random number expression, as supplied by user 01723 01724 item->u2.statements == a pval list of statements in the if () 01725 item->u3.else_statements == a pval list of statements in the else 01726 (could be zero) 01727 fall thru to PV_IF */ 01728 01729 case PV_IFTIME: 01730 /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list 01731 01732 item->u2.statements == a pval list of statements in the if () 01733 item->u3.else_statements == a pval list of statements in the else 01734 (could be zero) 01735 fall thru to PV_IF*/ 01736 case PV_IF: 01737 /* fields: item->u1.str == the if conditional, as supplied by user 01738 01739 item->u2.statements == a pval list of statements in the if () 01740 item->u3.else_statements == a pval list of statements in the else 01741 (could be zero) 01742 */ 01743 /* printf(" matching in IF/IFTIME/RANDOM\n"); */ 01744 if ((x=match_pval(item->u2.statements))) { 01745 return x; 01746 } 01747 if (item->u3.else_statements) { 01748 if ((x=match_pval(item->u3.else_statements))) { 01749 /* printf("IF/IFTIME/RANDOM: Responded with pval match %x\n", x); */ 01750 return x; 01751 } 01752 } 01753 break; 01754 01755 case PV_SWITCH: 01756 /* fields: item->u1.str == the switch expression 01757 01758 item->u2.statements == a pval list of statements in the switch, 01759 (will be case statements, most likely!) 01760 */ 01761 /* printf(" matching in SWITCH\n"); */ 01762 if ((x=match_pval(item->u2.statements))) { 01763 /* printf("SWITCH: Responded with pval match %x\n", x); */ 01764 return x; 01765 } 01766 break; 01767 01768 case PV_EXTENSION: 01769 /* fields: item->u1.str == the extension name, label, whatever it's called 01770 01771 item->u2.statements == a pval list of statements in the extension 01772 item->u3.hints == a char * hint argument 01773 item->u4.regexten == an int boolean. non-zero says that regexten was specified 01774 */ 01775 /* printf(" matching in EXTENSION\n"); */ 01776 if (!strcmp(match_exten,"*") || extension_matches(item, match_exten, item->u1.str) ) { 01777 /* printf("Descending into matching exten %s => %s\n", match_exten, item->u1.str); */ 01778 if (strcmp(match_label,"1") == 0) { 01779 if (item->u2.statements) { 01780 struct pval *p5 = item->u2.statements; 01781 while (p5 && p5->type == PV_LABEL) /* find the first non-label statement in this context. If it exists, there's a "1" */ 01782 p5 = p5->next; 01783 if (p5) 01784 return p5; 01785 else 01786 return 0; 01787 } 01788 else 01789 return 0; 01790 } 01791 01792 if ((x=match_pval(item->u2.statements))) { 01793 /* printf("EXTENSION: Responded with pval match %x\n", x); */ 01794 return x; 01795 } 01796 } else { 01797 /* printf("Skipping exten %s\n", item->u1.str); */ 01798 } 01799 break; 01800 default: 01801 /* printf(" matching in default = %d\n", item->type); */ 01802 break; 01803 } 01804 return 0; 01805 }
| struct ael_extension* new_exten | ( | void | ) | [read] |
Definition at line 2927 of file pval.c.
References calloc.
Referenced by ast_compile_ael2(), and gen_prios().
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 | ) | [read] |
Definition at line 2921 of file pval.c.
References calloc.
Referenced by ast_compile_ael2(), and gen_prios().
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 113 of file pval.c.
References pval::abstract, pval::arglist, pval::else_statements, pval::for_inc, pval::for_init, pval::for_statements, pval::for_test, pval::hints, pval::list, pval::macro_statements, pval::next, print_pval_list(), 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::regexten, pval::statements, pval::str, pval::type, pval::u1, pval::u2, pval::u3, pval::u4, and pval::val.
Referenced by print_pval_list().
00114 { 00115 int i; 00116 pval *lp; 00117 00118 for (i=0; i<depth; i++) { 00119 fprintf(fin, "\t"); /* depth == indentation */ 00120 } 00121 00122 switch ( item->type ) { 00123 case PV_WORD: 00124 fprintf(fin,"%s;\n", item->u1.str); /* usually, words are encapsulated in something else */ 00125 break; 00126 00127 case PV_MACRO: 00128 fprintf(fin,"macro %s(", item->u1.str); 00129 for (lp=item->u2.arglist; lp; lp=lp->next) { 00130 if (lp != item->u2.arglist ) 00131 fprintf(fin,", "); 00132 fprintf(fin,"%s", lp->u1.str); 00133 } 00134 fprintf(fin,") {\n"); 00135 print_pval_list(fin,item->u3.macro_statements,depth+1); 00136 for (i=0; i<depth; i++) { 00137 fprintf(fin,"\t"); /* depth == indentation */ 00138 } 00139 fprintf(fin,"};\n\n"); 00140 break; 00141 00142 case PV_CONTEXT: 00143 if ( item->u3.abstract ) 00144 fprintf(fin,"abstract context %s {\n", item->u1.str); 00145 else 00146 fprintf(fin,"context %s {\n", item->u1.str); 00147 print_pval_list(fin,item->u2.statements,depth+1); 00148 for (i=0; i<depth; i++) { 00149 fprintf(fin,"\t"); /* depth == indentation */ 00150 } 00151 fprintf(fin,"};\n\n"); 00152 break; 00153 00154 case PV_MACRO_CALL: 00155 fprintf(fin,"&%s(", item->u1.str); 00156 for (lp=item->u2.arglist; lp; lp=lp->next) { 00157 if ( lp != item->u2.arglist ) 00158 fprintf(fin,", "); 00159 fprintf(fin,"%s", lp->u1.str); 00160 } 00161 fprintf(fin,");\n"); 00162 break; 00163 00164 case PV_APPLICATION_CALL: 00165 fprintf(fin,"%s(", item->u1.str); 00166 for (lp=item->u2.arglist; lp; lp=lp->next) { 00167 if ( lp != item->u2.arglist ) 00168 fprintf(fin,","); 00169 fprintf(fin,"%s", lp->u1.str); 00170 } 00171 fprintf(fin,");\n"); 00172 break; 00173 00174 case PV_CASE: 00175 fprintf(fin,"case %s:\n", item->u1.str); 00176 print_pval_list(fin,item->u2.statements, depth+1); 00177 break; 00178 00179 case PV_PATTERN: 00180 fprintf(fin,"pattern %s:\n", item->u1.str); 00181 print_pval_list(fin,item->u2.statements, depth+1); 00182 break; 00183 00184 case PV_DEFAULT: 00185 fprintf(fin,"default:\n"); 00186 print_pval_list(fin,item->u2.statements, depth+1); 00187 break; 00188 00189 case PV_CATCH: 00190 fprintf(fin,"catch %s {\n", item->u1.str); 00191 print_pval_list(fin,item->u2.statements, depth+1); 00192 for (i=0; i<depth; i++) { 00193 fprintf(fin,"\t"); /* depth == indentation */ 00194 } 00195 fprintf(fin,"};\n"); 00196 break; 00197 00198 case PV_SWITCHES: 00199 fprintf(fin,"switches {\n"); 00200 print_pval_list(fin,item->u1.list,depth+1); 00201 for (i=0; i<depth; i++) { 00202 fprintf(fin,"\t"); /* depth == indentation */ 00203 } 00204 fprintf(fin,"};\n"); 00205 break; 00206 00207 case PV_ESWITCHES: 00208 fprintf(fin,"eswitches {\n"); 00209 print_pval_list(fin,item->u1.list,depth+1); 00210 for (i=0; i<depth; i++) { 00211 fprintf(fin,"\t"); /* depth == indentation */ 00212 } 00213 fprintf(fin,"};\n"); 00214 break; 00215 00216 case PV_INCLUDES: 00217 fprintf(fin,"includes {\n"); 00218 for (lp=item->u1.list; lp; lp=lp->next) { 00219 for (i=0; i<depth+1; i++) { 00220 fprintf(fin,"\t"); /* depth == indentation */ 00221 } 00222 fprintf(fin,"%s", lp->u1.str); /* usually, words are encapsulated in something else */ 00223 if (lp->u2.arglist) 00224 fprintf(fin,"|%s|%s|%s|%s", 00225 lp->u2.arglist->u1.str, 00226 lp->u2.arglist->next->u1.str, 00227 lp->u2.arglist->next->next->u1.str, 00228 lp->u2.arglist->next->next->next->u1.str 00229 ); 00230 fprintf(fin,";\n"); /* usually, words are encapsulated in something else */ 00231 } 00232 00233 for (i=0; i<depth; i++) { 00234 fprintf(fin,"\t"); /* depth == indentation */ 00235 } 00236 fprintf(fin,"};\n"); 00237 break; 00238 00239 case PV_STATEMENTBLOCK: 00240 fprintf(fin,"{\n"); 00241 print_pval_list(fin,item->u1.list, depth+1); 00242 for (i=0; i<depth; i++) { 00243 fprintf(fin,"\t"); /* depth == indentation */ 00244 } 00245 fprintf(fin,"}\n"); 00246 break; 00247 00248 case PV_VARDEC: 00249 fprintf(fin,"%s=%s;\n", item->u1.str, item->u2.val); 00250 break; 00251 00252 case PV_LOCALVARDEC: 00253 fprintf(fin,"local %s=%s;\n", item->u1.str, item->u2.val); 00254 break; 00255 00256 case PV_GOTO: 00257 fprintf(fin,"goto %s", item->u1.list->u1.str); 00258 if ( item->u1.list->next ) 00259 fprintf(fin,",%s", item->u1.list->next->u1.str); 00260 if ( item->u1.list->next && item->u1.list->next->next ) 00261 fprintf(fin,",%s", item->u1.list->next->next->u1.str); 00262 fprintf(fin,"\n"); 00263 break; 00264 00265 case PV_LABEL: 00266 fprintf(fin,"%s:\n", item->u1.str); 00267 break; 00268 00269 case PV_FOR: 00270 fprintf(fin,"for (%s; %s; %s)\n", item->u1.for_init, item->u2.for_test, item->u3.for_inc); 00271 print_pval_list(fin,item->u4.for_statements,depth+1); 00272 break; 00273 00274 case PV_WHILE: 00275 fprintf(fin,"while (%s)\n", item->u1.str); 00276 print_pval_list(fin,item->u2.statements,depth+1); 00277 break; 00278 00279 case PV_BREAK: 00280 fprintf(fin,"break;\n"); 00281 break; 00282 00283 case PV_RETURN: 00284 fprintf(fin,"return;\n"); 00285 break; 00286 00287 case PV_CONTINUE: 00288 fprintf(fin,"continue;\n"); 00289 break; 00290 00291 case PV_RANDOM: 00292 case PV_IFTIME: 00293 case PV_IF: 00294 if ( item->type == PV_IFTIME ) { 00295 00296 fprintf(fin,"ifTime ( %s|%s|%s|%s )\n", 00297 item->u1.list->u1.str, 00298 item->u1.list->next->u1.str, 00299 item->u1.list->next->next->u1.str, 00300 item->u1.list->next->next->next->u1.str 00301 ); 00302 } else if ( item->type == PV_RANDOM ) { 00303 fprintf(fin,"random ( %s )\n", item->u1.str ); 00304 } else 00305 fprintf(fin,"if ( %s )\n", item->u1.str); 00306 if ( item->u2.statements && item->u2.statements->next ) { 00307 for (i=0; i<depth; i++) { 00308 fprintf(fin,"\t"); /* depth == indentation */ 00309 } 00310 fprintf(fin,"{\n"); 00311 print_pval_list(fin,item->u2.statements,depth+1); 00312 for (i=0; i<depth; i++) { 00313 fprintf(fin,"\t"); /* depth == indentation */ 00314 } 00315 if ( item->u3.else_statements ) 00316 fprintf(fin,"}\n"); 00317 else 00318 fprintf(fin,"};\n"); 00319 } else if (item->u2.statements ) { 00320 print_pval_list(fin,item->u2.statements,depth+1); 00321 } else { 00322 if (item->u3.else_statements ) 00323 fprintf(fin, " {} "); 00324 else 00325 fprintf(fin, " {}; "); 00326 } 00327 if ( item->u3.else_statements ) { 00328 for (i=0; i<depth; i++) { 00329 fprintf(fin,"\t"); /* depth == indentation */ 00330 } 00331 fprintf(fin,"else\n"); 00332 print_pval_list(fin,item->u3.else_statements, depth); 00333 } 00334 break; 00335 00336 case PV_SWITCH: 00337 fprintf(fin,"switch( %s ) {\n", item->u1.str); 00338 print_pval_list(fin,item->u2.statements,depth+1); 00339 for (i=0; i<depth; i++) { 00340 fprintf(fin,"\t"); /* depth == indentation */ 00341 } 00342 fprintf(fin,"}\n"); 00343 break; 00344 00345 case PV_EXTENSION: 00346 if ( item->u4.regexten ) 00347 fprintf(fin, "regexten "); 00348 if ( item->u3.hints ) 00349 fprintf(fin,"hints(%s) ", item->u3.hints); 00350 00351 fprintf(fin,"%s => ", item->u1.str); 00352 print_pval_list(fin,item->u2.statements,depth+1); 00353 fprintf(fin,"\n"); 00354 break; 00355 00356 case PV_IGNOREPAT: 00357 fprintf(fin,"ignorepat => %s;\n", item->u1.str); 00358 break; 00359 00360 case PV_GLOBALS: 00361 fprintf(fin,"globals {\n"); 00362 print_pval_list(fin,item->u1.statements,depth+1); 00363 for (i=0; i<depth; i++) { 00364 fprintf(fin,"\t"); /* depth == indentation */ 00365 } 00366 fprintf(fin,"}\n"); 00367 break; 00368 } 00369 }
| static void print_pval_list | ( | FILE * | fin, | |
| pval * | item, | |||
| int | depth | |||
| ) | [static] |
Definition at line 371 of file pval.c.
References pval::next, and print_pval().
Referenced by ael2_print(), and print_pval().
00372 { 00373 pval *i; 00374 00375 for (i=item; i; i=i->next) { 00376 print_pval(fin, i, depth); 00377 } 00378 }
Definition at line 5176 of file pval.c.
References pval::arglist, linku1(), PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.
05177 { 05178 if (!pvalCheckType(p, "pvalAppCallAddArg", PV_APPLICATION_CALL)) 05179 return; 05180 if (!p->u2.arglist) 05181 p->u2.arglist = arg; 05182 else 05183 linku1(p->u2.arglist, arg); 05184 }
| char* pvalAppCallGetAppName | ( | pval * | p | ) |
Definition at line 5162 of file pval.c.
References PV_APPLICATION_CALL, pvalCheckType(), pval::str, and pval::u1.
05163 { 05164 if (!pvalCheckType(p, "pvalAppCallGetAppName", PV_APPLICATION_CALL)) 05165 return 0; 05166 return p->u1.str; 05167 }
| void pvalAppCallSetAppName | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5155 of file pval.c.
References PV_APPLICATION_CALL, pvalCheckType(), pval::str, and pval::u1.
05156 { 05157 if (!pvalCheckType(p, "pvalAppCallSetAppName", PV_APPLICATION_CALL)) 05158 return; 05159 p->u1.str = name; 05160 }
Definition at line 5169 of file pval.c.
References pval::arglist, PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.
05170 { 05171 if (!pvalCheckType(p, "pvalAppCallSetArglist", PV_APPLICATION_CALL)) 05172 return; 05173 p->u2.arglist = arglist; 05174 }
Definition at line 5186 of file pval.c.
References pval::arglist, pval::next, PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.
05187 { 05188 if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL)) 05189 return 0; 05190 if (!(*args)) 05191 *args = p->u2.arglist; 05192 else { 05193 *args = (*args)->next; 05194 } 05195 return *args; 05196 }
Definition at line 5211 of file pval.c.
References pval::arglist, linku1(), pval::statements, and pval::u2.
05212 { 05213 if (!p->u2.arglist) 05214 p->u2.statements = statement; 05215 else 05216 linku1(p->u2.statements, statement); 05217 }
Definition at line 5219 of file pval.c.
References pval::next, pval::statements, and pval::u2.
05220 { 05221 if (!(*statement)) 05222 *statement = p->u2.statements; 05223 else { 05224 *statement = (*statement)->next; 05225 } 05226 return *statement; 05227 }
| char* pvalCasePatGetVal | ( | pval * | p | ) |
| void pvalCasePatSetVal | ( | pval * | p, | |
| char * | val | |||
| ) |
Definition at line 5199 of file pval.c.
References PV_APPLICATION_CALL, pvalCheckType(), pval::str, and pval::u1.
05200 { 05201 if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL)) 05202 return; 05203 p->u1.str = val; 05204 }
| char* pvalCatchGetExtName | ( | pval * | p | ) |
Definition at line 5237 of file pval.c.
References PV_CATCH, pvalCheckType(), pval::str, and pval::u1.
05238 { 05239 if (!pvalCheckType(p, "pvalCatchGetExtName", PV_CATCH)) 05240 return 0; 05241 return p->u1.str; 05242 }
Definition at line 5251 of file pval.c.
References PV_CATCH, pvalCheckType(), pval::statements, and pval::u2.
05252 { 05253 if (!pvalCheckType(p, "pvalCatchGetStatement", PV_CATCH)) 05254 return 0; 05255 return p->u2.statements; 05256 }
| void pvalCatchSetExtName | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5244 of file pval.c.
References PV_CATCH, pvalCheckType(), pval::statements, and pval::u2.
05245 { 05246 if (!pvalCheckType(p, "pvalCatchSetStatement", PV_CATCH)) 05247 return; 05248 p->u2.statements = statement; 05249 }
Definition at line 4942 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().
Definition at line 5627 of file pval.c.
References pval::else_statements, and pval::u3.
05628 { 05629 return p->u3.else_statements; 05630 }
Definition at line 5622 of file pval.c.
References pval::statements, and pval::u2.
05623 { 05624 return p->u2.statements; 05625 }
Definition at line 5617 of file pval.c.
References pval::else_statements, and pval::u3.
05618 { 05619 p->u3.else_statements = statement; 05620 }
Definition at line 5612 of file pval.c.
References pval::statements, and pval::u2.
05613 { 05614 p->u2.statements = statement; 05615 }
Definition at line 5088 of file pval.c.
References linku1(), PV_CONTEXT, pvalCheckType(), pval::statements, and pval::u2.
05089 { 05090 if (!pvalCheckType(p, "pvalContextAddStatement", PV_CONTEXT)) 05091 return; 05092 if (!p->u2.statements) 05093 p->u2.statements = statement; 05094 else 05095 linku1(p->u2.statements, statement); 05096 }
| int pvalContextGetAbstract | ( | pval * | p | ) |
Definition at line 5079 of file pval.c.
References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.
05080 { 05081 if (!pvalCheckType(p, "pvalContextGetAbstract", PV_CONTEXT)) 05082 return 0; 05083 return p->u3.abstract; 05084 }
| char* pvalContextGetName | ( | pval * | p | ) |
Definition at line 5058 of file pval.c.
References PV_CONTEXT, pvalCheckType(), pval::str, and pval::u1.
05059 { 05060 if (!pvalCheckType(p, "pvalContextGetName", PV_CONTEXT)) 05061 return 0; 05062 return p->u1.str; 05063 }
| void pvalContextSetAbstract | ( | pval * | p | ) |
Definition at line 5065 of file pval.c.
References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.
05066 { 05067 if (!pvalCheckType(p, "pvalContextSetAbstract", PV_CONTEXT)) 05068 return; 05069 p->u3.abstract = 1; 05070 }
| void pvalContextSetName | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5051 of file pval.c.
References PV_CONTEXT, pvalCheckType(), pval::str, and pval::u1.
05052 { 05053 if (!pvalCheckType(p, "pvalContextSetName", PV_CONTEXT)) 05054 return; 05055 p->u1.str = name; 05056 }
| void pvalContextUnsetAbstract | ( | pval * | p | ) |
Definition at line 5072 of file pval.c.
References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.
05073 { 05074 if (!pvalCheckType(p, "pvalContextUnsetAbstract", PV_CONTEXT)) 05075 return; 05076 p->u3.abstract = 0; 05077 }
Definition at line 5098 of file pval.c.
References pval::next, PV_CONTEXT, pvalCheckType(), pval::statements, and pval::u2.
05099 { 05100 if (!pvalCheckType(p, "pvalContextWalkStatements", PV_CONTEXT)) 05101 return 0; 05102 if (!(*statements)) 05103 *statements = p->u2.statements; 05104 else { 05105 *statements = (*statements)->next; 05106 } 05107 return *statements; 05108 }
Definition at line 4953 of file pval.c.
References calloc, and pval::type.
Referenced by pvalESwitchesAddSwitch(), pvalGotoSetTarget(), pvalIfTimeSetCondition(), pvalIncludesAddInclude(), pvalIncludesAddIncludeWithTimeConstraints(), and pvalSwitchesAddSwitch().
| void pvalESwitchesAddSwitch | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5281 of file pval.c.
References linku1(), pval::list, PV_ESWITCHES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05282 { 05283 pval *s; 05284 if (!pvalCheckType(p, "pvalESwitchesAddSwitch", PV_ESWITCHES)) 05285 return; 05286 s = pvalCreateNode(PV_WORD); 05287 s->u1.str = name; 05288 p->u1.list = linku1(p->u1.list, s); 05289 }
Definition at line 5291 of file pval.c.
References pval::list, pval::next, PV_ESWITCHES, pvalCheckType(), pval::str, and pval::u1.
05292 { 05293 if (!pvalCheckType(p, "pvalESwitchesWalkNames", PV_ESWITCHES)) 05294 return 0; 05295 if (!(*next_item)) 05296 *next_item = p->u1.list; 05297 else { 05298 *next_item = (*next_item)->next; 05299 } 05300 return (*next_item)->u1.str; 05301 }
| char* pvalExtenGetHints | ( | pval * | p | ) |
Definition at line 5713 of file pval.c.
References pval::hints, PV_EXTENSION, pvalCheckType(), and pval::u3.
05714 { 05715 if (!pvalCheckType(p, "pvalExtenGetHints", PV_EXTENSION)) 05716 return 0; 05717 return p->u3.hints; 05718 }
| char* pvalExtenGetName | ( | pval * | p | ) |
Definition at line 5678 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::str, and pval::u1.
05679 { 05680 if (!pvalCheckType(p, "pvalExtenGetName", PV_EXTENSION)) 05681 return 0; 05682 return p->u1.str; 05683 }
| int pvalExtenGetRegexten | ( | pval * | p | ) |
Definition at line 5699 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.
05700 { 05701 if (!pvalCheckType(p, "pvalExtenGetRegexten", PV_EXTENSION)) 05702 return 0; 05703 return p->u4.regexten; 05704 }
Definition at line 5727 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::statements, and pval::u2.
05728 { 05729 if (!pvalCheckType(p, "pvalExtenGetStatement", PV_EXTENSION)) 05730 return 0; 05731 return p->u2.statements; 05732 }
| void pvalExtenSetHints | ( | pval * | p, | |
| char * | hints | |||
| ) |
Definition at line 5706 of file pval.c.
References pval::hints, PV_EXTENSION, pvalCheckType(), and pval::u3.
05707 { 05708 if (!pvalCheckType(p, "pvalExtenSetHints", PV_EXTENSION)) 05709 return; 05710 p->u3.hints = hints; 05711 }
| void pvalExtenSetName | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5671 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::str, and pval::u1.
05672 { 05673 if (!pvalCheckType(p, "pvalExtenSetName", PV_EXTENSION)) 05674 return; 05675 p->u1.str = name; 05676 }
| void pvalExtenSetRegexten | ( | pval * | p | ) |
Definition at line 5685 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.
05686 { 05687 if (!pvalCheckType(p, "pvalExtenSetRegexten", PV_EXTENSION)) 05688 return; 05689 p->u4.regexten = 1; 05690 }
Definition at line 5720 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::statements, and pval::u2.
05721 { 05722 if (!pvalCheckType(p, "pvalExtenSetStatement", PV_EXTENSION)) 05723 return; 05724 p->u2.statements = statement; 05725 }
| void pvalExtenUnSetRegexten | ( | pval * | p | ) |
Definition at line 5692 of file pval.c.
References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.
05693 { 05694 if (!pvalCheckType(p, "pvalExtenUnSetRegexten", PV_EXTENSION)) 05695 return; 05696 p->u4.regexten = 0; 05697 }
| char* pvalForGetInc | ( | pval * | p | ) |
Definition at line 5539 of file pval.c.
References pval::for_inc, PV_FOR, pvalCheckType(), and pval::u3.
05540 { 05541 if (!pvalCheckType(p, "pvalForGetInc", PV_FOR)) 05542 return 0; 05543 return p->u3.for_inc; 05544 }
| char* pvalForGetInit | ( | pval * | p | ) |
Definition at line 5525 of file pval.c.
References pval::for_init, PV_FOR, pvalCheckType(), and pval::u1.
05526 { 05527 if (!pvalCheckType(p, "pvalForGetInit", PV_FOR)) 05528 return 0; 05529 return p->u1.for_init; 05530 }
Definition at line 5546 of file pval.c.
References pval::for_statements, PV_FOR, pvalCheckType(), and pval::u4.
05547 { 05548 if (!pvalCheckType(p, "pvalForGetStatement", PV_FOR)) 05549 return 0; 05550 return p->u4.for_statements; 05551 }
| char* pvalForGetTest | ( | pval * | p | ) |
Definition at line 5532 of file pval.c.
References pval::for_test, PV_FOR, pvalCheckType(), and pval::u2.
05533 { 05534 if (!pvalCheckType(p, "pvalForGetTest", PV_FOR)) 05535 return 0; 05536 return p->u2.for_test; 05537 }
| void pvalForSetInc | ( | pval * | p, | |
| char * | inc | |||
| ) |
Definition at line 5511 of file pval.c.
References pval::for_inc, PV_FOR, pvalCheckType(), and pval::u3.
05512 { 05513 if (!pvalCheckType(p, "pvalForSetInc", PV_FOR)) 05514 return; 05515 p->u3.for_inc = inc; 05516 }
| void pvalForSetInit | ( | pval * | p, | |
| char * | init | |||
| ) |
Definition at line 5497 of file pval.c.
References pval::for_init, PV_FOR, pvalCheckType(), and pval::u1.
05498 { 05499 if (!pvalCheckType(p, "pvalForSetInit", PV_FOR)) 05500 return; 05501 p->u1.for_init = init; 05502 }
Definition at line 5518 of file pval.c.
References pval::for_statements, PV_FOR, pvalCheckType(), and pval::u4.
05519 { 05520 if (!pvalCheckType(p, "pvalForSetStatement", PV_FOR)) 05521 return; 05522 p->u4.for_statements = statement; 05523 }
| void pvalForSetTest | ( | pval * | p, | |
| char * | test | |||
| ) |
Definition at line 5504 of file pval.c.
References pval::for_test, PV_FOR, pvalCheckType(), and pval::u2.
05505 { 05506 if (!pvalCheckType(p, "pvalForSetTest", PV_FOR)) 05507 return; 05508 p->u2.for_test = test; 05509 }
Definition at line 5750 of file pval.c.
References ast_log(), linku1(), LOG_ERROR, PV_GLOBALS, pval::statements, pval::type, and pval::u1.
05751 { 05752 if (p->type != PV_GLOBALS) { 05753 ast_log(LOG_ERROR, "pvalGlobalsAddStatement called where first arg is not a Globals!\n"); 05754 } else { 05755 if (!p->u1.statements) { 05756 p->u1.statements = statement; 05757 } else { 05758 p->u1.statements = linku1(p->u1.statements,statement); 05759 } 05760 } 05761 }
Definition at line 5763 of file pval.c.
References pval::next, PV_GLOBALS, and pvalCheckType().
05764 { 05765 if (!pvalCheckType(p, "pvalGlobalsWalkStatements", PV_GLOBALS)) 05766 return 0; 05767 if (!next_statement) { 05768 *next_statement = p; 05769 return p; 05770 } else { 05771 *next_statement = (*next_statement)->next; 05772 return (*next_statement)->next; 05773 } 05774 }
| void pvalGotoGetTarget | ( | pval * | p, | |
| char ** | context, | |||
| char ** | exten, | |||
| char ** | label | |||
| ) |
Definition at line 5455 of file pval.c.
References pval::list, pval::next, PV_GOTO, pvalCheckType(), pval::str, and pval::u1.
05456 { 05457 if (!pvalCheckType(p, "pvalGotoGetTarget", PV_GOTO)) 05458 return; 05459 if (p->u1.list && p->u1.list->next && p->u1.list->next->next) { 05460 *context = p->u1.list->u1.str; 05461 *exten = p->u1.list->next->u1.str; 05462 *label = p->u1.list->next->next->u1.str; 05463 05464 } else if (p->u1.list && p->u1.list->next ) { 05465 *exten = p->u1.list->u1.str; 05466 *label = p->u1.list->next->u1.str; 05467 *context = 0; 05468 05469 } else if (p->u1.list) { 05470 *label = p->u1.list->u1.str; 05471 *context = 0; 05472 *exten = 0; 05473 05474 } else { 05475 *context = 0; 05476 *exten = 0; 05477 *label = 0; 05478 } 05479 }
| void pvalGotoSetTarget | ( | pval * | p, | |
| char * | context, | |||
| char * | exten, | |||
| char * | label | |||
| ) |
Definition at line 5419 of file pval.c.
References ext, pval::list, pval::next, PV_GOTO, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05420 { 05421 pval *con, *ext, *pri; 05422 05423 if (!pvalCheckType(p, "pvalGotoSetTarget", PV_GOTO)) 05424 return; 05425 if (context && strlen(context)) { 05426 con = pvalCreateNode(PV_WORD); 05427 ext = pvalCreateNode(PV_WORD); 05428 pri = pvalCreateNode(PV_WORD); 05429 05430 con->u1.str = context; 05431 ext->u1.str = exten; 05432 pri->u1.str = label; 05433 05434 con->next = ext; 05435 ext->next = pri; 05436 p->u1.list = con; 05437 } else if (exten && strlen(exten)) { 05438 ext = pvalCreateNode(PV_WORD); 05439 pri = pvalCreateNode(PV_WORD); 05440 05441 ext->u1.str = exten; 05442 pri->u1.str = label; 05443 05444 ext->next = pri; 05445 p->u1.list = ext; 05446 } else { 05447 pri = pvalCreateNode(PV_WORD); 05448 05449 pri->u1.str = label; 05450 05451 p->u1.list = pri; 05452 } 05453 }
| char* pvalIfGetCondition | ( | pval * | p | ) |
Definition at line 5562 of file pval.c.
References PV_IFTIME, pvalCheckType(), pval::str, and pval::u1.
05563 { 05564 if (!pvalCheckType(p, "pvalIfGetCondition", PV_IFTIME)) 05565 return 0; 05566 return p->u1.str; 05567 }
| void pvalIfSetCondition | ( | pval * | p, | |
| char * | expr | |||
| ) |
Definition at line 5555 of file pval.c.
References PV_IF, pvalCheckType(), pval::str, and pval::u1.
05556 { 05557 if (!pvalCheckType(p, "pvalIfSetCondition", PV_IF)) 05558 return; 05559 p->u1.str = expr; 05560 }
| void pvalIfTimeGetCondition | ( | pval * | p, | |
| char ** | hour_range, | |||
| char ** | dow_range, | |||
| char ** | dom_range, | |||
| char ** | month_range | |||
| ) |
Definition at line 5588 of file pval.c.
References pval::list, pval::next, PV_IFTIME, pvalCheckType(), pval::str, and pval::u1.
| void pvalIfTimeSetCondition | ( | pval * | p, | |
| char * | hour_range, | |||
| char * | dow_range, | |||
| char * | dom_range, | |||
| char * | mon_range | |||
| ) |
Definition at line 5569 of file pval.c.
References pval::list, pval::next, PV_IFTIME, PV_WORD, pvalCheckType(), pvalCreateNode(), pvalWordSetString(), and pval::u1.
05569 : 24-hour format begin-end|dow range|dom range|month range */ 05570 { 05571 pval *hr = pvalCreateNode(PV_WORD); 05572 pval *dow = pvalCreateNode(PV_WORD); 05573 pval *dom = pvalCreateNode(PV_WORD); 05574 pval *mon = pvalCreateNode(PV_WORD); 05575 if (!pvalCheckType(p, "pvalIfTimeSetCondition", PV_IFTIME)) 05576 return; 05577 pvalWordSetString(hr, hour_range); 05578 pvalWordSetString(dow, dow_range); 05579 pvalWordSetString(dom, dom_range); 05580 pvalWordSetString(mon, mon_range); 05581 dom->next = mon; 05582 dow->next = dom; 05583 hr->next = dow; 05584 p->u1.list = hr; 05585 }
| char* pvalIgnorePatGetPattern | ( | pval * | p | ) |
Definition at line 5742 of file pval.c.
References PV_IGNOREPAT, pvalCheckType(), pval::str, and pval::u1.
05743 { 05744 if (!pvalCheckType(p, "pvalIgnorePatGetPattern", PV_IGNOREPAT)) 05745 return 0; 05746 return p->u1.str; 05747 }
| void pvalIgnorePatSetPattern | ( | pval * | p, | |
| char * | pat | |||
| ) |
Definition at line 5735 of file pval.c.
References PV_IGNOREPAT, pvalCheckType(), pval::str, and pval::u1.
05736 { 05737 if (!pvalCheckType(p, "pvalIgnorePatSetPattern", PV_IGNOREPAT)) 05738 return; 05739 p->u1.str = pat; 05740 }
| void pvalIncludeGetTimeConstraints | ( | pval * | p, | |
| char ** | hour_range, | |||
| char ** | dom_range, | |||
| char ** | dow_range, | |||
| char ** | month_range | |||
| ) |
Definition at line 5342 of file pval.c.
References pval::arglist, pval::next, PV_WORD, pvalCheckType(), pval::str, pval::u1, and pval::u2.
05343 { 05344 if (!pvalCheckType(p, "pvalIncludeGetTimeConstraints", PV_WORD)) 05345 return; 05346 if (p->u2.arglist) { 05347 *hour_range = p->u2.arglist->u1.str; 05348 *dom_range = p->u2.arglist->next->u1.str; 05349 *dow_range = p->u2.arglist->next->next->u1.str; 05350 *month_range = p->u2.arglist->next->next->next->u1.str; 05351 } else { 05352 *hour_range = 0; 05353 *dom_range = 0; 05354 *dow_range = 0; 05355 *month_range = 0; 05356 } 05357 }
| void pvalIncludesAddInclude | ( | pval * | p, | |
| const char * | include | |||
| ) |
Definition at line 5304 of file pval.c.
References linku1(), pval::list, PV_INCLUDES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05305 { 05306 pval *s; 05307 if (!pvalCheckType(p, "pvalIncludesAddSwitch", PV_INCLUDES)) 05308 return; 05309 s = pvalCreateNode(PV_WORD); 05310 s->u1.str = (char *)include; 05311 p->u1.list = linku1(p->u1.list, s); 05312 }
| void pvalIncludesAddIncludeWithTimeConstraints | ( | pval * | p, | |
| const char * | include, | |||
| char * | hour_range, | |||
| char * | dom_range, | |||
| char * | dow_range, | |||
| char * | month_range | |||
| ) |
Definition at line 5315 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.
05316 { 05317 pval *hr = pvalCreateNode(PV_WORD); 05318 pval *dom = pvalCreateNode(PV_WORD); 05319 pval *dow = pvalCreateNode(PV_WORD); 05320 pval *mon = pvalCreateNode(PV_WORD); 05321 pval *s = pvalCreateNode(PV_WORD); 05322 05323 if (!pvalCheckType(p, "pvalIncludeAddIncludeWithTimeConstraints", PV_INCLUDES)) 05324 return; 05325 05326 s->u1.str = (char *)include; 05327 p->u1.list = linku1(p->u1.list, s); 05328 05329 hr->u1.str = hour_range; 05330 dom->u1.str = dom_range; 05331 dow->u1.str = dow_range; 05332 mon->u1.str = month_range; 05333 05334 s->u2.arglist = hr; 05335 05336 hr->next = dom; 05337 dom->next = dow; 05338 dow->next = mon; 05339 mon->next = 0; 05340 }
Definition at line 5359 of file pval.c.
References pval::list, pval::next, PV_INCLUDES, pvalCheckType(), pval::str, and pval::u1.
05360 { 05361 if (!pvalCheckType(p, "pvalIncludesWalk", PV_INCLUDES)) 05362 return 0; 05363 if (!(*next_item)) 05364 *next_item = p->u1.list; 05365 else { 05366 *next_item = (*next_item)->next; 05367 } 05368 return (*next_item)->u1.str; 05369 }
| char* pvalLabelGetName | ( | pval * | p | ) |
Definition at line 5489 of file pval.c.
References PV_LABEL, pvalCheckType(), pval::str, and pval::u1.
05490 { 05491 if (!pvalCheckType(p, "pvalLabelGetName", PV_LABEL)) 05492 return 0; 05493 return p->u1.str; 05494 }
| void pvalLabelSetName | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5002 of file pval.c.
References pval::arglist, linku1(), PV_MACRO, pvalCheckType(), and pval::u2.
Definition at line 5025 of file pval.c.
References linku1(), pval::macro_statements, PV_MACRO, pvalCheckType(), and pval::u3.
05026 { 05027 if (!pvalCheckType(p, "pvalMacroAddStatement", PV_MACRO)) 05028 return; 05029 if (!p->u3.macro_statements) 05030 p->u3.macro_statements = statement; 05031 else 05032 linku1(p->u3.macro_statements, statement); 05033 05034 05035 }
Definition at line 5132 of file pval.c.
References pval::arglist, linku1(), PV_MACRO_CALL, pvalCheckType(), and pval::u2.
05133 { 05134 if (!pvalCheckType(p, "pvalMacroCallGetAddArg", PV_MACRO_CALL)) 05135 return; 05136 if (!p->u2.arglist) 05137 p->u2.arglist = arg; 05138 else 05139 linku1(p->u2.arglist, arg); 05140 }
| char* pvalMacroCallGetMacroName | ( | pval * | p | ) |
Definition at line 5118 of file pval.c.
References PV_MACRO_CALL, pvalCheckType(), pval::str, and pval::u1.
05119 { 05120 if (!pvalCheckType(p, "pvalMacroCallGetMacroName", PV_MACRO_CALL)) 05121 return 0; 05122 return p->u1.str; 05123 }
Definition at line 5125 of file pval.c.
References pval::arglist, PV_MACRO_CALL, pvalCheckType(), and pval::u2.
05126 { 05127 if (!pvalCheckType(p, "pvalMacroCallSetArglist", PV_MACRO_CALL)) 05128 return; 05129 p->u2.arglist = arglist; 05130 }
| void pvalMacroCallSetMacroName | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5111 of file pval.c.
References PV_MACRO_CALL, pvalCheckType(), pval::str, and pval::u1.
05112 { 05113 if (!pvalCheckType(p, "pvalMacroCallSetMacroName", PV_MACRO_CALL)) 05114 return; 05115 p->u1.str = name; 05116 }
Definition at line 5142 of file pval.c.
References pval::arglist, pval::next, PV_MACRO_CALL, pvalCheckType(), and pval::u2.
05143 { 05144 if (!pvalCheckType(p, "pvalMacroCallWalkArgs", PV_MACRO_CALL)) 05145 return 0; 05146 if (!(*args)) 05147 *args = p->u2.arglist; 05148 else { 05149 *args = (*args)->next; 05150 } 05151 return *args; 05152 }
| char* pvalMacroGetName | ( | pval * | p | ) |
Definition at line 4988 of file pval.c.
References PV_MACRO, pvalCheckType(), pval::str, and pval::u1.
04989 { 04990 if (!pvalCheckType(p, "pvalMacroGetName", PV_MACRO)) 04991 return 0; 04992 return p->u1.str; 04993 }
Definition at line 4995 of file pval.c.
References pval::arglist, PV_MACRO, pvalCheckType(), and pval::u2.
04996 { 04997 if (!pvalCheckType(p, "pvalMacroSetArglist", PV_MACRO)) 04998 return; 04999 p->u2.arglist = arglist; 05000 }
| void pvalMacroSetName | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5013 of file pval.c.
References pval::arglist, pval::next, PV_MACRO, pvalCheckType(), and pval::u2.
05014 { 05015 if (!pvalCheckType(p, "pvalMacroWalkArgs", PV_MACRO)) 05016 return 0; 05017 if (!(*arg)) 05018 *arg = p->u2.arglist; 05019 else { 05020 *arg = (*arg)->next; 05021 } 05022 return *arg; 05023 }
Definition at line 5037 of file pval.c.
References pval::macro_statements, pval::next, PV_MACRO, pvalCheckType(), and pval::u3.
05038 { 05039 if (!pvalCheckType(p, "pvalMacroWalkStatements", PV_MACRO)) 05040 return 0; 05041 if (!(*next_statement)) 05042 *next_statement = p->u3.macro_statements; 05043 else { 05044 *next_statement = (*next_statement)->next; 05045 } 05046 return *next_statement; 05047 }
Definition at line 4960 of file pval.c.
References pval::type.
04961 { 04962 return p->type; 04963 }
| char* pvalRandomGetCondition | ( | pval * | p | ) |
Definition at line 5605 of file pval.c.
References PV_RANDOM, pvalCheckType(), pval::str, and pval::u1.
05606 { 05607 if (!pvalCheckType(p, "pvalRandomGetCondition", PV_RANDOM)) 05608 return 0; 05609 return p->u1.str; 05610 }
| void pvalRandomSetCondition | ( | pval * | p, | |
| char * | percent | |||
| ) |
Definition at line 5598 of file pval.c.
References PV_RANDOM, pvalCheckType(), pval::str, and pval::u1.
05599 { 05600 if (!pvalCheckType(p, "pvalRandomSetCondition", PV_RANDOM)) 05601 return; 05602 p->u1.str = percent; 05603 }
Definition at line 5372 of file pval.c.
References linku1(), pval::list, PV_STATEMENTBLOCK, pvalCheckType(), and pval::u1.
05373 { 05374 if (!pvalCheckType(p, "pvalStatementBlockAddStatement", PV_STATEMENTBLOCK)) 05375 return; 05376 p->u1.list = linku1(p->u1.list, statement); 05377 }
Definition at line 5379 of file pval.c.
References pval::list, pval::next, PV_STATEMENTBLOCK, pvalCheckType(), and pval::u1.
05380 { 05381 if (!pvalCheckType(p, "pvalStatementBlockWalkStatements", PV_STATEMENTBLOCK)) 05382 return 0; 05383 if (!(*next_statement)) 05384 *next_statement = p->u1.list; 05385 else { 05386 *next_statement = (*next_statement)->next; 05387 } 05388 return *next_statement; 05389 }
Definition at line 5646 of file pval.c.
References linku1(), PV_CASE, PV_SWITCH, pvalCheckType(), pval::statements, and pval::u2.
05647 { 05648 if (!pvalCheckType(p, "pvalSwitchAddCase", PV_SWITCH)) 05649 return; 05650 if (!pvalCheckType(Case, "pvalSwitchAddCase", PV_CASE)) 05651 return; 05652 if (!p->u2.statements) 05653 p->u2.statements = Case; 05654 else 05655 linku1(p->u2.statements, Case); 05656 }
| void pvalSwitchesAddSwitch | ( | pval * | p, | |
| char * | name | |||
| ) |
Definition at line 5259 of file pval.c.
References linku1(), pval::list, PV_SWITCHES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.
05260 { 05261 pval *s; 05262 if (!pvalCheckType(p, "pvalSwitchesAddSwitch", PV_SWITCHES)) 05263 return; 05264 s = pvalCreateNode(PV_WORD); 05265 s->u1.str = name; 05266 p->u1.list = linku1(p->u1.list, s); 05267 }
Definition at line 5269 of file pval.c.
References pval::list, pval::next, PV_SWITCHES, pvalCheckType(), pval::str, and pval::u1.
05270 { 05271 if (!pvalCheckType(p, "pvalSwitchesWalkNames", PV_SWITCHES)) 05272 return 0; 05273 if (!(*next_item)) 05274 *next_item = p->u1.list; 05275 else { 05276 *next_item = (*next_item)->next; 05277 } 05278 return (*next_item)->u1.str; 05279 }
| char* pvalSwitchGetTestexpr | ( | pval * | p | ) |
Definition at line 5639 of file pval.c.
References PV_SWITCH, pvalCheckType(), pval::str, and pval::u1.
05640 { 05641 if (!pvalCheckType(p, "pvalSwitchGetTestexpr", PV_SWITCH)) 05642 return 0; 05643 return p->u1.str; 05644 }
| void pvalSwitchSetTestexpr | ( | pval * | p, | |
| char * | expr | |||
| ) |
Definition at line 5632 of file pval.c.
References PV_SWITCH, pvalCheckType(), pval::str, and pval::u1.
05633 { 05634 if (!pvalCheckType(p, "pvalSwitchSetTestexpr", PV_SWITCH)) 05635 return; 05636 p->u1.str = expr; 05637 }
Definition at line 5658 of file pval.c.
References pval::next, PV_SWITCH, pvalCheckType(), pval::statements, and pval::u2.
05659 { 05660 if (!pvalCheckType(p, "pvalSwitchWalkCases", PV_SWITCH)) 05661 return 0; 05662 if (!(*next_case)) 05663 *next_case = p->u2.statements; 05664 else { 05665 *next_case = (*next_case)->next; 05666 } 05667 return *next_case; 05668 }
Definition at line 5786 of file pval.c.
References pval::next.
| char* pvalVarDecGetValue | ( | pval * | p | ) |
Definition at line 5412 of file pval.c.
References PV_VARDEC, pvalCheckType(), pval::u2, and pval::val.
05413 { 05414 if (!pvalCheckType(p, "pvalVarDecGetValue", PV_VARDEC)) 05415 return 0; 05416 return p->u2.val; 05417 }
| char* pvalVarDecGetVarname | ( | pval * | p | ) |
Definition at line 5405 of file pval.c.
References PV_VARDEC, pvalCheckType(), pval::str, and pval::u1.
05406 { 05407 if (!pvalCheckType(p, "pvalVarDecGetVarname", PV_VARDEC)) 05408 return 0; 05409 return p->u1.str; 05410 }
| void pvalVarDecSetValue | ( | pval * | p, | |
| char * | value | |||
| ) |
Definition at line 5398 of file pval.c.
References PV_VARDEC, pvalCheckType(), pval::u2, and pval::val.
05399 { 05400 if (!pvalCheckType(p, "pvalVarDecSetValue", PV_VARDEC)) 05401 return; 05402 p->u2.val = value; 05403 }
| void pvalVarDecSetVarname | ( | pval * | p, | |
| char * | name | |||
| ) |
| char* pvalWordGetString | ( | pval * | p | ) |
Definition at line 4973 of file pval.c.
References PV_WORD, pvalCheckType(), pval::str, and pval::u1.
04974 { 04975 if (!pvalCheckType(p, "pvalWordGetString", PV_WORD)) 04976 return 0; 04977 return p->u1.str; 04978 }
| void pvalWordSetString | ( | pval * | p, | |
| char * | str | |||
| ) |
Definition at line 4966 of file pval.c.
References PV_WORD, pvalCheckType(), pval::str, and pval::u1.
Referenced by pvalIfTimeSetCondition().
04967 { 04968 if (!pvalCheckType(p, "pvalWordSetString", PV_WORD)) 04969 return; 04970 p->u1.str = str; 04971 }
| static void remove_spaces_before_equals | ( | char * | str | ) | [static] |
Definition at line 3035 of file pval.c.
Referenced by ast_compile_ael2(), and gen_prios().
| void set_priorities | ( | struct ael_extension * | exten | ) |
Definition at line 4181 of file pval.c.
References ael_extension::is_switch, ael_priority::next, ael_extension::next_exten, ael_priority::origin, ael_extension::plist, ael_priority::priority_num, PV_LABEL, ael_extension::regexten, and pval::type.
Referenced by ast_compile_ael2().
04182 { 04183 int i; 04184 struct ael_priority *pr; 04185 do { 04186 if (exten->is_switch) 04187 i = 10; 04188 else if (exten->regexten) 04189 i=2; 04190 else 04191 i=1; 04192 04193 for (pr=exten->plist; pr; pr=pr->next) { 04194 pr->priority_num = i; 04195 04196 if (!pr->origin || (pr->origin && pr->origin->type != PV_LABEL) ) /* Labels don't show up in the dialplan, 04197 but we want them to point to the right 04198 priority, which would be the next line 04199 after the label; */ 04200 i++; 04201 } 04202 04203 exten = exten->next_exten; 04204 } while ( exten ); 04205 }
| void traverse_pval_item_template | ( | pval * | item, | |
| int | depth | |||
| ) |
Definition at line 398 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().
00400 { 00401 pval *lp; 00402 00403 switch ( item->type ) { 00404 case PV_WORD: 00405 /* fields: item->u1.str == string associated with this (word). */ 00406 break; 00407 00408 case PV_MACRO: 00409 /* fields: item->u1.str == name of macro 00410 item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user 00411 item->u2.arglist->u1.str == argument 00412 item->u2.arglist->next == next arg 00413 00414 item->u3.macro_statements == pval list of statements in macro body. 00415 */ 00416 for (lp=item->u2.arglist; lp; lp=lp->next) { 00417 00418 } 00419 traverse_pval_item_template(item->u3.macro_statements,depth+1); 00420 break; 00421 00422 case PV_CONTEXT: 00423 /* fields: item->u1.str == name of context 00424 item->u2.statements == pval list of statements in context body 00425 item->u3.abstract == int 1 if an abstract keyword were present 00426 */ 00427 traverse_pval_item_template(item->u2.statements,depth+1); 00428 break; 00429 00430 case PV_MACRO_CALL: 00431 /* fields: item->u1.str == name of macro to call 00432 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 00433 item->u2.arglist->u1.str == argument 00434 item->u2.arglist->next == next arg 00435 */ 00436 for (lp=item->u2.arglist; lp; lp=lp->next) { 00437 } 00438 break; 00439 00440 case PV_APPLICATION_CALL: 00441 /* fields: item->u1.str == name of application to call 00442 item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user 00443 item->u2.arglist->u1.str == argument 00444 item->u2.arglist->next == next arg 00445 */ 00446 for (lp=item->u2.arglist; lp; lp=lp->next) { 00447 } 00448 break; 00449 00450 case PV_CASE: 00451 /* fields: item->u1.str == value of case 00452 item->u2.statements == pval list of statements under the case 00453 */ 00454 traverse_pval_item_template(item->u2.statements,depth+1); 00455 break; 00456 00457 case PV_PATTERN: 00458 /* fields: item->u1.str == value of case 00459 item->u2.statements == pval list of statements under the case 00460 */ 00461 traverse_pval_item_template(item->u2.statements,depth+1); 00462 break; 00463 00464 case PV_DEFAULT: 00465 /* fields: 00466 item->u2.statements == pval list of statements under the case 00467 */ 00468 traverse_pval_item_template(item->u2.statements,depth+1); 00469 break; 00470 00471 case PV_CATCH: 00472 /* fields: item->u1.str == name of extension to catch 00473 item->u2.statements == pval list of statements in context body 00474 */ 00475 traverse_pval_item_template(item->u2.statements,depth+1); 00476 break; 00477 00478 case PV_SWITCHES: 00479 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 00480 */ 00481 traverse_pval_item_template(item->u1.list,depth+1); 00482 break; 00483 00484 case PV_ESWITCHES: 00485 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 00486 */ 00487 traverse_pval_item_template(item->u1.list,depth+1); 00488 break; 00489 00490 case PV_INCLUDES: 00491 /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list 00492 item->u2.arglist == pval list of 4 PV_WORD elements for time values 00493 */ 00494 traverse_pval_item_template(item->u1.list,depth+1); 00495 traverse_pval_item_template(item->u2.arglist,depth+1); 00496 break; 00497 00498 case PV_STATEMENTBLOCK: 00499 /* fields: item->u1.list == pval list of statements in block, one per entry in the list 00500 */ 00501 traverse_pval_item_template(item->u1.list,depth+1); 00502 break; 00503 00504 case PV_LOCALVARDEC: 00505 case PV_VARDEC: 00506 /* fields: item->u1.str == variable name 00507 item->u2.val == variable value to assign 00508 */ 00509 break; 00510 00511 case PV_GOTO: 00512 /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user. 00513 item->u1.list->u1.str == where the data on a PV_WORD will always be. 00514 */ 00515 00516 if ( item->u1.list->next ) 00517 ; 00518 if ( item->u1.list->next && item->u1.list->next->next ) 00519 ; 00520 00521 break; 00522 00523 case PV_LABEL: 00524 /* fields: item->u1.str == label name 00525 */ 00526 break; 00527 00528 case PV_FOR: 00529 /* fields: item->u1.for_init == a string containing the initalizer 00530 item->u2.for_test == a string containing the loop test 00531 item->u3.for_inc == a string containing the loop increment 00532 00533 item->u4.for_statements == a pval list of statements in the for () 00534 */ 00535 traverse_pval_item_template(item->u4.for_statements,depth+1); 00536 break; 00537 00538 case PV_WHILE: 00539 /* fields: item->u1.str == the while conditional, as supplied by user 00540 00541 item->u2.statements == a pval list of statements in the while () 00542 */ 00543 traverse_pval_item_template(item->u2.statements,depth+1); 00544 break; 00545 00546 case PV_BREAK: 00547 /* fields: none 00548 */ 00549 break; 00550 00551 case PV_RETURN: 00552 /* fields: none 00553 */ 00554 break; 00555 00556 case PV_CONTINUE: 00557 /* fields: none 00558 */ 00559 break; 00560 00561 case PV_IFTIME: 00562 /* fields: item->u1.list == there are 4 linked PV_WORDs here. 00563 00564 item->u2.statements == a pval list of statements in the if () 00565 item->u3.else_statements == a pval list of statements in the else 00566 (could be zero) 00567 */ 00568 traverse_pval_item_template(item->u2.statements,depth+1); 00569 if ( item->u3.else_statements ) { 00570 traverse_pval_item_template(item->u3.else_statements,depth+1); 00571 } 00572 break; 00573 00574 case PV_RANDOM: 00575 /* fields: item->u1.str == the random number expression, as supplied by user 00576 00577 item->u2.statements == a pval list of statements in the if () 00578 item->u3.else_statements == a pval list of statements in the else 00579 (could be zero) 00580 */ 00581 traverse_pval_item_template(item->u2.statements,depth+1); 00582 if ( item->u3.else_statements ) { 00583 traverse_pval_item_template(item->u3.else_statements,depth+1); 00584 } 00585 break; 00586 00587 case PV_IF: 00588 /* fields: item->u1.str == the if conditional, as supplied by user 00589 00590 item->u2.statements == a pval list of statements in the if () 00591 item->u3.else_statements == a pval list of statements in the else 00592 (could be zero) 00593 */ 00594 traverse_pval_item_template(item->u2.statements,depth+1); 00595 if ( item->u3.else_statements ) { 00596 traverse_pval_item_template(item->u3.else_statements,depth+1); 00597 } 00598 break; 00599 00600 case PV_SWITCH: 00601 /* fields: item->u1.str == the switch expression 00602 00603 item->u2.statements == a pval list of statements in the switch, 00604 (will be case statements, most likely!) 00605 */ 00606 traverse_pval_item_template(item->u2.statements,depth+1); 00607 break; 00608 00609 case PV_EXTENSION: 00610 /* fields: item->u1.str == the extension name, label, whatever it's called 00611 00612 item->u2.statements == a pval list of statements in the extension 00613 item->u3.hints == a char * hint argument 00614 item->u4.regexten == an int boolean. non-zero says that regexten was specified 00615 */ 00616 traverse_pval_item_template(item->u2.statements,depth+1); 00617 break; 00618 00619 case PV_IGNOREPAT: 00620 /* fields: item->u1.str == the ignorepat data 00621 */ 00622 break; 00623 00624 case PV_GLOBALS: 00625 /* fields: item->u1.statements == pval list of statements, usually vardecs 00626 */ 00627 traverse_pval_item_template(item->u1.statements,depth+1); 00628 break; 00629 } 00630 }
| void traverse_pval_template | ( | pval * | item, | |
| int | depth | |||
| ) |
Definition at line 632 of file pval.c.
References pval::next, and traverse_pval_item_template().
00634 { 00635 pval *i; 00636 00637 for (i=item; i; i=i->next) { 00638 traverse_pval_item_template(i, depth); 00639 } 00640 }
int control_statement_count = 0 [static] |
int count_labels [static] |
pval* current_context [static] |
pval* current_db [static] |
pval* current_extension [static] |
int errs [static] |
Definition at line 63 of file pval.c.
Referenced by pbx_load_module().
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] |
1.6.2