Wed Jan 8 2020 09:50:17

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"

Go to the source code of this file.

Macros

#define BUF_SIZE   2000
 

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)
 
int 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 More...
 
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)
 
static int context_used (struct ael_extension *exten_list, struct ast_context *context)
 
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 int 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.

Macro Definition Documentation

#define BUF_SIZE   2000

Definition at line 63 of file pval.c.

Referenced by gen_prios().

Function Documentation

void add_extensions ( struct ael_extension exten)

Definition at line 4251 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().

4252 {
4253  struct ael_priority *pr;
4254  char *label=0;
4255  char realext[AST_MAX_EXTENSION];
4256  if (!exten) {
4257  ast_log(LOG_WARNING, "This file is Empty!\n" );
4258  return;
4259  }
4260  do {
4261  struct ael_priority *last = 0;
4262 
4263  pbx_substitute_variables_helper(NULL, exten->name, realext, sizeof(realext) - 1);
4264  if (exten->hints) {
4265  if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, PRIORITY_HINT, NULL, exten->cidmatch,
4266  exten->hints, NULL, ast_free_ptr, registrar)) {
4267  ast_log(LOG_WARNING, "Unable to add step at priority 'hint' of extension '%s'\n",
4268  exten->name);
4269  }
4270  }
4271 
4272  for (pr=exten->plist; pr; pr=pr->next) {
4273  char app[2000];
4274  char appargs[2000];
4275 
4276  /* before we can add the extension, we need to prep the app/appargs;
4277  the CONTROL types need to be done after the priority numbers are calculated.
4278  */
4279  if (pr->type == AEL_LABEL) /* don't try to put labels in the dialplan! */ {
4280  last = pr;
4281  continue;
4282  }
4283 
4284  if (pr->app)
4285  strcpy(app, pr->app);
4286  else
4287  app[0] = 0;
4288  if (pr->appargs )
4289  strcpy(appargs, pr->appargs);
4290  else
4291  appargs[0] = 0;
4292  switch( pr->type ) {
4293  case AEL_APPCALL:
4294  /* easy case. Everything is all set up */
4295  break;
4296 
4297  case AEL_CONTROL1: /* FOR loop, WHILE loop, BREAK, CONTINUE, IF, IFTIME */
4298  /* simple, unconditional goto. */
4299  strcpy(app,"Goto");
4300  if (pr->goto_true->origin && pr->goto_true->origin->type == PV_SWITCH ) {
4301  snprintf(appargs,sizeof(appargs),"%s,%d", pr->goto_true->exten->name, pr->goto_true->priority_num);
4302  } else if (pr->goto_true->origin && pr->goto_true->origin->type == PV_IFTIME && pr->goto_true->origin->u3.else_statements ) {
4303  snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num+1);
4304  } else
4305  snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num);
4306  break;
4307 
4308  case AEL_FOR_CONTROL: /* WHILE loop test, FOR loop test */
4309  strcpy(app,"GotoIf");
4310  snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
4311  break;
4312 
4313  case AEL_IF_CONTROL:
4314  strcpy(app,"GotoIf");
4315  if (pr->origin->u3.else_statements )
4316  snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num+1);
4317  else
4318  snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
4319  break;
4320 
4321  case AEL_RAND_CONTROL:
4322  strcpy(app,"Random");
4323  snprintf(appargs,sizeof(appargs),"%s:%d", pr->appargs, pr->goto_true->priority_num+1);
4324  break;
4325 
4326  case AEL_IFTIME_CONTROL:
4327  strcpy(app,"GotoIfTime");
4328  snprintf(appargs,sizeof(appargs),"%s?%d", pr->appargs, pr->priority_num+2);
4329  break;
4330 
4331  case AEL_RETURN:
4332  strcpy(app,"Return");
4333  appargs[0] = 0;
4334  break;
4335 
4336  default:
4337  break;
4338  }
4339  if (last && last->type == AEL_LABEL ) {
4340  label = last->origin->u1.str;
4341  }
4342  else
4343  label = 0;
4344 
4345  if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, pr->priority_num, (label?label:NULL), exten->cidmatch,
4346  app, strdup(appargs), ast_free_ptr, registrar)) {
4347  ast_log(LOG_WARNING, "Unable to add step at priority '%d' of extension '%s'\n", pr->priority_num,
4348  exten->name);
4349  }
4350  last = pr;
4351  }
4352  exten = exten->next_exten;
4353  } while ( exten );
4354 }
union pval::@198 u1
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: pbx.c:4676
struct pval * origin
Definition: ael_structs.h:95
Definition: pval.h:32
struct ael_priority * goto_true
Definition: ael_structs.h:98
#define LOG_WARNING
Definition: logger.h:144
int ast_add_extension2(struct ast_context *con, int replace, const char *extension, int priority, const char *label, const char *callerid, const char *application, void *data, void(*datad)(void *), const char *registrar)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:9052
struct ael_priority * plist
Definition: ael_structs.h:115
struct ael_priority * goto_false
Definition: ael_structs.h:99
char * appargs
Definition: ael_structs.h:93
void ast_free_ptr(void *ptr)
struct ael_extension * next_exten
Definition: ael_structs.h:117
union pval::@200 u3
struct ast_context * context
Definition: ael_structs.h:113
char * cidmatch
Definition: ael_structs.h:106
static const char app[]
Definition: app_adsiprog.c:49
struct sla_ringing_trunk * last
Definition: app_meetme.c:965
#define AST_MAX_EXTENSION
Definition: channel.h:135
struct ael_extension * exten
Definition: ael_structs.h:96
char * str
Definition: pval.h:59
#define PRIORITY_HINT
Definition: pbx.h:53
char * app
Definition: ael_structs.h:92
static char * registrar
Definition: pval.c:72
struct pval * else_statements
Definition: pval.h:78
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct ael_priority * next
Definition: ael_structs.h:100
pvaltype type
Definition: pval.h:50
int priority_num
Definition: ael_structs.h:89
Definition: pval.h:30
ael_priority_type type
Definition: ael_structs.h:90
#define strdup(a)
Definition: astmm.h:106
void ael2_print ( char *  fname,
pval tree 
)

Definition at line 384 of file pval.c.

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

385 {
386  FILE *fin = fopen(fname,"w");
387  if ( !fin ) {
388  ast_log(LOG_ERROR, "Couldn't open %s for writing.\n", fname);
389  return;
390  }
391  print_pval_list(fin, tree, 0);
392  fclose(fin);
393 }
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void print_pval_list(FILE *fin, pval *item, int depth)
Definition: pval.c:375
void ael2_semantic_check ( pval item,
int *  arg_errs,
int *  arg_warns,
int *  arg_notes 
)

Definition at line 2892 of file pval.c.

References ast_alloca, ast_config_AST_VAR_DIR, check_context_names(), check_pval(), errs, notes, and warns.

Referenced by pbx_load_module().

2893 {
2894 
2895 #ifdef AAL_ARGCHECK
2896  int argapp_errs =0;
2897  char *rfilename;
2898 #endif
2899  struct argapp *apps=0;
2900 
2901  if (!item)
2902  return; /* don't check an empty tree */
2903 #ifdef AAL_ARGCHECK
2904  rfilename = ast_alloca(10 + strlen(ast_config_AST_VAR_DIR));
2905  sprintf(rfilename, "%s/applist", ast_config_AST_VAR_DIR);
2906 
2907  apps = argdesc_parse(rfilename, &argapp_errs); /* giveth */
2908 #endif
2909  current_db = item;
2910  errs = warns = notes = 0;
2911 
2913  check_pval(item, apps, 0);
2914 
2915 #ifdef AAL_ARGCHECK
2916  argdesc_destroy(apps); /* taketh away */
2917 #endif
2918  current_db = 0;
2919 
2920  *arg_errs = errs;
2921  *arg_warns = warns;
2922  *arg_notes = notes;
2923 }
void check_pval(pval *item, struct argapp *apps, int in_globals)
Definition: pval.c:2872
static int errs
Definition: pval.c:67
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
Definition: pbx.c:1301
Definition: pval.h:110
static int notes
Definition: pval.c:68
static int warns
Definition: pval.c:67
const char * ast_config_AST_VAR_DIR
Definition: asterisk.c:261
static pval * current_db
Definition: pval.c:74
static void check_context_names(void)
Definition: pval.c:2317
int ast_compile_ael2 ( struct ast_context **  local_contexts,
struct ast_hashtab local_table,
struct pval root 
)

Definition at line 4451 of file pval.c.

References add_extensions(), AEL_APPCALL, AEL_LABEL, ael_priority::app, ael_priority::appargs, pval::arglist, ARRAY_LEN, ast_compat_app_set, ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_find_or_create(), ast_custom_function_find(), ast_get_context_name(), attach_exten(), buf2, ael_extension::cidmatch, context, ael_extension::context, context_used(), destroy_extensions(), exten, fix_gotos_in_extensions(), gen_prios(), pval::hints, ael_extension::hints, linkprio(), pval::list, pval::macro_statements, ael_extension::name, new_exten(), new_prio(), pval::next, ael_extension::next_exten, ael_priority::origin, pbx_builtin_setvar(), ael_extension::plist_last, ael_priority::priority_num, 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, pval::type, ael_priority::type, pval::u1, pval::u2, pval::u3, pval::u4, and pval::val.

Referenced by pbx_load_module().

4452 {
4453  pval *p,*p2;
4454  struct ast_context *context;
4455  char buf[2000];
4456  struct ael_extension *exten;
4457  struct ael_extension *exten_list = 0;
4458 
4459  for (p=root; p; p=p->next ) { /* do the globals first, so they'll be there
4460  when we try to eval them */
4461  switch (p->type) {
4462  case PV_GLOBALS:
4463  /* just VARDEC elements */
4464  for (p2=p->u1.list; p2; p2=p2->next) {
4465  char buf2[2000];
4466  snprintf(buf2,sizeof(buf2),"%s=%s", p2->u1.str, p2->u2.val);
4467  pbx_builtin_setvar(NULL, buf2);
4468  }
4469  break;
4470  default:
4471  break;
4472  }
4473  }
4474 
4475  for (p=root; p; p=p->next ) {
4476  pval *lp;
4477  int argc;
4478 
4479  switch (p->type) {
4480  case PV_MACRO:
4481 
4482  context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar);
4483 
4484  exten = new_exten();
4485  exten->context = context;
4486  exten->name = strdup("~~s~~");
4487  argc = 1;
4488  for (lp=p->u2.arglist; lp; lp=lp->next) {
4489  /* for each arg, set up a "Set" command */
4490  struct ael_priority *np2 = new_prio();
4491  np2->type = AEL_APPCALL;
4492  if (!ast_compat_app_set) {
4493  np2->app = strdup("MSet");
4494  } else {
4495  np2->app = strdup("Set");
4496  }
4497  snprintf(buf,sizeof(buf),"LOCAL(%s)=${ARG%d}", lp->u1.str, argc++);
4499  np2->appargs = strdup(buf);
4500  linkprio(exten, np2, NULL);
4501  }
4502 
4503  /* CONTAINS APPCALLS, CATCH, just like extensions... */
4504  if (gen_prios(exten, p->u1.str, p->u3.macro_statements, 0, context)) {
4505  return -1;
4506  }
4507  if (exten->return_needed) { /* most likely, this will go away */
4508  struct ael_priority *np2 = new_prio();
4509  np2->type = AEL_APPCALL;
4510  np2->app = strdup("NoOp");
4511  snprintf(buf,sizeof(buf),"End of Macro %s-%s",p->u1.str, exten->name);
4512  np2->appargs = strdup(buf);
4513  linkprio(exten, np2, NULL);
4514  exten-> return_target = np2;
4515  }
4516 
4517  set_priorities(exten);
4518  attach_exten(&exten_list, exten);
4519  break;
4520 
4521  case PV_GLOBALS:
4522  /* already done */
4523  break;
4524 
4525  case PV_CONTEXT:
4526  context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar);
4527 
4528  /* contexts contain: ignorepat, includes, switches, eswitches, extensions, */
4529  for (p2=p->u2.statements; p2; p2=p2->next) {
4530  pval *p3;
4531  char *s3;
4532 
4533  switch (p2->type) {
4534  case PV_EXTENSION:
4535  exten = new_exten();
4536  exten->name = strdup(p2->u1.str);
4537  exten->context = context;
4538 
4539  if( (s3=strchr(exten->name, '/') ) != 0 )
4540  {
4541  *s3 = 0;
4542  exten->cidmatch = s3+1;
4543  }
4544 
4545  if ( p2->u3.hints )
4546  exten->hints = strdup(p2->u3.hints);
4547  exten->regexten = p2->u4.regexten;
4548  if (gen_prios(exten, p->u1.str, p2->u2.statements, 0, context)) {
4549  return -1;
4550  }
4551  if (exten->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */
4552  struct ael_priority *np2 = new_prio();
4553  np2->type = AEL_APPCALL;
4554  np2->app = strdup("NoOp");
4555  snprintf(buf,sizeof(buf),"End of Extension %s", exten->name);
4556  np2->appargs = strdup(buf);
4557  linkprio(exten, np2, NULL);
4558  exten-> return_target = np2;
4559  }
4560  /* is the last priority in the extension a label? Then add a trailing no-op */
4561  if ( exten->plist_last && exten->plist_last->type == AEL_LABEL ) {
4562  struct ael_priority *np2 = new_prio();
4563  np2->type = AEL_APPCALL;
4564  np2->app = strdup("NoOp");
4565  snprintf(buf,sizeof(buf),"A NoOp to follow a trailing label %s", exten->plist_last->origin->u1.str);
4566  np2->appargs = strdup(buf);
4567  linkprio(exten, np2, NULL);
4568  }
4569 
4570  set_priorities(exten);
4571  attach_exten(&exten_list, exten);
4572  break;
4573 
4574  case PV_IGNOREPAT:
4575  ast_context_add_ignorepat2(context, p2->u1.str, registrar);
4576  break;
4577 
4578  case PV_INCLUDES:
4579  for (p3 = p2->u1.list; p3 ;p3=p3->next) {
4580  if ( p3->u2.arglist ) {
4581  snprintf(buf,sizeof(buf), "%s,%s,%s,%s,%s",
4582  p3->u1.str,
4583  p3->u2.arglist->u1.str,
4584  p3->u2.arglist->next->u1.str,
4585  p3->u2.arglist->next->next->u1.str,
4586  p3->u2.arglist->next->next->next->u1.str);
4587  ast_context_add_include2(context, buf, registrar);
4588  } else
4589  ast_context_add_include2(context, p3->u1.str, registrar);
4590  }
4591  break;
4592 
4593  case PV_SWITCHES:
4594  for (p3 = p2->u1.list; p3 ;p3=p3->next) {
4595  char *c = strchr(p3->u1.str, '/');
4596  if (c) {
4597  *c = '\0';
4598  c++;
4599  } else
4600  c = "";
4601 
4602  ast_context_add_switch2(context, p3->u1.str, c, 0, registrar);
4603  }
4604  break;
4605 
4606  case PV_ESWITCHES:
4607  for (p3 = p2->u1.list; p3 ;p3=p3->next) {
4608  char *c = strchr(p3->u1.str, '/');
4609  if (c) {
4610  *c = '\0';
4611  c++;
4612  } else
4613  c = "";
4614 
4615  ast_context_add_switch2(context, p3->u1.str, c, 1, registrar);
4616  }
4617  break;
4618  default:
4619  break;
4620  }
4621  }
4622 
4623  break;
4624 
4625  default:
4626  /* huh? what? */
4627  break;
4628 
4629  }
4630  }
4631 
4632  /* Create default "h" bubble context */
4633  if (ast_custom_function_find("DIALPLAN_EXISTS") && ast_custom_function_find("STACK_PEEK")) {
4634  int i;
4635  const char *h_context = "ael-builtin-h-bubble";
4636  struct ael_priority *np;
4637  struct {
4638  int priority;
4639  const char *app;
4640  const char *arg;
4641  } steps[] = {
4642  /* Start high, to avoid conflict with existing h extensions */
4643  { 1, "Goto", "9991" },
4644  /* Save the context, because after the StackPop, it disappears */
4645  { 9991, "Set", "~~parentcxt~~=${STACK_PEEK(1,c,1)}" },
4646  /* If we're not in a Gosub frame, exit */
4647  { 9992, "GotoIf", "$[\"${~~parentcxt~~}\"=\"\"]?9996" },
4648  /* Check for an "h" extension in that context */
4649  { 9993, "GotoIf", "${DIALPLAN_EXISTS(${~~parentcxt~~},h,1)}?9994:9996" },
4650  /* Pop off the stack frame to prevent an infinite loop */
4651  { 9994, "StackPop", "" },
4652  /* Finally, go there. */
4653  { 9995, "Goto", "${~~parentcxt~~},h,1" },
4654  /* Just an empty priority for jumping out early */
4655  { 9996, "NoOp", "" }
4656  };
4657  context = ast_context_find_or_create(local_contexts, local_table, h_context, registrar);
4658  if (context_used(exten_list, context)) {
4659  int found = 0;
4660  while (!found) {
4661  /* Pick a new context name that is not used. */
4662  char h_context_template[] = "/tmp/ael-builtin-h-bubble-XXXXXX";
4663  int fd = mkstemp(h_context_template);
4664  unlink(h_context_template);
4665  close(fd);
4666  context = ast_context_find_or_create(local_contexts, local_table, h_context_template + 5, registrar);
4667  found = !context_used(exten_list, context);
4668  }
4669  h_context = ast_get_context_name(context);
4670  }
4671  exten = new_exten();
4672  exten->context = context;
4673  exten->name = strdup("h");
4674 
4675  for (i = 0; i < ARRAY_LEN(steps); i++) {
4676  np = new_prio();
4677  np->type = AEL_APPCALL;
4678  np->priority_num = steps[i].priority;
4679  np->app = strdup(steps[i].app);
4680  np->appargs = strdup(steps[i].arg);
4681  linkprio(exten, np, NULL);
4682  }
4683  attach_exten(&exten_list, exten);
4684 
4685  /* Include the default "h" bubble context in each macro context */
4686  for (exten = exten_list; exten; exten = exten->next_exten) {
4687  /* All macros contain a "~~s~~" extension, and it's the first created. If
4688  * we perchance get a non-macro context, it's no big deal; the logic is
4689  * designed to exit out smoothly if not called from within a Gosub. */
4690  if (!strcmp(exten->name, "~~s~~")) {
4691  ast_context_add_include2(exten->context, h_context, registrar);
4692  }
4693  }
4694  }
4695 
4696  /* moved these from being done after a macro or extension were processed,
4697  to after all processing is done, for the sake of fixing gotos to labels inside cases... */
4698  /* I guess this would be considered 2nd pass of compiler now... */
4699  fix_gotos_in_extensions(exten_list); /* find and fix extension ref in gotos to labels that are in case statements */
4700  add_extensions(exten_list); /* actually makes calls to create priorities in ast_contexts -- feeds dialplan to asterisk */
4701  destroy_extensions(exten_list); /* all that remains is an empty husk, discard of it as is proper */
4702 
4703  return 0;
4704 }
union pval::@198 u1
static int context_used(struct ael_extension *exten_list, struct ast_context *context)
Definition: pval.c:4436
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
int regexten
Definition: pval.h:90
int ast_context_add_include2(struct ast_context *con, const char *include, const char *registrar)
Add a context include.
Definition: pbx.c:8411
struct ael_priority * new_prio(void)
Definition: pval.c:2931
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct pval * origin
Definition: ael_structs.h:95
struct pval * list
Definition: pval.h:60
static void fix_gotos_in_extensions(struct ael_extension *exten)
Definition: pval.c:4393
struct ael_priority * plist_last
Definition: ael_structs.h:116
void add_extensions(struct ael_extension *exten)
Definition: pval.c:4251
struct pval * statements
Definition: pval.h:61
#define ast_compat_app_set
Definition: options.h:144
static struct ast_threadstorage buf2
char * appargs
Definition: ael_structs.h:93
int ast_context_add_switch2(struct ast_context *con, const char *sw, const char *data, int eval, const char *registrar)
Adds a switch (first param is a ast_context)
Definition: pbx.c:8494
static int gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *this_context)
Definition: pval.c:3348
struct ael_extension * next_exten
Definition: ael_structs.h:117
union pval::@200 u3
union pval::@199 u2
struct ast_context * context
Definition: ael_structs.h:113
struct ael_extension * new_exten(void)
Definition: pval.c:2937
char * cidmatch
Definition: ael_structs.h:106
char * val
Definition: pval.h:70
static const char app[]
Definition: app_adsiprog.c:49
char * str
Definition: pval.h:59
Definition: pval.h:48
int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
Definition: pbx.c:8611
const char * ast_get_context_name(struct ast_context *con)
Definition: pbx.c:11073
struct ast_custom_function * ast_custom_function_find(const char *name)
Definition: pbx.c:3800
char * hints
Definition: pval.h:81
char * app
Definition: ael_structs.h:92
static char * registrar
Definition: pval.c:72
union pval::@201 u4
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static void attach_exten(struct ael_extension **list, struct ael_extension *newmem)
Definition: pval.c:4356
int pbx_builtin_setvar(struct ast_channel *chan, const char *data)
Parse and set a single channel variable, where the name and value are separated with an &#39;=&#39; character...
Definition: pbx.c:10603
void destroy_extensions(struct ael_extension *exten)
Definition: pval.c:2985
int priority_num
Definition: ael_structs.h:89
static void remove_spaces_before_equals(char *str)
Definition: pval.c:3045
void set_priorities(struct ael_extension *exten)
Definition: pval.c:4225
struct pval * next
Definition: pval.h:93
ael_priority_type type
Definition: ael_structs.h:90
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
struct ast_context * ast_context_find_or_create(struct ast_context **extcontexts, struct ast_hashtab *exttable, const char *name, const char *registrar)
Register a new context or find an existing one.
Definition: pbx.c:7726
#define strdup(a)
Definition: astmm.h:106
void linkprio(struct ael_extension *exten, struct ael_priority *prio, struct ael_extension *mother_exten)
Definition: pval.c:2943
ast_context: An extension context
Definition: pbx.c:955
struct pval * macro_statements
Definition: pval.h:79
static void attach_exten ( struct ael_extension **  list,
struct ael_extension newmem 
)
static

Definition at line 4356 of file pval.c.

References ael_extension::next_exten.

Referenced by ast_compile_ael2().

4357 {
4358  /* travel to the end of the list... */
4359  struct ael_extension *lptr;
4360  if( !*list ) {
4361  *list = newmem;
4362  return;
4363  }
4364  lptr = *list;
4365 
4366  while( lptr->next_exten ) {
4367  lptr = lptr->next_exten;
4368  }
4369  /* lptr should now pointing to the last element in the list; it has a null next_exten pointer */
4370  lptr->next_exten = newmem;
4371 }
struct ael_extension * next_exten
Definition: ael_structs.h:117
static void check_abstract_reference ( pval abstract_context)
static

Definition at line 2336 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().

2337 {
2338  pval *i,*j;
2339  /* find some context includes that reference this context */
2340 
2341 
2342  /* otherwise, print out a warning */
2343  for (i=current_db; i; i=i->next) {
2344  if (i->type == PV_CONTEXT) {
2345  for (j=i->u2. statements; j; j=j->next) {
2346  if ( j->type == PV_INCLUDES ) {
2347  struct pval *p4;
2348  for (p4=j->u1.list; p4; p4=p4->next) {
2349  /* for each context pointed to, find it, then find a context/label that matches the
2350  target here! */
2351  if ( !strcmp(p4->u1.str, abstract_context->u1.str) )
2352  return; /* found a match! */
2353  }
2354  }
2355  }
2356  }
2357  }
2358  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",
2359  abstract_context->filename, abstract_context->startline, abstract_context->endline, abstract_context->u1.str);
2360  warns++;
2361 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
union pval::@199 u2
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
pvaltype type
Definition: pval.h:50
static int warns
Definition: pval.c:67
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52
static pval * current_db
Definition: pval.c:74
int check_app_args ( pval appcall,
pval arglist,
struct argapp app 
)

Definition at line 2137 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().

2138 {
2139 #ifdef AAL_ARGCHECK
2140  struct argdesc *ad = app->args;
2141  pval *pa;
2142  int z;
2143 
2144  for (pa = arglist; pa; pa=pa->next) {
2145  if (!ad) {
2146  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n",
2147  arglist->filename, arglist->startline, arglist->endline, pa->u1.str, app->name);
2148  warns++;
2149  return 1;
2150  } else {
2151  /* find the first entry in the ad list that will match */
2152  do {
2153  if ( ad->dtype == ARGD_VARARG ) /* once we hit the VARARG, all bets are off. Discontinue the comparisons */
2154  break;
2155 
2156  z= option_matches( ad, pa, app);
2157  if (!z) {
2158  if ( !arglist )
2159  arglist=appcall;
2160 
2161  if (ad->type == ARGD_REQUIRED) {
2162  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2163  arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
2164  warns++;
2165  return 1;
2166  }
2167  } else if (z && ad->dtype == ARGD_OPTIONSET) {
2168  option_matches_j( ad, pa, app);
2169  }
2170  ad = ad->next;
2171  } while (ad && !z);
2172  }
2173  }
2174  /* any app nodes left, that are not optional? */
2175  for ( ; ad; ad=ad->next) {
2176  if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) {
2177  if ( !arglist )
2178  arglist=appcall;
2179  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2180  arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
2181  warns++;
2182  return 1;
2183  }
2184  }
2185  return 0;
2186 #else
2187  return 0;
2188 #endif
2189 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int warns
Definition: pval.c:67
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52
static int check_break ( pval item)
static

Definition at line 1045 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().

1046 {
1047  pval *p = item;
1048 
1049  while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
1050  /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make
1051  no sense */
1052  if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN
1053  || p->type == PV_WHILE || p->type == PV_FOR ) {
1054  return 1;
1055  }
1056  p = p->dad;
1057  }
1058  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'break' not in switch, for, or while statement!\n",
1059  item->filename, item->startline, item->endline);
1060  errs++;
1061 
1062  return 0;
1063 }
static int errs
Definition: pval.c:67
struct pval * dad
Definition: pval.h:96
int startline
Definition: pval.h:51
Definition: pval.h:13
char * filename
Definition: pval.h:55
Definition: pval.h:48
#define LOG_ERROR
Definition: logger.h:155
Definition: pval.h:24
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: pval.h:9
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
int endline
Definition: pval.h:52
static void check_context_names ( void  )
static

Definition at line 2317 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().

2318 {
2319  pval *i,*j;
2320  for (i=current_db; i; i=i->next) {
2321  if (i->type == PV_CONTEXT || i->type == PV_MACRO) {
2322  for (j=i->next; j; j=j->next) {
2323  if ( j->type == PV_CONTEXT || j->type == PV_MACRO ) {
2324  if ( !strcmp(i->u1.str, j->u1.str) && !(i->u3.abstract&2) && !(j->u3.abstract&2) )
2325  {
2326  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",
2327  i->filename, i->startline, i->endline, i->u1.str, j->filename, j->startline, j->endline);
2328  warns++;
2329  }
2330  }
2331  }
2332  }
2333  }
2334 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
int abstract
Definition: pval.h:80
union pval::@200 u3
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static int warns
Definition: pval.c:67
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52
static pval * current_db
Definition: pval.c:74
static int check_continue ( pval item)
static

Definition at line 1065 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().

1066 {
1067  pval *p = item;
1068 
1069  while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
1070  /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make
1071  no sense */
1072  if( p->type == PV_WHILE || p->type == PV_FOR ) {
1073  return 1;
1074  }
1075  p = p->dad;
1076  }
1077  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'continue' not in 'for' or 'while' statement!\n",
1078  item->filename, item->startline, item->endline);
1079  errs++;
1080 
1081  return 0;
1082 }
static int errs
Definition: pval.c:67
struct pval * dad
Definition: pval.h:96
int startline
Definition: pval.h:51
char * filename
Definition: pval.h:55
Definition: pval.h:48
#define LOG_ERROR
Definition: logger.h:155
Definition: pval.h:24
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: pval.h:9
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
int endline
Definition: pval.h:52
static void check_day ( pval DAY)
static

Definition at line 944 of file pval.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.

Referenced by check_pval_item().

945 {
946  char *day;
947  char *c;
948  /* The following line is coincidence, really! */
949  int s, e;
950 
951  day = ast_strdupa(DAY->u1.str);
952 
953  /* Check for all days */
954  if (ast_strlen_zero(day) || !strcmp(day, "*")) {
955  return;
956  }
957  /* Get start and ending days */
958  c = strchr(day, '-');
959  if (c) {
960  *c = '\0';
961  c++;
962  }
963  /* Find the start */
964  if (sscanf(day, "%2d", &s) != 1) {
965  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n",
966  DAY->filename, DAY->startline, DAY->endline, day);
967  warns++;
968  }
969  else if ((s < 1) || (s > 31)) {
970  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",
971  DAY->filename, DAY->startline, DAY->endline, day);
972  warns++;
973  }
974  s--;
975  if (c) {
976  if (sscanf(c, "%2d", &e) != 1) {
977  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n",
978  DAY->filename, DAY->startline, DAY->endline, c);
979  warns++;
980  }
981  else if ((e < 1) || (e > 31)) {
982  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",
983  DAY->filename, DAY->startline, DAY->endline, day);
984  warns++;
985  }
986  e--;
987  } else
988  e = s;
989 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int warns
Definition: pval.c:67
int endline
Definition: pval.h:52
static void check_dow ( pval DOW)
static

get_dow: Get day of week

Definition at line 905 of file pval.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.

Referenced by check_pval_item().

