Fri Nov 12 12:07:14 2010

Asterisk developer's documentation


pval.c File Reference

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"
Include dependency graph for pval.c:

Go to the source code of this file.

Defines

#define AST_PBX_MAX_STACK   128

Functions

void add_extensions (struct ael_extension *exten)
void ael2_print (char *fname, pval *tree)
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 ast_hashtab *local_table, struct pval *root)
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_macro_returns (pval *macro)
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)
struct pvalfind_context (char *name)
static struct pvalfind_first_label_in_current_context (char *label, pval *curr_cont)
static struct pvalfind_label_in_current_context (char *exten, char *label, pval *curr_cont)
static struct pvalfind_label_in_current_db (const char *context, const char *exten, const char *label)
static struct pvalfind_label_in_current_extension (const char *label, pval *curr_ext)
struct pvalfind_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 *this_context)
static pvalget_contxt (pval *p)
static pvalget_extension_or_contxt (pval *p)
static pvalget_goto_target (pval *item)
static struct pvalin_context (pval *item)
static struct pvalin_macro (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)
pvallinku1 (pval *head, pval *tail)
int localized_pbx_load_module (void)
struct pvalmatch_pval (pval *item)
static struct pvalmatch_pval_item (pval *item)
struct ael_extensionnew_exten (void)
struct ael_prioritynew_prio (void)
static void print_pval (FILE *fin, pval *item, int depth)
static void print_pval_list (FILE *fin, pval *item, int depth)
void pvalAppCallAddArg (pval *p, pval *arg)
char * pvalAppCallGetAppName (pval *p)
void pvalAppCallSetAppName (pval *p, char *name)
void pvalAppCallSetArglist (pval *p, pval *arglist)
pvalpvalAppCallWalkArgs (pval *p, pval **args)
void pvalCasePatDefAddStatement (pval *p, pval *statement)
pvalpvalCasePatDefWalkStatements (pval *p, pval **statement)
char * pvalCasePatGetVal (pval *p)
void pvalCasePatSetVal (pval *p, char *val)
char * pvalCatchGetExtName (pval *p)
pvalpvalCatchGetStatement (pval *p)
void pvalCatchSetExtName (pval *p, char *name)
void pvalCatchSetStatement (pval *p, pval *statement)
int pvalCheckType (pval *p, char *funcname, pvaltype type)
pvalpvalConditionalGetElseStatement (pval *p)
pvalpvalConditionalGetThenStatement (pval *p)
void pvalConditionalSetElseStatement (pval *p, pval *statement)
void pvalConditionalSetThenStatement (pval *p, pval *statement)
void pvalContextAddStatement (pval *p, pval *statement)
int pvalContextGetAbstract (pval *p)
char * pvalContextGetName (pval *p)
void pvalContextSetAbstract (pval *p)
void pvalContextSetName (pval *p, char *name)
void pvalContextUnsetAbstract (pval *p)
pvalpvalContextWalkStatements (pval *p, pval **statements)
pvalpvalCreateNode (pvaltype type)
void pvalESwitchesAddSwitch (pval *p, char *name)
char * pvalESwitchesWalkNames (pval *p, pval **next_item)
char * pvalExtenGetHints (pval *p)
char * pvalExtenGetName (pval *p)
int pvalExtenGetRegexten (pval *p)
pvalpvalExtenGetStatement (pval *p)
void pvalExtenSetHints (pval *p, char *hints)
void pvalExtenSetName (pval *p, char *name)
void pvalExtenSetRegexten (pval *p)
void pvalExtenSetStatement (pval *p, pval *statement)
void pvalExtenUnSetRegexten (pval *p)
char * pvalForGetInc (pval *p)
char * pvalForGetInit (pval *p)
pvalpvalForGetStatement (pval *p)
char * pvalForGetTest (pval *p)
void pvalForSetInc (pval *p, char *inc)
void pvalForSetInit (pval *p, char *init)
void pvalForSetStatement (pval *p, pval *statement)
void pvalForSetTest (pval *p, char *test)
void pvalGlobalsAddStatement (pval *p, pval *statement)
pvalpvalGlobalsWalkStatements (pval *p, pval **next_statement)
void pvalGotoGetTarget (pval *p, char **context, char **exten, char **label)
void pvalGotoSetTarget (pval *p, char *context, char *exten, char *label)
char * pvalIfGetCondition (pval *p)
void pvalIfSetCondition (pval *p, char *expr)
void pvalIfTimeGetCondition (pval *p, char **hour_range, char **dow_range, char **dom_range, char **month_range)
void pvalIfTimeSetCondition (pval *p, char *hour_range, char *dow_range, char *dom_range, char *mon_range)
char * pvalIgnorePatGetPattern (pval *p)
void pvalIgnorePatSetPattern (pval *p, char *pat)
void pvalIncludeGetTimeConstraints (pval *p, char **hour_range, char **dom_range, char **dow_range, char **month_range)
void pvalIncludesAddInclude (pval *p, const char *include)
void pvalIncludesAddIncludeWithTimeConstraints (pval *p, const char *include, char *hour_range, char *dom_range, char *dow_range, char *month_range)
char * pvalIncludesWalk (pval *p, pval **next_item)
char * pvalLabelGetName (pval *p)
void pvalLabelSetName (pval *p, char *name)
void pvalMacroAddArg (pval *p, pval *arg)
void pvalMacroAddStatement (pval *p, pval *statement)
void pvalMacroCallAddArg (pval *p, pval *arg)
char * pvalMacroCallGetMacroName (pval *p)
void pvalMacroCallSetArglist (pval *p, pval *arglist)
void pvalMacroCallSetMacroName (pval *p, char *name)
pvalpvalMacroCallWalkArgs (pval *p, pval **args)
char * pvalMacroGetName (pval *p)
void pvalMacroSetArglist (pval *p, pval *arglist)
void pvalMacroSetName (pval *p, char *name)
pvalpvalMacroWalkArgs (pval *p, pval **arg)
pvalpvalMacroWalkStatements (pval *p, pval **next_statement)
pvaltype pvalObjectGetType (pval *p)
char * pvalRandomGetCondition (pval *p)
void pvalRandomSetCondition (pval *p, char *percent)
void pvalStatementBlockAddStatement (pval *p, pval *statement)
pvalpvalStatementBlockWalkStatements (pval *p, pval **next_statement)
void pvalSwitchAddCase (pval *p, pval *Case)
void pvalSwitchesAddSwitch (pval *p, char *name)
char * pvalSwitchesWalkNames (pval *p, pval **next_item)
char * pvalSwitchGetTestexpr (pval *p)
void pvalSwitchSetTestexpr (pval *p, char *expr)
pvalpvalSwitchWalkCases (pval *p, pval **next_case)
void pvalTopLevAddObject (pval *p, pval *contextOrObj)
pvalpvalTopLevWalkObjects (pval *p, pval **next_obj)
char * pvalVarDecGetValue (pval *p)
char * pvalVarDecGetVarname (pval *p)
void pvalVarDecSetValue (pval *p, char *value)
void pvalVarDecSetVarname (pval *p, char *name)
char * pvalWordGetString (pval *p)
void pvalWordSetString (pval *p, char *str)
static void remove_spaces_before_equals (char *str)
void set_priorities (struct ael_extension *exten)
void traverse_pval_item_template (pval *item, int depth)
void traverse_pval_template (pval *item, int depth)

