#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/callerid.h"
#include "asterisk/ael_structs.h"
Include dependency graph for pbx_ael.c:

Go to the source code of this file.
Data Structures | |
| struct | argapp |
Defines | |
| #define | DEBUG_CONTEXTS (1 << 3) |
| #define | DEBUG_MACROS (1 << 2) |
| #define | DEBUG_READ (1 << 0) |
| #define | DEBUG_TOKENS (1 << 1) |
Functions | |
| void | add_extensions (struct ael_extension *exten) |
| static int | ael2_debug_contexts (int fd, int argc, char *argv[]) |
| static int | ael2_debug_macros (int fd, int argc, char *argv[]) |
| static int | ael2_debug_read (int fd, int argc, char *argv[]) |
| static int | ael2_debug_tokens (int fd, int argc, char *argv[]) |
| static int | ael2_no_debug (int fd, int argc, char *argv[]) |
| static int | ael2_reload (int fd, int argc, char *argv[]) |
| static void | ael2_semantic_check (pval *item, int *arg_errs, int *arg_warns, int *arg_notes) |
| void | ast_compile_ael2 (struct ast_context **local_contexts, struct pval *root) |
| int | ast_expr (char *expr, char *buf, int length) |
| void | ast_expr_clear_extra_error_info (void) |
| void | ast_expr_register_extra_error_info (char *errmsg) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"Asterisk Extension Language Compiler",.load=load_module,.unload=unload_module,.reload=reload,) | |
| static void | attach_exten (struct ael_extension **list, struct ael_extension *newmem) |
| static void | check_abstract_reference (pval *abstract_context) |
| int | check_app_args (pval *appcall, pval *arglist, struct argapp *app) |
| static int | check_break (pval *item) |
| static void | check_context_names (void) |
| static int | check_continue (pval *item) |
| static void | check_day (pval *DAY) |
| static void | check_dow (pval *DOW) |
| get_dow: Get day of week | |
| static void | check_expr2_input (pval *expr, char *str) |
| static void | check_goto (pval *item) |
| static void | check_includes (pval *includes) |
| static void | check_label (pval *item) |
| static void | check_month (pval *MON) |
| void | check_pval (pval *item, struct argapp *apps, int in_globals) |
| void | check_pval_item (pval *item, struct argapp *apps, int in_globals) |
| void | check_switch_expr (pval *item, struct argapp *apps) |
| static void | check_timerange (pval *p) |
| int | contains_switch (pval *item) |
| void | destroy_extensions (struct ael_extension *exten) |
| void | destroy_pval (pval *item) |
| void | destroy_pval_item (pval *item) |
| static int | extension_matches (pval *here, const char *exten, const char *pattern) |
| pval * | find_context (char *name) |
| static struct pval * | find_first_label_in_current_context (char *label, pval *curr_cont) |
| static struct pval * | find_label_in_current_context (char *exten, char *label, pval *curr_cont) |
| static struct pval * | find_label_in_current_db (const char *context, const char *exten, const char *label) |
| static struct pval * | find_label_in_current_extension (const char *label, pval *curr_ext) |
| pval * | find_macro (char *name) |
| static void | find_pval_goto_item (pval *item, int lev) |
| static void | find_pval_gotos (pval *item, int lev) |
| int | find_switch_item (pval *item) |
| static void | fix_gotos_in_extensions (struct ael_extension *exten) |
| static void | gen_match_to_pattern (char *pattern, char *result) |
| static void | gen_prios (struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *context) |
| static pval * | get_contxt (pval *p) |
| static pval * | get_extension_or_contxt (pval *p) |
| static pval * | get_goto_target (pval *item) |
| int | is_empty (char *arg) |
| int | is_float (char *arg) |
| int | is_int (char *arg) |
| static int | label_inside_case (pval *label) |
| static void | linkexten (struct ael_extension *exten, struct ael_extension *add) |
| void | linkprio (struct ael_extension *exten, struct ael_priority *prio, struct ael_extension *mother_exten) |
| static int | load_module (void) |
| pval * | match_pval (pval *item) |
| static struct pval * | match_pval_item (pval *item) |
| ael_extension * | new_exten (void) |
| ael_priority * | new_prio (void) |
| static int | pbx_load_module (void) |
| static void | print_pval (FILE *fin, pval *item, int depth) |
| static void | print_pval_list (FILE *fin, pval *item, int depth) |
| static int | reload (void) |
| static void | remove_spaces_before_equals (char *str) |
| void | set_priorities (struct ael_extension *exten) |
| static void | substitute_commas (char *str) |
| void | traverse_pval_item_template (pval *item, int depth) |
| void | traverse_pval_template (pval *item, int depth) |
| static int | unload_module (void) |
Variables | |
| static int | aeldebug = 0 |
| static struct ast_cli_entry | cli_ael [] |
| static struct ast_cli_entry | cli_ael_no_debug |
| static char * | config = "extensions.ael" |
| static int | control_statement_count = 0 |
| static int | count_labels |
| static pval * | current_context = 0 |
| static pval * | current_db = 0 |
| static pval * | current_extension = 0 |
| static char * | days [] |
| static int | errs |
| static char | expr_output [2096] |
| static int | in_abstract_context |
| static int | label_count |
| static pval * | last_matched_label |
| static const char * | match_context |
| static const char * | match_exten |
| static const char * | match_label |
| static char * | months [] |
| static int | notes |
| static char * | registrar = "pbx_ael" |
| static int | return_on_context_match |
| static int | warns |
Definition in file pbx_ael.c.
| #define DEBUG_CONTEXTS (1 << 3) |
| #define DEBUG_MACROS (1 << 2) |
| #define DEBUG_READ (1 << 0) |
| #define DEBUG_TOKENS (1 << 1) |
| void add_extensions | ( | struct ael_extension * | exten | ) |
Definition at line 4065 of file pbx_ael.c.
References AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_LABEL, AEL_RAND_CONTROL, AEL_RETURN, ael_priority::app, app, ael_priority::appargs, ast_add_extension2(), ast_free, ast_log(), AST_MAX_EXTENSION, pval::else_statements, ael_priority::exten, exten, ael_priority::goto_false, ael_priority::goto_true, last, LOG_WARNING, ael_extension::name, ael_priority::next, ael_priority::origin, pbx_substitute_variables_helper(), PRIORITY_HINT, ael_priority::priority_num, PV_IFTIME, PV_SWITCH, strdup, pval::type, ael_priority::type, and pval::u3.
04066 { 04067 struct ael_priority *pr; 04068 char *label=0; 04069 char realext[AST_MAX_EXTENSION]; 04070 if (!exten) { 04071 ast_log(LOG_WARNING, "This file is Empty!\n" ); 04072 return; 04073 } 04074 do { 04075 struct ael_priority *last = 0; 04076 04077 memset(realext, '\0', sizeof(realext)); 04078 pbx_substitute_variables_helper(NULL, exten->name, realext, sizeof(realext) - 1); 04079 if (exten->hints) { 04080 if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, PRIORITY_HINT, NULL, exten->cidmatch, 04081 exten->hints, NULL, ast_free, registrar)) { 04082 ast_log(LOG_WARNING, "Unable to add step at priority 'hint' of extension '%s'\n", 04083 exten->name); 04084 } 04085 } 04086 04087 for (pr=exten->plist; pr; pr=pr->next) { 04088 char app[2000]; 04089 char appargs[2000]; 04090 04091 /* before we can add the extension, we need to prep the app/appargs; 04092 the CONTROL types need to be done after the priority numbers are calculated. 04093 */ 04094 if (pr->type == AEL_LABEL) /* don't try to put labels in the dialplan! */ { 04095 last = pr; 04096 continue; 04097 } 04098 04099 if (pr->app) 04100 strcpy(app, pr->app); 04101 else 04102 app[0] = 0; 04103 if (pr->appargs ) 04104 strcpy(appargs, pr->appargs); 04105 else 04106 appargs[0] = 0; 04107 switch( pr->type ) { 04108 case AEL_APPCALL: 04109 /* easy case. Everything is all set up */ 04110 break; 04111 04112 case AEL_CONTROL1: /* FOR loop, WHILE loop, BREAK, CONTINUE, IF, IFTIME */ 04113 /* simple, unconditional goto. */ 04114 strcpy(app,"Goto"); 04115 if (pr->goto_true->origin && pr->goto_true->origin->type == PV_SWITCH ) { 04116 snprintf(appargs,sizeof(appargs),"%s|%d", pr->goto_true->exten->name, pr->goto_true->priority_num); 04117 } else if (pr->goto_true->origin && pr->goto_true->origin->type == PV_IFTIME && pr->goto_true->origin->u3.else_statements ) { 04118 snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num+1); 04119 } else 04120 snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num); 04121 break; 04122 04123 case AEL_FOR_CONTROL: /* WHILE loop test, FOR loop test */ 04124 strcpy(app,"GotoIf"); 04125 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num); 04126 break; 04127 04128 case AEL_IF_CONTROL: 04129 strcpy(app,"GotoIf"); 04130 if (pr->origin->u3.else_statements ) 04131 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num+1); 04132 else 04133 snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num); 04134 break; 04135 04136 case AEL_RAND_CONTROL: 04137 strcpy(app,"Random"); 04138 snprintf(appargs,sizeof(appargs),"%s:%d", pr->appargs, pr->goto_true->priority_num+1); 04139 break; 04140 04141 case AEL_IFTIME_CONTROL: 04142 strcpy(app,"GotoIfTime"); 04143 snprintf(appargs,sizeof(appargs),"%s?%d", pr->appargs, pr->priority_num+2); 04144 break; 04145 04146 case AEL_RETURN: 04147 strcpy(app,"Goto"); 04148 snprintf(appargs,sizeof(appargs), "%d", exten->return_target->priority_num); 04149 break; 04150 04151 default: 04152 break; 04153 } 04154 if (last && last->type == AEL_LABEL ) { 04155 label = last->origin->u1.str; 04156 } 04157 else 04158 label = 0; 04159 04160 if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, pr->priority_num, (label?label:NULL), exten->cidmatch, 04161 app, strdup(appargs), ast_free, registrar)) { 04162 ast_log(LOG_WARNING, "Unable to add step at priority '%d' of extension '%s'\n", pr->priority_num, 04163 exten->name); 04164 } 04165 last = pr; 04166 } 04167 exten = exten->next_exten; 04168 } while ( exten ); 04169 }
| static int ael2_debug_contexts | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4526 of file pbx_ael.c.
References DEBUG_CONTEXTS.
04527 { 04528 aeldebug |= DEBUG_CONTEXTS; 04529 return 0; 04530 }
| static int ael2_debug_macros | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4520 of file pbx_ael.c.
References DEBUG_MACROS.
04521 { 04522 aeldebug |= DEBUG_MACROS; 04523 return 0; 04524 }
| static int ael2_debug_read | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4508 of file pbx_ael.c.
References DEBUG_READ.
04509 { 04510 aeldebug |= DEBUG_READ; 04511 return 0; 04512 }
| static int ael2_debug_tokens | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4514 of file pbx_ael.c.
References DEBUG_TOKENS.
04515 { 04516 aeldebug |= DEBUG_TOKENS; 04517 return 0; 04518 }
| static int ael2_no_debug | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
| static int ael2_reload | ( | int | fd, | |
| int | argc, | |||
| char * | argv[] | |||
| ) | [static] |
Definition at line 4538 of file pbx_ael.c.
References pbx_load_module().
04539 { 04540 return (pbx_load_module()); 04541 }
| static void ael2_semantic_check | ( | pval * | item, | |
| int * | arg_errs, | |||
| int * | arg_warns, | |||
| int * | arg_notes | |||
| ) | [static] |
Definition at line 2743 of file pbx_ael.c.
References ast_config_AST_VAR_DIR, check_context_names(), check_pval(), and current_db.
Referenced by pbx_load_module().
02744 { 02745 02746 #ifdef AAL_ARGCHECK 02747 int argapp_errs =0; 02748 char *rfilename; 02749 #endif 02750 struct argapp *apps=0; 02751 02752 if (!item) 02753 return; /* don't check an empty tree */ 02754 #ifdef AAL_ARGCHECK 02755 rfilename = alloca(10 + strlen(ast_config_AST_VAR_DIR)); 02756 sprintf(rfilename, "%s/applist", ast_config_AST_VAR_DIR); 02757 02758 apps = argdesc_parse(rfilename, &argapp_errs); /* giveth */ 02759 #endif 02760 current_db = item; 02761 errs = warns = notes = 0; 02762 02763 check_context_names(); 02764 check_pval(item, apps, 0); 02765 02766 #ifdef AAL_ARGCHECK 02767 argdesc_destroy(apps); /* taketh away */ 02768 #endif 02769 current_db = 0; 02770 02771 *arg_errs = errs; 02772 *arg_warns = warns; 02773 *arg_notes = notes; 02774 }
| void ast_compile_ael2 | ( | struct ast_context ** | local_contexts, | |
| struct pval * | root | |||
| ) |
Definition at line 4252 of file pbx_ael.c.
References context, exten, pval::list, pval::next, pbx_builtin_setvar(), PV_GLOBALS, pval::str, pval::type, pval::u1, pval::u2, and pval::val.
Referenced by pbx_load_module().
04253 { 04254 pval *p,*p2; 04255 struct ast_context *context; 04256 char buf[2000]; 04257 struct ael_extension *exten; 04258 struct ael_extension *exten_list = 0; 04259 04260 for (p=root; p; p=p->next ) { /* do the globals first, so they'll be there 04261 when we try to eval them */ 04262 switch (p->type) { 04263 case PV_GLOBALS: 04264 /* just VARDEC elements */ 04265 for (p2=p->u1.list; p2; p2=p2->next) { 04266 char buf2[2000]; 04267 snprintf(buf2,sizeof(buf2),"%s=%s", p2->u1.str, p2->u2.val); 04268 pbx_builtin_setvar(NULL, buf2); 04269 } 04270 break; 04271 default: 04272 break; 04273 } 04274 } 04275 04276 for (p=root; p; p=p->next ) { 04277 pval *lp; 04278 int argc; 04279 04280 switch (p->type) { 04281 case PV_MACRO: 04282 strcpy(buf,"macro-"); 04283 strcat(buf,p->u1.str); 04284 context = ast_context_create(local_contexts, buf, registrar); 04285 04286 exten = new_exten(); 04287 exten->context = context; 04288 exten->name = strdup("s"); 04289 argc = 1; 04290 for (lp=p->u2.arglist; lp; lp=lp->next) { 04291 /* for each arg, set up a "Set" command */ 04292 struct ael_priority *np2 = new_prio(); 04293 np2->type = AEL_APPCALL; 04294 np2->app = strdup("Set"); 04295 snprintf(buf,sizeof(buf),"%s=${ARG%d}", lp->u1.str, argc++); 04296 remove_spaces_before_equals(buf); 04297 np2->appargs = strdup(buf); 04298 linkprio(exten, np2, NULL); 04299 } 04300 /* add any includes */ 04301 for (p2=p->u3.macro_statements; p2; p2=p2->next) { 04302 pval *p3; 04303 04304 switch (p2->type) { 04305 case PV_INCLUDES: 04306 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04307 if ( p3->u2.arglist ) { 04308 snprintf(buf,sizeof(buf), "%s|%s|%s|%s|%s", 04309 p3->u1.str, 04310 p3->u2.arglist->u1.str, 04311 p3->u2.arglist->next->u1.str, 04312 p3->u2.arglist->next->next->u1.str, 04313 p3->u2.arglist->next->next->next->u1.str); 04314 ast_context_add_include2(context, buf, registrar); 04315 } else 04316 ast_context_add_include2(context, p3->u1.str, registrar); 04317 } 04318 break; 04319 default: 04320 break; 04321 } 04322 } 04323 /* CONTAINS APPCALLS, CATCH, just like extensions... */ 04324 gen_prios(exten, p->u1.str, p->u3.macro_statements, 0, context ); 04325 if (exten->return_needed) { 04326 struct ael_priority *np2 = new_prio(); 04327 np2->type = AEL_APPCALL; 04328 np2->app = strdup("NoOp"); 04329 snprintf(buf,sizeof(buf),"End of Macro %s-%s",p->u1.str, exten->name); 04330 np2->appargs = strdup(buf); 04331 linkprio(exten, np2, NULL); 04332 exten-> return_target = np2; 04333 } 04334 04335 set_priorities(exten); 04336 attach_exten(&exten_list, exten); 04337 break; 04338 04339 case PV_GLOBALS: 04340 /* already done */ 04341 break; 04342 04343 case PV_CONTEXT: 04344 context = ast_context_find_or_create(local_contexts, p->u1.str, registrar); 04345 04346 /* contexts contain: ignorepat, includes, switches, eswitches, extensions, */ 04347 for (p2=p->u2.statements; p2; p2=p2->next) { 04348 pval *p3; 04349 char *s3; 04350 04351 switch (p2->type) { 04352 case PV_EXTENSION: 04353 exten = new_exten(); 04354 exten->name = strdup(p2->u1.str); 04355 exten->context = context; 04356 04357 if( (s3=strchr(exten->name, '/') ) != 0 ) 04358 { 04359 *s3 = 0; 04360 exten->cidmatch = s3+1; 04361 } 04362 04363 if ( p2->u3.hints ) 04364 exten->hints = strdup(p2->u3.hints); 04365 exten->regexten = p2->u4.regexten; 04366 gen_prios(exten, p->u1.str, p2->u2.statements, 0, context ); 04367 if (exten->return_needed) { 04368 struct ael_priority *np2 = new_prio(); 04369 np2->type = AEL_APPCALL; 04370 np2->app = strdup("NoOp"); 04371 snprintf(buf,sizeof(buf),"End of Extension %s", exten->name); 04372 np2->appargs = strdup(buf); 04373 linkprio(exten, np2, NULL); 04374 exten-> return_target = np2; 04375 } 04376 /* is the last priority in the extension a label? Then add a trailing no-op */ 04377 if ( exten->plist_last && exten->plist_last->type == AEL_LABEL ) { 04378 struct ael_priority *np2 = new_prio(); 04379 np2->type = AEL_APPCALL; 04380 np2->app = strdup("NoOp"); 04381 snprintf(buf,sizeof(buf),"A NoOp to follow a trailing label %s", exten->plist_last->origin->u1.str); 04382 np2->appargs = strdup(buf); 04383 linkprio(exten, np2, NULL); 04384 } 04385 04386 set_priorities(exten); 04387 attach_exten(&exten_list, exten); 04388 break; 04389 04390 case PV_IGNOREPAT: 04391 ast_context_add_ignorepat2(context, p2->u1.str, registrar); 04392 break; 04393 04394 case PV_INCLUDES: 04395 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04396 if ( p3->u2.arglist ) { 04397 snprintf(buf,sizeof(buf), "%s|%s|%s|%s|%s", 04398 p3->u1.str, 04399 p3->u2.arglist->u1.str, 04400 p3->u2.arglist->next->u1.str, 04401 p3->u2.arglist->next->next->u1.str, 04402 p3->u2.arglist->next->next->next->u1.str); 04403 ast_context_add_include2(context, buf, registrar); 04404 } else 04405 ast_context_add_include2(context, p3->u1.str, registrar); 04406 } 04407 break; 04408 04409 case PV_SWITCHES: 04410 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04411 char *c = strchr(p3->u1.str, '/'); 04412 if (c) { 04413 *c = '\0'; 04414 c++; 04415 } else 04416 c = ""; 04417 04418 ast_context_add_switch2(context, p3->u1.str, c, 0, registrar); 04419 } 04420 break; 04421 04422 case PV_ESWITCHES: 04423 for (p3 = p2->u1.list; p3 ;p3=p3->next) { 04424 char *c = strchr(p3->u1.str, '/'); 04425 if (c) { 04426 *c = '\0'; 04427 c++; 04428 } else 04429 c = ""; 04430 04431 ast_context_add_switch2(context, p3->u1.str, c, 1, registrar); 04432 } 04433 break; 04434 default: 04435 break; 04436 } 04437 } 04438 04439 break; 04440 04441 default: 04442 /* huh? what? */ 04443 break; 04444 04445 } 04446 } 04447 /* moved these from being done after a macro or extension were processed, 04448 to after all processing is done, for the sake of fixing gotos to labels inside cases... */ 04449 /* I guess this would be considered 2nd pass of compiler now... */ 04450 fix_gotos_in_extensions(exten_list); /* find and fix extension ref in gotos to labels that are in case statements */ 04451 add_extensions(exten_list); /* actually makes calls to create priorities in ast_contexts -- feeds dialplan to asterisk */ 04452 destroy_extensions(exten_list); /* all that remains is an empty husk, discard of it as is proper */ 04453 04454 }
| int ast_expr | ( | char * | expr, | |
| char * | buf, | |||
| int | length | |||
| ) |
Definition at line 2288 of file ast_expr2f.c.
References AST_EXPR_integer, ast_yy_scan_string(), ast_yylex_destroy(), ast_yylex_init(), ast_yyparse(), free, and io.
Referenced by check_pval_item(), and pbx_substitute_variables_helper_full().
02289 { 02290 struct parse_io io; 02291 int return_value = 0; 02292 02293 memset(&io, 0, sizeof(io)); 02294 io.string = expr; /* to pass to the error routine */ 02295 02296 ast_yylex_init(&io.scanner); 02297 02298 ast_yy_scan_string(expr, io.scanner); 02299 02300 ast_yyparse ((void *) &io); 02301 02302 ast_yylex_destroy(io.scanner); 02303 02304 if (!io.val) { 02305 if (length > 1) { 02306 strcpy(buf, "0"); 02307 return_value = 1; 02308 } 02309 } else { 02310 if (io.val->type == AST_EXPR_integer) { 02311 int res_length; 02312 02313 res_length = snprintf(buf, length, "%ld", (long int) io.val->u.i); 02314 return_value = (res_length <= length) ? res_length : length; 02315 } else { 02316 #if defined(STANDALONE) || defined(LOW_MEMORY) || defined(STANDALONE_AEL) 02317 strncpy(buf, io.val->u.s, length - 1); 02318 #else /* !STANDALONE && !LOW_MEMORY */ 02319 ast_copy_string(buf, io.val->u.s, length); 02320 #endif /* STANDALONE || LOW_MEMORY */ 02321 return_value = strlen(buf); 02322 free(io.val->u.s); 02323 } 02324 free(io.val); 02325 } 02326 return return_value; 02327 }
| void ast_expr_clear_extra_error_info | ( | void | ) |
| void ast_expr_register_extra_error_info | ( | char * | errmsg | ) |
| AST_MODULE_INFO | ( | ASTERISK_GPL_KEY | , | |
| AST_MODFLAG_DEFAULT | , | |||
| "Asterisk Extension Language Compiler" | , | |||
| . | load = load_module, |
|||
| . | unload = unload_module, |
|||
| . | reload = reload | |||
| ) |
| static void attach_exten | ( | struct ael_extension ** | list, | |
| struct ael_extension * | newmem | |||
| ) | [static] |
Definition at line 4171 of file pbx_ael.c.
References ael_extension::next_exten.
04172 { 04173 /* travel to the end of the list... */ 04174 struct ael_extension *lptr; 04175 if( !*list ) { 04176 *list = newmem; 04177 return; 04178 } 04179 lptr = *list; 04180 04181 while( lptr->next_exten ) { 04182 lptr = lptr->next_exten; 04183 } 04184 /* lptr should now pointing to the last element in the list; it has a null next_exten pointer */ 04185 lptr->next_exten = newmem; 04186 }
| static void check_abstract_reference | ( | pval * | abstract_context | ) | [static] |
Definition at line 2276 of file pbx_ael.c.
References current_db, pval::list, pval::next, PV_CONTEXT, PV_INCLUDES, pval::str, pval::type, pval::u1, and pval::u2.
Referenced by check_pval_item().
02277 { 02278 pval *i,*j; 02279 /* find some context includes that reference this context */ 02280 02281 02282 /* otherwise, print out a warning */ 02283 for (i=current_db; i; i=i->next) { 02284 if (i->type == PV_CONTEXT) { 02285 for (j=i->u2. statements; j; j=j->next) { 02286 if ( j->type == PV_INCLUDES ) { 02287 struct pval *p4; 02288 for (p4=j->u1.list; p4; p4=p4->next) { 02289 /* for each context pointed to, find it, then find a context/label that matches the 02290 target here! */ 02291 if ( !strcmp(p4->u1.str, abstract_context->u1.str) ) 02292 return; /* found a match! */ 02293 } 02294 } 02295 } 02296 } 02297 } 02298 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", 02299 abstract_context->filename, abstract_context->startline, abstract_context->endline, abstract_context->u1.str); 02300 warns++; 02301 }