906 {
907  char *dow;
908  char *c;
909  /* The following line is coincidence, really! */
910  int s, e;
911 
912  dow = ast_strdupa(DOW->u1.str);
913 
914  /* Check for all days */
915  if (ast_strlen_zero(dow) || !strcmp(dow, "*"))
916  return;
917  /* Get start and ending days */
918  c = strchr(dow, '-');
919  if (c) {
920  *c = '\0';
921  c++;
922  } else
923  c = NULL;
924  /* Find the start */
925  s = 0;
926  while ((s < 7) && strcasecmp(dow, days[s])) s++;
927  if (s >= 7) {
928  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",
929  DOW->filename, DOW->startline, DOW->endline, dow);
930  warns++;
931  }
932  if (c) {
933  e = 0;
934  while ((e < 7) && strcasecmp(c, days[e])) e++;
935  if (e >= 7) {
936  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",
937  DOW->filename, DOW->startline, DOW->endline, c);
938  warns++;
939  }
940  } else
941  e = s;
942 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char * days[]
Definition: pval.c:893
static int warns
Definition: pval.c:67
int endline
Definition: pval.h:52
static void check_expr2_input ( pval expr,
char *  str 
)
static

Definition at line 808 of file pval.c.

References ast_log(), pval::endline, pval::filename, LOG_WARNING, and pval::startline.

Referenced by check_pval_item().

809 {
810  int spaces = strspn(str,"\t \n");
811  if ( !strncmp(str+spaces,"$[",2) ) {
812  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n",
813  expr->filename, expr->startline, expr->endline, str);
814  warns++;
815  }
816 }
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
const char * str
Definition: app_jack.c:144
char * filename
Definition: pval.h:55
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int warns
Definition: pval.c:67
int endline
Definition: pval.h:52
static void check_goto ( pval item)
static

Definition at line 1232 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().

1233 {
1234  if (!item->u1.list) {
1235  return;
1236  }
1237 
1238  /* check for the target of the goto-- does it exist? */
1239  if ( !(item->u1.list)->next && !(item->u1.list)->u1.str ) {
1240  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: empty label reference found!\n",
1241  item->filename, item->startline, item->endline);
1242  errs++;
1243  }
1244 
1245  /* just one item-- the label should be in the current extension */
1246  if (!item->u1.list->next && !strstr(item->u1.list->u1.str,"${")) {
1247  struct pval *z = get_extension_or_contxt(item);
1248  struct pval *x = 0;
1249  if (z)
1250  x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), z); /* if in macro, use current context instead */
1251  /* printf("Called find_label_in_current_extension with arg %s; current_extension is %x: %d\n",
1252  (char*)((item->u1.list)->u1.str), current_extension?current_extension:current_context, current_extension?current_extension->type:current_context->type); */
1253  if (!x) {
1254  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s exists in the current extension!\n",
1255  item->filename, item->startline, item->endline, item->u1.list->u1.str);
1256  errs++;
1257  }
1258  else
1259  return;
1260  }
1261 
1262  /* TWO items */
1263  if (item->u1.list->next && !item->u1.list->next->next) {
1264  /* two items */
1265  /* printf("Calling find_label_in_current_context with args %s, %s\n",
1266  (char*)((item->u1.list)->u1.str), (char *)item->u1.list->next->u1.str); */
1267  if (!strstr((item->u1.list)->u1.str,"${")
1268  && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ {
1269  struct pval *z = get_contxt(item);
1270  struct pval *x = 0;
1271 
1272  if (z)
1273  x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, z);
1274 
1275  if (!x) {
1276  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",
1277  item->filename, item->startline, item->endline, item->u1.list->u1.str, item->u1.list->next->u1.str );
1278  errs++;
1279  }
1280  else
1281  return;
1282  }
1283  }
1284 
1285  /* All 3 items! */
1286  if (item->u1.list->next && item->u1.list->next->next) {
1287  /* all three */
1288  pval *first = item->u1.list;
1289  pval *second = item->u1.list->next;
1290  pval *third = item->u1.list->next->next;
1291 
1292  /* printf("Calling find_label_in_current_db with args %s, %s, %s\n",
1293  (char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str); */
1294  if (!strstr((item->u1.list)->u1.str,"${")
1295  && !strstr(item->u1.list->next->u1.str,"${")
1296  && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ {
1297  struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str);
1298  if (!x) {
1299  struct pval *p3;
1300  struct pval *found = 0;
1301  struct pval *that_context = find_context(item->u1.list->u1.str);
1302 
1303  /* the target of the goto could be in an included context!! Fancy that!! */
1304  /* look for includes in the current context */
1305  if (that_context) {
1306  for (p3=that_context->u2.statements; p3; p3=p3->next) {
1307  if (p3->type == PV_INCLUDES) {
1308  struct pval *p4;
1309  for (p4=p3->u1.list; p4; p4=p4->next) {
1310  /* for each context pointed to, find it, then find a context/label that matches the
1311  target here! */
1312  char *incl_context = p4->u1.str;
1313  /* find a matching context name */
1314  struct pval *that_other_context = find_context(incl_context);
1315  if (that_other_context) {
1316  struct pval *x3;
1317  x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context);
1318  if (x3) {
1319  found = x3;
1320  break;
1321  }
1322  }
1323  }
1324  }
1325  }
1326  if (!found) {
1327  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: goto: no label %s|%s exists in the context %s or its inclusions!\n",
1328  item->filename, item->startline, item->endline, item->u1.list->next->u1.str, item->u1.list->next->next->u1.str, item->u1.list->u1.str );
1329  errs++;
1330  } else {
1331  struct pval *mac = in_macro(item); /* is this goto inside a macro? */
1332  if( mac ) { /* yes! */
1333  struct pval *targ = in_context(found);
1334  if( mac != targ )
1335  {
1336  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",
1337  item->filename, item->startline, item->endline);
1338  warns++;
1339  }
1340  }
1341  }
1342  } else {
1343  /* here is where code would go to check for target existence in extensions.conf files */
1344 #ifdef STANDALONE
1345  struct pbx_find_info pfiq = {.stacklen = 0 };
1346  extern int localized_pbx_load_module(void);
1347  /* if this is a standalone, we will need to make sure the
1348  localized load of extensions.conf is done */
1349  if (!extensions_dot_conf_loaded) {
1351  extensions_dot_conf_loaded++;
1352  }
1353 
1354  pbx_find_extension(NULL, NULL, &pfiq, first->u1.str, second->u1.str, atoi(third->u1.str),
1355  atoi(third->u1.str) ? NULL : third->u1.str, NULL,
1356  atoi(third->u1.str) ? E_MATCH : E_FINDLABEL);
1357 
1358  if (pfiq.status != STATUS_SUCCESS) {
1359  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",
1360  item->filename, item->startline, item->endline, first->u1.str, second->u1.str, third->u1.str);
1361  warns++;
1362  }
1363 #else
1364  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: goto: Couldn't find goto target %s|%s|%s in the AEL code!\n",
1365  item->filename, item->startline, item->endline, first->u1.str, second->u1.str, third->u1.str);
1366  warns++;
1367 #endif
1368  }
1369  } else {
1370  struct pval *mac = in_macro(item); /* is this goto inside a macro? */
1371  if( mac ) { /* yes! */
1372  struct pval *targ = in_context(x);
1373  if( mac != targ )
1374  {
1375  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",
1376  item->filename, item->startline, item->endline);
1377  warns++;
1378  }
1379  }
1380  }
1381  }
1382  }
1383 }
union pval::@198 u1
static struct pval * in_macro(pval *item)
Definition: pval.c:1084
static int errs
Definition: pval.c:67
struct pval * list
Definition: pval.h:60
static struct pval * find_label_in_current_extension(const char *label, pval *curr_ext)
Definition: pval.c:1925
#define LOG_WARNING
Definition: logger.h:144
struct pval * statements
Definition: pval.h:61
int startline
Definition: pval.h:51
union pval::@199 u2
static struct pval * in_context(pval *item)
Definition: pval.c:1097
static pval * get_contxt(pval *p)
Definition: pval.c:4383
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
static struct pval * find_label_in_current_context(char *exten, char *label, pval *curr_cont)
Definition: pval.c:1886
#define LOG_ERROR
Definition: logger.h:155
struct sla_ringing_trunk * first
Definition: app_meetme.c:965
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct pval * find_label_in_current_db(const char *context, const char *exten, const char *label)
Definition: pval.c:1936
#define STATUS_SUCCESS
Definition: extconf.h:245
int stacklen
Definition: extconf.h:234
pvaltype type
Definition: pval.h:50
int localized_pbx_load_module(void)
struct pval * find_context(char *name)
Definition: pval.c:1960
static int warns
Definition: pval.c:67
struct pval * next
Definition: pval.h:93
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: pbx.c:3013
int endline
Definition: pval.h:52
static pval * get_extension_or_contxt(pval *p)
Definition: pval.c:4373
static void check_includes ( pval includes)
static

Definition at line 818 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().

819 {
820  struct pval *p4;
821  for (p4=includes->u1.list; p4; p4=p4->next) {
822  /* for each context pointed to, find it, then find a context/label that matches the
823  target here! */
824  char *incl_context = p4->u1.str;
825  /* find a matching context name */
826  struct pval *that_other_context = find_context(incl_context);
827  if (!that_other_context && strcmp(incl_context, "parkedcalls") != 0) {
828  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\
829  (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n",
830  includes->filename, includes->startline, includes->endline, incl_context, incl_context);
831  warns++;
832  }
833  }
834 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
struct pval * find_context(char *name)
Definition: pval.c:1960
static int warns
Definition: pval.c:67
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52
static void check_label ( pval item)
static

Definition at line 1113 of file pval.c.

References ast_log(), current_context, current_extension, pval::dad, pval::endline, pval::filename, find_first_label_in_current_context(), LOG_ERROR, PV_EXTENSION, PV_MACRO, pval::startline, pval::str, pval::type, and pval::u1.

Referenced by check_pval_item().

1114 {
1115  struct pval *curr;
1116  struct pval *x;
1117  int alright = 0;
1118 
1119  /* A label outside an extension just plain does not make sense! */
1120 
1121  curr = item;
1122 
1123  while( curr ) {
1124  if( curr->type == PV_MACRO || curr->type == PV_EXTENSION ) {
1125  alright = 1;
1126  break;
1127  }
1128  curr = curr->dad;
1129  }
1130  if( !alright )
1131  {
1132  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Label %s is not within an extension or macro!\n",
1133  item->filename, item->startline, item->endline, item->u1.str);
1134  errs++;
1135  }
1136 
1137 
1138  /* basically, ensure that a label is not repeated in a context. Period.
1139  The method: well, for each label, find the first label in the context
1140  with the same name. If it's not the current label, then throw an error. */
1141 
1142 
1143  /* printf("==== check_label: ====\n"); */
1144  if( !current_extension )
1145  curr = current_context;
1146  else
1147  curr = current_extension;
1148 
1149  x = find_first_label_in_current_context((char *)item->u1.str, curr);
1150  /* 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); */
1151  if( x && x != item )
1152  {
1153  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Duplicate label %s! Previously defined at file %s, line %d.\n",
1154  item->filename, item->startline, item->endline, item->u1.str, x->filename, x->startline);
1155  errs++;
1156  }
1157  /* printf("<<<<< check_label: ====\n"); */
1158 }
union pval::@198 u1
static int errs
Definition: pval.c:67
struct pval * dad
Definition: pval.h:96
int startline
Definition: pval.h:51
static pval * current_extension
Definition: pval.c:76
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static pval * current_context
Definition: pval.c:75
static struct pval * find_first_label_in_current_context(char *label, pval *curr_cont)
Definition: pval.c:1846
int endline
Definition: pval.h:52
static void check_macro_returns ( pval macro)
static

Definition at line 652 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().

653 {
654  pval *i;
655  if (!macro->u3.macro_statements)
656  {
657  pval *z = calloc(1, sizeof(struct pval));
658  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s is empty! I will insert a return.\n",
659  macro->filename, macro->startline, macro->endline, macro->u1.str);
660 
661  z->type = PV_RETURN;
662  z->startline = macro->startline;
663  z->endline = macro->endline;
664  z->startcol = macro->startcol;
665  z->endcol = macro->endcol;
666  z->filename = strdup(macro->filename);
667 
668  macro->u3.macro_statements = z;
669  return;
670  }
671  for (i=macro->u3.macro_statements; i; i=i->next) {
672  /* if the last statement in the list is not return, then insert a return there */
673  if (i->next == NULL) {
674  if (i->type != PV_RETURN) {
675  pval *z = calloc(1, sizeof(struct pval));
676  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s does not end with a return; I will insert one.\n",
677  macro->filename, macro->startline, macro->endline, macro->u1.str);
678 
679  z->type = PV_RETURN;
680  z->startline = macro->startline;
681  z->endline = macro->endline;
682  z->startcol = macro->startcol;
683  z->endcol = macro->endcol;
684  z->filename = strdup(macro->filename);
685 
686  i->next = z;
687  return;
688  }
689  }
690  }
691  return;
692 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
#define calloc(a, b)
Definition: astmm.h:79
union pval::@200 u3
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
int endcol
Definition: pval.h:54
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
pvaltype type
Definition: pval.h:50
struct pval * next
Definition: pval.h:93
Definition: pval.h:27
#define strdup(a)
Definition: astmm.h:106
int endline
Definition: pval.h:52
int startcol
Definition: pval.h:53
struct pval * macro_statements
Definition: pval.h:79
static void check_month ( pval MON)
static

Definition at line 1007 of file pval.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.

Referenced by check_pval_item().

1008 {
1009  char *mon;
1010  char *c;
1011  /* The following line is coincidence, really! */
1012  int s, e;
1013 
1014  mon = ast_strdupa(MON->u1.str);
1015 
1016  /* Check for all days */
1017  if (ast_strlen_zero(mon) || !strcmp(mon, "*"))
1018  return ;
1019  /* Get start and ending days */
1020  c = strchr(mon, '-');
1021  if (c) {
1022  *c = '\0';
1023  c++;
1024  }
1025  /* Find the start */
1026  s = 0;
1027  while ((s < 12) && strcasecmp(mon, months[s])) s++;
1028  if (s >= 12) {
1029  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1030  MON->filename, MON->startline, MON->endline, mon);
1031  warns++;
1032  }
1033  if (c) {
1034  e = 0;
1035  while ((e < 12) && strcasecmp(mon, months[e])) e++;
1036  if (e >= 12) {
1037  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1038  MON->filename, MON->startline, MON->endline, c);
1039  warns++;
1040  }
1041  } else
1042  e = s;
1043 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static char * months[]
Definition: pval.c:991
static int warns
Definition: pval.c:67
int endline
Definition: pval.h:52
void check_pval ( pval item,
struct argapp apps,
int  in_globals 
)

Definition at line 2872 of file pval.c.

References check_pval_item(), and pval::next.

Referenced by ael2_semantic_check(), and check_pval_item().

2873 {
2874  pval *i;
2875 
2876  /* checks to do:
2877  1. Do goto's point to actual labels?
2878  2. Do macro calls reference a macro?
2879  3. Does the number of macro args match the definition?
2880  4. Is a macro call missing its & at the front?
2881  5. Application calls-- we could check syntax for existing applications,
2882  but I need some some sort of universal description bnf for a general
2883  sort of method for checking arguments, in number, maybe even type, at least.
2884  Don't want to hand code checks for hundreds of applications.
2885  */
2886 
2887  for (i=item; i; i=i->next) {
2888  check_pval_item(i,apps,in_globals);
2889  }
2890 }
void check_pval_item(pval *item, struct argapp *apps, int in_globals)
Definition: pval.c:2364
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
void check_pval_item ( pval item,
struct argapp apps,
int  in_globals 
)

Definition at line 2364 of file pval.c.

References pval::abstract, app, pval::arglist, ast_expr(), ast_expr_clear_extra_error_info(), ast_expr_register_extra_error_info(), ast_log(), check_abstract_reference(), check_app_args(), check_break(), check_continue(), check_day(), check_dow(), check_expr2_input(), check_goto(), check_includes(), check_label(), check_macro_returns(), check_month(), check_pval(), check_switch_expr(), check_timerange(), E_MATCH, pval::else_statements, pval::endcol, pval::endline, pval::filename, find_context(), find_macro(), find_pval_gotos(), pval::for_inc, pval::for_init, pval::for_statements, pval::for_test, free, pval::list, localized_pbx_load_module(), LOG_ERROR, LOG_WARNING, pval::macro_statements, pval::next, argapp::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().

2365 {
2366  pval *lp;
2367 #ifdef AAL_ARGCHECK
2368  struct argapp *app, *found;
2369 #endif
2370  struct pval *macro_def;
2371  struct pval *app_def;
2372 
2373  char errmsg[4096];
2374  char *strp;
2375 
2376  switch (item->type) {
2377  case PV_WORD:
2378  /* fields: item->u1.str == string associated with this (word).
2379  item->u2.arglist == pval list of 4 PV_WORD elements for time values (only in PV_INCLUDES) */
2380  break;
2381 
2382  case PV_MACRO:
2383  /* fields: item->u1.str == name of macro
2384  item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
2385  item->u2.arglist->u1.str == argument
2386  item->u2.arglist->next == next arg
2387 
2388  item->u3.macro_statements == pval list of statements in macro body.
2389  */
2390  in_abstract_context = 0;
2391  current_context = item;
2392  current_extension = 0;
2393 
2394  check_macro_returns(item);
2395 
2396  for (lp=item->u2.arglist; lp; lp=lp->next) {
2397 
2398  }
2399  check_pval(item->u3.macro_statements, apps,in_globals);
2400  break;
2401 
2402  case PV_CONTEXT:
2403  /* fields: item->u1.str == name of context
2404  item->u2.statements == pval list of statements in context body
2405  item->u3.abstract == int 1 if an abstract keyword were present
2406  */
2407  current_context = item;
2408  current_extension = 0;
2409  if ( item->u3.abstract ) {
2410  in_abstract_context = 1;
2412  } else
2413  in_abstract_context = 0;
2414  check_pval(item->u2.statements, apps,in_globals);
2415  break;
2416 
2417  case PV_MACRO_CALL:
2418  /* fields: item->u1.str == name of macro to call
2419  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
2420  item->u2.arglist->u1.str == argument
2421  item->u2.arglist->next == next arg
2422  */
2423 #ifdef STANDALONE
2424  /* if this is a standalone, we will need to make sure the
2425  localized load of extensions.conf is done */
2426  if (!extensions_dot_conf_loaded) {
2428  extensions_dot_conf_loaded++;
2429  }
2430 #endif
2431  macro_def = find_macro(item->u1.str);
2432  if (!macro_def) {
2433 #ifdef STANDALONE
2434  struct pbx_find_info pfiq = {.stacklen = 0 };
2435  struct pbx_find_info pfiq2 = {.stacklen = 0 };
2436 
2437  /* look for the macro in the extensions.conf world */
2438  pbx_find_extension(NULL, NULL, &pfiq, item->u1.str, "s", 1, NULL, NULL, E_MATCH);
2439 
2440  if (pfiq.status != STATUS_SUCCESS) {
2441  char namebuf2[256];
2442  snprintf(namebuf2, 256, "macro-%s", item->u1.str);
2443 
2444  /* look for the macro in the extensions.conf world */
2445  pbx_find_extension(NULL, NULL, &pfiq2, namebuf2, "s", 1, NULL, NULL, E_MATCH);
2446 
2447  if (pfiq2.status == STATUS_SUCCESS) {
2448  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",
2449  item->filename, item->startline, item->endline, item->u1.str, item->u1.str);
2450  warns++;
2451  } else {
2452  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to non-existent %s! (Not even in the extensions.conf stuff!)\n",
2453  item->filename, item->startline, item->endline, item->u1.str);
2454  warns++;
2455  }
2456  }
2457 #else
2458  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to %s cannot be found in the AEL code!\n",
2459  item->filename, item->startline, item->endline, item->u1.str);
2460  warns++;
2461 
2462 #endif
2463 #ifdef THIS_IS_1DOT4
2464  char namebuf2[256];
2465  snprintf(namebuf2, 256, "macro-%s", item->u1.str);
2466 
2467  /* look for the macro in the extensions.conf world */
2468  pbx_find_extension(NULL, NULL, &pfiq, namebuf2, "s", 1, NULL, NULL, E_MATCH);
2469 
2470  if (pfiq.status != STATUS_SUCCESS) {
2471  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: macro call to %s was not found in the AEL, nor the extensions.conf !\n",
2472  item->filename, item->startline, item->endline, item->u1.str);
2473  warns++;
2474  }
2475 
2476 #endif
2477 
2478  } else if (macro_def->type != PV_MACRO) {
2479  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: macro call to %s references a context, not a macro!\n",
2480  item->filename, item->startline, item->endline, item->u1.str);
2481  errs++;
2482  } else {
2483  /* macro_def is a MACRO, so do the args match in number? */
2484  int hereargs = 0;
2485  int thereargs = 0;
2486 
2487  for (lp=item->u2.arglist; lp; lp=lp->next) {
2488  hereargs++;
2489  }
2490  for (lp=macro_def->u2.arglist; lp; lp=lp->next) {
2491  thereargs++;
2492  }
2493  if (hereargs != thereargs ) {
2494  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",
2495  item->filename, item->startline, item->endline, item->u1.str, hereargs, thereargs);
2496  errs++;
2497  }
2498  }
2499  break;
2500 
2501  case PV_APPLICATION_CALL:
2502  /* fields: item->u1.str == name of application to call
2503  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
2504  item->u2.arglist->u1.str == argument
2505  item->u2.arglist->next == next arg
2506  */
2507  /* Need to check to see if the application is available! */
2508  app_def = find_context(item->u1.str);
2509  if (app_def && app_def->type == PV_MACRO) {
2510  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: application call to %s references an existing macro, but had no & preceding it!\n",
2511  item->filename, item->startline, item->endline, item->u1.str);
2512  errs++;
2513  }
2514  if (strcasecmp(item->u1.str,"GotoIf") == 0
2515  || strcasecmp(item->u1.str,"GotoIfTime") == 0
2516  || strcasecmp(item->u1.str,"while") == 0
2517  || strcasecmp(item->u1.str,"endwhile") == 0
2518  || strcasecmp(item->u1.str,"random") == 0
2519  || strcasecmp(item->u1.str,"gosub") == 0
2520  || strcasecmp(item->u1.str,"gosubif") == 0
2521  || strcasecmp(item->u1.str,"continuewhile") == 0
2522  || strcasecmp(item->u1.str,"endwhile") == 0
2523  || strcasecmp(item->u1.str,"execif") == 0
2524  || strcasecmp(item->u1.str,"execiftime") == 0
2525  || strcasecmp(item->u1.str,"exitwhile") == 0
2526  || strcasecmp(item->u1.str,"goto") == 0
2527  || strcasecmp(item->u1.str,"macro") == 0
2528  || strcasecmp(item->u1.str,"macroexclusive") == 0
2529  || strcasecmp(item->u1.str,"macroif") == 0
2530  || strcasecmp(item->u1.str,"stackpop") == 0
2531  || strcasecmp(item->u1.str,"execIf") == 0 ) {
2532  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",
2533  item->filename, item->startline, item->endline, item->u1.str);
2534  warns++;
2535  }
2536  if (strcasecmp(item->u1.str,"macroexit") == 0) {
2537  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: I am converting the MacroExit call here to a return statement.\n",
2538  item->filename, item->startline, item->endline);
2539  item->type = PV_RETURN;
2540  free(item->u1.str);
2541  item->u1.str = 0;
2542  }
2543 
2544 #ifdef AAL_ARGCHECK
2545  found = 0;
2546  for (app=apps; app; app=app->next) {
2547  if (strcasecmp(app->name, item->u1.str) == 0) {
2548  found =app;
2549  break;
2550  }
2551  }
2552  if (!found) {
2553  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: application call to %s not listed in applist database!\n",
2554  item->filename, item->startline, item->endline, item->u1.str);
2555  warns++;
2556  } else
2557  check_app_args(item, item->u2.arglist, app);
2558 #endif
2559  break;
2560 
2561  case PV_CASE:
2562  /* fields: item->u1.str == value of case
2563  item->u2.statements == pval list of statements under the case
2564  */
2565  /* Make sure sequence of statements under case is terminated with goto, return, or break */
2566  /* find the last statement */
2567  check_pval(item->u2.statements, apps,in_globals);
2568  break;
2569 
2570  case PV_PATTERN:
2571  /* fields: item->u1.str == value of case
2572  item->u2.statements == pval list of statements under the case
2573  */
2574  /* Make sure sequence of statements under case is terminated with goto, return, or break */
2575  /* find the last statement */
2576 
2577  check_pval(item->u2.statements, apps,in_globals);
2578  break;
2579 
2580  case PV_DEFAULT:
2581  /* fields:
2582  item->u2.statements == pval list of statements under the case
2583  */
2584 
2585  check_pval(item->u2.statements, apps,in_globals);
2586  break;
2587 
2588  case PV_CATCH:
2589  /* fields: item->u1.str == name of extension to catch
2590  item->u2.statements == pval list of statements in context body
2591  */
2592  check_pval(item->u2.statements, apps,in_globals);
2593  break;
2594 
2595  case PV_SWITCHES:
2596  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
2597  */
2598  check_pval(item->u1.list, apps,in_globals);
2599  break;
2600 
2601  case PV_ESWITCHES:
2602  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
2603  */
2604  check_pval(item->u1.list, apps,in_globals);
2605  break;
2606 
2607  case PV_INCLUDES:
2608  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
2609  */
2610  check_pval(item->u1.list, apps,in_globals);
2611  check_includes(item);
2612  for (lp=item->u1.list; lp; lp=lp->next){
2613  char *incl_context = lp->u1.str;
2614  struct pval *that_context = find_context(incl_context);
2615 
2616  if ( lp->u2.arglist ) {
2617  check_timerange(lp->u2.arglist);
2618  check_dow(lp->u2.arglist->next);
2619  check_day(lp->u2.arglist->next->next);
2620  check_month(lp->u2.arglist->next->next->next);
2621  }
2622 
2623  if (that_context) {
2624  find_pval_gotos(that_context->u2.statements,0);
2625 
2626  }
2627  }
2628  break;
2629 
2630  case PV_STATEMENTBLOCK:
2631  /* fields: item->u1.list == pval list of statements in block, one per entry in the list
2632  */
2633  check_pval(item->u1.list, apps,in_globals);
2634  break;
2635 
2636  case PV_VARDEC:
2637  /* fields: item->u1.str == variable name
2638  item->u2.val == variable value to assign
2639  */
2640  /* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */
2641  if( !in_globals ) { /* don't check stuff inside the globals context; no wrapping in $[ ] there... */
2642  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);
2644  ast_expr(item->u2.val, expr_output, sizeof(expr_output),NULL);
2646  if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) {
2647  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2648  item->filename, item->startline, item->endline, item->u2.val);
2649  warns++;
2650  }
2651  check_expr2_input(item,item->u2.val);
2652  }
2653  break;
2654 
2655  case PV_LOCALVARDEC:
2656  /* fields: item->u1.str == variable name
2657  item->u2.val == variable value to assign
2658  */
2659  /* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */
2660  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);
2662  ast_expr(item->u2.val, expr_output, sizeof(expr_output),NULL);
2664  if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) {
2665  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2666  item->filename, item->startline, item->endline, item->u2.val);
2667  warns++;
2668  }
2669  check_expr2_input(item,item->u2.val);
2670  break;
2671 
2672  case PV_GOTO:
2673  /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
2674  item->u1.list->u1.str == where the data on a PV_WORD will always be.
2675  */
2676  /* don't check goto's in abstract contexts */
2677  if ( in_abstract_context )
2678  break;
2679 
2680  check_goto(item);
2681  break;
2682 
2683  case PV_LABEL:
2684  /* fields: item->u1.str == label name
2685  */
2686  if ( strspn(item->u1.str, "0123456789") == strlen(item->u1.str) ) {
2687  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: label '%s' is numeric, this is bad practice!\n",
2688  item->filename, item->startline, item->endline, item->u1.str);
2689  warns++;
2690  }
2691 
2692  check_label(item);
2693  break;
2694 
2695  case PV_FOR:
2696  /* fields: item->u1.for_init == a string containing the initalizer
2697  item->u2.for_test == a string containing the loop test
2698  item->u3.for_inc == a string containing the loop increment
2699 
2700  item->u4.for_statements == a pval list of statements in the for ()
2701  */
2702  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);
2704 
2705  strp = strchr(item->u1.for_init, '=');
2706  if (strp) {
2707  ast_expr(strp+1, expr_output, sizeof(expr_output),NULL);
2708  }
2709  ast_expr(item->u2.for_test, expr_output, sizeof(expr_output),NULL);
2710  strp = strchr(item->u3.for_inc, '=');
2711  if (strp) {
2712  ast_expr(strp+1, expr_output, sizeof(expr_output),NULL);
2713  }
2714  if ( strpbrk(item->u2.for_test,"~!-+<>=*/&^") && !strstr(item->u2.for_test,"${") ) {
2715  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2716  item->filename, item->startline, item->endline, item->u2.for_test);
2717  warns++;
2718  }
2719  if ( strpbrk(item->u3.for_inc,"~!-+<>=*/&^") && !strstr(item->u3.for_inc,"${") ) {
2720  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2721  item->filename, item->startline, item->endline, item->u3.for_inc);
2722  warns++;
2723  }
2724  check_expr2_input(item,item->u2.for_test);
2725  check_expr2_input(item,item->u3.for_inc);
2726 
2728  check_pval(item->u4.for_statements, apps,in_globals);
2729  break;
2730 
2731  case PV_WHILE:
2732  /* fields: item->u1.str == the while conditional, as supplied by user
2733 
2734  item->u2.statements == a pval list of statements in the while ()
2735  */
2736  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);
2738  ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL);
2740  if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
2741  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
2742  item->filename, item->startline, item->endline, item->u1.str);
2743  warns++;
2744  }
2745  check_expr2_input(item,item->u1.str);
2746  check_pval(item->u2.statements, apps,in_globals);
2747  break;
2748 
2749  case PV_BREAK:
2750  /* fields: none
2751  */
2752  check_break(item);
2753  break;
2754 
2755  case PV_RETURN:
2756  /* fields: none
2757  */
2758  break;
2759 
2760  case PV_CONTINUE:
2761  /* fields: none
2762  */
2763  check_continue(item);
2764  break;
2765 
2766  case PV_RANDOM:
2767  /* fields: item->u1.str == the random number expression, as supplied by user
2768 
2769  item->u2.statements == a pval list of statements in the if ()
2770  item->u3.else_statements == a pval list of statements in the else
2771  (could be zero)
2772  */
2773  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);
2775  ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL);
2777  if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
2778  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n",
2779  item->filename, item->startline, item->endline, item->u1.str);
2780  warns++;
2781  }
2782  check_expr2_input(item,item->u1.str);
2783  check_pval(item->u2.statements, apps,in_globals);
2784  if (item->u3.else_statements) {
2785  check_pval(item->u3.else_statements, apps,in_globals);
2786  }
2787  break;
2788 
2789  case PV_IFTIME:
2790  /* fields: item->u1.list == the if time values, 4 of them, each in PV_WORD, linked list
2791 
2792  item->u2.statements == a pval list of statements in the if ()
2793  item->u3.else_statements == a pval list of statements in the else
2794  (could be zero)
2795  */
2796  if ( item->u2.arglist ) {
2797  check_timerange(item->u1.list);
2798  check_dow(item->u1.list->next);
2799  check_day(item->u1.list->next->next);
2800  check_month(item->u1.list->next->next->next);
2801  }
2802 
2803  check_pval(item->u2.statements, apps,in_globals);
2804  if (item->u3.else_statements) {
2805  check_pval(item->u3.else_statements, apps,in_globals);
2806  }
2807  break;
2808 
2809  case PV_IF:
2810  /* fields: item->u1.str == the if conditional, as supplied by user
2811 
2812  item->u2.statements == a pval list of statements in the if ()
2813  item->u3.else_statements == a pval list of statements in the else
2814  (could be zero)
2815  */
2816  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);
2818  ast_expr(item->u1.str, expr_output, sizeof(expr_output),NULL);
2820  if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
2821  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n",
2822  item->filename, item->startline, item->endline, item->u1.str);
2823  warns++;
2824  }
2825  check_expr2_input(item,item->u1.str);
2826  check_pval(item->u2.statements, apps,in_globals);
2827  if (item->u3.else_statements) {
2828  check_pval(item->u3.else_statements, apps,in_globals);
2829  }
2830  break;
2831 
2832  case PV_SWITCH:
2833  /* fields: item->u1.str == the switch expression
2834 
2835  item->u2.statements == a pval list of statements in the switch,
2836  (will be case statements, most likely!)
2837  */
2838  /* we can check the switch expression, see if it matches any of the app variables...
2839  if it does, then, are all the possible cases accounted for? */
2840  check_switch_expr(item, apps);
2841  check_pval(item->u2.statements, apps,in_globals);
2842  break;
2843 
2844  case PV_EXTENSION:
2845  /* fields: item->u1.str == the extension name, label, whatever it's called
2846 
2847  item->u2.statements == a pval list of statements in the extension
2848  item->u3.hints == a char * hint argument
2849  item->u4.regexten == an int boolean. non-zero says that regexten was specified
2850  */
2851  current_extension = item ;
2852 
2853  check_pval(item->u2.statements, apps,in_globals);
2854  break;
2855 
2856  case PV_IGNOREPAT:
2857  /* fields: item->u1.str == the ignorepat data
2858  */
2859  break;
2860 
2861  case PV_GLOBALS:
2862  /* fields: item->u1.statements == pval list of statements, usually vardecs
2863  */
2864  in_abstract_context = 0;
2865  check_pval(item->u1.statements, apps, 1);
2866  break;
2867  default:
2868  break;
2869  }
2870 }
union pval::@198 u1
char * for_inc
Definition: pval.h:77
static void find_pval_gotos(pval *item, int lev)
Definition: pval.c:1557
void check_switch_expr(pval *item, struct argapp *apps)
Definition: pval.c:2191
void check_pval(pval *item, struct argapp *apps, int in_globals)
Definition: pval.c:2872
static int check_break(pval *item)
Definition: pval.c:1045
static int errs
Definition: pval.c:67
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
#define LOG_WARNING
Definition: logger.h:144
struct pval * statements
Definition: pval.h:61
static void check_day(pval *DAY)
Definition: pval.c:944
Definition: pval.h:22
int startline
Definition: pval.h:51
int abstract
Definition: pval.h:80
Definition: pval.h:8
Definition: pval.h:110
static void check_abstract_reference(pval *abstract_context)
Definition: pval.c:2336
union pval::@200 u3
union pval::@199 u2
char * val
Definition: pval.h:70
static const char app[]
Definition: app_adsiprog.c:49
static int check_continue(pval *item)
Definition: pval.c:1065
static pval * current_extension
Definition: pval.c:76
Definition: pval.h:13
static int in_abstract_context
Definition: pval.c:81
static void check_timerange(pval *p)
Definition: pval.c:837
char * filename
Definition: pval.h:55
static void check_macro_returns(pval *macro)
Definition: pval.c:652
Definition: pval.h:21
char * str
Definition: pval.h:59
Definition: pval.h:48
char * for_test
Definition: pval.h:71
static char expr_output[2096]
Definition: pval.c:62
void ast_expr_clear_extra_error_info(void)
Definition: ast_expr2f.c:2475
#define LOG_ERROR
Definition: logger.h:155
struct pval * else_statements
Definition: pval.h:78
#define free(a)
Definition: astmm.h:94
static void check_goto(pval *item)
Definition: pval.c:1232
Definition: pval.h:24
union pval::@201 u4
struct pval * arglist
Definition: pval.h:68
int endcol
Definition: pval.h:54
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static void check_label(pval *item)
Definition: pval.c:1113
#define STATUS_SUCCESS
Definition: extconf.h:245
Definition: pval.h:9
Definition: pval.h:31
static void check_includes(pval *includes)
Definition: pval.c:818
Definition: pval.h:25
int stacklen
Definition: extconf.h:234
pvaltype type
Definition: pval.h:50
int localized_pbx_load_module(void)
struct pval * find_context(char *name)
Definition: pval.c:1960
void ast_expr_register_extra_error_info(char *errmsg)
Definition: ast_expr2f.c:2469
static void check_month(pval *MON)
Definition: pval.c:1007
Definition: pval.h:30
Definition: pval.h:23
static pval * current_context
Definition: pval.c:75
int check_app_args(pval *appcall, pval *arglist, struct argapp *app)
Definition: pval.c:2137
static int warns
Definition: pval.c:67
struct argapp * next
Definition: pval.h:112
struct pval * find_macro(char *name)
Definition: pval.c:1950
struct pval * next
Definition: pval.h:93
static void check_expr2_input(pval *expr, char *str)
Definition: pval.c:808
struct ast_exten * pbx_find_extension(struct ast_channel *chan, struct ast_context *bypass, struct pbx_find_info *q, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action)
Definition: pbx.c:3013
Definition: pval.h:27
struct pval * for_statements
Definition: pval.h:89
int endline
Definition: pval.h:52
int startcol
Definition: pval.h:53
int ast_expr(char *expr, char *buf, int length, struct ast_channel *chan)
Evaluate the given expression.
Definition: ast_expr2f.c:2396
Definition: pval.h:26
char * for_init
Definition: pval.h:62
Definition: pval.h:16
static void check_dow(pval *DOW)
get_dow: Get day of week
Definition: pval.c:905
struct pval * macro_statements
Definition: pval.h:79
void check_switch_expr ( pval item,
struct argapp apps 
)