Variables

struct ast_flags ast_compat
static int control_statement_count = 0
static int count_labels
static pvalcurrent_context
static pvalcurrent_db
static pvalcurrent_extension
static char * days []
static int errs
static char expr_output [2096]
static int in_abstract_context
static int label_count
static pvallast_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

Detailed Description

Compile symbolic Asterisk Extension Logic into Asterisk extensions, version 2.

Definition in file pval.c.


Define Documentation

#define AST_PBX_MAX_STACK   128

Definition at line 59 of file pval.c.


Function Documentation

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 }

int check_app_args ( pval appcall,
pval arglist,
struct argapp app 
)

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().

00805 {
00806    int spaces = strspn(str,"\t \n");
00807    if ( !strncmp(str+spaces,"$[",2) ) {
00808       ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n",
00809             expr->filename, expr->startline, expr->endline, str);
00810       warns++;
00811    }
00812 }

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 }

void check_pval ( pval item,
struct argapp apps,
int  in_globals 
)

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 }

void check_pval_item ( pval item,
struct argapp apps,
int  in_globals 
)

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 }

void check_switch_expr ( pval item,
struct argapp apps 
)

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 }

struct pval * find_first_label_in_current_context ( char *  label,
pval curr_cont 
) [static, read]

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 }

static pval * get_contxt ( pval p  )  [static]

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 }