Definition at line 2191 of file pval.c.

References ast_log(), ast_strdupa, 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().

2192 {
2193 #ifdef AAL_ARGCHECK
2194  /* get and clean the variable name */
2195  char *buff1, *p;
2196  struct argapp *a,*a2;
2197  struct appsetvar *v,*v2;
2198  struct argchoice *c;
2199  pval *t;
2200 
2201  p = item->u1.str;
2202  while (p && *p && (*p == ' ' || *p == '\t' || *p == '$' || *p == '{' ) )
2203  p++;
2204 
2205  buff1 = ast_strdupa(p);
2206 
2207  while (strlen(buff1) > 0 && ( buff1[strlen(buff1)-1] == '}' || buff1[strlen(buff1)-1] == ' ' || buff1[strlen(buff1)-1] == '\t'))
2208  buff1[strlen(buff1)-1] = 0;
2209  /* buff1 now contains the variable name */
2210  v = 0;
2211  for (a=apps; a; a=a->next) {
2212  for (v=a->setvars;v;v=v->next) {
2213  if (strcmp(v->name,buff1) == 0) {
2214  break;
2215  }
2216  }
2217  if ( v )
2218  break;
2219  }
2220  if (v && v->vals) {
2221  /* we have a match, to a variable that has a set of determined values */
2222  int def= 0;
2223  int pat = 0;
2224  int f1 = 0;
2225 
2226  /* first of all, does this switch have a default case ? */
2227  for (t=item->u2.statements; t; t=t->next) {
2228  if (t->type == PV_DEFAULT) {
2229  def =1;
2230  break;
2231  }
2232  if (t->type == PV_PATTERN) {
2233  pat++;
2234  }
2235  }
2236  if (def || pat) /* nothing to check. All cases accounted for! */
2237  return;
2238  for (c=v->vals; c; c=c->next) {
2239  f1 = 0;
2240  for (t=item->u2.statements; t; t=t->next) {
2241  if (t->type == PV_CASE || t->type == PV_PATTERN) {
2242  if (!strcmp(t->u1.str,c->name)) {
2243  f1 = 1;
2244  break;
2245  }
2246  }
2247  }
2248  if (!f1) {
2249  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: switch with expression(%s) does not handle the case of %s !\n",
2250  item->filename, item->startline, item->endline, item->u1.str, c->name);
2251  warns++;
2252  }
2253  }
2254  /* next, is there an app call in the current exten, that would set this var? */
2255  f1 = 0;
2257  if ( t && t->type == PV_STATEMENTBLOCK )
2258  t = t->u1.statements;
2259  for (; t && t != item; t=t->next) {
2260  if (t->type == PV_APPLICATION_CALL) {
2261  /* find the application that matches the u1.str */
2262  for (a2=apps; a2; a2=a2->next) {
2263  if (strcasecmp(a2->name, t->u1.str)==0) {
2264  for (v2=a2->setvars; v2; v2=v2->next) {
2265  if (strcmp(v2->name, buff1) == 0) {
2266  /* found an app that sets the var */
2267  f1 = 1;
2268  break;
2269  }
2270  }
2271  }
2272  if (f1)
2273  break;
2274  }
2275  }
2276  if (f1)
2277  break;
2278  }
2279 
2280  /* see if it sets the var */
2281  if (!f1) {
2282  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",
2283  item->filename, item->startline, item->endline, item->u1.str);
2284  warns++;
2285  }
2286  }
2287 #else
2288  pval *t,*tl=0,*p2;
2289  int def= 0;
2290 
2291  /* first of all, does this switch have a default case ? */
2292  for (t=item->u2.statements; t; t=t->next) {
2293  if (t->type == PV_DEFAULT) {
2294  def =1;
2295  break;
2296  }
2297  tl = t;
2298  }
2299  if (def) /* nothing to check. All cases accounted for! */
2300  return;
2301  /* if no default, warn and insert a default case at the end */
2302  p2 = tl->next = calloc(1, sizeof(struct pval));
2303 
2304  p2->type = PV_DEFAULT;
2305  p2->startline = tl->startline;
2306  p2->endline = tl->endline;
2307  p2->startcol = tl->startcol;
2308  p2->endcol = tl->endcol;
2309  p2->filename = strdup(tl->filename);
2310  ast_log(LOG_WARNING,"Warning: file %s, line %d-%d: A default case was automatically added to the switch.\n",
2311  p2->filename, p2->startline, p2->endline);
2312  warns++;
2313 
2314 #endif
2315 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
struct pval * statements
Definition: pval.h:61
int startline
Definition: pval.h:51
Definition: pval.h:110
#define calloc(a, b)
Definition: astmm.h:79
union pval::@199 u2
static pval * current_extension
Definition: pval.c:76
Definition: pval.h:13
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int endcol
Definition: pval.h:54
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
pvaltype type
Definition: pval.h:50
static int warns
Definition: pval.c:67
struct argapp * next
Definition: pval.h:112
struct pval * next
Definition: pval.h:93
#define strdup(a)
Definition: astmm.h:106
int endline
Definition: pval.h:52
int startcol
Definition: pval.h:53
static void check_timerange ( pval p)
static

Definition at line 837 of file pval.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, and pval::u1.

Referenced by check_pval_item().

838 {
839  char *times;
840  char *e;
841  int s1, s2;
842  int e1, e2;
843 
844  times = ast_strdupa(p->u1.str);
845 
846  /* Star is all times */
847  if (ast_strlen_zero(times) || !strcmp(times, "*")) {
848  return;
849  }
850  /* Otherwise expect a range */
851  e = strchr(times, '-');
852  if (!e) {
853  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",
854  p->filename, p->startline, p->endline, times);
855  warns++;
856  return;
857  }
858  *e = '\0';
859  e++;
860  while (*e && !isdigit(*e))
861  e++;
862  if (!*e) {
863  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n",
864  p->filename, p->startline, p->endline, p->u1.str);
865  warns++;
866  }
867  if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) {
868  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n",
869  p->filename, p->startline, p->endline, times);
870  warns++;
871  }
872  if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) {
873  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n",
874  p->filename, p->startline, p->endline, times);
875  warns++;
876  }
877 
878  s1 = s1 * 30 + s2/2;
879  if ((s1 < 0) || (s1 >= 24*30)) {
880  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) is out of range!\n",
881  p->filename, p->startline, p->endline, times);
882  warns++;
883  }
884  e1 = e1 * 30 + e2/2;
885  if ((e1 < 0) || (e1 >= 24*30)) {
886  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) is out of range!\n",
887  p->filename, p->startline, p->endline, e);
888  warns++;
889  }
890  return;
891 }
union pval::@198 u1
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static int warns
Definition: pval.c:67
int endline
Definition: pval.h:52
int contains_switch ( pval item)

Definition at line 3336 of file pval.c.

References find_switch_item(), and pval::next.

Referenced by find_switch_item(), and gen_prios().

3337 {
3338  pval *i;
3339 
3340  for (i=item; i; i=i->next) {
3341  if (find_switch_item(i))
3342  return 1;
3343  }
3344  return 0;
3345 }
Definition: pval.h:48
int find_switch_item(pval *item)
Definition: pval.c:3097
struct pval * next
Definition: pval.h:93
static int context_used ( struct ael_extension exten_list,
struct ast_context context 
)
static

Definition at line 4436 of file pval.c.

References ast_walk_context_extensions(), ast_walk_context_ignorepats(), ast_walk_context_includes(), ast_walk_context_switches(), ael_extension::context, exten, and ael_extension::next_exten.

Referenced by ast_compile_ael2().

4437 {
4438  struct ael_extension *exten;
4439  /* Check the simple elements first */
4440  if (ast_walk_context_extensions(context, NULL) || ast_walk_context_includes(context, NULL) || ast_walk_context_ignorepats(context, NULL) || ast_walk_context_switches(context, NULL)) {
4441  return 1;
4442  }
4443  for (exten = exten_list; exten; exten = exten->next_exten) {
4444  if (exten->context == context) {
4445  return 1;
4446  }
4447  }
4448  return 0;
4449 }
struct ast_include * ast_walk_context_includes(struct ast_context *con, struct ast_include *inc)
Definition: pbx.c:11203
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
struct ael_extension * next_exten
Definition: ael_structs.h:117
struct ast_context * context
Definition: ael_structs.h:113
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: pbx.c:11179
struct ast_ignorepat * ast_walk_context_ignorepats(struct ast_context *con, struct ast_ignorepat *ip)
Definition: pbx.c:11212
struct ast_sw * ast_walk_context_switches(struct ast_context *con, struct ast_sw *sw)
Definition: pbx.c:11188
void destroy_extensions ( struct ael_extension exten)

Definition at line 2985 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().

2986 {
2987  struct ael_extension *ne, *nen;
2988  for (ne=exten; ne; ne=nen) {
2989  struct ael_priority *pe, *pen;
2990 
2991  if (ne->name)
2992  free(ne->name);
2993 
2994  /* cidmatch fields are allocated with name, and freed when
2995  the name field is freed. Don't do a free for this field,
2996  unless you LIKE to see a crash! */
2997 
2998  if (ne->hints)
2999  free(ne->hints);
3000 
3001  for (pe=ne->plist; pe; pe=pen) {
3002  pen = pe->next;
3003  if (pe->app)
3004  free(pe->app);
3005  pe->app = 0;
3006  if (pe->appargs)
3007  free(pe->appargs);
3008  pe->appargs = 0;
3009  pe->origin = 0;
3010  pe->goto_true = 0;
3011  pe->goto_false = 0;
3012  free(pe);
3013  }
3014  nen = ne->next_exten;
3015  ne->next_exten = 0;
3016  ne->plist =0;
3017  ne->plist_last = 0;
3018  ne->next_exten = 0;
3019  ne->loop_break = 0;
3020  ne->loop_continue = 0;
3021  free(ne);
3022  }
3023 }
struct pval * origin
Definition: ael_structs.h:95
struct ael_priority * goto_true
Definition: ael_structs.h:98
struct ael_priority * plist_last
Definition: ael_structs.h:116
struct ael_priority * plist
Definition: ael_structs.h:115
struct ael_priority * goto_false
Definition: ael_structs.h:99
char * appargs
Definition: ael_structs.h:93
struct ael_extension * next_exten
Definition: ael_structs.h:117
struct ael_priority * loop_break
Definition: ael_structs.h:119
char * app
Definition: ael_structs.h:92
#define free(a)
Definition: astmm.h:94
struct ael_priority * loop_continue
Definition: ael_structs.h:120
struct ael_priority * next
Definition: ael_structs.h:100
void destroy_pval ( pval item)

Definition at line 4979 of file pval.c.

References destroy_pval_item(), and pval::next.

Referenced by destroy_pval_item(), pbx_load_module(), and switch().

4980 {
4981  pval *i,*nxt;
4982 
4983  for (i=item; i; i=nxt) {
4984  nxt = i->next;
4985 
4986  destroy_pval_item(i);
4987  }
4988 }
void destroy_pval_item(pval *item)
Definition: pval.c:4711
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
void destroy_pval_item ( pval item)

Definition at line 4711 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().

4712 {
4713  if (item == NULL) {
4714  ast_log(LOG_WARNING, "null item\n");
4715  return;
4716  }
4717 
4718  if (item->filename)
4719  free(item->filename);
4720 
4721  switch (item->type) {
4722  case PV_WORD:
4723  /* fields: item->u1.str == string associated with this (word). */
4724  if (item->u1.str )
4725  free(item->u1.str);
4726  if ( item->u2.arglist )
4727  destroy_pval(item->u2.arglist);
4728  break;
4729 
4730  case PV_MACRO:
4731  /* fields: item->u1.str == name of macro
4732  item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
4733  item->u2.arglist->u1.str == argument
4734  item->u2.arglist->next == next arg
4735 
4736  item->u3.macro_statements == pval list of statements in macro body.
4737  */
4738  destroy_pval(item->u2.arglist);
4739  if (item->u1.str )
4740  free(item->u1.str);
4742  break;
4743 
4744  case PV_CONTEXT:
4745  /* fields: item->u1.str == name of context
4746  item->u2.statements == pval list of statements in context body
4747  item->u3.abstract == int 1 if an abstract keyword were present
4748  */
4749  if (item->u1.str)
4750  free(item->u1.str);
4751  destroy_pval(item->u2.statements);
4752  break;
4753 
4754  case PV_MACRO_CALL:
4755  /* fields: item->u1.str == name of macro to call
4756  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
4757  item->u2.arglist->u1.str == argument
4758  item->u2.arglist->next == next arg
4759  */
4760  if (item->u1.str)
4761  free(item->u1.str);
4762  destroy_pval(item->u2.arglist);
4763  break;
4764 
4765  case PV_APPLICATION_CALL:
4766  /* fields: item->u1.str == name of application to call
4767  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
4768  item->u2.arglist->u1.str == argument
4769  item->u2.arglist->next == next arg
4770  */
4771  if (item->u1.str)
4772  free(item->u1.str);
4773  destroy_pval(item->u2.arglist);
4774  break;
4775 
4776  case PV_CASE:
4777  /* fields: item->u1.str == value of case
4778  item->u2.statements == pval list of statements under the case
4779  */
4780  if (item->u1.str)
4781  free(item->u1.str);
4782  destroy_pval(item->u2.statements);
4783  break;
4784 
4785  case PV_PATTERN:
4786  /* fields: item->u1.str == value of case
4787  item->u2.statements == pval list of statements under the case
4788  */
4789  if (item->u1.str)
4790  free(item->u1.str);
4791  destroy_pval(item->u2.statements);
4792  break;
4793 
4794  case PV_DEFAULT:
4795  /* fields:
4796  item->u2.statements == pval list of statements under the case
4797  */
4798  destroy_pval(item->u2.statements);
4799  break;
4800 
4801  case PV_CATCH:
4802  /* fields: item->u1.str == name of extension to catch
4803  item->u2.statements == pval list of statements in context body
4804  */
4805  if (item->u1.str)
4806  free(item->u1.str);
4807  destroy_pval(item->u2.statements);
4808  break;
4809 
4810  case PV_SWITCHES:
4811  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
4812  */
4813  destroy_pval(item->u1.list);
4814  break;
4815 
4816  case PV_ESWITCHES:
4817  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
4818  */
4819  destroy_pval(item->u1.list);
4820  break;
4821 
4822  case PV_INCLUDES:
4823  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
4824  item->u2.arglist == pval list of 4 PV_WORD elements for time values
4825  */
4826  destroy_pval(item->u1.list);
4827  break;
4828 
4829  case PV_STATEMENTBLOCK:
4830  /* fields: item->u1.list == pval list of statements in block, one per entry in the list
4831  */
4832  destroy_pval(item->u1.list);
4833  break;
4834 
4835  case PV_LOCALVARDEC:
4836  case PV_VARDEC:
4837  /* fields: item->u1.str == variable name
4838  item->u2.val == variable value to assign
4839  */
4840  if (item->u1.str)
4841  free(item->u1.str);
4842  if (item->u2.val)
4843  free(item->u2.val);
4844  break;
4845 
4846  case PV_GOTO:
4847  /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
4848  item->u1.list->u1.str == where the data on a PV_WORD will always be.
4849  */
4850 
4851  destroy_pval(item->u1.list);
4852  break;
4853 
4854  case PV_LABEL:
4855  /* fields: item->u1.str == label name
4856  */
4857  if (item->u1.str)
4858  free(item->u1.str);
4859  break;
4860 
4861  case PV_FOR:
4862  /* fields: item->u1.for_init == a string containing the initalizer
4863  item->u2.for_test == a string containing the loop test
4864  item->u3.for_inc == a string containing the loop increment
4865 
4866  item->u4.for_statements == a pval list of statements in the for ()
4867  */
4868  if (item->u1.for_init)
4869  free(item->u1.for_init);
4870  if (item->u2.for_test)
4871  free(item->u2.for_test);
4872  if (item->u3.for_inc)
4873  free(item->u3.for_inc);
4875  break;
4876 
4877  case PV_WHILE:
4878  /* fields: item->u1.str == the while conditional, as supplied by user
4879 
4880  item->u2.statements == a pval list of statements in the while ()
4881  */
4882  if (item->u1.str)
4883  free(item->u1.str);
4884  destroy_pval(item->u2.statements);
4885  break;
4886 
4887  case PV_BREAK:
4888  /* fields: none
4889  */
4890  break;
4891 
4892  case PV_RETURN:
4893  /* fields: none
4894  */
4895  break;
4896 
4897  case PV_CONTINUE:
4898  /* fields: none
4899  */
4900  break;
4901 
4902  case PV_IFTIME:
4903  /* fields: item->u1.list == the 4 time values, in PV_WORD structs, linked list
4904 
4905  item->u2.statements == a pval list of statements in the if ()
4906  item->u3.else_statements == a pval list of statements in the else
4907  (could be zero)
4908  */
4909  destroy_pval(item->u1.list);
4910  destroy_pval(item->u2.statements);
4911  if (item->u3.else_statements) {
4913  }
4914  break;
4915 
4916  case PV_RANDOM:
4917  /* fields: item->u1.str == the random percentage, as supplied by user
4918 
4919  item->u2.statements == a pval list of statements in the true part ()
4920  item->u3.else_statements == a pval list of statements in the else
4921  (could be zero)
4922  fall thru to If */
4923  case PV_IF:
4924  /* fields: item->u1.str == the if conditional, as supplied by user
4925 
4926  item->u2.statements == a pval list of statements in the if ()
4927  item->u3.else_statements == a pval list of statements in the else
4928  (could be zero)
4929  */
4930  if (item->u1.str)
4931  free(item->u1.str);
4932  destroy_pval(item->u2.statements);
4933  if (item->u3.else_statements) {
4935  }
4936  break;
4937 
4938  case PV_SWITCH:
4939  /* fields: item->u1.str == the switch expression
4940 
4941  item->u2.statements == a pval list of statements in the switch,
4942  (will be case statements, most likely!)
4943  */
4944  if (item->u1.str)
4945  free(item->u1.str);
4946  destroy_pval(item->u2.statements);
4947  break;
4948 
4949  case PV_EXTENSION:
4950  /* fields: item->u1.str == the extension name, label, whatever it's called
4951 
4952  item->u2.statements == a pval list of statements in the extension
4953  item->u3.hints == a char * hint argument
4954  item->u4.regexten == an int boolean. non-zero says that regexten was specified
4955  */
4956  if (item->u1.str)
4957  free(item->u1.str);
4958  if (item->u3.hints)
4959  free(item->u3.hints);
4960  destroy_pval(item->u2.statements);
4961  break;
4962 
4963  case PV_IGNOREPAT:
4964  /* fields: item->u1.str == the ignorepat data
4965  */
4966  if (item->u1.str)
4967  free(item->u1.str);
4968  break;
4969 
4970  case PV_GLOBALS:
4971  /* fields: item->u1.statements == pval list of statements, usually vardecs
4972  */
4973  destroy_pval(item->u1.statements);
4974  break;
4975  }
4976  free(item);
4977 }
union pval::@198 u1
char * for_inc
Definition: pval.h:77
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
#define LOG_WARNING
Definition: logger.h:144
struct pval * statements
Definition: pval.h:61
Definition: pval.h:22
Definition: pval.h:8
union pval::@200 u3
union pval::@199 u2
char * val
Definition: pval.h:70
Definition: pval.h:13
char * filename
Definition: pval.h:55
Definition: pval.h:21
char * str
Definition: pval.h:59
void destroy_pval(pval *item)
Definition: pval.c:4979
char * for_test
Definition: pval.h:71
char * hints
Definition: pval.h:81
struct pval * else_statements
Definition: pval.h:78
#define free(a)
Definition: astmm.h:94
Definition: pval.h:24
union pval::@201 u4
struct pval * arglist
Definition: pval.h:68
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: pval.h:9
Definition: pval.h:31
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
Definition: pval.h:30
Definition: pval.h:23
Definition: pval.h:27
struct pval * for_statements
Definition: pval.h:89
Definition: pval.h:26
char * for_init
Definition: pval.h:62
Definition: pval.h:16
struct pval * macro_statements
Definition: pval.h:79
static int extension_matches ( pval here,
const char *  exten,
const char *  pattern 
)
static

Definition at line 696 of file pval.c.

References ast_log(), pval::endline, pval::filename, LOG_ERROR, LOG_WARNING, and pval::startline.

Referenced by match_pval_item().

697 {
698  int err1;
699  regex_t preg;
700 
701  /* simple case, they match exactly, the pattern and exten name */
702  if (strcmp(pattern,exten) == 0)
703  return 1;
704 
705  if (pattern[0] == '_') {
706  char reg1[2000];
707  const char *p;
708  char *r = reg1;
709 
710  if ( strlen(pattern)*5 >= 2000 ) /* safety valve */ {
711  ast_log(LOG_ERROR,"Error: The pattern %s is way too big. Pattern matching cancelled.\n",
712  pattern);
713  return 0;
714  }
715  /* form a regular expression from the pattern, and then match it against exten */
716  *r++ = '^'; /* what if the extension is a pattern ?? */
717  *r++ = '_'; /* what if the extension is a pattern ?? */
718  *r++ = '?';
719  for (p=pattern+1; *p; p++) {
720  switch ( *p ) {
721  case 'X':
722  *r++ = '[';
723  *r++ = '0';
724  *r++ = '-';
725  *r++ = '9';
726  *r++ = 'X';
727  *r++ = ']';
728  break;
729 
730  case 'Z':
731  *r++ = '[';
732  *r++ = '1';
733  *r++ = '-';
734  *r++ = '9';
735  *r++ = 'Z';
736  *r++ = ']';
737  break;
738 
739  case 'N':
740  *r++ = '[';
741  *r++ = '2';
742  *r++ = '-';
743  *r++ = '9';
744  *r++ = 'N';
745  *r++ = ']';
746  break;
747 
748  case '[':
749  while ( *p && *p != ']' ) {
750  *r++ = *p++;
751  }
752  *r++ = ']';
753  if ( *p != ']') {
754  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The extension pattern '%s' is missing a closing bracket \n",
755  here->filename, here->startline, here->endline, pattern);
756  }
757  break;
758 
759  case '.':
760  case '!':
761  *r++ = '.';
762  *r++ = '*';
763  break;
764  case '*':
765  *r++ = '\\';
766  *r++ = '*';
767  break;
768  default:
769  *r++ = *p;
770  break;
771 
772  }
773  }
774  *r++ = '$'; /* what if the extension is a pattern ?? */
775  *r++ = *p++; /* put in the closing null */
776  err1 = regcomp(&preg, reg1, REG_NOSUB|REG_EXTENDED);
777  if ( err1 ) {
778  char errmess[500];
779  regerror(err1,&preg,errmess,sizeof(errmess));
780  regfree(&preg);
781  ast_log(LOG_WARNING, "Regcomp of %s failed, error code %d\n",
782  reg1, err1);
783  return 0;
784  }
785  err1 = regexec(&preg, exten, 0, 0, 0);
786  regfree(&preg);
787 
788  if ( err1 ) {
789  /* ast_log(LOG_NOTICE,"*****************************[%d]Extension %s did not match %s(%s)\n",
790  err1,exten, pattern, reg1); */
791  return 0; /* no match */
792  } else {
793  /* ast_log(LOG_NOTICE,"*****************************Extension %s matched %s\n",
794  exten, pattern); */
795  return 1;
796  }
797 
798 
799  } else {
800  if ( strcmp(exten,pattern) == 0 ) {
801  return 1;
802  } else
803  return 0;
804  }
805 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
#define LOG_WARNING
Definition: logger.h:144
int startline
Definition: pval.h:51
char * filename
Definition: pval.h:55
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int endline
Definition: pval.h:52
struct pval* find_context ( char *  name)