static pval * get_extension_or_contxt ( pval p  )  [static]

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 }

static pval * get_goto_target ( pval item  )  [static]

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 }

static struct pval* in_context ( pval item  )  [static, read]

Definition at line 1093 of file pval.c.

References pval::dad, PV_CONTEXT, PV_MACRO, and pval::type.

Referenced by check_goto().

01094 {
01095    struct pval *curr;
01096    curr = item;   
01097    while( curr ) {
01098       if( curr->type == PV_MACRO || curr->type == PV_CONTEXT ) {
01099          return curr;
01100       }
01101       curr = curr->dad;
01102    }
01103    return 0;
01104 }

static struct pval* in_macro ( pval item  )  [static, read]

Definition at line 1080 of file pval.c.

References pval::dad, PV_MACRO, and pval::type.

Referenced by check_goto().

01081 {
01082    struct pval *curr;
01083    curr = item;   
01084    while( curr ) {
01085       if( curr->type == PV_MACRO  ) {
01086          return curr;
01087       }
01088       curr = curr->dad;
01089    }
01090    return 0;
01091 }

int is_empty ( char *  arg  ) 

Definition at line 1977 of file pval.c.

01978 {
01979    if (!arg)
01980       return 1;
01981    if (*arg == 0)
01982       return 1;
01983    while (*arg) {
01984       if (*arg != ' ' && *arg != '\t')
01985          return 0;
01986       arg++;
01987    }
01988    return 1;
01989 }

int is_float ( char *  arg  ) 

Definition at line 1959 of file pval.c.

References s.

01960 {
01961    char *s;
01962    for (s=arg; *s; s++) {
01963       if (*s != '.' && (*s < '0' || *s > '9'))
01964          return 0;
01965    }
01966    return 1;
01967 }

int is_int ( char *  arg  ) 

Definition at line 1968 of file pval.c.

References s.

01969 {
01970    char *s;
01971    for (s=arg; *s; s++) {
01972       if (*s < '0' || *s > '9')
01973          return 0;
01974    }
01975    return 1;
01976 }

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 }

pval* linku1 ( pval head,
pval tail 
)

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   ) 
struct pval * match_pval ( pval item  )  [read]

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 }

static struct pval* match_pval_item ( pval item  )  [static, read]

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 }

void pvalAppCallAddArg ( pval p,
pval arg 
)

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 }

void pvalAppCallSetArglist ( pval p,
pval arglist 
)

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 }

pval* pvalAppCallWalkArgs ( pval p,
pval **  args 
)

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 }

void pvalCasePatDefAddStatement ( pval p,
pval statement 
)

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 }

pval* pvalCasePatDefWalkStatements ( pval p,
pval **  statement 
)

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  ) 

Definition at line 5206 of file pval.c.

References pval::str, and pval::u1.

05207 {
05208    return p->u1.str;
05209 }

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 }

pval* pvalCatchGetStatement ( pval p  ) 

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 5230 of file pval.c.

References PV_CATCH, pvalCheckType(), pval::str, and pval::u1.

05231 {
05232    if (!pvalCheckType(p, "pvalCatchSetExtName", PV_CATCH))
05233       return;
05234    p->u1.str = name;
05235 }

void pvalCatchSetStatement ( pval p,
pval statement 
)

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 }