Definition at line 1960 of file pval.c.

References match_pval(), and name.

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(), get_goto_target(), and pbx_find_extension().

1961 {
1963  count_labels = 0;
1964  match_context = name;
1965  match_exten = "*"; /* don't really need to set these, shouldn't be reached */
1966  match_label = "*";
1967  return match_pval(current_db);
1968 }
static int count_labels
Definition: pval.c:82
static const char name[]
static const char * match_exten
Definition: pval.c:79
static int return_on_context_match
Definition: pval.c:84
static pval * current_db
Definition: pval.c:74
struct pval * match_pval(pval *item)
Definition: pval.c:1818
static const char * match_context
Definition: pval.c:78
static const char * match_label
Definition: pval.c:80
struct pval * find_first_label_in_current_context ( char *  label,
pval curr_cont 
)
static

Definition at line 1846 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().

1847 {
1848  /* printf(" --- Got args %s, %s\n", exten, label); */
1849  struct pval *ret;
1850  struct pval *p3;
1851 
1852  count_labels = 0;
1854  match_context = "*";
1855  match_exten = "*";
1856  match_label = label;
1857 
1858  ret = match_pval(curr_cont);
1859  if (ret)
1860  return ret;
1861 
1862  /* the target of the goto could be in an included context!! Fancy that!! */
1863  /* look for includes in the current context */
1864  for (p3=curr_cont->u2.statements; p3; p3=p3->next) {
1865  if (p3->type == PV_INCLUDES) {
1866  struct pval *p4;
1867  for (p4=p3->u1.list; p4; p4=p4->next) {
1868  /* for each context pointed to, find it, then find a context/label that matches the
1869  target here! */
1870  char *incl_context = p4->u1.str;
1871  /* find a matching context name */
1872  struct pval *that_context = find_context(incl_context);
1873  if (that_context) {
1874  struct pval *x3;
1875  x3 = find_first_label_in_current_context(label, that_context);
1876  if (x3) {
1877  return x3;
1878  }
1879  }
1880  }
1881  }
1882  }
1883  return 0;
1884 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
char * str
Definition: pval.h:59
Definition: pval.h:48
static int count_labels
Definition: pval.c:82
pvaltype type
Definition: pval.h:50
struct pval * find_context(char *name)
Definition: pval.c:1960
static struct pval * find_first_label_in_current_context(char *label, pval *curr_cont)
Definition: pval.c:1846
struct pval * next
Definition: pval.h:93
static const char * match_exten
Definition: pval.c:79
static int return_on_context_match
Definition: pval.c:84
struct pval * match_pval(pval *item)
Definition: pval.c:1818
static const char * match_context
Definition: pval.c:78
static const char * match_label
Definition: pval.c:80
struct pval * find_label_in_current_context ( char *  exten,
char *  label,
pval curr_cont 
)
static

Definition at line 1886 of file pval.c.

References exten, 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().

1887 {
1888  /* printf(" --- Got args %s, %s\n", exten, label); */
1889  struct pval *ret;
1890  struct pval *p3;
1891 
1892  count_labels = 0;
1894  match_context = "*";
1895  match_exten = exten;
1896  match_label = label;
1897  ret = match_pval(curr_cont->u2.statements);
1898  if (ret)
1899  return ret;
1900 
1901  /* the target of the goto could be in an included context!! Fancy that!! */
1902  /* look for includes in the current context */
1903  for (p3=curr_cont->u2.statements; p3; p3=p3->next) {
1904  if (p3->type == PV_INCLUDES) {
1905  struct pval *p4;
1906  for (p4=p3->u1.list; p4; p4=p4->next) {
1907  /* for each context pointed to, find it, then find a context/label that matches the
1908  target here! */
1909  char *incl_context = p4->u1.str;
1910  /* find a matching context name */
1911  struct pval *that_context = find_context(incl_context);
1912  if (that_context) {
1913  struct pval *x3;
1914  x3 = find_label_in_current_context(exten, label, that_context);
1915  if (x3) {
1916  return x3;
1917  }
1918  }
1919  }
1920  }
1921  }
1922  return 0;
1923 }
union pval::@198 u1
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
struct pval * list
Definition: pval.h:60
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
char * str
Definition: pval.h:59
Definition: pval.h:48
static struct pval * find_label_in_current_context(char *exten, char *label, pval *curr_cont)
Definition: pval.c:1886
static int count_labels
Definition: pval.c:82
pvaltype type
Definition: pval.h:50
struct pval * find_context(char *name)
Definition: pval.c:1960
struct pval * next
Definition: pval.h:93
static const char * match_exten
Definition: pval.c:79
static int return_on_context_match
Definition: pval.c:84
struct pval * match_pval(pval *item)
Definition: pval.c:1818
static const char * match_context
Definition: pval.c:78
static const char * match_label
Definition: pval.c:80
static struct pval * find_label_in_current_db ( const char *  context,
const char *  exten,
const char *  label 
)
static

Definition at line 1936 of file pval.c.

References context, exten, and match_pval().

Referenced by check_goto(), and get_goto_target().

1937 {
1938  /* printf(" --- Got args %s, %s, %s\n", context, exten, label); */
1939  count_labels = 0;
1941 
1943  match_exten = exten;
1944  match_label = label;
1945 
1946  return match_pval(current_db);
1947 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static int count_labels
Definition: pval.c:82
static const char * match_exten
Definition: pval.c:79
static int return_on_context_match
Definition: pval.c:84
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
static pval * current_db
Definition: pval.c:74
struct pval * match_pval(pval *item)
Definition: pval.c:1818
static const char * match_context
Definition: pval.c:78
static const char * match_label
Definition: pval.c:80
static struct pval * find_label_in_current_extension ( const char *  label,
pval curr_ext 
)
static

Definition at line 1925 of file pval.c.

References match_pval().

Referenced by check_goto(), and get_goto_target().

1926 {
1927  /* printf(" --- Got args %s\n", label); */
1928  count_labels = 0;
1930  match_context = "*";
1931  match_exten = "*";
1932  match_label = label;
1933  return match_pval(curr_ext);
1934 }
static int count_labels
Definition: pval.c:82
static const char * match_exten
Definition: pval.c:79
static int return_on_context_match
Definition: pval.c:84
struct pval * match_pval(pval *item)
Definition: pval.c:1818
static const char * match_context
Definition: pval.c:78
static const char * match_label
Definition: pval.c:80
struct pval* find_macro ( char *  name)

Definition at line 1950 of file pval.c.

References match_pval(), and name.

Referenced by check_pval_item().

1951 {
1953  count_labels = 0;
1954  match_context = name;
1955  match_exten = "*"; /* don't really need to set these, shouldn't be reached */
1956  match_label = "*";
1957  return match_pval(current_db);
1958 }
static int count_labels
Definition: pval.c:82
static const char name[]
static const char * match_exten
Definition: pval.c:79
static int return_on_context_match
Definition: pval.c:84
static pval * current_db
Definition: pval.c:74
struct pval * match_pval(pval *item)
Definition: pval.c:1818
static const char * match_context
Definition: pval.c:78
static const char * match_label
Definition: pval.c:80
static void find_pval_goto_item ( pval item,
int  lev 
)
static

Definition at line 1386 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().

1387 {
1388  struct pval *p4;
1389 
1390  if (lev>100) {
1391  ast_log(LOG_ERROR,"find_pval_goto in infinite loop! item_type: %u\n\n", item->type);
1392  return;
1393  }
1394 
1395  switch ( item->type ) {
1396  case PV_MACRO:
1397  /* fields: item->u1.str == name of macro
1398  item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
1399  item->u2.arglist->u1.str == argument
1400  item->u2.arglist->next == next arg
1401 
1402  item->u3.macro_statements == pval list of statements in macro body.
1403  */
1404 
1405  /* printf("Descending into macro %s at line %d\n", item->u1.str, item->startline); */
1406  find_pval_gotos(item->u3.macro_statements,lev+1); /* if we're just searching for a context, don't bother descending into them */
1407 
1408  break;
1409 
1410  case PV_CONTEXT:
1411  /* fields: item->u1.str == name of context
1412  item->u2.statements == pval list of statements in context body
1413  item->u3.abstract == int 1 if an abstract keyword were present
1414  */
1415  break;
1416 
1417  case PV_CASE:
1418  /* fields: item->u1.str == value of case
1419  item->u2.statements == pval list of statements under the case
1420  */
1421  /* printf("Descending into Case of %s\n", item->u1.str); */
1422  find_pval_gotos(item->u2.statements,lev+1);
1423  break;
1424 
1425  case PV_PATTERN:
1426  /* fields: item->u1.str == value of case
1427  item->u2.statements == pval list of statements under the case
1428  */
1429  /* printf("Descending into Pattern of %s\n", item->u1.str); */
1430  find_pval_gotos(item->u2.statements,lev+1);
1431  break;
1432 
1433  case PV_DEFAULT:
1434  /* fields:
1435  item->u2.statements == pval list of statements under the case
1436  */
1437  /* printf("Descending into default\n"); */
1438  find_pval_gotos(item->u2.statements,lev+1);
1439  break;
1440 
1441  case PV_CATCH:
1442  /* fields: item->u1.str == name of extension to catch
1443  item->u2.statements == pval list of statements in context body
1444  */
1445  /* printf("Descending into catch of %s\n", item->u1.str); */
1446  find_pval_gotos(item->u2.statements,lev+1);
1447  break;
1448 
1449  case PV_STATEMENTBLOCK:
1450  /* fields: item->u1.list == pval list of statements in block, one per entry in the list
1451  */
1452  /* printf("Descending into statement block\n"); */
1453  find_pval_gotos(item->u1.list,lev+1);
1454  break;
1455 
1456  case PV_GOTO:
1457  /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
1458  item->u1.list->u1.str == where the data on a PV_WORD will always be.
1459  */
1460  check_goto(item); /* THE WHOLE FUNCTION OF THIS ENTIRE ROUTINE!!!! */
1461  break;
1462 
1463  case PV_INCLUDES:
1464  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
1465  */
1466  for (p4=item->u1.list; p4; p4=p4->next) {
1467  /* for each context pointed to, find it, then find a context/label that matches the
1468  target here! */
1469  char *incl_context = p4->u1.str;
1470  /* find a matching context name */
1471  struct pval *that_context = find_context(incl_context);
1472  if (that_context && that_context->u2.statements) {
1473  /* 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); */
1474  find_pval_gotos(that_context->u2.statements,lev+1); /* keep working up the includes */
1475  }
1476  }
1477  break;
1478 
1479  case PV_FOR:
1480  /* fields: item->u1.for_init == a string containing the initalizer
1481  item->u2.for_test == a string containing the loop test
1482  item->u3.for_inc == a string containing the loop increment
1483 
1484  item->u4.for_statements == a pval list of statements in the for ()
1485  */
1486  /* printf("Descending into for at line %d\n", item->startline); */
1487  find_pval_gotos(item->u4.for_statements,lev+1);
1488  break;
1489 
1490  case PV_WHILE:
1491  /* fields: item->u1.str == the while conditional, as supplied by user
1492 
1493  item->u2.statements == a pval list of statements in the while ()
1494  */
1495  /* printf("Descending into while at line %d\n", item->startline); */
1496  find_pval_gotos(item->u2.statements,lev+1);
1497  break;
1498 
1499  case PV_RANDOM:
1500  /* fields: item->u1.str == the random number expression, as supplied by user
1501 
1502  item->u2.statements == a pval list of statements in the if ()
1503  item->u3.else_statements == a pval list of statements in the else
1504  (could be zero)
1505  fall thru to PV_IF */
1506 
1507  case PV_IFTIME:
1508  /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list
1509 
1510  item->u2.statements == a pval list of statements in the if ()
1511  item->u3.else_statements == a pval list of statements in the else
1512  (could be zero)
1513  fall thru to PV_IF*/
1514  case PV_IF:
1515  /* fields: item->u1.str == the if conditional, as supplied by user
1516 
1517  item->u2.statements == a pval list of statements in the if ()
1518  item->u3.else_statements == a pval list of statements in the else
1519  (could be zero)
1520  */
1521  /* printf("Descending into random/iftime/if at line %d\n", item->startline); */
1522  find_pval_gotos(item->u2.statements,lev+1);
1523 
1524  if (item->u3.else_statements) {
1525  /* printf("Descending into random/iftime/if's ELSE at line %d\n", item->startline); */
1526  find_pval_gotos(item->u3.else_statements,lev+1);
1527  }
1528  break;
1529 
1530  case PV_SWITCH:
1531  /* fields: item->u1.str == the switch expression
1532 
1533  item->u2.statements == a pval list of statements in the switch,
1534  (will be case statements, most likely!)
1535  */
1536  /* printf("Descending into switch at line %d\n", item->startline); */
1537  find_pval_gotos(item->u3.else_statements,lev+1);
1538  break;
1539 
1540  case PV_EXTENSION:
1541  /* fields: item->u1.str == the extension name, label, whatever it's called
1542 
1543  item->u2.statements == a pval list of statements in the extension
1544  item->u3.hints == a char * hint argument
1545  item->u4.regexten == an int boolean. non-zero says that regexten was specified
1546  */
1547 
1548  /* printf("Descending into extension %s at line %d\n", item->u1.str, item->startline); */
1549  find_pval_gotos(item->u2.statements,lev+1);
1550  break;
1551 
1552  default:
1553  break;
1554  }
1555 }
union pval::@198 u1
static void find_pval_gotos(pval *item, int lev)
Definition: pval.c:1557
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
struct pval * statements
Definition: pval.h:61
Definition: pval.h:22
union pval::@200 u3
union pval::@199 u2
Definition: pval.h:13
char * str
Definition: pval.h:59
Definition: pval.h:48
#define LOG_ERROR
Definition: logger.h:155
struct pval * else_statements
Definition: pval.h:78
static void check_goto(pval *item)
Definition: pval.c:1232
Definition: pval.h:24
union pval::@201 u4
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: pval.h:9
Definition: pval.h:31
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
struct pval * find_context(char *name)
Definition: pval.c:1960
Definition: pval.h:30
struct pval * next
Definition: pval.h:93
struct pval * for_statements
Definition: pval.h:89
Definition: pval.h:16
struct pval * macro_statements
Definition: pval.h:79
static void find_pval_gotos ( pval item,
int  lev 
)
static

Definition at line 1557 of file pval.c.

References find_pval_goto_item(), and pval::next.

Referenced by check_pval_item(), and find_pval_goto_item().

1558 {
1559  pval *i;
1560 
1561  for (i=item; i; i=i->next) {
1562  /* printf("About to call pval_goto_item, itemcount=%d, itemtype=%d\n", item_count, i->type); */
1563  find_pval_goto_item(i, lev);
1564  }
1565 }
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
static void find_pval_goto_item(pval *item, int lev)
Definition: pval.c:1386
int find_switch_item ( pval item)

Definition at line 3097 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().

3098 {
3099  switch ( item->type ) {
3100  case PV_LOCALVARDEC:
3101  /* fields: item->u1.str == string associated with this (word). */
3102  break;
3103 
3104  case PV_WORD:
3105  /* fields: item->u1.str == string associated with this (word). */
3106  break;
3107 
3108  case PV_MACRO:
3109  /* fields: item->u1.str == name of macro
3110  item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
3111  item->u2.arglist->u1.str == argument
3112  item->u2.arglist->next == next arg
3113 
3114  item->u3.macro_statements == pval list of statements in macro body.
3115  */
3116  /* had better not see this */
3117  if (contains_switch(item->u3.macro_statements))
3118  return 1;
3119  break;
3120 
3121  case PV_CONTEXT:
3122  /* fields: item->u1.str == name of context
3123  item->u2.statements == pval list of statements in context body
3124  item->u3.abstract == int 1 if an abstract keyword were present
3125  */
3126  /* had better not see this */
3127  if (contains_switch(item->u2.statements))
3128  return 1;
3129  break;
3130 
3131  case PV_MACRO_CALL:
3132  /* fields: item->u1.str == name of macro to call
3133  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
3134  item->u2.arglist->u1.str == argument
3135  item->u2.arglist->next == next arg
3136  */
3137  break;
3138 
3139  case PV_APPLICATION_CALL:
3140  /* fields: item->u1.str == name of application to call
3141  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
3142  item->u2.arglist->u1.str == argument
3143  item->u2.arglist->next == next arg
3144  */
3145  break;
3146 
3147  case PV_CASE:
3148  /* fields: item->u1.str == value of case
3149  item->u2.statements == pval list of statements under the case
3150  */
3151  /* had better not see this */
3152  if (contains_switch(item->u2.statements))
3153  return 1;
3154  break;
3155 
3156  case PV_PATTERN:
3157  /* fields: item->u1.str == value of case
3158  item->u2.statements == pval list of statements under the case
3159  */
3160  /* had better not see this */
3161  if (contains_switch(item->u2.statements))
3162  return 1;
3163  break;
3164 
3165  case PV_DEFAULT:
3166  /* fields:
3167  item->u2.statements == pval list of statements under the case
3168  */
3169  /* had better not see this */
3170  if (contains_switch(item->u2.statements))
3171  return 1;
3172  break;
3173 
3174  case PV_CATCH:
3175  /* fields: item->u1.str == name of extension to catch
3176  item->u2.statements == pval list of statements in context body
3177  */
3178  /* had better not see this */
3179  if (contains_switch(item->u2.statements))
3180  return 1;
3181  break;
3182 
3183  case PV_SWITCHES:
3184  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
3185  */
3186  break;
3187 
3188  case PV_ESWITCHES:
3189  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
3190  */
3191  break;
3192 
3193  case PV_INCLUDES:
3194  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
3195  item->u2.arglist == pval list of 4 PV_WORD elements for time values
3196  */
3197  break;
3198 
3199  case PV_STATEMENTBLOCK:
3200  /* fields: item->u1.list == pval list of statements in block, one per entry in the list
3201  */
3202  if (contains_switch(item->u1.list) )
3203  return 1;
3204  break;
3205 
3206  case PV_VARDEC:
3207  /* fields: item->u1.str == variable name
3208  item->u2.val == variable value to assign
3209  */
3210  break;
3211 
3212  case PV_GOTO:
3213  /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
3214  item->u1.list->u1.str == where the data on a PV_WORD will always be.
3215  */
3216  break;
3217 
3218  case PV_LABEL:
3219  /* fields: item->u1.str == label name
3220  */
3221  break;
3222 
3223  case PV_FOR:
3224  /* fields: item->u1.for_init == a string containing the initalizer
3225  item->u2.for_test == a string containing the loop test
3226  item->u3.for_inc == a string containing the loop increment
3227 
3228  item->u4.for_statements == a pval list of statements in the for ()
3229  */
3230  if (contains_switch(item->u4.for_statements))
3231  return 1;
3232  break;
3233 
3234  case PV_WHILE:
3235  /* fields: item->u1.str == the while conditional, as supplied by user
3236 
3237  item->u2.statements == a pval list of statements in the while ()
3238  */
3239  if (contains_switch(item->u2.statements))
3240  return 1;
3241  break;
3242 
3243  case PV_BREAK:
3244  /* fields: none
3245  */
3246  break;
3247 
3248  case PV_RETURN:
3249  /* fields: none
3250  */
3251  break;
3252 
3253  case PV_CONTINUE:
3254  /* fields: none
3255  */
3256  break;
3257 
3258  case PV_IFTIME:
3259  /* fields: item->u1.list == there are 4 linked PV_WORDs here.
3260 
3261  item->u2.statements == a pval list of statements in the if ()
3262  item->u3.else_statements == a pval list of statements in the else
3263  (could be zero)
3264  */
3265  if (contains_switch(item->u2.statements))
3266  return 1;
3267  if ( item->u3.else_statements ) {
3268  if (contains_switch(item->u3.else_statements))
3269  return 1;
3270  }
3271  break;
3272 
3273  case PV_RANDOM:
3274  /* fields: item->u1.str == the random number expression, as supplied by user
3275 
3276  item->u2.statements == a pval list of statements in the if ()
3277  item->u3.else_statements == a pval list of statements in the else
3278  (could be zero)
3279  */
3280  if (contains_switch(item->u2.statements))
3281  return 1;
3282  if ( item->u3.else_statements ) {
3283  if (contains_switch(item->u3.else_statements))
3284  return 1;
3285  }
3286  break;
3287 
3288  case PV_IF:
3289  /* fields: item->u1.str == the if conditional, as supplied by user
3290 
3291  item->u2.statements == a pval list of statements in the if ()
3292  item->u3.else_statements == a pval list of statements in the else
3293  (could be zero)
3294  */
3295  if (contains_switch(item->u2.statements))
3296  return 1;
3297  if ( item->u3.else_statements ) {
3298  if (contains_switch(item->u3.else_statements))
3299  return 1;
3300  }
3301  break;
3302 
3303  case PV_SWITCH:
3304  /* fields: item->u1.str == the switch expression
3305 
3306  item->u2.statements == a pval list of statements in the switch,
3307  (will be case statements, most likely!)
3308  */
3309  return 1; /* JACKPOT */
3310  break;
3311 
3312  case PV_EXTENSION:
3313  /* fields: item->u1.str == the extension name, label, whatever it's called
3314 
3315  item->u2.statements == a pval list of statements in the extension
3316  item->u3.hints == a char * hint argument
3317  item->u4.regexten == an int boolean. non-zero says that regexten was specified
3318  */
3319  if (contains_switch(item->u2.statements))
3320  return 1;
3321  break;
3322 
3323  case PV_IGNOREPAT:
3324  /* fields: item->u1.str == the ignorepat data
3325  */
3326  break;
3327 
3328  case PV_GLOBALS:
3329  /* fields: item->u1.statements == pval list of statements, usually vardecs
3330  */
3331  break;
3332  }
3333  return 0;
3334 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
struct pval * statements
Definition: pval.h:61
Definition: pval.h:22
Definition: pval.h:8
union pval::@200 u3
union pval::@199 u2
Definition: pval.h:13
Definition: pval.h:21
struct pval * else_statements
Definition: pval.h:78
Definition: pval.h:24
union pval::@201 u4
Definition: pval.h:9
Definition: pval.h:31
Definition: pval.h:25
int contains_switch(pval *item)
Definition: pval.c:3336
pvaltype type
Definition: pval.h:50
Definition: pval.h:30
Definition: pval.h:23
Definition: pval.h:27
struct pval * for_statements
Definition: pval.h:89
Definition: pval.h:26
Definition: pval.h:16
struct pval * macro_statements
Definition: pval.h:79
static void fix_gotos_in_extensions ( struct ael_extension exten)
static

Definition at line 4393 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().

4394 {
4395  struct ael_extension *e;
4396  for(e=exten;e;e=e->next_exten) {
4397 
4398  struct ael_priority *p;
4399  for(p=e->plist;p;p=p->next) {
4400 
4401  if( p->origin && p->origin->type == PV_GOTO && p->origin->u3.goto_target_in_case ) {
4402 
4403  /* fix the extension of the goto target to the actual extension in the post-compiled dialplan */
4404 
4405  pval *target = p->origin->u2.goto_target;
4406  struct ael_extension *z = target->u3.compiled_label;
4407  pval *pv2 = p->origin;
4408  char buf1[500];
4409  char *apparg_save = p->appargs;
4410 
4411  p->appargs = 0;
4412  if (!pv2->u1.list->next) /* just one -- it won't hurt to repeat the extension */ {
4413  snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->u1.str);
4414  p->appargs = strdup(buf1);
4415 
4416  } else if (pv2->u1.list->next && !pv2->u1.list->next->next) /* two */ {
4417  snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->next->u1.str);
4418  p->appargs = strdup(buf1);
4419  } else if (pv2->u1.list->next && pv2->u1.list->next->next) {
4420  snprintf(buf1,sizeof(buf1),"%s,%s,%s", pv2->u1.list->u1.str,
4421  z->name,
4422  pv2->u1.list->next->next->u1.str);
4423  p->appargs = strdup(buf1);
4424  }
4425  else
4426  printf("WHAT? The goto doesn't fall into one of three cases for GOTO????\n");
4427 
4428  if( apparg_save ) {
4429  free(apparg_save);
4430  }
4431  }
4432  }
4433  }
4434 }
union pval::@198 u1
struct pval * origin
Definition: ael_structs.h:95
struct pval * list
Definition: pval.h:60
struct ael_priority * plist
Definition: ael_structs.h:115
Definition: pval.h:22
char * appargs
Definition: ael_structs.h:93
struct ael_extension * next_exten
Definition: ael_structs.h:117
union pval::@200 u3
union pval::@199 u2
struct pval * goto_target
Definition: pval.h:72
char * str
Definition: pval.h:59
Definition: pval.h:48
struct ael_extension * compiled_label
Definition: pval.h:83
int goto_target_in_case
Definition: pval.h:82
#define free(a)
Definition: astmm.h:94
static struct ast_threadstorage buf1
struct ael_priority * next
Definition: ael_structs.h:100
pvaltype type
Definition: pval.h:50
struct pval * next
Definition: pval.h:93
#define strdup(a)
Definition: astmm.h:106
static void gen_match_to_pattern ( char *  pattern,
char *  result 
)
static

Definition at line 3068 of file pval.c.

Referenced by gen_prios().

3069 {
3070  /* the result will be a string that will be matched by pattern */
3071  char *p=pattern, *t=result;
3072  while (*p) {
3073  if (*p == 'x' || *p == 'n' || *p == 'z' || *p == 'X' || *p == 'N' || *p == 'Z')
3074  *t++ = '9';
3075  else if (*p == '[') {
3076  char *z = p+1;
3077  while (*z != ']')
3078  z++;
3079  if (*(z+1)== ']')
3080  z++;
3081  *t++=*(p+1); /* use the first char in the set */
3082  p = z;
3083  } else {
3084  *t++ = *p;
3085  }
3086  p++;
3087  }
3088  *t++ = 0; /* cap it off */
3089 }
static int gen_prios ( struct ael_extension exten,
char *  label,
pval statement,
struct ael_extension mother_exten,
struct ast_context this_context 
)
static

Definition at line 3348 of file pval.c.

References AEL_APPCALL, AEL_CONTROL1, AEL_FOR_CONTROL, AEL_IF_CONTROL, AEL_IFTIME_CONTROL, AEL_LABEL, AEL_RETURN, ael_priority::app, ael_priority::appargs, pval::arglist, ast_compat_app_set, buf1, buf2, BUF_SIZE, ael_extension::checked_switch, pval::compiled_label, contains_switch(), ael_extension::context, control_statement_count, pval::else_statements, ael_priority::exten, exten, first, pval::for_inc, pval::for_init, pval::for_statements, pval::for_test, free, gen_match_to_pattern(), get_goto_target(), ael_priority::goto_false, pval::goto_target, pval::goto_target_in_case, ael_priority::goto_true, ael_extension::has_switch, ael_extension::is_switch, label_inside_case(), linkexten(), linkprio(), pval::list, ael_extension::loop_break, ael_extension::loop_continue, malloc, ael_extension::name, new_exten(), new_prio(), pval::next, ael_priority::origin, PV_APPLICATION_CALL, PV_BREAK, PV_CASE, PV_CATCH, PV_CONTINUE, PV_DEFAULT, PV_FOR, PV_GOTO, PV_IF, PV_IFTIME, PV_LABEL, PV_LOCALVARDEC, PV_MACRO_CALL, PV_PATTERN, PV_RANDOM, PV_RETURN, PV_STATEMENTBLOCK, PV_SWITCH, PV_VARDEC, PV_WHILE, remove_spaces_before_equals(), ael_extension::return_needed, pval::statements, pval::str, strdup, pval::type, ael_priority::type, pval::u1, pval::u2, pval::u3, pval::u4, and pval::val.

Referenced by ast_compile_ael2().

3349 {
3350  pval *p,*p2,*p3;
3351  struct ael_priority *pr;
3352  struct ael_priority *for_init, *for_test, *for_inc, *for_loop, *for_end;
3353  struct ael_priority *while_test, *while_loop, *while_end;
3354  struct ael_priority *switch_set, *switch_test, *switch_end, *fall_thru, *switch_empty;
3355  struct ael_priority *if_test, *if_end, *if_skip, *if_false;
3356 #ifdef OLD_RAND_ACTION
3357  struct ael_priority *rand_test, *rand_end, *rand_skip;
3358 #endif
3359  char *buf1;
3360  char *buf2;
3361  char *new_label;
3362  char *strp, *strp2;
3363  int default_exists;
3364  int local_control_statement_count;
3365  int first;
3366  struct ael_priority *loop_break_save;
3367  struct ael_priority *loop_continue_save;
3368  struct ael_extension *switch_case,*switch_null;
3369 
3370  if (!(buf1 = malloc(BUF_SIZE))) {
3371  return -1;
3372  }
3373  if (!(buf2 = malloc(BUF_SIZE))) {
3374  return -1;
3375  }
3376  if (!(new_label = malloc(BUF_SIZE))) {
3377  return -1;
3378  }
3379 
3380  if ((mother_exten && !mother_exten->checked_switch) || (exten && !exten->checked_switch)) {
3381  if (contains_switch(statement)) { /* only run contains_switch if you haven't checked before */
3382  if (mother_exten) {
3383  if (!mother_exten->has_switch) {
3384  for (first = 1; first >= 0; first--) {
3385  switch_set = new_prio();
3386  switch_set->type = AEL_APPCALL;
3387  if (!ast_compat_app_set) {
3388  switch_set->app = strdup("MSet");
3389  } else {
3390  switch_set->app = strdup("Set");
3391  }
3392  /* Are we likely inside a gosub subroutine? */
3393  if (!strcmp(mother_exten->name, "~~s~~") && first) {
3394  /* If we're not actually within a gosub, this will fail, but the
3395  * second time through, it will get set. If we are within gosub,
3396  * the second time through is redundant, but acceptable. */
3397  switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}");
3398  } else {
3399  switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
3400  first = 0;
3401  }
3402  linkprio(exten, switch_set, mother_exten);
3403  mother_exten->has_switch = 1;
3404  mother_exten->checked_switch = 1;
3405  if (exten) {
3406  exten->has_switch = 1;
3407  exten->checked_switch = 1;
3408  }
3409  }
3410  }
3411  } else if (exten) {
3412  if (!exten->has_switch) {
3413  for (first = 1; first >= 0; first--) {
3414  switch_set = new_prio();
3415  switch_set->type = AEL_APPCALL;
3416  if (!ast_compat_app_set) {
3417  switch_set->app = strdup("MSet");
3418  } else {
3419  switch_set->app = strdup("Set");
3420  }
3421  /* Are we likely inside a gosub subroutine? */
3422  if (!strcmp(exten->name, "~~s~~")) {
3423  /* If we're not actually within a gosub, this will fail, but the
3424  * second time through, it will get set. If we are within gosub,
3425  * the second time through is redundant, but acceptable. */
3426  switch_set->appargs = strdup("LOCAL(~~EXTEN~~)=${EXTEN}");
3427  } else {
3428  switch_set->appargs = strdup("~~EXTEN~~=${EXTEN}");
3429  first = 0;
3430  }
3431  linkprio(exten, switch_set, mother_exten);
3432  exten->has_switch = 1;
3433  exten->checked_switch = 1;
3434  if (mother_exten) {
3435  mother_exten->has_switch = 1;
3436  mother_exten->checked_switch = 1;
3437  }
3438  }
3439  }
3440  }
3441  } else {
3442  if (mother_exten) {
3443  mother_exten->checked_switch = 1;
3444  }
3445  if (exten) {
3446  exten->checked_switch = 1;
3447  }
3448  }
3449  }
3450  for (p=statement; p; p=p->next) {
3451  switch (p->type) {
3452  case PV_VARDEC:
3453  pr = new_prio();
3454  pr->type = AEL_APPCALL;
3455  snprintf(buf1, BUF_SIZE, "%s=$[%s]", p->u1.str, p->u2.val);
3456  if (!ast_compat_app_set) {
3457  pr->app = strdup("MSet");
3458  } else {
3459  pr->app = strdup("Set");
3460  }
3462  pr->appargs = strdup(buf1);
3463  pr->origin = p;
3464  linkprio(exten, pr, mother_exten);
3465  break;
3466 
3467  case PV_LOCALVARDEC:
3468  pr = new_prio();
3469  pr->type = AEL_APPCALL;
3470  snprintf(buf1, BUF_SIZE, "LOCAL(%s)=$[%s]", p->u1.str, p->u2.val);
3471  if (!ast_compat_app_set) {
3472  pr->app = strdup("MSet");
3473  } else {
3474  pr->app = strdup("Set");
3475  }
3477  pr->appargs = strdup(buf1);
3478  pr->origin = p;
3479  linkprio(exten, pr, mother_exten);
3480  break;
3481 
3482  case PV_GOTO:
3483  pr = new_prio();
3484  pr->type = AEL_APPCALL;
3485  p->u2.goto_target = get_goto_target(p);
3486  if( p->u2.goto_target ) {
3488  }
3489 
3490  if (!p->u1.list->next) /* just one */ {
3491  pr->app = strdup("Goto");
3492  if (!mother_exten)
3493  pr->appargs = strdup(p->u1.list->u1.str);
3494  else { /* for the case of simple within-extension gotos in case/pattern/default statement blocks: */
3495  snprintf(buf1, BUF_SIZE, "%s,%s", mother_exten->name, p->u1.list->u1.str);
3496  pr->appargs = strdup(buf1);
3497  }
3498 
3499  } else if (p->u1.list->next && !p->u1.list->next->next) /* two */ {
3500  snprintf(buf1, BUF_SIZE, "%s,%s", p->u1.list->u1.str, p->u1.list->next->u1.str);
3501  pr->app = strdup("Goto");
3502  pr->appargs = strdup(buf1);
3503  } else if (p->u1.list->next && p->u1.list->next->next) {
3504  snprintf(buf1, BUF_SIZE, "%s,%s,%s", p->u1.list->u1.str,
3505  p->u1.list->next->u1.str,
3506  p->u1.list->next->next->u1.str);
3507  pr->app = strdup("Goto");
3508  pr->appargs = strdup(buf1);
3509  }
3510  pr->origin = p;
3511  linkprio(exten, pr, mother_exten);
3512  break;
3513 
3514  case PV_LABEL:
3515  pr = new_prio();
3516  pr->type = AEL_LABEL;
3517  pr->origin = p;
3518  p->u3.compiled_label = exten;
3519  linkprio(exten, pr, mother_exten);
3520  break;
3521 
3522  case PV_FOR:
3524  loop_break_save = exten->loop_break; /* save them, then restore before leaving */
3525  loop_continue_save = exten->loop_continue;
3526  snprintf(new_label, BUF_SIZE, "for_%s_%d", label, control_statement_count);
3527  for_init = new_prio();
3528  for_inc = new_prio();
3529  for_test = new_prio();
3530  for_loop = new_prio();
3531  for_end = new_prio();
3532  for_init->type = AEL_APPCALL;
3533  for_inc->type = AEL_APPCALL;
3534  for_test->type = AEL_FOR_CONTROL;
3535  for_test->goto_false = for_end;
3536  for_loop->type = AEL_CONTROL1; /* simple goto */
3537  for_end->type = AEL_APPCALL;
3538  if (!ast_compat_app_set) {
3539  for_init->app = strdup("MSet");
3540  } else {
3541  for_init->app = strdup("Set");
3542  }
3543 
3544  strcpy(buf2,p->u1.for_init);
3546  strp = strchr(buf2, '=');
3547  if (strp) {
3548  strp2 = strchr(p->u1.for_init, '=');
3549  *(strp+1) = 0;
3550  strcat(buf2,"$[");
3551  strncat(buf2,strp2+1, BUF_SIZE-strlen(strp2+1)-2);
3552  strcat(buf2,"]");
3553  for_init->appargs = strdup(buf2);
3554  } else {
3555  strp2 = p->u1.for_init;
3556  while (*strp2 && isspace(*strp2))
3557  strp2++;
3558  if (*strp2 == '&') { /* itsa macro call */
3559  char *strp3 = strp2+1;
3560  while (*strp3 && isspace(*strp3))
3561  strp3++;
3562  strcpy(buf2, strp3);
3563  strp3 = strchr(buf2,'(');
3564  if (strp3) {
3565  *strp3 = '|';
3566  }
3567  while ((strp3=strchr(buf2,','))) {
3568  *strp3 = '|';
3569  }
3570  strp3 = strrchr(buf2, ')');
3571  if (strp3)
3572  *strp3 = 0; /* remove the closing paren */
3573 
3574  for_init->appargs = strdup(buf2);
3575  free(for_init->app);
3576  for_init->app = strdup("Macro");
3577  } else { /* must be a regular app call */
3578  char *strp3;
3579  strcpy(buf2, strp2);
3580  strp3 = strchr(buf2,'(');
3581  if (strp3) {
3582  *strp3 = 0;
3583  free(for_init->app);
3584  for_init->app = strdup(buf2);
3585  for_init->appargs = strdup(strp3+1);
3586  strp3 = strrchr(for_init->appargs, ')');
3587  if (strp3)
3588  *strp3 = 0; /* remove the closing paren */
3589  }
3590  }
3591  }
3592 
3593  strcpy(buf2,p->u3.for_inc);
3595  strp = strchr(buf2, '=');
3596  if (strp) { /* there's an = in this part; that means an assignment. set it up */
3597  strp2 = strchr(p->u3.for_inc, '=');
3598  *(strp+1) = 0;
3599  strcat(buf2,"$[");
3600  strncat(buf2,strp2+1, BUF_SIZE-strlen(strp2+1)-2);
3601  strcat(buf2,"]");
3602  for_inc->appargs = strdup(buf2);
3603  if (!ast_compat_app_set) {
3604  for_inc->app = strdup("MSet");
3605  } else {
3606  for_inc->app = strdup("Set");
3607  }
3608  } else {
3609  strp2 = p->u3.for_inc;
3610  while (*strp2 && isspace(*strp2))
3611  strp2++;
3612  if (*strp2 == '&') { /* itsa macro call */
3613  char *strp3 = strp2+1;
3614  while (*strp3 && isspace(*strp3))
3615  strp3++;
3616  strcpy(buf2, strp3);
3617  strp3 = strchr(buf2,'(');
3618  if (strp3) {
3619  *strp3 = ',';
3620  }
3621  strp3 = strrchr(buf2, ')');
3622  if (strp3)
3623  *strp3 = 0; /* remove the closing paren */
3624 
3625  for_inc->appargs = strdup(buf2);
3626 
3627  for_inc->app = strdup("Macro");
3628  } else { /* must be a regular app call */
3629  char *strp3;
3630  strcpy(buf2, strp2);
3631  strp3 = strchr(buf2,'(');
3632  if (strp3) {
3633  *strp3 = 0;
3634  for_inc->app = strdup(buf2);
3635  for_inc->appargs = strdup(strp3+1);
3636  strp3 = strrchr(for_inc->appargs, ')');
3637  if (strp3)
3638  *strp3 = 0; /* remove the closing paren */
3639  }
3640  }
3641  }
3642  snprintf(buf1, BUF_SIZE, "$[%s]",p->u2.for_test);
3643  for_test->app = 0;
3644  for_test->appargs = strdup(buf1);
3645  for_loop->goto_true = for_test;
3646  snprintf(buf1, BUF_SIZE, "Finish for_%s_%d", label, control_statement_count);
3647  for_end->app = strdup("NoOp");
3648  for_end->appargs = strdup(buf1);
3649  /* link & load! */
3650  linkprio(exten, for_init, mother_exten);
3651  linkprio(exten, for_test, mother_exten);
3652 
3653  /* now, put the body of the for loop here */
3654  exten->loop_break = for_end;
3655  exten->loop_continue = for_inc;
3656 
3657  if (gen_prios(exten, new_label, p->u4.for_statements, mother_exten, this_context)) { /* this will link in all the statements here */
3658  return -1;
3659  }
3660 
3661  linkprio(exten, for_inc, mother_exten);
3662  linkprio(exten, for_loop, mother_exten);
3663  linkprio(exten, for_end, mother_exten);
3664 
3665 
3666  exten->loop_break = loop_break_save;
3667  exten->loop_continue = loop_continue_save;
3668  for_loop->origin = p;
3669  break;
3670 
3671  case PV_WHILE:
3673  loop_break_save = exten->loop_break; /* save them, then restore before leaving */
3674  loop_continue_save = exten->loop_continue;
3675  snprintf(new_label, BUF_SIZE, "while_%s_%d", label, control_statement_count);
3676  while_test = new_prio();
3677  while_loop = new_prio();
3678  while_end = new_prio();
3679  while_test->type = AEL_FOR_CONTROL;
3680  while_test->goto_false = while_end;
3681  while_loop->type = AEL_CONTROL1; /* simple goto */
3682  while_end->type = AEL_APPCALL;
3683  snprintf(buf1, BUF_SIZE, "$[%s]",p->u1.str);
3684  while_test->app = 0;
3685  while_test->appargs = strdup(buf1);
3686  while_loop->goto_true = while_test;
3687  snprintf(buf1, BUF_SIZE, "Finish while_%s_%d", label, control_statement_count);
3688  while_end->app = strdup("NoOp");
3689  while_end->appargs = strdup(buf1);
3690 
3691  linkprio(exten, while_test, mother_exten);
3692 
3693  /* now, put the body of the for loop here */
3694  exten->loop_break = while_end;
3695  exten->loop_continue = while_test;
3696 
3697  if (gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context)) { /* this will link in all the while body statements here */
3698  return -1;
3699  }
3700 
3701  linkprio(exten, while_loop, mother_exten);
3702  linkprio(exten, while_end, mother_exten);
3703 
3704 
3705  exten->loop_break = loop_break_save;
3706  exten->loop_continue = loop_continue_save;
3707  while_loop->origin = p;
3708  break;
3709 
3710  case PV_SWITCH:
3712  local_control_statement_count = control_statement_count;
3713  loop_break_save = exten->loop_break; /* save them, then restore before leaving */
3714  loop_continue_save = exten->loop_continue;
3715  snprintf(new_label, BUF_SIZE, "sw_%s_%d", label, control_statement_count);
3716  switch_test = new_prio();
3717  switch_end = new_prio();
3718  switch_test->type = AEL_APPCALL;
3719  switch_end->type = AEL_APPCALL;
3720  snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", control_statement_count, p->u1.str);
3721  switch_test->app = strdup("Goto");
3722  switch_test->appargs = strdup(buf1);
3723  snprintf(buf1, BUF_SIZE, "Finish switch_%s_%d", label, control_statement_count);
3724  switch_end->app = strdup("NoOp");
3725  switch_end->appargs = strdup(buf1);
3726  switch_end->origin = p;
3727  switch_end->exten = exten;
3728 
3729  linkprio(exten, switch_test, mother_exten);
3730  linkprio(exten, switch_end, mother_exten);
3731 
3732  exten->loop_break = switch_end;
3733  exten->loop_continue = 0;
3734  default_exists = 0;
3735 
3736  for (p2=p->u2.statements; p2; p2=p2->next) {
3737  /* now, for each case/default put the body of the for loop here */
3738  if (p2->type == PV_CASE) {
3739  /* ok, generate a extension and link it in */
3740  switch_case = new_exten();
3741  if (mother_exten && mother_exten->checked_switch) {
3742  switch_case->has_switch = mother_exten->has_switch;
3743  switch_case->checked_switch = mother_exten->checked_switch;
3744  }
3745  if (exten && exten->checked_switch) {
3746  switch_case->has_switch = exten->has_switch;
3747  switch_case->checked_switch = exten->checked_switch;
3748  }
3749  switch_case->context = this_context;
3750  switch_case->is_switch = 1;
3751  /* the break/continue locations are inherited from parent */
3752  switch_case->loop_break = exten->loop_break;
3753  switch_case->loop_continue = exten->loop_continue;
3754 
3755  linkexten(exten,switch_case);
3756  snprintf(buf1, BUF_SIZE, "sw_%d_%s", local_control_statement_count, p2->u1.str);
3757  switch_case->name = strdup(buf1);
3758  snprintf(new_label, BUF_SIZE, "sw_%s_%s_%d", label, p2->u1.str, local_control_statement_count);
3759 
3760  if (gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context)) { /* this will link in all the case body statements here */
3761  return -1;
3762  }
3763 
3764  /* here is where we write code to "fall thru" to the next case... if there is one... */
3765  for (p3=p2->u2.statements; p3; p3=p3->next) {
3766  if (!p3->next)
3767  break;
3768  }
3769  /* p3 now points the last statement... */
3770  if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN) ) {
3771  /* is there a following CASE/PATTERN/DEFAULT? */
3772  if (p2->next && p2->next->type == PV_CASE) {
3773  fall_thru = new_prio();
3774  fall_thru->type = AEL_APPCALL;
3775  fall_thru->app = strdup("Goto");
3776  snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, p2->next->u1.str);
3777  fall_thru->appargs = strdup(buf1);
3778  linkprio(switch_case, fall_thru, mother_exten);
3779  } else if (p2->next && p2->next->type == PV_PATTERN) {
3780  fall_thru = new_prio();
3781  fall_thru->type = AEL_APPCALL;
3782  fall_thru->app = strdup("Goto");
3783  gen_match_to_pattern(p2->next->u1.str, buf2);
3784  snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, buf2);
3785  fall_thru->appargs = strdup(buf1);
3786  linkprio(switch_case, fall_thru, mother_exten);
3787  } else if (p2->next && p2->next->type == PV_DEFAULT) {
3788  fall_thru = new_prio();
3789  fall_thru->type = AEL_APPCALL;
3790  fall_thru->app = strdup("Goto");
3791  snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count);
3792  fall_thru->appargs = strdup(buf1);
3793  linkprio(switch_case, fall_thru, mother_exten);
3794  } else if (!p2->next) {
3795  fall_thru = new_prio();
3796  fall_thru->type = AEL_CONTROL1;
3797  fall_thru->goto_true = switch_end;
3798  fall_thru->app = strdup("Goto");
3799  linkprio(switch_case, fall_thru, mother_exten);
3800  }
3801  }
3802  if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */
3803  char buf[2000];
3804  struct ael_priority *np2 = new_prio();
3805  np2->type = AEL_APPCALL;
3806  np2->app = strdup("NoOp");
3807  snprintf(buf, BUF_SIZE, "End of Extension %s", switch_case->name);
3808  np2->appargs = strdup(buf);
3809  linkprio(switch_case, np2, mother_exten);
3810  switch_case-> return_target = np2;
3811  }
3812  } else if (p2->type == PV_PATTERN) {
3813  /* ok, generate a extension and link it in */
3814  switch_case = new_exten();
3815  if (mother_exten && mother_exten->checked_switch) {
3816  switch_case->has_switch = mother_exten->has_switch;
3817  switch_case->checked_switch = mother_exten->checked_switch;
3818  }
3819  if (exten && exten->checked_switch) {
3820  switch_case->has_switch = exten->has_switch;
3821  switch_case->checked_switch = exten->checked_switch;
3822  }
3823  switch_case->context = this_context;
3824  switch_case->is_switch = 1;
3825  /* the break/continue locations are inherited from parent */
3826  switch_case->loop_break = exten->loop_break;
3827  switch_case->loop_continue = exten->loop_continue;
3828 
3829  linkexten(exten,switch_case);
3830  snprintf(buf1, BUF_SIZE, "_sw_%d_%s", local_control_statement_count, p2->u1.str);
3831  switch_case->name = strdup(buf1);
3832  snprintf(new_label, BUF_SIZE, "sw_%s_%s_%d", label, p2->u1.str, local_control_statement_count);
3833 
3834  if (gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context)) { /* this will link in all the while body statements here */
3835  return -1;
3836  }
3837  /* here is where we write code to "fall thru" to the next case... if there is one... */
3838  for (p3=p2->u2.statements; p3; p3=p3->next) {
3839  if (!p3->next)
3840  break;
3841  }
3842  /* p3 now points the last statement... */
3843  if (!p3 || ( p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) {
3844  /* is there a following CASE/PATTERN/DEFAULT? */
3845  if (p2->next && p2->next->type == PV_CASE) {
3846  fall_thru = new_prio();
3847  fall_thru->type = AEL_APPCALL;
3848  fall_thru->app = strdup("Goto");
3849  snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, p2->next->u1.str);
3850  fall_thru->appargs = strdup(buf1);
3851  linkprio(switch_case, fall_thru, mother_exten);
3852  } else if (p2->next && p2->next->type == PV_PATTERN) {
3853  fall_thru = new_prio();
3854  fall_thru->type = AEL_APPCALL;
3855  fall_thru->app = strdup("Goto");
3856  gen_match_to_pattern(p2->next->u1.str, buf2);
3857  snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, buf2);
3858  fall_thru->appargs = strdup(buf1);
3859  linkprio(switch_case, fall_thru, mother_exten);
3860  } else if (p2->next && p2->next->type == PV_DEFAULT) {
3861  fall_thru = new_prio();
3862  fall_thru->type = AEL_APPCALL;
3863  fall_thru->app = strdup("Goto");
3864  snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count);
3865  fall_thru->appargs = strdup(buf1);
3866  linkprio(switch_case, fall_thru, mother_exten);
3867  } else if (!p2->next) {
3868  fall_thru = new_prio();
3869  fall_thru->type = AEL_CONTROL1;
3870  fall_thru->goto_true = switch_end;
3871  fall_thru->app = strdup("Goto");
3872  linkprio(switch_case, fall_thru, mother_exten);
3873  }
3874  }
3875  if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */
3876  char buf[2000];
3877  struct ael_priority *np2 = new_prio();
3878  np2->type = AEL_APPCALL;
3879  np2->app = strdup("NoOp");
3880  snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
3881  np2->appargs = strdup(buf);
3882  linkprio(switch_case, np2, mother_exten);
3883  switch_case-> return_target = np2;
3884  }
3885  } else if (p2->type == PV_DEFAULT) {
3886  /* ok, generate a extension and link it in */
3887  switch_case = new_exten();
3888  if (mother_exten && mother_exten->checked_switch) {
3889  switch_case->has_switch = mother_exten->has_switch;
3890  switch_case->checked_switch = mother_exten->checked_switch;
3891  }
3892  if (exten && exten->checked_switch) {
3893  switch_case->has_switch = exten->has_switch;
3894  switch_case->checked_switch = exten->checked_switch;
3895  }
3896  switch_case->context = this_context;
3897  switch_case->is_switch = 1;
3898 
3899  /* new: the default case intros a pattern with ., which covers ALMOST everything.
3900  but it doesn't cover a NULL pattern. So, we'll define a null extension to match
3901  that goto's the default extension. */
3902 
3903  default_exists++;
3904  switch_null = new_exten();
3905  if (mother_exten && mother_exten->checked_switch) {
3906  switch_null->has_switch = mother_exten->has_switch;
3907  switch_null->checked_switch = mother_exten->checked_switch;
3908  }
3909  if (exten && exten->checked_switch) {
3910  switch_null->has_switch = exten->has_switch;
3911  switch_null->checked_switch = exten->checked_switch;
3912  }
3913  switch_null->context = this_context;
3914  switch_null->is_switch = 1;
3915  switch_empty = new_prio();
3916  snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count);
3917  switch_empty->app = strdup("Goto");
3918  switch_empty->appargs = strdup(buf1);
3919  linkprio(switch_null, switch_empty, mother_exten);
3920  snprintf(buf1, BUF_SIZE, "sw_%d_", local_control_statement_count);
3921  switch_null->name = strdup(buf1);
3922  switch_null->loop_break = exten->loop_break;
3923  switch_null->loop_continue = exten->loop_continue;
3924  linkexten(exten,switch_null);
3925 
3926  /* the break/continue locations are inherited from parent */
3927  switch_case->loop_break = exten->loop_break;
3928  switch_case->loop_continue = exten->loop_continue;
3929  linkexten(exten,switch_case);
3930  snprintf(buf1, BUF_SIZE, "_sw_%d_.", local_control_statement_count);
3931  switch_case->name = strdup(buf1);
3932 
3933  snprintf(new_label, BUF_SIZE, "sw_%s_default_%d", label, local_control_statement_count);
3934 
3935  if (gen_prios(switch_case, new_label, p2->u2.statements, exten, this_context)) { /* this will link in all the default: body statements here */
3936  return -1;
3937  }
3938 
3939  /* here is where we write code to "fall thru" to the next case... if there is one... */
3940  for (p3=p2->u2.statements; p3; p3=p3->next) {
3941  if (!p3->next)
3942  break;
3943  }
3944  /* p3 now points the last statement... */
3945  if (!p3 || (p3->type != PV_GOTO && p3->type != PV_BREAK && p3->type != PV_RETURN)) {
3946  /* is there a following CASE/PATTERN/DEFAULT? */
3947  if (p2->next && p2->next->type == PV_CASE) {
3948  fall_thru = new_prio();
3949  fall_thru->type = AEL_APPCALL;
3950  fall_thru->app = strdup("Goto");
3951  snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, p2->next->u1.str);
3952  fall_thru->appargs = strdup(buf1);
3953  linkprio(switch_case, fall_thru, mother_exten);
3954  } else if (p2->next && p2->next->type == PV_PATTERN) {
3955  fall_thru = new_prio();
3956  fall_thru->type = AEL_APPCALL;
3957  fall_thru->app = strdup("Goto");
3958  gen_match_to_pattern(p2->next->u1.str, buf2);
3959  snprintf(buf1, BUF_SIZE, "sw_%d_%s,10", local_control_statement_count, buf2);
3960  fall_thru->appargs = strdup(buf1);
3961  linkprio(switch_case, fall_thru, mother_exten);
3962  } else if (p2->next && p2->next->type == PV_DEFAULT) {
3963  fall_thru = new_prio();
3964  fall_thru->type = AEL_APPCALL;
3965  fall_thru->app = strdup("Goto");
3966  snprintf(buf1, BUF_SIZE, "sw_%d_.,10", local_control_statement_count);
3967  fall_thru->appargs = strdup(buf1);
3968  linkprio(switch_case, fall_thru, mother_exten);
3969  } else if (!p2->next) {
3970  fall_thru = new_prio();
3971  fall_thru->type = AEL_CONTROL1;
3972  fall_thru->goto_true = switch_end;
3973  fall_thru->app = strdup("Goto");
3974  linkprio(switch_case, fall_thru, mother_exten);
3975  }
3976  }
3977  if (switch_case->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */
3978  char buf[2000];
3979  struct ael_priority *np2 = new_prio();
3980  np2->type = AEL_APPCALL;
3981  np2->app = strdup("NoOp");
3982  snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
3983  np2->appargs = strdup(buf);
3984  linkprio(switch_case, np2, mother_exten);
3985  switch_case-> return_target = np2;
3986  }
3987  } else {
3988  /* what could it be??? */
3989  }
3990  }
3991 
3992  exten->loop_break = loop_break_save;
3993  exten->loop_continue = loop_continue_save;
3994  switch_test->origin = p;
3995  switch_end->origin = p;
3996  break;
3997 
3998  case PV_MACRO_CALL:
3999  pr = new_prio();
4000  pr->type = AEL_APPCALL;
4001  snprintf(buf1, BUF_SIZE, "%s,~~s~~,1", p->u1.str);
4002  first = 1;
4003  for (p2 = p->u2.arglist; p2; p2 = p2->next) {
4004  if (first)
4005  {
4006  strcat(buf1,"(");
4007  first = 0;
4008  }
4009  else
4010  strcat(buf1,",");
4011  strcat(buf1,p2->u1.str);
4012  }
4013  if (!first)
4014  strcat(buf1,")");
4015 
4016  pr->app = strdup("Gosub");
4017  pr->appargs = strdup(buf1);
4018  pr->origin = p;
4019  linkprio(exten, pr, mother_exten);
4020  break;
4021 
4022  case PV_APPLICATION_CALL:
4023  pr = new_prio();
4024  pr->type = AEL_APPCALL;
4025  buf1[0] = 0;
4026  for (p2 = p->u2.arglist; p2; p2 = p2->next) {
4027  if (p2 != p->u2.arglist )
4028  strcat(buf1,",");
4029  strcat(buf1,p2->u1.str);
4030  }
4031  pr->app = strdup(p->u1.str);
4032  pr->appargs = strdup(buf1);
4033  pr->origin = p;
4034  linkprio(exten, pr, mother_exten);
4035  break;
4036 
4037  case PV_BREAK:
4038  pr = new_prio();
4039  pr->type = AEL_CONTROL1; /* simple goto */
4040  pr->goto_true = exten->loop_break;
4041  pr->origin = p;
4042  linkprio(exten, pr, mother_exten);
4043  break;
4044 
4045  case PV_RETURN: /* hmmmm */
4046  pr = new_prio();
4047  pr->type = AEL_RETURN; /* simple Return */
4048  /* exten->return_needed++; */
4049  pr->app = strdup("Return");
4050  pr->appargs = strdup("");
4051  pr->origin = p;
4052  linkprio(exten, pr, mother_exten);
4053  break;
4054 
4055  case PV_CONTINUE:
4056  pr = new_prio();
4057  pr->type = AEL_CONTROL1; /* simple goto */
4058  pr->goto_true = exten->loop_continue;
4059  pr->origin = p;
4060  linkprio(exten, pr, mother_exten);
4061  break;
4062 
4063  case PV_IFTIME:
4065  snprintf(new_label, BUF_SIZE, "iftime_%s_%d", label, control_statement_count);
4066 
4067  if_test = new_prio();
4068  if_test->type = AEL_IFTIME_CONTROL;
4069  snprintf(buf1, BUF_SIZE, "%s,%s,%s,%s",
4070  p->u1.list->u1.str,
4071  p->u1.list->next->u1.str,
4072  p->u1.list->next->next->u1.str,
4073  p->u1.list->next->next->next->u1.str);
4074  if_test->app = 0;
4075  if_test->appargs = strdup(buf1);
4076  if_test->origin = p;
4077 
4078  if_end = new_prio();
4079  if_end->type = AEL_APPCALL;
4080  snprintf(buf1, BUF_SIZE, "Finish iftime_%s_%d", label, control_statement_count);
4081  if_end->app = strdup("NoOp");
4082  if_end->appargs = strdup(buf1);
4083 
4084  if (p->u3.else_statements) {
4085  if_skip = new_prio();
4086  if_skip->type = AEL_CONTROL1; /* simple goto */
4087  if_skip->goto_true = if_end;
4088  if_skip->origin = p;
4089 
4090  } else {
4091  if_skip = 0;
4092 
4093  if_test->goto_false = if_end;
4094  }
4095 
4096  if_false = new_prio();
4097  if_false->type = AEL_CONTROL1;
4098  if (p->u3.else_statements) {
4099  if_false->goto_true = if_skip; /* +1 */
4100  } else {
4101  if_false->goto_true = if_end;
4102  }
4103 
4104  /* link & load! */
4105  linkprio(exten, if_test, mother_exten);
4106  linkprio(exten, if_false, mother_exten);
4107 
4108  /* now, put the body of the if here */
4109 
4110  if (gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context)) { /* this will link in all the statements here */
4111  return -1;
4112  }
4113 
4114  if (p->u3.else_statements) {
4115  linkprio(exten, if_skip, mother_exten);
4116  if (gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context)) { /* this will link in all the statements here */
4117  return -1;
4118  }
4119  }
4120 
4121  linkprio(exten, if_end, mother_exten);
4122 
4123  break;
4124 
4125  case PV_RANDOM:
4126  case PV_IF:
4128  snprintf(new_label, BUF_SIZE, "if_%s_%d", label, control_statement_count);
4129 
4130  if_test = new_prio();
4131  if_end = new_prio();
4132  if_test->type = AEL_IF_CONTROL;
4133  if_end->type = AEL_APPCALL;
4134  if ( p->type == PV_RANDOM )
4135  snprintf(buf1, BUF_SIZE, "$[${RAND(0,99)} < (%s)]", p->u1.str);
4136  else
4137  snprintf(buf1, BUF_SIZE, "$[%s]", p->u1.str);
4138  if_test->app = 0;
4139  if_test->appargs = strdup(buf1);
4140  snprintf(buf1, BUF_SIZE, "Finish if_%s_%d", label, control_statement_count);
4141  if_end->app = strdup("NoOp");
4142  if_end->appargs = strdup(buf1);
4143  if_test->origin = p;
4144 
4145  if (p->u3.else_statements) {
4146  if_skip = new_prio();
4147  if_skip->type = AEL_CONTROL1; /* simple goto */
4148  if_skip->goto_true = if_end;
4149  if_test->goto_false = if_skip;;
4150  } else {
4151  if_skip = 0;
4152  if_test->goto_false = if_end;;
4153  }
4154 
4155  /* link & load! */
4156  linkprio(exten, if_test, mother_exten);
4157 
4158  /* now, put the body of the if here */
4159 
4160  if (gen_prios(exten, new_label, p->u2.statements, mother_exten, this_context)) { /* this will link in all the statements here */
4161  return -1;
4162  }
4163 
4164  if (p->u3.else_statements) {
4165  linkprio(exten, if_skip, mother_exten);
4166  if (gen_prios(exten, new_label, p->u3.else_statements, mother_exten, this_context)) { /* this will link in all the statements here */
4167  return -1;
4168  }
4169  }
4170 
4171  linkprio(exten, if_end, mother_exten);
4172 
4173  break;
4174 
4175  case PV_STATEMENTBLOCK:
4176  if (gen_prios(exten, label, p->u1.list, mother_exten, this_context)) { /* recurse into the block */
4177  return -1;
4178  }
4179  break;
4180 
4181  case PV_CATCH:
4183  /* generate an extension with name of catch, put all catch stats
4184  into this exten! */
4185  switch_case = new_exten();
4186  if (mother_exten && mother_exten->checked_switch) {
4187  switch_case->has_switch = mother_exten->has_switch;
4188  switch_case->checked_switch = mother_exten->checked_switch;
4189  }
4190  if (exten && exten->checked_switch) {
4191  switch_case->has_switch = exten->has_switch;
4192  switch_case->checked_switch = exten->checked_switch;
4193  }
4194 
4195  switch_case->context = this_context;
4196  linkexten(exten,switch_case);
4197  switch_case->name = strdup(p->u1.str);
4198  snprintf(new_label, BUF_SIZE, "catch_%s_%d",p->u1.str, control_statement_count);
4199 
4200  if (gen_prios(switch_case, new_label, p->u2.statements, mother_exten,this_context)) { /* this will link in all the catch body statements here */
4201  return -1;
4202  }
4203  if (switch_case->return_needed) { /* returns now generate a Return() app call, no longer a goto to the end of the exten */
4204  char buf[2000];
4205  struct ael_priority *np2 = new_prio();
4206  np2->type = AEL_APPCALL;
4207  np2->app = strdup("NoOp");
4208  snprintf(buf,sizeof(buf),"End of Extension %s", switch_case->name);
4209  np2->appargs = strdup(buf);
4210  linkprio(switch_case, np2, mother_exten);
4211  switch_case-> return_target = np2;
4212  }
4213 
4214  break;
4215  default:
4216  break;
4217  }
4218  }
4219  free(buf1);
4220  free(buf2);
4221  free(new_label);
4222  return 0;
4223 }
union pval::@198 u1
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
static int control_statement_count
Definition: pval.c:2929
char * for_inc
Definition: pval.h:77
struct ael_priority * new_prio(void)
Definition: pval.c:2931
struct pval * origin
Definition: ael_structs.h:95
struct pval * list
Definition: pval.h:60
#define malloc(a)
Definition: astmm.h:88
Definition: pval.h:32
Definition: pval.h:29
struct ael_priority * goto_true
Definition: ael_structs.h:98
static void linkexten(struct ael_extension *exten, struct ael_extension *add)
Definition: pval.c:3039
static int label_inside_case(pval *label)
Definition: pval.c:3025
struct pval * statements
Definition: pval.h:61
#define ast_compat_app_set
Definition: options.h:144
static struct ast_threadstorage buf2
Definition: pval.h:22
struct ael_priority * goto_false
Definition: ael_structs.h:99
char * appargs
Definition: ael_structs.h:93
static int gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten, struct ast_context *this_context)
Definition: pval.c:3348
union pval::@200 u3
union pval::@199 u2
struct ast_context * context
Definition: ael_structs.h:113
struct ael_extension * new_exten(void)
Definition: pval.c:2937
char * val
Definition: pval.h:70
Definition: pval.h:13
struct pval * goto_target
Definition: pval.h:72
Definition: pval.h:21
struct ael_extension * exten
Definition: ael_structs.h:96
char * str
Definition: pval.h:59
Definition: pval.h:48
struct ael_priority * loop_break
Definition: ael_structs.h:119
char * for_test
Definition: pval.h:71
struct ael_extension * compiled_label
Definition: pval.h:83
int goto_target_in_case
Definition: pval.h:82
char * app
Definition: ael_structs.h:92
static void gen_match_to_pattern(char *pattern, char *result)
Definition: pval.c:3068
struct pval * else_statements
Definition: pval.h:78
#define free(a)
Definition: astmm.h:94
Definition: pval.h:24
union pval::@201 u4
struct pval * arglist
Definition: pval.h:68
struct ael_priority * loop_continue
Definition: ael_structs.h:120
#define BUF_SIZE
Definition: pval.c:63
struct sla_ringing_trunk * first
Definition: app_meetme.c:965
static struct ast_threadstorage buf1
Definition: pval.h:31
Definition: pval.h:25
int contains_switch(pval *item)
Definition: pval.c:3336
pvaltype type
Definition: pval.h:50
Definition: pval.h:30
Definition: pval.h:23
static void remove_spaces_before_equals(char *str)
Definition: pval.c:3045
struct pval * next
Definition: pval.h:93
ael_priority_type type
Definition: ael_structs.h:90
Definition: pval.h:27
struct pval * for_statements
Definition: pval.h:89
#define strdup(a)
Definition: astmm.h:106
void linkprio(struct ael_extension *exten, struct ael_priority *prio, struct ael_extension *mother_exten)
Definition: pval.c:2943
static pval * get_goto_target(pval *item)
Definition: pval.c:1160
Definition: pval.h:26
char * for_init
Definition: pval.h:62
Definition: pval.h:16
static pval * get_contxt ( pval p)
static