int pvalCheckType ( pval p,
char *  funcname,
pvaltype  type 
)

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().

04943 {
04944    if (p->type != type)
04945    {
04946       ast_log(LOG_ERROR, "Func: %s the pval passed is not appropriate for this function!\n", funcname);
04947       return 0;
04948    }
04949    return 1;
04950 }

pval* pvalConditionalGetElseStatement ( pval p  ) 

Definition at line 5627 of file pval.c.

References pval::else_statements, and pval::u3.

05628 {
05629    return p->u3.else_statements;
05630 }

pval* pvalConditionalGetThenStatement ( pval p  ) 

Definition at line 5622 of file pval.c.

References pval::statements, and pval::u2.

05623 {
05624    return p->u2.statements;
05625 }

void pvalConditionalSetElseStatement ( pval p,
pval statement 
)

Definition at line 5617 of file pval.c.

References pval::else_statements, and pval::u3.

05618 {
05619    p->u3.else_statements = statement;
05620 }

void pvalConditionalSetThenStatement ( pval p,
pval statement 
)

Definition at line 5612 of file pval.c.

References pval::statements, and pval::u2.

05613 {
05614    p->u2.statements = statement;
05615 }

void pvalContextAddStatement ( pval p,
pval statement 
)

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 }

pval* pvalContextWalkStatements ( pval p,
pval **  statements 
)

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 }

pval* pvalCreateNode ( pvaltype  type  ) 

Definition at line 4953 of file pval.c.

References calloc, and pval::type.

Referenced by pvalESwitchesAddSwitch(), pvalGotoSetTarget(), pvalIfTimeSetCondition(), pvalIncludesAddInclude(), pvalIncludesAddIncludeWithTimeConstraints(), and pvalSwitchesAddSwitch().

04954 {
04955    pval *p = calloc(1,sizeof(pval)); /* why, oh why, don't I use ast_calloc? Way, way, way too messy if I do! */
04956    p->type = type;                   /* remember, this can be used externally or internally to asterisk */
04957    return p;
04958 }

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 }

char* pvalESwitchesWalkNames ( pval p,
pval **  next_item 
)

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 }

pval* pvalExtenGetStatement ( pval p  ) 

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 }

void pvalExtenSetStatement ( pval p,
pval statement 
)

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 }

pval* pvalForGetStatement ( pval p  ) 

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 }

void pvalForSetStatement ( pval p,
pval statement 
)

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 }

void pvalGlobalsAddStatement ( pval p,
pval statement 
)

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 }

pval* pvalGlobalsWalkStatements ( pval p,
pval **  next_statement 
)

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.

05589 {
05590    if (!pvalCheckType(p, "pvalIfTimeGetCondition", PV_IFTIME))
05591       return;
05592    *hour_range = p->u1.list->u1.str;
05593    *dow_range = p->u1.list->next->u1.str;
05594    *dom_range = p->u1.list->next->next->u1.str;
05595    *month_range = p->u1.list->next->next->next->u1.str;
05596 }

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 }

char* pvalIncludesWalk ( pval p,
pval **  next_item 
)

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 5482 of file pval.c.

References PV_LABEL, pvalCheckType(), pval::str, and pval::u1.

05483 {
05484    if (!pvalCheckType(p, "pvalLabelSetName", PV_LABEL))
05485       return;
05486    p->u1.str = name;
05487 }

void pvalMacroAddArg ( pval p,
pval arg 
)

Definition at line 5002 of file pval.c.

References pval::arglist, linku1(), PV_MACRO, pvalCheckType(), and pval::u2.

05003 {
05004    if (!pvalCheckType(p, "pvalMacroAddArg", PV_MACRO))
05005       return;
05006    if (!p->u2.arglist)
05007       p->u2.arglist = arg;
05008    else
05009       linku1(p->u2.arglist, arg);
05010 
05011 }

void pvalMacroAddStatement ( pval p,
pval statement 
)

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 }

void pvalMacroCallAddArg ( pval p,
pval arg 
)

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 }