Definition at line 4383 of file pval.c.

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

Referenced by check_goto(), and get_goto_target().

4384 {
4385  while( p && p->type != PV_CONTEXT && p->type != PV_MACRO ) {
4386 
4387  p = p->dad;
4388  }
4389 
4390  return p;
4391 }
struct pval * dad
Definition: pval.h:96
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static pval * get_extension_or_contxt ( pval p)
static

Definition at line 4373 of file pval.c.

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

Referenced by check_goto(), and get_goto_target().

4374 {
4375  while( p && p->type != PV_EXTENSION && p->type != PV_CONTEXT && p->type != PV_MACRO ) {
4376 
4377  p = p->dad;
4378  }
4379 
4380  return p;
4381 }
struct pval * dad
Definition: pval.h:96
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static pval * get_goto_target ( pval item)
static

Definition at line 1160 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().

1161 {
1162  /* just one item-- the label should be in the current extension */
1163  pval *curr_ext = get_extension_or_contxt(item); /* containing exten, or macro */
1164  pval *curr_cont;
1165 
1166  if (!item->u1.list) {
1167  return NULL;
1168  }
1169 
1170  if (!item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) {
1171  struct pval *x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), curr_ext);
1172  return x;
1173  }
1174 
1175  curr_cont = get_contxt(item);
1176 
1177  /* TWO items */
1178  if (item->u1.list->next && !item->u1.list->next->next) {
1179  if (!strstr((item->u1.list)->u1.str,"${")
1180  && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ {
1181  struct pval *x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, curr_cont);
1182  return x;
1183  }
1184  }
1185 
1186  /* All 3 items! */
1187  if (item->u1.list->next && item->u1.list->next->next) {
1188  /* all three */
1189  pval *first = item->u1.list;
1190  pval *second = item->u1.list->next;
1191  pval *third = item->u1.list->next->next;
1192 
1193  if (!strstr((item->u1.list)->u1.str,"${")
1194  && !strstr(item->u1.list->next->u1.str,"${")
1195  && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ {
1196  struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str);
1197  if (!x) {
1198 
1199  struct pval *p3;
1200  struct pval *that_context = find_context(item->u1.list->u1.str);
1201 
1202  /* the target of the goto could be in an included context!! Fancy that!! */
1203  /* look for includes in the current context */
1204  if (that_context) {
1205  for (p3=that_context->u2.statements; p3; p3=p3->next) {
1206  if (p3->type == PV_INCLUDES) {
1207  struct pval *p4;
1208  for (p4=p3->u1.list; p4; p4=p4->next) {
1209  /* for each context pointed to, find it, then find a context/label that matches the
1210  target here! */
1211  char *incl_context = p4->u1.str;
1212  /* find a matching context name */
1213  struct pval *that_other_context = find_context(incl_context);
1214  if (that_other_context) {
1215  struct pval *x3;
1216  x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context);
1217  if (x3) {
1218  return x3;
1219  }
1220  }
1221  }
1222  }
1223  }
1224  }
1225  }
1226  return x;
1227  }
1228  }
1229  return NULL;
1230 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
static struct pval * find_label_in_current_extension(const char *label, pval *curr_ext)
Definition: pval.c:1925
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
static pval * get_contxt(pval *p)
Definition: pval.c:4383
char * str
Definition: pval.h:59
Definition: pval.h:48
static struct pval * find_label_in_current_context(char *exten, char *label, pval *curr_cont)
Definition: pval.c:1886
struct sla_ringing_trunk * first
Definition: app_meetme.c:965
static struct pval * find_label_in_current_db(const char *context, const char *exten, const char *label)
Definition: pval.c:1936
pvaltype type
Definition: pval.h:50
struct pval * find_context(char *name)
Definition: pval.c:1960
struct pval * next
Definition: pval.h:93
static pval * get_extension_or_contxt(pval *p)
Definition: pval.c:4373
static struct pval* in_context ( pval item)
static

Definition at line 1097 of file pval.c.

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

Referenced by check_goto().

1098 {
1099  struct pval *curr;
1100  curr = item;
1101  while( curr ) {
1102  if( curr->type == PV_MACRO || curr->type == PV_CONTEXT ) {
1103  return curr;
1104  }
1105  curr = curr->dad;
1106  }
1107  return 0;
1108 }
struct pval * dad
Definition: pval.h:96
Definition: pval.h:48
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static struct pval* in_macro ( pval item)
static

Definition at line 1084 of file pval.c.

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

Referenced by check_goto().

1085 {
1086  struct pval *curr;
1087  curr = item;
1088  while( curr ) {
1089  if( curr->type == PV_MACRO ) {
1090  return curr;
1091  }
1092  curr = curr->dad;
1093  }
1094  return 0;
1095 }
struct pval * dad
Definition: pval.h:96
Definition: pval.h:48
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
int is_empty ( char *  arg)

Definition at line 1988 of file pval.c.

1989 {
1990  if (!arg)
1991  return 1;
1992  if (*arg == 0)
1993  return 1;
1994  while (*arg) {
1995  if (*arg != ' ' && *arg != '\t')
1996  return 0;
1997  arg++;
1998  }
1999  return 1;
2000 }
int is_float ( char *  arg)

Definition at line 1970 of file pval.c.

1971 {
1972  char *s;
1973  for (s=arg; *s; s++) {
1974  if (*s != '.' && (*s < '0' || *s > '9'))
1975  return 0;
1976  }
1977  return 1;
1978 }
int is_int ( char *  arg)

Definition at line 1979 of file pval.c.

1980 {
1981  char *s;
1982  for (s=arg; *s; s++) {
1983  if (*s < '0' || *s > '9')
1984  return 0;
1985  }
1986  return 1;
1987 }
static int label_inside_case ( pval label)
static

Definition at line 3025 of file pval.c.

References pval::dad, PV_CASE, PV_CONTEXT, PV_DEFAULT, PV_MACRO, PV_PATTERN, and pval::type.

Referenced by gen_prios().

3026 {
3027  pval *p = label;
3028 
3029  while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
3030  if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN ) {
3031  return 1;
3032  }
3033 
3034  p = p->dad;
3035  }
3036  return 0;
3037 }
struct pval * dad
Definition: pval.h:96
Definition: pval.h:13
Definition: pval.h:48
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static void linkexten ( struct ael_extension exten,
struct ael_extension add 
)
static

Definition at line 3039 of file pval.c.

References ael_extension::next_exten.

Referenced by gen_prios().

3040 {
3041  add->next_exten = exten->next_exten; /* this will reverse the order. Big deal. */
3042  exten->next_exten = add;
3043 }
struct ael_extension * next_exten
Definition: ael_structs.h:117
void linkprio ( struct ael_extension exten,
struct ael_priority prio,
struct ael_extension mother_exten 
)

Definition at line 2943 of file pval.c.

References ael_priority::appargs, ael_priority::exten, 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().

2944 {
2945  char *p1, *p2;
2946 
2947  if (!exten->plist) {
2948  exten->plist = prio;
2949  exten->plist_last = prio;
2950  } else {
2951  exten->plist_last->next = prio;
2952  exten->plist_last = prio;
2953  }
2954  if( !prio->exten )
2955  prio->exten = exten; /* don't override the switch value */
2956  /* The following code will cause all priorities within an extension
2957  to have ${EXTEN} or ${EXTEN: replaced with ~~EXTEN~~, which is
2958  set just before the first switch in an exten. The switches
2959  will muck up the original ${EXTEN} value, so we save it away
2960  and the user accesses this copy instead. */
2961  if (prio->appargs && ((mother_exten && mother_exten->has_switch) || exten->has_switch) ) {
2962  while ((p1 = strstr(prio->appargs, "${EXTEN}"))) {
2963  p2 = malloc(strlen(prio->appargs)+5);
2964  *p1 = 0;
2965  strcpy(p2, prio->appargs);
2966  strcat(p2, "${~~EXTEN~~}");
2967  if (*(p1+8))
2968  strcat(p2, p1+8);
2969  free(prio->appargs);
2970  prio->appargs = p2;
2971  }
2972  while ((p1 = strstr(prio->appargs, "${EXTEN:"))) {
2973  p2 = malloc(strlen(prio->appargs)+5);
2974  *p1 = 0;
2975  strcpy(p2, prio->appargs);
2976  strcat(p2, "${~~EXTEN~~:");
2977  if (*(p1+8))
2978  strcat(p2, p1+8);
2979  free(prio->appargs);
2980  prio->appargs = p2;
2981  }
2982  }
2983 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
#define malloc(a)
Definition: astmm.h:88
struct ael_priority * plist_last
Definition: ael_structs.h:116
struct ael_priority * plist
Definition: ael_structs.h:115
char * appargs
Definition: ael_structs.h:93
struct ael_extension * exten
Definition: ael_structs.h:96
#define free(a)
Definition: astmm.h:94
struct ael_priority * next
Definition: ael_structs.h:100
pval* linku1 ( pval head,
pval tail 
)

Definition at line 5926 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 switch().

5927 {
5928  if (!head)
5929  return tail;
5930  if (tail) {
5931  if (!head->next) {
5932  head->next = tail;
5933  } else {
5934  head->u1_last->next = tail;
5935  }
5936  head->u1_last = tail;
5937  tail->prev = head; /* the dad link only points to containers */
5938  }
5939  return head;
5940 }
struct pval * u1_last
Definition: pval.h:64
struct pval * prev
Definition: pval.h:97
struct pval * next
Definition: pval.h:93
int localized_pbx_load_module ( void  )
struct pval * match_pval ( pval item)

Definition at line 1818 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().

1819 {
1820  pval *i;
1821 
1822  for (i=item; i; i=i->next) {
1823  pval *x;
1824  /* printf(" -- match pval: item %d\n", i->type); */
1825 
1826  if ((x = match_pval_item(i))) {
1827  /* printf("match_pval: returning x=%x\n", (int)x); */
1828  return x; /* cut the search short */
1829  }
1830  }
1831  return 0;
1832 }
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
static struct pval * match_pval_item(pval *item)
Definition: pval.c:1570
static struct pval* match_pval_item ( pval item)
static

Definition at line 1570 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().

1571 {
1572  pval *x;
1573 
1574  switch ( item->type ) {
1575  case PV_MACRO:
1576  /* fields: item->u1.str == name of macro
1577  item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
1578  item->u2.arglist->u1.str == argument
1579  item->u2.arglist->next == next arg
1580 
1581  item->u3.macro_statements == pval list of statements in macro body.
1582  */
1583  /* printf(" matching in MACRO %s, match_context=%s; retoncontmtch=%d; \n", item->u1.str, match_context, return_on_context_match); */
1584  if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) {
1585 
1586  /* printf("MACRO: match context is: %s\n", match_context); */
1587 
1588  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 */ {
1589  /* printf("Returning on matching macro %s\n", match_context); */
1590  return item;
1591  }
1592 
1593 
1594  if (!return_on_context_match) {
1595  /* printf("Descending into matching macro %s/%s\n", match_context, item->u1.str); */
1596  if ((x=match_pval(item->u3.macro_statements))) {
1597  /* printf("Responded with pval match %x\n", x); */
1598  return x;
1599  }
1600  }
1601  } else {
1602  /* printf("Skipping context/macro %s\n", item->u1.str); */
1603  }
1604 
1605  break;
1606 
1607  case PV_CONTEXT:
1608  /* fields: item->u1.str == name of context
1609  item->u2.statements == pval list of statements in context body
1610  item->u3.abstract == int 1 if an abstract keyword were present
1611  */
1612  /* printf(" matching in CONTEXT\n"); */
1613  if (!strcmp(match_context,"*") || !strcmp(item->u1.str, match_context)) {
1614  if (return_on_context_match && !strcmp(item->u1.str, match_context)) {
1615  /* printf("Returning on matching context %s\n", match_context); */
1616  /* printf("non-CONTEXT: Responded with pval match %x\n", x); */
1617  return item;
1618  }
1619 
1620  if (!return_on_context_match ) {
1621  /* printf("Descending into matching context %s\n", match_context); */
1622  if ((x=match_pval(item->u2.statements))) /* if we're just searching for a context, don't bother descending into them */ {
1623  /* printf("CONTEXT: Responded with pval match %x\n", x); */
1624  return x;
1625  }
1626  }
1627  } else {
1628  /* printf("Skipping context/macro %s\n", item->u1.str); */
1629  }
1630  break;
1631 
1632  case PV_CASE:
1633  /* fields: item->u1.str == value of case
1634  item->u2.statements == pval list of statements under the case
1635  */
1636  /* printf(" matching in CASE\n"); */
1637  if ((x=match_pval(item->u2.statements))) {
1638  /* printf("CASE: Responded with pval match %x\n", x); */
1639  return x;
1640  }
1641  break;
1642 
1643  case PV_PATTERN:
1644  /* fields: item->u1.str == value of case
1645  item->u2.statements == pval list of statements under the case
1646  */
1647  /* printf(" matching in PATTERN\n"); */
1648  if ((x=match_pval(item->u2.statements))) {
1649  /* printf("PATTERN: Responded with pval match %x\n", x); */
1650  return x;
1651  }
1652  break;
1653 
1654  case PV_DEFAULT:
1655  /* fields:
1656  item->u2.statements == pval list of statements under the case
1657  */
1658  /* printf(" matching in DEFAULT\n"); */
1659  if ((x=match_pval(item->u2.statements))) {
1660  /* printf("DEFAULT: Responded with pval match %x\n", x); */
1661  return x;
1662  }
1663  break;
1664 
1665  case PV_CATCH:
1666  /* fields: item->u1.str == name of extension to catch
1667  item->u2.statements == pval list of statements in context body
1668  */
1669  /* printf(" matching in CATCH\n"); */
1670  if ((x=match_pval(item->u2.statements))) {
1671  /* printf("CATCH: Responded with pval match %x\n", x); */
1672  return x;
1673  }
1674  break;
1675 
1676  case PV_STATEMENTBLOCK:
1677  /* fields: item->u1.list == pval list of statements in block, one per entry in the list
1678  */
1679  /* printf(" matching in STATEMENTBLOCK\n"); */
1680  if ((x=match_pval(item->u1.list))) {
1681  /* printf("STATEMENTBLOCK: Responded with pval match %x\n", x); */
1682  return x;
1683  }
1684  break;
1685 
1686  case PV_LABEL:
1687  /* fields: item->u1.str == label name
1688  */
1689  /* printf("PV_LABEL %s (cont=%s, exten=%s\n",
1690  item->u1.str, current_context->u1.str, (current_extension?current_extension->u1.str:"<macro>"));*/
1691 
1692  if (count_labels) {
1693  if (!strcmp(match_label, item->u1.str)) {
1694  label_count++;
1695  last_matched_label = item;
1696  }
1697 
1698  } else {
1699  if (!strcmp(match_label, item->u1.str)) {
1700  /* printf("LABEL: Responded with pval match %x\n", x); */
1701  return item;
1702  }
1703  }
1704  break;
1705 
1706  case PV_FOR:
1707  /* fields: item->u1.for_init == a string containing the initalizer
1708  item->u2.for_test == a string containing the loop test
1709  item->u3.for_inc == a string containing the loop increment
1710 
1711  item->u4.for_statements == a pval list of statements in the for ()
1712  */
1713  /* printf(" matching in FOR\n"); */
1714  if ((x=match_pval(item->u4.for_statements))) {
1715  /* printf("FOR: Responded with pval match %x\n", x);*/
1716  return x;
1717  }
1718  break;
1719 
1720  case PV_WHILE:
1721  /* fields: item->u1.str == the while conditional, as supplied by user
1722 
1723  item->u2.statements == a pval list of statements in the while ()
1724  */
1725  /* printf(" matching in WHILE\n"); */
1726  if ((x=match_pval(item->u2.statements))) {
1727  /* printf("WHILE: Responded with pval match %x\n", x); */
1728  return x;
1729  }
1730  break;
1731 
1732  case PV_RANDOM:
1733  /* fields: item->u1.str == the random number expression, as supplied by user
1734 
1735  item->u2.statements == a pval list of statements in the if ()
1736  item->u3.else_statements == a pval list of statements in the else
1737  (could be zero)
1738  fall thru to PV_IF */
1739 
1740  case PV_IFTIME:
1741  /* fields: item->u1.list == the time values, 4 of them, as PV_WORD structs in a list
1742 
1743  item->u2.statements == a pval list of statements in the if ()
1744  item->u3.else_statements == a pval list of statements in the else
1745  (could be zero)
1746  fall thru to PV_IF*/
1747  case PV_IF:
1748  /* fields: item->u1.str == the if conditional, as supplied by user
1749 
1750  item->u2.statements == a pval list of statements in the if ()
1751  item->u3.else_statements == a pval list of statements in the else
1752  (could be zero)
1753  */
1754  /* printf(" matching in IF/IFTIME/RANDOM\n"); */
1755  if ((x=match_pval(item->u2.statements))) {
1756  return x;
1757  }
1758  if (item->u3.else_statements) {
1759  if ((x=match_pval(item->u3.else_statements))) {
1760  /* printf("IF/IFTIME/RANDOM: Responded with pval match %x\n", x); */
1761  return x;
1762  }
1763  }
1764  break;
1765 
1766  case PV_SWITCH:
1767  /* fields: item->u1.str == the switch expression
1768 
1769  item->u2.statements == a pval list of statements in the switch,
1770  (will be case statements, most likely!)
1771  */
1772  /* printf(" matching in SWITCH\n"); */
1773  if ((x=match_pval(item->u2.statements))) {
1774  /* printf("SWITCH: Responded with pval match %x\n", x); */
1775  return x;
1776  }
1777  break;
1778 
1779  case PV_EXTENSION:
1780  /* fields: item->u1.str == the extension name, label, whatever it's called
1781 
1782  item->u2.statements == a pval list of statements in the extension
1783  item->u3.hints == a char * hint argument
1784  item->u4.regexten == an int boolean. non-zero says that regexten was specified
1785  */
1786  /* printf(" matching in EXTENSION\n"); */
1787  if (!strcmp(match_exten,"*") || extension_matches(item, match_exten, item->u1.str) ) {
1788  /* printf("Descending into matching exten %s => %s\n", match_exten, item->u1.str); */
1789  if (strcmp(match_label,"1") == 0) {
1790  if (item->u2.statements) {
1791  struct pval *p5 = item->u2.statements;
1792  while (p5 && p5->type == PV_LABEL) /* find the first non-label statement in this context. If it exists, there's a "1" */
1793  p5 = p5->next;
1794  if (p5)
1795  return p5;
1796  else
1797  return 0;
1798  }
1799  else
1800  return 0;
1801  }
1802 
1803  if ((x=match_pval(item->u2.statements))) {
1804  /* printf("EXTENSION: Responded with pval match %x\n", x); */
1805  return x;
1806  }
1807  } else {
1808  /* printf("Skipping exten %s\n", item->u1.str); */
1809  }
1810  break;
1811  default:
1812  /* printf(" matching in default = %d\n", item->type); */
1813  break;
1814  }
1815  return 0;
1816 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
struct pval * statements
Definition: pval.h:61
union pval::@200 u3
union pval::@199 u2
static int extension_matches(pval *here, const char *exten, const char *pattern)
Definition: pval.c:696
static int label_count
Definition: pval.c:83
Definition: pval.h:13
char * str
Definition: pval.h:59
Definition: pval.h:48
struct pval * else_statements
Definition: pval.h:78
Definition: pval.h:24
union pval::@201 u4
static int count_labels
Definition: pval.c:82
Definition: pval.h:9
Definition: pval.h:31
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
Definition: pval.h:30
Definition: pval.h:23
struct pval * next
Definition: pval.h:93
static const char * match_exten
Definition: pval.c:79
static int return_on_context_match
Definition: pval.c:84
struct pval * for_statements
Definition: pval.h:89
static pval * last_matched_label
Definition: pval.c:85
struct pval * match_pval(pval *item)
Definition: pval.c:1818
static const char * match_context
Definition: pval.c:78
Definition: pval.h:16
struct pval * macro_statements
Definition: pval.h:79
static const char * match_label
Definition: pval.c:80
struct ael_extension* new_exten ( void  )

Definition at line 2937 of file pval.c.

References calloc.

Referenced by ast_compile_ael2(), and gen_prios().

2938 {
2939  struct ael_extension *x = (struct ael_extension *)calloc(sizeof(struct ael_extension),1);
2940  return x;
2941 }
#define calloc(a, b)
Definition: astmm.h:79
struct ael_priority* new_prio ( void  )

Definition at line 2931 of file pval.c.

References calloc.

Referenced by ast_compile_ael2(), and gen_prios().

2932 {
2933  struct ael_priority *x = (struct ael_priority *)calloc(sizeof(struct ael_priority),1);
2934  return x;
2935 }
#define calloc(a, b)
Definition: astmm.h:79
static void print_pval ( FILE *  fin,
pval item,
int  depth 
)
static

Definition at line 117 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().

118 {
119  int i;
120  pval *lp;
121 
122  for (i=0; i<depth; i++) {
123  fprintf(fin, "\t"); /* depth == indentation */
124  }
125 
126  switch ( item->type ) {
127  case PV_WORD:
128  fprintf(fin,"%s;\n", item->u1.str); /* usually, words are encapsulated in something else */
129  break;
130 
131  case PV_MACRO:
132  fprintf(fin,"macro %s(", item->u1.str);
133  for (lp=item->u2.arglist; lp; lp=lp->next) {
134  if (lp != item->u2.arglist )
135  fprintf(fin,", ");
136  fprintf(fin,"%s", lp->u1.str);
137  }
138  fprintf(fin,") {\n");
139  print_pval_list(fin,item->u3.macro_statements,depth+1);
140  for (i=0; i<depth; i++) {
141  fprintf(fin,"\t"); /* depth == indentation */
142  }
143  fprintf(fin,"};\n\n");
144  break;
145 
146  case PV_CONTEXT:
147  if ( item->u3.abstract )
148  fprintf(fin,"abstract context %s {\n", item->u1.str);
149  else
150  fprintf(fin,"context %s {\n", item->u1.str);
151  print_pval_list(fin,item->u2.statements,depth+1);
152  for (i=0; i<depth; i++) {
153  fprintf(fin,"\t"); /* depth == indentation */
154  }
155  fprintf(fin,"};\n\n");
156  break;
157 
158  case PV_MACRO_CALL:
159  fprintf(fin,"&%s(", item->u1.str);
160  for (lp=item->u2.arglist; lp; lp=lp->next) {
161  if ( lp != item->u2.arglist )
162  fprintf(fin,", ");
163  fprintf(fin,"%s", lp->u1.str);
164  }
165  fprintf(fin,");\n");
166  break;
167 
168  case PV_APPLICATION_CALL:
169  fprintf(fin,"%s(", item->u1.str);
170  for (lp=item->u2.arglist; lp; lp=lp->next) {
171  if ( lp != item->u2.arglist )
172  fprintf(fin,",");
173  fprintf(fin,"%s", lp->u1.str);
174  }
175  fprintf(fin,");\n");
176  break;
177 
178  case PV_CASE:
179  fprintf(fin,"case %s:\n", item->u1.str);
180  print_pval_list(fin,item->u2.statements, depth+1);
181  break;
182 
183  case PV_PATTERN:
184  fprintf(fin,"pattern %s:\n", item->u1.str);
185  print_pval_list(fin,item->u2.statements, depth+1);
186  break;
187 
188  case PV_DEFAULT:
189  fprintf(fin,"default:\n");
190  print_pval_list(fin,item->u2.statements, depth+1);
191  break;
192 
193  case PV_CATCH:
194  fprintf(fin,"catch %s {\n", item->u1.str);
195  print_pval_list(fin,item->u2.statements, depth+1);
196  for (i=0; i<depth; i++) {
197  fprintf(fin,"\t"); /* depth == indentation */
198  }
199  fprintf(fin,"};\n");
200  break;
201 
202  case PV_SWITCHES:
203  fprintf(fin,"switches {\n");
204  print_pval_list(fin,item->u1.list,depth+1);
205  for (i=0; i<depth; i++) {
206  fprintf(fin,"\t"); /* depth == indentation */
207  }
208  fprintf(fin,"};\n");
209  break;
210 
211  case PV_ESWITCHES:
212  fprintf(fin,"eswitches {\n");
213  print_pval_list(fin,item->u1.list,depth+1);
214  for (i=0; i<depth; i++) {
215  fprintf(fin,"\t"); /* depth == indentation */
216  }
217  fprintf(fin,"};\n");
218  break;
219 
220  case PV_INCLUDES:
221  fprintf(fin,"includes {\n");
222  for (lp=item->u1.list; lp; lp=lp->next) {
223  for (i=0; i<depth+1; i++) {
224  fprintf(fin,"\t"); /* depth == indentation */
225  }
226  fprintf(fin,"%s", lp->u1.str); /* usually, words are encapsulated in something else */
227  if (lp->u2.arglist)
228  fprintf(fin,"|%s|%s|%s|%s",
229  lp->u2.arglist->u1.str,
230  lp->u2.arglist->next->u1.str,
231  lp->u2.arglist->next->next->u1.str,
232  lp->u2.arglist->next->next->next->u1.str
233  );
234  fprintf(fin,";\n"); /* usually, words are encapsulated in something else */
235  }
236 
237  for (i=0; i<depth; i++) {
238  fprintf(fin,"\t"); /* depth == indentation */
239  }
240  fprintf(fin,"};\n");
241  break;
242 
243  case PV_STATEMENTBLOCK:
244  fprintf(fin,"{\n");
245  print_pval_list(fin,item->u1.list, depth+1);
246  for (i=0; i<depth; i++) {
247  fprintf(fin,"\t"); /* depth == indentation */
248  }
249  fprintf(fin,"}\n");
250  break;
251 
252  case PV_VARDEC:
253  fprintf(fin,"%s=%s;\n", item->u1.str, item->u2.val);
254  break;
255 
256  case PV_LOCALVARDEC:
257  fprintf(fin,"local %s=%s;\n", item->u1.str, item->u2.val);
258  break;
259 
260  case PV_GOTO:
261  fprintf(fin,"goto %s", item->u1.list->u1.str);
262  if ( item->u1.list->next )
263  fprintf(fin,",%s", item->u1.list->next->u1.str);
264  if ( item->u1.list->next && item->u1.list->next->next )
265  fprintf(fin,",%s", item->u1.list->next->next->u1.str);
266  fprintf(fin,"\n");
267  break;
268 
269  case PV_LABEL:
270  fprintf(fin,"%s:\n", item->u1.str);
271  break;
272 
273  case PV_FOR:
274  fprintf(fin,"for (%s; %s; %s)\n", item->u1.for_init, item->u2.for_test, item->u3.for_inc);
275  print_pval_list(fin,item->u4.for_statements,depth+1);
276  break;
277 
278  case PV_WHILE:
279  fprintf(fin,"while (%s)\n", item->u1.str);
280  print_pval_list(fin,item->u2.statements,depth+1);
281  break;
282 
283  case PV_BREAK:
284  fprintf(fin,"break;\n");
285  break;
286 
287  case PV_RETURN:
288  fprintf(fin,"return;\n");
289  break;
290 
291  case PV_CONTINUE:
292  fprintf(fin,"continue;\n");
293  break;
294 
295  case PV_RANDOM:
296  case PV_IFTIME:
297  case PV_IF:
298  if ( item->type == PV_IFTIME ) {
299 
300  fprintf(fin,"ifTime ( %s|%s|%s|%s )\n",
301  item->u1.list->u1.str,
302  item->u1.list->next->u1.str,
303  item->u1.list->next->next->u1.str,
304  item->u1.list->next->next->next->u1.str
305  );
306  } else if ( item->type == PV_RANDOM ) {
307  fprintf(fin,"random ( %s )\n", item->u1.str );
308  } else
309  fprintf(fin,"if ( %s )\n", item->u1.str);
310  if ( item->u2.statements && item->u2.statements->next ) {
311  for (i=0; i<depth; i++) {
312  fprintf(fin,"\t"); /* depth == indentation */
313  }
314  fprintf(fin,"{\n");
315  print_pval_list(fin,item->u2.statements,depth+1);
316  for (i=0; i<depth; i++) {
317  fprintf(fin,"\t"); /* depth == indentation */
318  }
319  if ( item->u3.else_statements )
320  fprintf(fin,"}\n");
321  else
322  fprintf(fin,"};\n");
323  } else if (item->u2.statements ) {
324  print_pval_list(fin,item->u2.statements,depth+1);
325  } else {
326  if (item->u3.else_statements )
327  fprintf(fin, " {} ");
328  else
329  fprintf(fin, " {}; ");
330  }
331  if ( item->u3.else_statements ) {
332  for (i=0; i<depth; i++) {
333  fprintf(fin,"\t"); /* depth == indentation */
334  }
335  fprintf(fin,"else\n");
336  print_pval_list(fin,item->u3.else_statements, depth);
337  }
338  break;
339 
340  case PV_SWITCH:
341  fprintf(fin,"switch( %s ) {\n", item->u1.str);
342  print_pval_list(fin,item->u2.statements,depth+1);
343  for (i=0; i<depth; i++) {
344  fprintf(fin,"\t"); /* depth == indentation */
345  }
346  fprintf(fin,"}\n");
347  break;
348 
349  case PV_EXTENSION:
350  if ( item->u4.regexten )
351  fprintf(fin, "regexten ");
352  if ( item->u3.hints )
353  fprintf(fin,"hints(%s) ", item->u3.hints);
354 
355  fprintf(fin,"%s => ", item->u1.str);
356  print_pval_list(fin,item->u2.statements,depth+1);
357  fprintf(fin,"\n");
358  break;
359 
360  case PV_IGNOREPAT:
361  fprintf(fin,"ignorepat => %s;\n", item->u1.str);
362  break;
363 
364  case PV_GLOBALS:
365  fprintf(fin,"globals {\n");
366  print_pval_list(fin,item->u1.statements,depth+1);
367  for (i=0; i<depth; i++) {
368  fprintf(fin,"\t"); /* depth == indentation */
369  }
370  fprintf(fin,"}\n");
371  break;
372  }
373 }
union pval::@198 u1
int regexten
Definition: pval.h:90
char * for_inc
Definition: pval.h:77
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
struct pval * statements
Definition: pval.h:61
Definition: pval.h:22
int abstract
Definition: pval.h:80
Definition: pval.h:8
union pval::@200 u3
union pval::@199 u2
char * val
Definition: pval.h:70
Definition: pval.h:13
Definition: pval.h:21
char * str
Definition: pval.h:59
Definition: pval.h:48
char * for_test
Definition: pval.h:71
char * hints
Definition: pval.h:81
struct pval * else_statements
Definition: pval.h:78
Definition: pval.h:24
union pval::@201 u4
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
Definition: pval.h:31
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
Definition: pval.h:30
Definition: pval.h:23
struct pval * next
Definition: pval.h:93
Definition: pval.h:27
struct pval * for_statements
Definition: pval.h:89
static void print_pval_list(FILE *fin, pval *item, int depth)
Definition: pval.c:375
Definition: pval.h:26
char * for_init
Definition: pval.h:62
Definition: pval.h:16
struct pval * macro_statements
Definition: pval.h:79
static void print_pval_list ( FILE *  fin,
pval item,
int  depth 
)
static

Definition at line 375 of file pval.c.

References pval::next, and print_pval().

Referenced by ael2_print(), and print_pval().

376 {
377  pval *i;
378 
379  for (i=item; i; i=i->next) {
380  print_pval(fin, i, depth);
381  }
382 }
static void print_pval(FILE *fin, pval *item, int depth)
Definition: pval.c:117
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
void pvalAppCallAddArg ( pval p,
pval arg 
)

Definition at line 5304 of file pval.c.

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

5305 {
5306  if (!pvalCheckType(p, "pvalAppCallAddArg", PV_APPLICATION_CALL))
5307  return;
5308  if (!p->u2.arglist)
5309  p->u2.arglist = arg;
5310  else
5311  linku1(p->u2.arglist, arg);
5312 }
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalAppCallGetAppName ( pval p)

Definition at line 5290 of file pval.c.

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

5291 {
5292  if (!pvalCheckType(p, "pvalAppCallGetAppName", PV_APPLICATION_CALL))
5293  return 0;
5294  return p->u1.str;
5295 }
union pval::@198 u1
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalAppCallSetAppName ( pval p,
char *  name 
)

Definition at line 5283 of file pval.c.

References name, PV_APPLICATION_CALL, pvalCheckType(), pval::str, and pval::u1.

5284 {
5285  if (!pvalCheckType(p, "pvalAppCallSetAppName", PV_APPLICATION_CALL))
5286  return;
5287  p->u1.str = name;
5288 }
union pval::@198 u1
char * str
Definition: pval.h:59
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalAppCallSetArglist ( pval p,
pval arglist 
)

Definition at line 5297 of file pval.c.

References pval::arglist, PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.

5298 {
5299  if (!pvalCheckType(p, "pvalAppCallSetArglist", PV_APPLICATION_CALL))
5300  return;
5301  p->u2.arglist = arglist;
5302 }
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalAppCallWalkArgs ( pval p,
pval **  args 
)

Definition at line 5314 of file pval.c.

References pval::arglist, args, pval::next, PV_APPLICATION_CALL, pvalCheckType(), and pval::u2.

5315 {
5316  if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL))
5317  return 0;
5318  if (!(*args))
5319  *args = p->u2.arglist;
5320  else {
5321  *args = (*args)->next;
5322  }
5323  return *args;
5324 }
union pval::@199 u2
static struct @350 args
struct pval * arglist
Definition: pval.h:68
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalCasePatDefAddStatement ( pval p,
pval statement 
)