void pvalMacroCallSetArglist ( pval p,
pval arglist 
)

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 }

pval* pvalMacroCallWalkArgs ( pval p,
pval **  args 
)

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 }

void pvalMacroSetArglist ( pval p,
pval arglist 
)

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 4981 of file pval.c.

References PV_MACRO, pvalCheckType(), pval::str, and pval::u1.

04982 {
04983    if (!pvalCheckType(p, "pvalMacroSetName", PV_MACRO))
04984       return;
04985    p->u1.str = name;
04986 }

pval* pvalMacroWalkArgs ( pval p,
pval **  arg 
)

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 }

pval* pvalMacroWalkStatements ( pval p,
pval **  next_statement 
)

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 }

pvaltype pvalObjectGetType ( pval p  ) 

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 }

void pvalStatementBlockAddStatement ( pval p,
pval statement 
)

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 }

pval* pvalStatementBlockWalkStatements ( pval p,
pval **  next_statement 
)

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 }

void pvalSwitchAddCase ( pval p,
pval Case 
)

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 }

char* pvalSwitchesWalkNames ( pval p,
pval **  next_item 
)

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 }

pval* pvalSwitchWalkCases ( pval p,
pval **  next_case 
)

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 }

void pvalTopLevAddObject ( pval p,
pval contextOrObj 
)

Definition at line 5777 of file pval.c.

References ast_log(), linku1(), and LOG_ERROR.

05778 {
05779    if (p) {
05780       linku1(p,contextOrObj);
05781    } else {
05782       ast_log(LOG_ERROR, "First arg to pvalTopLevel is NULL!\n");
05783    }
05784 }

pval* pvalTopLevWalkObjects ( pval p,
pval **  next_obj 
)

Definition at line 5786 of file pval.c.

References pval::next.

05787 {
05788    if (!next_obj) {
05789       *next_obj = p;
05790       return p;
05791    } else {
05792       *next_obj = (*next_obj)->next;
05793       return (*next_obj)->next;
05794    }
05795 }

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 
)

Definition at line 5391 of file pval.c.

References PV_VARDEC, pvalCheckType(), pval::str, and pval::u1.

05392 {
05393    if (!pvalCheckType(p, "pvalVarDecSetVarname", PV_VARDEC))
05394       return;
05395    p->u1.str = name;
05396 }

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().

03036 {
03037    char *p;
03038    while( str && *str && *str != '=' )
03039    {
03040       if( *str == ' ' || *str == '\n' || *str == '\r' || *str == '\t' )
03041       {
03042          p = str;
03043          while( *p )
03044          {
03045             *p = *(p+1);
03046             p++;
03047          }
03048       }
03049       else
03050          str++;
03051    }
03052 }

void set_priorities ( struct ael_extension exten  ) 

Definition at line 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 }


Variable Documentation

int control_statement_count = 0 [static]

Definition at line 2919 of file pval.c.

int count_labels [static]

Definition at line 78 of file pval.c.

pval* current_context [static]

Definition at line 71 of file pval.c.

pval* current_db [static]

Definition at line 70 of file pval.c.

Definition at line 72 of file pval.c.

char* days[] [static]

Definition at line 889 of file pval.c.

int errs [static]

Definition at line 63 of file pval.c.

Referenced by pbx_load_module().

char expr_output[2096] [static]

Definition at line 58 of file pval.c.

int in_abstract_context [static]

Definition at line 77 of file pval.c.

int label_count [static]

Definition at line 79 of file pval.c.

Definition at line 81 of file pval.c.

const char* match_context [static]

Definition at line 74 of file pval.c.

const char* match_exten [static]

Definition at line 75 of file pval.c.

const char* match_label [static]

Definition at line 76 of file pval.c.

char* months[] [static]

Definition at line 987 of file pval.c.

int notes [static]

Definition at line 64 of file pval.c.

char* registrar = "pbx_ael" [static]

Definition at line 68 of file pval.c.

Definition at line 80 of file pval.c.

int warns [static]

Definition at line 63 of file pval.c.


Generated by  doxygen 1.6.2