Definition at line 5339 of file pval.c.

References pval::arglist, linku1(), pval::statements, and pval::u2.

5340 {
5341  if (!p->u2.arglist)
5342  p->u2.statements = statement;
5343  else
5344  linku1(p->u2.statements, statement);
5345 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
pval* pvalCasePatDefWalkStatements ( pval p,
pval **  statement 
)

Definition at line 5347 of file pval.c.

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

5348 {
5349  if (!(*statement))
5350  *statement = p->u2.statements;
5351  else {
5352  *statement = (*statement)->next;
5353  }
5354  return *statement;
5355 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
struct pval * next
Definition: pval.h:93
char* pvalCasePatGetVal ( pval p)

Definition at line 5334 of file pval.c.

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

5335 {
5336  return p->u1.str;
5337 }
union pval::@198 u1
char * str
Definition: pval.h:59
void pvalCasePatSetVal ( pval p,
char *  val 
)

Definition at line 5327 of file pval.c.

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

5328 {
5329  if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL))
5330  return;
5331  p->u1.str = val;
5332 }
union pval::@198 u1
Definition: ast_expr2.c:325
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalCatchGetExtName ( pval p)

Definition at line 5365 of file pval.c.

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

5366 {
5367  if (!pvalCheckType(p, "pvalCatchGetExtName", PV_CATCH))
5368  return 0;
5369  return p->u1.str;
5370 }
union pval::@198 u1
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
Definition: pval.h:16
pval* pvalCatchGetStatement ( pval p)

Definition at line 5379 of file pval.c.

References PV_CATCH, pvalCheckType(), pval::statements, and pval::u2.

5380 {
5381  if (!pvalCheckType(p, "pvalCatchGetStatement", PV_CATCH))
5382  return 0;
5383  return p->u2.statements;
5384 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
Definition: pval.h:16
void pvalCatchSetExtName ( pval p,
char *  name 
)

Definition at line 5358 of file pval.c.

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

5359 {
5360  if (!pvalCheckType(p, "pvalCatchSetExtName", PV_CATCH))
5361  return;
5362  p->u1.str = name;
5363 }
union pval::@198 u1
char * str
Definition: pval.h:59
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
Definition: pval.h:16
void pvalCatchSetStatement ( pval p,
pval statement 
)

Definition at line 5372 of file pval.c.

References PV_CATCH, pvalCheckType(), pval::statements, and pval::u2.

5373 {
5374  if (!pvalCheckType(p, "pvalCatchSetStatement", PV_CATCH))
5375  return;
5376  p->u2.statements = statement;
5377 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
Definition: pval.h:16
int pvalCheckType ( pval p,
char *  funcname,
pvaltype  type 
)

Definition at line 5070 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().

5071 {
5072  if (p->type != type)
5073  {
5074  ast_log(LOG_ERROR, "Func: %s the pval passed is not appropriate for this function!\n", funcname);
5075  return 0;
5076  }
5077  return 1;
5078 }
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
pvaltype type
Definition: pval.h:50
static const char type[]
Definition: chan_nbs.c:57
pval* pvalConditionalGetElseStatement ( pval p)

Definition at line 5755 of file pval.c.

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

5756 {
5757  return p->u3.else_statements;
5758 }
union pval::@200 u3
struct pval * else_statements
Definition: pval.h:78
pval* pvalConditionalGetThenStatement ( pval p)

Definition at line 5750 of file pval.c.

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

5751 {
5752  return p->u2.statements;
5753 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
void pvalConditionalSetElseStatement ( pval p,
pval statement 
)

Definition at line 5745 of file pval.c.

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

5746 {
5747  p->u3.else_statements = statement;
5748 }
union pval::@200 u3
struct pval * else_statements
Definition: pval.h:78
void pvalConditionalSetThenStatement ( pval p,
pval statement 
)

Definition at line 5740 of file pval.c.

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

5741 {
5742  p->u2.statements = statement;
5743 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
void pvalContextAddStatement ( pval p,
pval statement 
)

Definition at line 5216 of file pval.c.

References linku1(), PV_CONTEXT, pvalCheckType(), pval::statements, and pval::u2.

5217 {
5218  if (!pvalCheckType(p, "pvalContextAddStatement", PV_CONTEXT))
5219  return;
5220  if (!p->u2.statements)
5221  p->u2.statements = statement;
5222  else
5223  linku1(p->u2.statements, statement);
5224 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
int pvalContextGetAbstract ( pval p)

Definition at line 5207 of file pval.c.

References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.

5208 {
5209  if (!pvalCheckType(p, "pvalContextGetAbstract", PV_CONTEXT))
5210  return 0;
5211  return p->u3.abstract;
5212 }
int abstract
Definition: pval.h:80
union pval::@200 u3
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalContextGetName ( pval p)

Definition at line 5186 of file pval.c.

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

5187 {
5188  if (!pvalCheckType(p, "pvalContextGetName", PV_CONTEXT))
5189  return 0;
5190  return p->u1.str;
5191 }
union pval::@198 u1
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalContextSetAbstract ( pval p)

Definition at line 5193 of file pval.c.

References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.

5194 {
5195  if (!pvalCheckType(p, "pvalContextSetAbstract", PV_CONTEXT))
5196  return;
5197  p->u3.abstract = 1;
5198 }
int abstract
Definition: pval.h:80
union pval::@200 u3
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalContextSetName ( pval p,
char *  name 
)

Definition at line 5179 of file pval.c.

References name, PV_CONTEXT, pvalCheckType(), pval::str, and pval::u1.

5180 {
5181  if (!pvalCheckType(p, "pvalContextSetName", PV_CONTEXT))
5182  return;
5183  p->u1.str = name;
5184 }
union pval::@198 u1
char * str
Definition: pval.h:59
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalContextUnsetAbstract ( pval p)

Definition at line 5200 of file pval.c.

References pval::abstract, PV_CONTEXT, pvalCheckType(), and pval::u3.

5201 {
5202  if (!pvalCheckType(p, "pvalContextUnsetAbstract", PV_CONTEXT))
5203  return;
5204  p->u3.abstract = 0;
5205 }
int abstract
Definition: pval.h:80
union pval::@200 u3
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalContextWalkStatements ( pval p,
pval **  statements 
)

Definition at line 5226 of file pval.c.

References pval::next, PV_CONTEXT, pvalCheckType(), pval::statements, and pval::u2.

5227 {
5228  if (!pvalCheckType(p, "pvalContextWalkStatements", PV_CONTEXT))
5229  return 0;
5230  if (!(*statements))
5231  *statements = p->u2.statements;
5232  else {
5233  *statements = (*statements)->next;
5234  }
5235  return *statements;
5236 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalCreateNode ( pvaltype  type)

Definition at line 5081 of file pval.c.

References calloc, pval::type, and type.

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

5082 {
5083  pval *p = calloc(1,sizeof(pval)); /* why, oh why, don't I use ast_calloc? Way, way, way too messy if I do! */
5084  p->type = type; /* remember, this can be used externally or internally to asterisk */
5085  return p;
5086 }
#define calloc(a, b)
Definition: astmm.h:79
Definition: pval.h:48
pvaltype type
Definition: pval.h:50
static const char type[]
Definition: chan_nbs.c:57
void pvalESwitchesAddSwitch ( pval p,
char *  name 
)

Definition at line 5409 of file pval.c.

References linku1(), pval::list, name, PV_ESWITCHES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.

5410 {
5411  pval *s;
5412  if (!pvalCheckType(p, "pvalESwitchesAddSwitch", PV_ESWITCHES))
5413  return;
5414  s = pvalCreateNode(PV_WORD);
5415  s->u1.str = name;
5416  p->u1.list = linku1(p->u1.list, s);
5417 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5081
Definition: pval.h:8
char * str
Definition: pval.h:59
Definition: pval.h:48
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalESwitchesWalkNames ( pval p,
pval **  next_item 
)

Definition at line 5419 of file pval.c.

References pval::list, pval::next, PV_ESWITCHES, pvalCheckType(), pval::str, and pval::u1.

5420 {
5421  if (!pvalCheckType(p, "pvalESwitchesWalkNames", PV_ESWITCHES))
5422  return 0;
5423  if (!(*next_item))
5424  *next_item = p->u1.list;
5425  else {
5426  *next_item = (*next_item)->next;
5427  }
5428  return (*next_item)->u1.str;
5429 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalExtenGetHints ( pval p)

Definition at line 5841 of file pval.c.

References pval::hints, PV_EXTENSION, pvalCheckType(), and pval::u3.

5842 {
5843  if (!pvalCheckType(p, "pvalExtenGetHints", PV_EXTENSION))
5844  return 0;
5845  return p->u3.hints;
5846 }
union pval::@200 u3
char * hints
Definition: pval.h:81
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalExtenGetName ( pval p)

Definition at line 5806 of file pval.c.

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

5807 {
5808  if (!pvalCheckType(p, "pvalExtenGetName", PV_EXTENSION))
5809  return 0;
5810  return p->u1.str;
5811 }
union pval::@198 u1
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
int pvalExtenGetRegexten ( pval p)

Definition at line 5827 of file pval.c.

References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.

5828 {
5829  if (!pvalCheckType(p, "pvalExtenGetRegexten", PV_EXTENSION))
5830  return 0;
5831  return p->u4.regexten;
5832 }
int regexten
Definition: pval.h:90
union pval::@201 u4
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalExtenGetStatement ( pval p)

Definition at line 5855 of file pval.c.

References PV_EXTENSION, pvalCheckType(), pval::statements, and pval::u2.

5856 {
5857  if (!pvalCheckType(p, "pvalExtenGetStatement", PV_EXTENSION))
5858  return 0;
5859  return p->u2.statements;
5860 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalExtenSetHints ( pval p,
char *  hints 
)

Definition at line 5834 of file pval.c.

References pval::hints, hints, PV_EXTENSION, pvalCheckType(), and pval::u3.

5835 {
5836  if (!pvalCheckType(p, "pvalExtenSetHints", PV_EXTENSION))
5837  return;
5838  p->u3.hints = hints;
5839 }
static struct ao2_container * hints
Definition: pbx.c:1314
union pval::@200 u3
char * hints
Definition: pval.h:81
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalExtenSetName ( pval p,
char *  name 
)

Definition at line 5799 of file pval.c.

References name, PV_EXTENSION, pvalCheckType(), pval::str, and pval::u1.

5800 {
5801  if (!pvalCheckType(p, "pvalExtenSetName", PV_EXTENSION))
5802  return;
5803  p->u1.str = name;
5804 }
union pval::@198 u1
char * str
Definition: pval.h:59
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalExtenSetRegexten ( pval p)

Definition at line 5813 of file pval.c.

References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.

5814 {
5815  if (!pvalCheckType(p, "pvalExtenSetRegexten", PV_EXTENSION))
5816  return;
5817  p->u4.regexten = 1;
5818 }
int regexten
Definition: pval.h:90
union pval::@201 u4
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalExtenSetStatement ( pval p,
pval statement 
)

Definition at line 5848 of file pval.c.

References PV_EXTENSION, pvalCheckType(), pval::statements, and pval::u2.

5849 {
5850  if (!pvalCheckType(p, "pvalExtenSetStatement", PV_EXTENSION))
5851  return;
5852  p->u2.statements = statement;
5853 }
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalExtenUnSetRegexten ( pval p)

Definition at line 5820 of file pval.c.

References PV_EXTENSION, pvalCheckType(), pval::regexten, and pval::u4.

5821 {
5822  if (!pvalCheckType(p, "pvalExtenUnSetRegexten", PV_EXTENSION))
5823  return;
5824  p->u4.regexten = 0;
5825 }
int regexten
Definition: pval.h:90
union pval::@201 u4
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalForGetInc ( pval p)

Definition at line 5667 of file pval.c.

References pval::for_inc, PV_FOR, pvalCheckType(), and pval::u3.

5668 {
5669  if (!pvalCheckType(p, "pvalForGetInc", PV_FOR))
5670  return 0;
5671  return p->u3.for_inc;
5672 }
char * for_inc
Definition: pval.h:77
union pval::@200 u3
Definition: pval.h:24
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalForGetInit ( pval p)

Definition at line 5653 of file pval.c.

References pval::for_init, PV_FOR, pvalCheckType(), and pval::u1.

5654 {
5655  if (!pvalCheckType(p, "pvalForGetInit", PV_FOR))
5656  return 0;
5657  return p->u1.for_init;
5658 }
union pval::@198 u1
Definition: pval.h:24
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char * for_init
Definition: pval.h:62
pval* pvalForGetStatement ( pval p)

Definition at line 5674 of file pval.c.

References pval::for_statements, PV_FOR, pvalCheckType(), and pval::u4.

5675 {
5676  if (!pvalCheckType(p, "pvalForGetStatement", PV_FOR))
5677  return 0;
5678  return p->u4.for_statements;
5679 }
Definition: pval.h:24
union pval::@201 u4
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
struct pval * for_statements
Definition: pval.h:89
char* pvalForGetTest ( pval p)

Definition at line 5660 of file pval.c.

References pval::for_test, PV_FOR, pvalCheckType(), and pval::u2.

5661 {
5662  if (!pvalCheckType(p, "pvalForGetTest", PV_FOR))
5663  return 0;
5664  return p->u2.for_test;
5665 }
union pval::@199 u2
char * for_test
Definition: pval.h:71
Definition: pval.h:24
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalForSetInc ( pval p,
char *  inc 
)

Definition at line 5639 of file pval.c.

References pval::for_inc, PV_FOR, pvalCheckType(), and pval::u3.

5640 {
5641  if (!pvalCheckType(p, "pvalForSetInc", PV_FOR))
5642  return;
5643  p->u3.for_inc = inc;
5644 }
char * for_inc
Definition: pval.h:77
union pval::@200 u3
Definition: pval.h:24
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalForSetInit ( pval p,
char *  init 
)

Definition at line 5625 of file pval.c.

References pval::for_init, PV_FOR, pvalCheckType(), and pval::u1.

5626 {
5627  if (!pvalCheckType(p, "pvalForSetInit", PV_FOR))
5628  return;
5629  p->u1.for_init = init;
5630 }
union pval::@198 u1
Definition: pval.h:24
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char * for_init
Definition: pval.h:62
void pvalForSetStatement ( pval p,
pval statement 
)

Definition at line 5646 of file pval.c.

References pval::for_statements, PV_FOR, pvalCheckType(), and pval::u4.

5647 {
5648  if (!pvalCheckType(p, "pvalForSetStatement", PV_FOR))
5649  return;
5650  p->u4.for_statements = statement;
5651 }
Definition: pval.h:24
union pval::@201 u4
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
struct pval * for_statements
Definition: pval.h:89
void pvalForSetTest ( pval p,
char *  test 
)

Definition at line 5632 of file pval.c.

References pval::for_test, PV_FOR, pvalCheckType(), and pval::u2.

5633 {
5634  if (!pvalCheckType(p, "pvalForSetTest", PV_FOR))
5635  return;
5636  p->u2.for_test = test;
5637 }
union pval::@199 u2
char * for_test
Definition: pval.h:71
Definition: pval.h:24
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalGlobalsAddStatement ( pval p,
pval statement 
)

Definition at line 5878 of file pval.c.

References ast_log(), linku1(), LOG_ERROR, PV_GLOBALS, pval::statements, pval::type, and pval::u1.

5879 {
5880  if (p->type != PV_GLOBALS) {
5881  ast_log(LOG_ERROR, "pvalGlobalsAddStatement called where first arg is not a Globals!\n");
5882  } else {
5883  if (!p->u1.statements) {
5884  p->u1.statements = statement;
5885  } else {
5886  p->u1.statements = linku1(p->u1.statements,statement);
5887  }
5888  }
5889 }
union pval::@198 u1
struct pval * statements
Definition: pval.h:61
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
pvaltype type
Definition: pval.h:50
pval* pvalGlobalsWalkStatements ( pval p,
pval **  next_statement 
)

Definition at line 5891 of file pval.c.

References pval::next, PV_GLOBALS, and pvalCheckType().

5892 {
5893  if (!pvalCheckType(p, "pvalGlobalsWalkStatements", PV_GLOBALS))
5894  return 0;
5895  if (!*next_statement) {
5896  *next_statement = p;
5897  return p;
5898  } else {
5899  *next_statement = (*next_statement)->next;
5900  return (*next_statement)->next;
5901  }
5902 }
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalGotoGetTarget ( pval p,
char **  context,
char **  exten,
char **  label 
)

Definition at line 5583 of file pval.c.

References pval::list, pval::next, PV_GOTO, pvalCheckType(), pval::str, and pval::u1.

5584 {
5585  if (!pvalCheckType(p, "pvalGotoGetTarget", PV_GOTO))
5586  return;
5587  if (p->u1.list && p->u1.list->next && p->u1.list->next->next) {
5588  *context = p->u1.list->u1.str;
5589  *exten = p->u1.list->next->u1.str;
5590  *label = p->u1.list->next->next->u1.str;
5591 
5592  } else if (p->u1.list && p->u1.list->next ) {
5593  *exten = p->u1.list->u1.str;
5594  *label = p->u1.list->next->u1.str;
5595  *context = 0;
5596 
5597  } else if (p->u1.list) {
5598  *label = p->u1.list->u1.str;
5599  *context = 0;
5600  *exten = 0;
5601 
5602  } else {
5603  *context = 0;
5604  *exten = 0;
5605  *label = 0;
5606  }
5607 }
union pval::@198 u1
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
struct pval * list
Definition: pval.h:60
Definition: pval.h:22
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
void pvalGotoSetTarget ( pval p,
char *  context,
char *  exten,
char *  label 
)

Definition at line 5547 of file pval.c.

References context, ext, exten, pval::list, pval::next, PV_GOTO, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.

5548 {
5549  pval *con, *ext, *pri;
5550 
5551  if (!pvalCheckType(p, "pvalGotoSetTarget", PV_GOTO))
5552  return;
5553  if (context && strlen(context)) {
5554  con = pvalCreateNode(PV_WORD);
5555  ext = pvalCreateNode(PV_WORD);
5556  pri = pvalCreateNode(PV_WORD);
5557 
5558  con->u1.str = context;
5559  ext->u1.str = exten;
5560  pri->u1.str = label;
5561 
5562  con->next = ext;
5563  ext->next = pri;
5564  p->u1.list = con;
5565  } else if (exten && strlen(exten)) {
5566  ext = pvalCreateNode(PV_WORD);
5567  pri = pvalCreateNode(PV_WORD);
5568 
5569  ext->u1.str = exten;
5570  pri->u1.str = label;
5571 
5572  ext->next = pri;
5573  p->u1.list = ext;
5574  } else {
5575  pri = pvalCreateNode(PV_WORD);
5576 
5577  pri->u1.str = label;
5578 
5579  p->u1.list = pri;
5580  }
5581 }
union pval::@198 u1
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:109
struct pval * list
Definition: pval.h:60
Definition: pval.h:22
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5081
const char * ext
Definition: http.c:112
Definition: pval.h:8
char * str
Definition: pval.h:59
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:107
char* pvalIfGetCondition ( pval p)

Definition at line 5690 of file pval.c.

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

5691 {
5692  if (!pvalCheckType(p, "pvalIfGetCondition", PV_IFTIME))
5693  return 0;
5694  return p->u1.str;
5695 }
union pval::@198 u1
char * str
Definition: pval.h:59
Definition: pval.h:30
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalIfSetCondition ( pval p,
char *  expr 
)

Definition at line 5683 of file pval.c.

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

5684 {
5685  if (!pvalCheckType(p, "pvalIfSetCondition", PV_IF))
5686  return;
5687  p->u1.str = expr;
5688 }
union pval::@198 u1
Definition: pval.h:29
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalIfTimeGetCondition ( pval p,
char **  hour_range,
char **  dow_range,
char **  dom_range,
char **  month_range 
)

Definition at line 5716 of file pval.c.

References pval::list, pval::next, PV_IFTIME, pvalCheckType(), pval::str, and pval::u1.

5717 {
5718  if (!pvalCheckType(p, "pvalIfTimeGetCondition", PV_IFTIME))
5719  return;
5720  *hour_range = p->u1.list->u1.str;
5721  *dow_range = p->u1.list->next->u1.str;
5722  *dom_range = p->u1.list->next->next->u1.str;
5723  *month_range = p->u1.list->next->next->next->u1.str;
5724 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
char * str
Definition: pval.h:59
Definition: pval.h:30
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalIfTimeSetCondition ( pval p,
char *  hour_range,
char *  dow_range,
char *  dom_range,
char *  mon_range 
)

Definition at line 5697 of file pval.c.

References pval::list, pval::next, PV_IFTIME, PV_WORD, pvalCheckType(), pvalCreateNode(), pvalWordSetString(), and pval::u1.

5698 {
5699  pval *hr = pvalCreateNode(PV_WORD);
5700  pval *dow = pvalCreateNode(PV_WORD);
5701  pval *dom = pvalCreateNode(PV_WORD);
5702  pval *mon = pvalCreateNode(PV_WORD);
5703  if (!pvalCheckType(p, "pvalIfTimeSetCondition", PV_IFTIME))
5704  return;
5705  pvalWordSetString(hr, hour_range);
5706  pvalWordSetString(dow, dow_range);
5707  pvalWordSetString(dom, dom_range);
5708  pvalWordSetString(mon, mon_range);
5709  dom->next = mon;
5710  dow->next = dom;
5711  hr->next = dow;
5712  p->u1.list = hr;
5713 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
void pvalWordSetString(pval *p, char *str)
Definition: pval.c:5094
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5081
Definition: pval.h:8
Definition: pval.h:48
Definition: pval.h:30
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalIgnorePatGetPattern ( pval p)

Definition at line 5870 of file pval.c.

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

5871 {
5872  if (!pvalCheckType(p, "pvalIgnorePatGetPattern", PV_IGNOREPAT))
5873  return 0;
5874  return p->u1.str;
5875 }
union pval::@198 u1
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalIgnorePatSetPattern ( pval p,
char *  pat 
)

Definition at line 5863 of file pval.c.

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

5864 {
5865  if (!pvalCheckType(p, "pvalIgnorePatSetPattern", PV_IGNOREPAT))
5866  return;
5867  p->u1.str = pat;
5868 }
union pval::@198 u1
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalIncludeGetTimeConstraints ( pval p,
char **  hour_range,
char **  dom_range,
char **  dow_range,
char **  month_range 
)

Definition at line 5470 of file pval.c.

References pval::arglist, pval::next, PV_WORD, pvalCheckType(), pval::str, pval::u1, and pval::u2.

5471 {
5472  if (!pvalCheckType(p, "pvalIncludeGetTimeConstraints", PV_WORD))
5473  return;
5474  if (p->u2.arglist) {
5475  *hour_range = p->u2.arglist->u1.str;
5476  *dom_range = p->u2.arglist->next->u1.str;
5477  *dow_range = p->u2.arglist->next->next->u1.str;
5478  *month_range = p->u2.arglist->next->next->next->u1.str;
5479  } else {
5480  *hour_range = 0;
5481  *dom_range = 0;
5482  *dow_range = 0;
5483  *month_range = 0;
5484  }
5485 }
union pval::@198 u1
Definition: pval.h:8
union pval::@199 u2
char * str
Definition: pval.h:59
struct pval * arglist
Definition: pval.h:68
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalIncludesAddInclude ( pval p,
const char *  include 
)

Definition at line 5432 of file pval.c.

References linku1(), pval::list, PV_INCLUDES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.

5433 {
5434  pval *s;
5435  if (!pvalCheckType(p, "pvalIncludesAddSwitch", PV_INCLUDES))
5436  return;
5437  s = pvalCreateNode(PV_WORD);
5438  s->u1.str = (char *)include;
5439  p->u1.list = linku1(p->u1.list, s);
5440 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5081
Definition: pval.h:8
char * str
Definition: pval.h:59
Definition: pval.h:48
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalIncludesAddIncludeWithTimeConstraints ( pval p,
const char *  include,
char *  hour_range,
char *  dom_range,
char *  dow_range,
char *  month_range 
)

Definition at line 5443 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.

5444 {
5445  pval *hr = pvalCreateNode(PV_WORD);
5446  pval *dom = pvalCreateNode(PV_WORD);
5447  pval *dow = pvalCreateNode(PV_WORD);
5448  pval *mon = pvalCreateNode(PV_WORD);
5449  pval *s = pvalCreateNode(PV_WORD);
5450 
5451  if (!pvalCheckType(p, "pvalIncludeAddIncludeWithTimeConstraints", PV_INCLUDES))
5452  return;
5453 
5454  s->u1.str = (char *)include;
5455  p->u1.list = linku1(p->u1.list, s);
5456 
5457  hr->u1.str = hour_range;
5458  dom->u1.str = dom_range;
5459  dow->u1.str = dow_range;
5460  mon->u1.str = month_range;
5461 
5462  s->u2.arglist = hr;
5463 
5464  hr->next = dom;
5465  dom->next = dow;
5466  dow->next = mon;
5467  mon->next = 0;
5468 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5081
Definition: pval.h:8
union pval::@199 u2
char * str
Definition: pval.h:59
Definition: pval.h:48
struct pval * arglist
Definition: pval.h:68
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalIncludesWalk ( pval p,
pval **  next_item 
)

Definition at line 5487 of file pval.c.

References pval::list, pval::next, PV_INCLUDES, pvalCheckType(), pval::str, and pval::u1.

5488 {
5489  if (!pvalCheckType(p, "pvalIncludesWalk", PV_INCLUDES))
5490  return 0;
5491  if (!(*next_item))
5492  *next_item = p->u1.list;
5493  else {
5494  *next_item = (*next_item)->next;
5495  }
5496  return (*next_item)->u1.str;
5497 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalLabelGetName ( pval p)

Definition at line 5617 of file pval.c.

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

5618 {
5619  if (!pvalCheckType(p, "pvalLabelGetName", PV_LABEL))
5620  return 0;
5621  return p->u1.str;
5622 }
union pval::@198 u1
char * str
Definition: pval.h:59
Definition: pval.h:23
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalLabelSetName ( pval p,
char *  name 
)

Definition at line 5610 of file pval.c.

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

5611 {
5612  if (!pvalCheckType(p, "pvalLabelSetName", PV_LABEL))
5613  return;
5614  p->u1.str = name;
5615 }
union pval::@198 u1
char * str
Definition: pval.h:59
static const char name[]
Definition: pval.h:23
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalMacroAddArg ( pval p,
pval arg 
)

Definition at line 5130 of file pval.c.

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

5131 {
5132  if (!pvalCheckType(p, "pvalMacroAddArg", PV_MACRO))
5133  return;
5134  if (!p->u2.arglist)
5135  p->u2.arglist = arg;
5136  else
5137  linku1(p->u2.arglist, arg);
5138 
5139 }
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalMacroAddStatement ( pval p,
pval statement 
)

Definition at line 5153 of file pval.c.

References linku1(), pval::macro_statements, PV_MACRO, pvalCheckType(), and pval::u3.

5154 {
5155  if (!pvalCheckType(p, "pvalMacroAddStatement", PV_MACRO))
5156  return;
5157  if (!p->u3.macro_statements)
5158  p->u3.macro_statements = statement;
5159  else
5160  linku1(p->u3.macro_statements, statement);
5161 
5162 
5163 }
union pval::@200 u3
Definition: pval.h:9
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
struct pval * macro_statements
Definition: pval.h:79
void pvalMacroCallAddArg ( pval p,
pval arg 
)

Definition at line 5260 of file pval.c.

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

5261 {
5262  if (!pvalCheckType(p, "pvalMacroCallGetAddArg", PV_MACRO_CALL))
5263  return;
5264  if (!p->u2.arglist)
5265  p->u2.arglist = arg;
5266  else
5267  linku1(p->u2.arglist, arg);
5268 }
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalMacroCallGetMacroName ( pval p)

Definition at line 5246 of file pval.c.

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

5247 {
5248  if (!pvalCheckType(p, "pvalMacroCallGetMacroName", PV_MACRO_CALL))
5249  return 0;
5250  return p->u1.str;
5251 }
union pval::@198 u1
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalMacroCallSetArglist ( pval p,
pval arglist 
)

Definition at line 5253 of file pval.c.

References pval::arglist, PV_MACRO_CALL, pvalCheckType(), and pval::u2.

5254 {
5255  if (!pvalCheckType(p, "pvalMacroCallSetArglist", PV_MACRO_CALL))
5256  return;
5257  p->u2.arglist = arglist;
5258 }
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalMacroCallSetMacroName ( pval p,
char *  name 
)

Definition at line 5239 of file pval.c.

References name, PV_MACRO_CALL, pvalCheckType(), pval::str, and pval::u1.

5240 {
5241  if (!pvalCheckType(p, "pvalMacroCallSetMacroName", PV_MACRO_CALL))
5242  return;
5243  p->u1.str = name;
5244 }
union pval::@198 u1
char * str
Definition: pval.h:59
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalMacroCallWalkArgs ( pval p,
pval **  args 
)

Definition at line 5270 of file pval.c.

References pval::arglist, args, pval::next, PV_MACRO_CALL, pvalCheckType(), and pval::u2.

5271 {
5272  if (!pvalCheckType(p, "pvalMacroCallWalkArgs", PV_MACRO_CALL))
5273  return 0;
5274  if (!(*args))
5275  *args = p->u2.arglist;
5276  else {
5277  *args = (*args)->next;
5278  }
5279  return *args;
5280 }
union pval::@199 u2
static struct @350 args
struct pval * arglist
Definition: pval.h:68
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalMacroGetName ( pval p)

Definition at line 5116 of file pval.c.

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

5117 {
5118  if (!pvalCheckType(p, "pvalMacroGetName", PV_MACRO))
5119  return 0;
5120  return p->u1.str;
5121 }
union pval::@198 u1
char * str
Definition: pval.h:59
Definition: pval.h:9
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalMacroSetArglist ( pval p,
pval arglist 
)

Definition at line 5123 of file pval.c.

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

5124 {
5125  if (!pvalCheckType(p, "pvalMacroSetArglist", PV_MACRO))
5126  return;
5127  p->u2.arglist = arglist;
5128 }
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalMacroSetName ( pval p,
char *  name 
)

Definition at line 5109 of file pval.c.

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

5110 {
5111  if (!pvalCheckType(p, "pvalMacroSetName", PV_MACRO))
5112  return;
5113  p->u1.str = name;
5114 }
union pval::@198 u1
char * str
Definition: pval.h:59
Definition: pval.h:9
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalMacroWalkArgs ( pval p,
pval **  arg 
)

Definition at line 5141 of file pval.c.

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

5142 {
5143  if (!pvalCheckType(p, "pvalMacroWalkArgs", PV_MACRO))
5144  return 0;
5145  if (!(*arg))
5146  *arg = p->u2.arglist;
5147  else {
5148  *arg = (*arg)->next;
5149  }
5150  return *arg;
5151 }
union pval::@199 u2
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalMacroWalkStatements ( pval p,
pval **  next_statement 
)

Definition at line 5165 of file pval.c.

References pval::macro_statements, pval::next, PV_MACRO, pvalCheckType(), and pval::u3.

5166 {
5167  if (!pvalCheckType(p, "pvalMacroWalkStatements", PV_MACRO))
5168  return 0;
5169  if (!(*next_statement))
5170  *next_statement = p->u3.macro_statements;
5171  else {
5172  *next_statement = (*next_statement)->next;
5173  }
5174  return *next_statement;
5175 }
union pval::@200 u3
Definition: pval.h:9
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
struct pval * macro_statements
Definition: pval.h:79
pvaltype pvalObjectGetType ( pval p)

Definition at line 5088 of file pval.c.

References pval::type.

5089 {
5090  return p->type;
5091 }
pvaltype type
Definition: pval.h:50
char* pvalRandomGetCondition ( pval p)

Definition at line 5733 of file pval.c.

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

5734 {
5735  if (!pvalCheckType(p, "pvalRandomGetCondition", PV_RANDOM))
5736  return 0;
5737  return p->u1.str;
5738 }
union pval::@198 u1
char * str
Definition: pval.h:59
Definition: pval.h:31
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalRandomSetCondition ( pval p,
char *  percent 
)

Definition at line 5726 of file pval.c.

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

5727 {
5728  if (!pvalCheckType(p, "pvalRandomSetCondition", PV_RANDOM))
5729  return;
5730  p->u1.str = percent;
5731 }
union pval::@198 u1
char * str
Definition: pval.h:59
Definition: pval.h:31
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalStatementBlockAddStatement ( pval p,
pval statement 
)

Definition at line 5500 of file pval.c.

References linku1(), pval::list, PV_STATEMENTBLOCK, pvalCheckType(), and pval::u1.

5501 {
5502  if (!pvalCheckType(p, "pvalStatementBlockAddStatement", PV_STATEMENTBLOCK))
5503  return;
5504  p->u1.list = linku1(p->u1.list, statement);
5505 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalStatementBlockWalkStatements ( pval p,
pval **  next_statement 
)

Definition at line 5507 of file pval.c.

References pval::list, pval::next, PV_STATEMENTBLOCK, pvalCheckType(), and pval::u1.

5508 {
5509  if (!pvalCheckType(p, "pvalStatementBlockWalkStatements", PV_STATEMENTBLOCK))
5510  return 0;
5511  if (!(*next_statement))
5512  *next_statement = p->u1.list;
5513  else {
5514  *next_statement = (*next_statement)->next;
5515  }
5516  return *next_statement;
5517 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalSwitchAddCase ( pval p,
pval Case 
)

Definition at line 5774 of file pval.c.

References linku1(), PV_CASE, PV_SWITCH, pvalCheckType(), pval::statements, and pval::u2.

5775 {
5776  if (!pvalCheckType(p, "pvalSwitchAddCase", PV_SWITCH))
5777  return;
5778  if (!pvalCheckType(Case, "pvalSwitchAddCase", PV_CASE))
5779  return;
5780  if (!p->u2.statements)
5781  p->u2.statements = Case;
5782  else
5783  linku1(p->u2.statements, Case);
5784 }
Definition: pval.h:32
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
Definition: pval.h:13
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalSwitchesAddSwitch ( pval p,
char *  name 
)

Definition at line 5387 of file pval.c.

References linku1(), pval::list, name, PV_SWITCHES, PV_WORD, pvalCheckType(), pvalCreateNode(), pval::str, and pval::u1.

5388 {
5389  pval *s;
5390  if (!pvalCheckType(p, "pvalSwitchesAddSwitch", PV_SWITCHES))
5391  return;
5392  s = pvalCreateNode(PV_WORD);
5393  s->u1.str = name;
5394  p->u1.list = linku1(p->u1.list, s);
5395 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5081
Definition: pval.h:8
char * str
Definition: pval.h:59
Definition: pval.h:48
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalSwitchesWalkNames ( pval p,
pval **  next_item 
)

Definition at line 5397 of file pval.c.

References pval::list, pval::next, PV_SWITCHES, pvalCheckType(), pval::str, and pval::u1.

5398 {
5399  if (!pvalCheckType(p, "pvalSwitchesWalkNames", PV_SWITCHES))
5400  return 0;
5401  if (!(*next_item))
5402  *next_item = p->u1.list;
5403  else {
5404  *next_item = (*next_item)->next;
5405  }
5406  return (*next_item)->u1.str;
5407 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalSwitchGetTestexpr ( pval p)

Definition at line 5767 of file pval.c.

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

5768 {
5769  if (!pvalCheckType(p, "pvalSwitchGetTestexpr", PV_SWITCH))
5770  return 0;
5771  return p->u1.str;
5772 }
union pval::@198 u1
Definition: pval.h:32
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalSwitchSetTestexpr ( pval p,
char *  expr 
)

Definition at line 5760 of file pval.c.

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

5761 {
5762  if (!pvalCheckType(p, "pvalSwitchSetTestexpr", PV_SWITCH))
5763  return;
5764  p->u1.str = expr;
5765 }
union pval::@198 u1
Definition: pval.h:32
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
pval* pvalSwitchWalkCases ( pval p,
pval **  next_case 
)

Definition at line 5786 of file pval.c.

References pval::next, PV_SWITCH, pvalCheckType(), pval::statements, and pval::u2.

5787 {
5788  if (!pvalCheckType(p, "pvalSwitchWalkCases", PV_SWITCH))
5789  return 0;
5790  if (!(*next_case))
5791  *next_case = p->u2.statements;
5792  else {
5793  *next_case = (*next_case)->next;
5794  }
5795  return *next_case;
5796 }
Definition: pval.h:32
struct pval * statements
Definition: pval.h:61
union pval::@199 u2
struct pval * next
Definition: pval.h:93
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalTopLevAddObject ( pval p,
pval contextOrObj 
)

Definition at line 5905 of file pval.c.

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

5906 {
5907  if (p) {
5908  linku1(p,contextOrObj);
5909  } else {
5910  ast_log(LOG_ERROR, "First arg to pvalTopLevel is NULL!\n");
5911  }
5912 }
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5926
pval* pvalTopLevWalkObjects ( pval p,
pval **  next_obj 
)

Definition at line 5914 of file pval.c.

References pval::next.

5915 {
5916  if (!*next_obj) {
5917  *next_obj = p;
5918  return p;
5919  } else {
5920  *next_obj = (*next_obj)->next;
5921  return (*next_obj)->next;
5922  }
5923 }
struct pval * next
Definition: pval.h:93
char* pvalVarDecGetValue ( pval p)

Definition at line 5540 of file pval.c.

References PV_VARDEC, pvalCheckType(), pval::u2, and pval::val.

5541 {
5542  if (!pvalCheckType(p, "pvalVarDecGetValue", PV_VARDEC))
5543  return 0;
5544  return p->u2.val;
5545 }
union pval::@199 u2
char * val
Definition: pval.h:70
Definition: pval.h:21
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalVarDecGetVarname ( pval p)

Definition at line 5533 of file pval.c.

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

5534 {
5535  if (!pvalCheckType(p, "pvalVarDecGetVarname", PV_VARDEC))
5536  return 0;
5537  return p->u1.str;
5538 }
union pval::@198 u1
Definition: pval.h:21
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalVarDecSetValue ( pval p,
char *  value 
)

Definition at line 5526 of file pval.c.

References PV_VARDEC, pvalCheckType(), pval::u2, pval::val, and value.

5527 {
5528  if (!pvalCheckType(p, "pvalVarDecSetValue", PV_VARDEC))
5529  return;
5530  p->u2.val = value;
5531 }
int value
Definition: syslog.c:39
union pval::@199 u2
char * val
Definition: pval.h:70
Definition: pval.h:21
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalVarDecSetVarname ( pval p,
char *  name 
)

Definition at line 5519 of file pval.c.

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

5520 {
5521  if (!pvalCheckType(p, "pvalVarDecSetVarname", PV_VARDEC))
5522  return;
5523  p->u1.str = name;
5524 }
union pval::@198 u1
Definition: pval.h:21
char * str
Definition: pval.h:59
static const char name[]
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
char* pvalWordGetString ( pval p)

Definition at line 5101 of file pval.c.

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

5102 {
5103  if (!pvalCheckType(p, "pvalWordGetString", PV_WORD))
5104  return 0;
5105  return p->u1.str;
5106 }
union pval::@198 u1
Definition: pval.h:8
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
void pvalWordSetString ( pval p,
char *  str 
)

Definition at line 5094 of file pval.c.

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

Referenced by pvalIfTimeSetCondition().

5095 {
5096  if (!pvalCheckType(p, "pvalWordSetString", PV_WORD))
5097  return;
5098  p->u1.str = str;
5099 }
union pval::@198 u1
const char * str
Definition: app_jack.c:144
Definition: pval.h:8
char * str
Definition: pval.h:59
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5070
static void remove_spaces_before_equals ( char *  str)
static

Definition at line 3045 of file pval.c.

References str.

Referenced by ast_compile_ael2(), and gen_prios().

3046 {
3047  char *p;
3048  while( str && *str && *str != '=' )
3049  {
3050  if( *str == ' ' || *str == '\n' || *str == '\r' || *str == '\t' )
3051  {
3052  p = str;
3053  while( *p )
3054  {
3055  *p = *(p+1);
3056  p++;
3057  }
3058  }
3059  else
3060  str++;
3061  }
3062 }
const char * str
Definition: app_jack.c:144
void set_priorities ( struct ael_extension exten)

Definition at line 4225 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().

4226 {
4227  int i;
4228  struct ael_priority *pr;
4229  do {
4230  if (exten->is_switch)
4231  i = 10;
4232  else if (exten->regexten)
4233  i=2;
4234  else
4235  i=1;
4236 
4237  for (pr=exten->plist; pr; pr=pr->next) {
4238  pr->priority_num = i;
4239 
4240  if (!pr->origin || (pr->origin && pr->origin->type != PV_LABEL) ) /* Labels don't show up in the dialplan,
4241  but we want them to point to the right
4242  priority, which would be the next line
4243  after the label; */
4244  i++;
4245  }
4246 
4247  exten = exten->next_exten;
4248  } while ( exten );
4249 }
struct pval * origin
Definition: ael_structs.h:95
struct ael_priority * plist
Definition: ael_structs.h:115
struct ael_extension * next_exten
Definition: ael_structs.h:117
struct ael_priority * next
Definition: ael_structs.h:100
pvaltype type
Definition: pval.h:50
int priority_num
Definition: ael_structs.h:89
Definition: pval.h:23
void traverse_pval_item_template ( pval item,
int  depth 
)

Definition at line 402 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().

404 {
405  pval *lp;
406 
407  switch ( item->type ) {
408  case PV_WORD:
409  /* fields: item->u1.str == string associated with this (word). */
410  break;
411 
412  case PV_MACRO:
413  /* fields: item->u1.str == name of macro
414  item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
415  item->u2.arglist->u1.str == argument
416  item->u2.arglist->next == next arg
417 
418  item->u3.macro_statements == pval list of statements in macro body.
419  */
420  for (lp=item->u2.arglist; lp; lp=lp->next) {
421 
422  }
424  break;
425 
426  case PV_CONTEXT:
427  /* fields: item->u1.str == name of context
428  item->u2.statements == pval list of statements in context body
429  item->u3.abstract == int 1 if an abstract keyword were present
430  */
432  break;
433 
434  case PV_MACRO_CALL:
435  /* fields: item->u1.str == name of macro to call
436  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
437  item->u2.arglist->u1.str == argument
438  item->u2.arglist->next == next arg
439  */
440  for (lp=item->u2.arglist; lp; lp=lp->next) {
441  }
442  break;
443 
444  case PV_APPLICATION_CALL:
445  /* fields: item->u1.str == name of application to call
446  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
447  item->u2.arglist->u1.str == argument
448  item->u2.arglist->next == next arg
449  */
450  for (lp=item->u2.arglist; lp; lp=lp->next) {
451  }
452  break;
453 
454  case PV_CASE:
455  /* fields: item->u1.str == value of case
456  item->u2.statements == pval list of statements under the case
457  */
459  break;
460 
461  case PV_PATTERN:
462  /* fields: item->u1.str == value of case
463  item->u2.statements == pval list of statements under the case
464  */
466  break;
467 
468  case PV_DEFAULT:
469  /* fields:
470  item->u2.statements == pval list of statements under the case
471  */
473  break;
474 
475  case PV_CATCH:
476  /* fields: item->u1.str == name of extension to catch
477  item->u2.statements == pval list of statements in context body
478  */
480  break;
481 
482  case PV_SWITCHES:
483  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
484  */
485  traverse_pval_item_template(item->u1.list,depth+1);
486  break;
487 
488  case PV_ESWITCHES:
489  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
490  */
491  traverse_pval_item_template(item->u1.list,depth+1);
492  break;
493 
494  case PV_INCLUDES:
495  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
496  item->u2.arglist == pval list of 4 PV_WORD elements for time values
497  */
498  traverse_pval_item_template(item->u1.list,depth+1);
499  traverse_pval_item_template(item->u2.arglist,depth+1);
500  break;
501 
502  case PV_STATEMENTBLOCK:
503  /* fields: item->u1.list == pval list of statements in block, one per entry in the list
504  */
505  traverse_pval_item_template(item->u1.list,depth+1);
506  break;
507 
508  case PV_LOCALVARDEC:
509  case PV_VARDEC:
510  /* fields: item->u1.str == variable name
511  item->u2.val == variable value to assign
512  */
513  break;
514 
515  case PV_GOTO:
516  /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
517  item->u1.list->u1.str == where the data on a PV_WORD will always be.
518  */
519 
520  if ( item->u1.list->next )
521  ;
522  if ( item->u1.list->next && item->u1.list->next->next )
523  ;
524 
525  break;
526 
527  case PV_LABEL:
528  /* fields: item->u1.str == label name
529  */
530  break;
531 
532  case PV_FOR:
533  /* fields: item->u1.for_init == a string containing the initalizer
534  item->u2.for_test == a string containing the loop test
535  item->u3.for_inc == a string containing the loop increment
536 
537  item->u4.for_statements == a pval list of statements in the for ()
538  */
540  break;
541 
542  case PV_WHILE:
543  /* fields: item->u1.str == the while conditional, as supplied by user
544 
545  item->u2.statements == a pval list of statements in the while ()
546  */
548  break;
549 
550  case PV_BREAK:
551  /* fields: none
552  */
553  break;
554 
555  case PV_RETURN:
556  /* fields: none
557  */
558  break;
559 
560  case PV_CONTINUE:
561  /* fields: none
562  */
563  break;
564 
565  case PV_IFTIME:
566  /* fields: item->u1.list == there are 4 linked PV_WORDs here.
567 
568  item->u2.statements == a pval list of statements in the if ()
569  item->u3.else_statements == a pval list of statements in the else
570  (could be zero)
571  */
573  if ( item->u3.else_statements ) {
575  }
576  break;
577 
578  case PV_RANDOM:
579  /* fields: item->u1.str == the random number expression, as supplied by user
580 
581  item->u2.statements == a pval list of statements in the if ()
582  item->u3.else_statements == a pval list of statements in the else
583  (could be zero)
584  */
586  if ( item->u3.else_statements ) {
588  }
589  break;
590 
591  case PV_IF:
592  /* fields: item->u1.str == the if conditional, as supplied by user
593 
594  item->u2.statements == a pval list of statements in the if ()
595  item->u3.else_statements == a pval list of statements in the else
596  (could be zero)
597  */
599  if ( item->u3.else_statements ) {
601  }
602  break;
603 
604  case PV_SWITCH:
605  /* fields: item->u1.str == the switch expression
606 
607  item->u2.statements == a pval list of statements in the switch,
608  (will be case statements, most likely!)
609  */
611  break;
612 
613  case PV_EXTENSION:
614  /* fields: item->u1.str == the extension name, label, whatever it's called
615 
616  item->u2.statements == a pval list of statements in the extension
617  item->u3.hints == a char * hint argument
618  item->u4.regexten == an int boolean. non-zero says that regexten was specified
619  */
621  break;
622 
623  case PV_IGNOREPAT:
624  /* fields: item->u1.str == the ignorepat data
625  */
626  break;
627 
628  case PV_GLOBALS:
629  /* fields: item->u1.statements == pval list of statements, usually vardecs
630  */
632  break;
633  }
634 }
union pval::@198 u1
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
struct pval * statements
Definition: pval.h:61
Definition: pval.h:22
Definition: pval.h:8
union pval::@200 u3
union pval::@199 u2
Definition: pval.h:13
Definition: pval.h:21
Definition: pval.h:48
struct pval * else_statements
Definition: pval.h:78
Definition: pval.h:24
union pval::@201 u4
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
Definition: pval.h:31
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
Definition: pval.h:30
Definition: pval.h:23
struct pval * next
Definition: pval.h:93
Definition: pval.h:27
struct pval * for_statements
Definition: pval.h:89
void traverse_pval_item_template(pval *item, int depth)
Definition: pval.c:402
Definition: pval.h:26
Definition: pval.h:16
struct pval * macro_statements
Definition: pval.h:79
void traverse_pval_template ( pval item,
int  depth 
)

Definition at line 636 of file pval.c.

References pval::next, and traverse_pval_item_template().

638 {
639  pval *i;
640 
641  for (i=item; i; i=i->next) {
642  traverse_pval_item_template(i, depth);
643  }
644 }
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
void traverse_pval_item_template(pval *item, int depth)
Definition: pval.c:402

Variable Documentation

int control_statement_count = 0
static

Definition at line 2929 of file pval.c.

Referenced by gen_prios().

int count_labels
static

Definition at line 82 of file pval.c.

pval* current_context
static

Definition at line 75 of file pval.c.

Referenced by check_label().

pval* current_db
static

Definition at line 74 of file pval.c.

pval* current_extension
static

Definition at line 76 of file pval.c.

Referenced by check_label().

char* days[]
static

Definition at line 893 of file pval.c.

int errs
static

Definition at line 67 of file pval.c.

Referenced by ael2_semantic_check(), and pbx_load_module().

char expr_output[2096]
static

Definition at line 62 of file pval.c.

int in_abstract_context
static

Definition at line 81 of file pval.c.

int label_count
static

Definition at line 83 of file pval.c.

pval* last_matched_label
static

Definition at line 85 of file pval.c.

const char* match_context
static

Definition at line 78 of file pval.c.

const char* match_exten
static

Definition at line 79 of file pval.c.

const char* match_label
static

Definition at line 80 of file pval.c.

char* months[]
static

Definition at line 991 of file pval.c.

int notes
static

Definition at line 68 of file pval.c.

Referenced by ael2_semantic_check().

char* registrar = "pbx_ael"
static

Definition at line 72 of file pval.c.

int return_on_context_match
static

Definition at line 84 of file pval.c.

int warns
static

Definition at line 67 of file pval.c.

Referenced by ael2_semantic_check().