Asterisk - The Open Source Telephony Project  18.5.0
Macros | Functions | Variables
pval.c File Reference

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

#include "asterisk.h"
#include <sys/types.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <regex.h>
#include <sys/stat.h>
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/channel.h"
#include "asterisk/callerid.h"
#include "asterisk/pval.h"
#include "asterisk/ael_structs.h"
#include "asterisk/utils.h"
Include dependency graph for pval.c:

Go to the source code of this file.

Macros

#define ASTMM_LIBC   ASTMM_REDIRECT
 
#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

static int control_statement_count
 
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

◆ ASTMM_LIBC

#define ASTMM_LIBC   ASTMM_REDIRECT

Definition at line 30 of file pval.c.

◆ BUF_SIZE

#define BUF_SIZE   2000

Definition at line 61 of file pval.c.

Referenced by gen_prios().

Function Documentation

◆ add_extensions()

void add_extensions ( struct ael_extension exten)

Definition at line 4213 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, NULL, ael_priority::origin, pbx_substitute_variables_helper(), ael_extension::plist, PRIORITY_HINT, ael_priority::priority_num, PV_IFTIME, PV_SWITCH, registrar, pval::str, strdup, pval::type, ael_priority::type, pval::u1, and pval::u3.

Referenced by ast_compile_ael2().

4214 {
4215  struct ael_priority *pr;
4216  char *label=0;
4217  char realext[AST_MAX_EXTENSION];
4218  if (!exten) {
4219  ast_log(LOG_WARNING, "This file is Empty!\n" );
4220  return;
4221  }
4222  do {
4223  struct ael_priority *last = 0;
4224 
4225  pbx_substitute_variables_helper(NULL, exten->name, realext, sizeof(realext) - 1);
4226  if (exten->hints) {
4227  if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, PRIORITY_HINT, NULL, exten->cidmatch,
4228  exten->hints, NULL, ast_free_ptr, registrar, NULL, 0)) {
4229  ast_log(LOG_WARNING, "Unable to add step at priority 'hint' of extension '%s'\n",
4230  exten->name);
4231  }
4232  }
4233 
4234  for (pr=exten->plist; pr; pr=pr->next) {
4235  char app[2000];
4236  char appargs[2000];
4237 
4238  /* before we can add the extension, we need to prep the app/appargs;
4239  the CONTROL types need to be done after the priority numbers are calculated.
4240  */
4241  if (pr->type == AEL_LABEL) /* don't try to put labels in the dialplan! */ {
4242  last = pr;
4243  continue;
4244  }
4245 
4246  if (pr->app)
4247  strcpy(app, pr->app);
4248  else
4249  app[0] = 0;
4250  if (pr->appargs )
4251  strcpy(appargs, pr->appargs);
4252  else
4253  appargs[0] = 0;
4254  switch( pr->type ) {
4255  case AEL_APPCALL:
4256  /* easy case. Everything is all set up */
4257  break;
4258 
4259  case AEL_CONTROL1: /* FOR loop, WHILE loop, BREAK, CONTINUE, IF, IFTIME */
4260  /* simple, unconditional goto. */
4261  strcpy(app,"Goto");
4262  if (pr->goto_true->origin && pr->goto_true->origin->type == PV_SWITCH ) {
4263  snprintf(appargs,sizeof(appargs),"%s,%d", pr->goto_true->exten->name, pr->goto_true->priority_num);
4264  } else if (pr->goto_true->origin && pr->goto_true->origin->type == PV_IFTIME && pr->goto_true->origin->u3.else_statements ) {
4265  snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num+1);
4266  } else
4267  snprintf(appargs,sizeof(appargs),"%d", pr->goto_true->priority_num);
4268  break;
4269 
4270  case AEL_FOR_CONTROL: /* WHILE loop test, FOR loop test */
4271  strcpy(app,"GotoIf");
4272  snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
4273  break;
4274 
4275  case AEL_IF_CONTROL:
4276  strcpy(app,"GotoIf");
4277  if (pr->origin->u3.else_statements )
4278  snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num+1);
4279  else
4280  snprintf(appargs,sizeof(appargs),"%s?%d:%d", pr->appargs, pr->priority_num+1, pr->goto_false->priority_num);
4281  break;
4282 
4283  case AEL_RAND_CONTROL:
4284  strcpy(app,"Random");
4285  snprintf(appargs,sizeof(appargs),"%s:%d", pr->appargs, pr->goto_true->priority_num+1);
4286  break;
4287 
4288  case AEL_IFTIME_CONTROL:
4289  strcpy(app,"GotoIfTime");
4290  snprintf(appargs,sizeof(appargs),"%s?%d", pr->appargs, pr->priority_num+2);
4291  break;
4292 
4293  case AEL_RETURN:
4294  strcpy(app,"Return");
4295  appargs[0] = 0;
4296  break;
4297 
4298  default:
4299  break;
4300  }
4301  if (last && last->type == AEL_LABEL ) {
4302  label = last->origin->u1.str;
4303  }
4304  else
4305  label = 0;
4306 
4307  if (ast_add_extension2(exten->context, 0 /*no replace*/, realext, pr->priority_num, (label?label:NULL), exten->cidmatch,
4308  app, strdup(appargs), ast_free_ptr, registrar, NULL, 0)) {
4309  ast_log(LOG_WARNING, "Unable to add step at priority '%d' of extension '%s'\n", pr->priority_num,
4310  exten->name);
4311  }
4312  last = pr;
4313  }
4314  exten = exten->next_exten;
4315  } while ( exten );
4316 }
union pval::@285 u1
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:274
struct ael_priority * plist
Definition: ael_structs.h:115
#define NULL
Definition: resample.c:96
struct ael_priority * goto_false
Definition: ael_structs.h:99
char * appargs
Definition: ael_structs.h:93
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1771
struct ael_extension * next_exten
Definition: ael_structs.h:117
struct ast_context * context
Definition: ael_structs.h:113
char * cidmatch
Definition: ael_structs.h:106
#define ast_log
Definition: astobj2.c:42
struct sla_ringing_trunk * last
Definition: app_meetme.c:1092
#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:54
char * app
Definition: ael_structs.h:92
static char * registrar
Definition: pval.c:70
struct pval * else_statements
Definition: pval.h:78
union pval::@287 u3
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
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, const char *registrar_file, int registrar_line)
Add an extension to an extension context, this time with an ast_context *.
Definition: pbx.c:7299
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: ael_main.c:211
ael_priority_type type
Definition: ael_structs.h:90
#define strdup(a)
Definition: astmm.h:165
static const char app[]
Definition: app_mysql.c:62

◆ ael2_print()

void ael2_print ( char *  fname,
pval tree 
)

Definition at line 382 of file pval.c.

References ast_log, item, LOG_ERROR, print_pval_list(), traverse_pval_item_template(), and traverse_pval_template().

Referenced by main().

383 {
384  FILE *fin = fopen(fname,"w");
385  if ( !fin ) {
386  ast_log(LOG_ERROR, "Couldn't open %s for writing.\n", fname);
387  return;
388  }
389  print_pval_list(fin, tree, 0);
390  fclose(fin);
391 }
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
static void print_pval_list(FILE *fin, pval *item, int depth)
Definition: pval.c:373

◆ ael2_semantic_check()

void ael2_semantic_check ( pval item,
int *  arg_errs,
int *  arg_warns,
int *  arg_notes 
)

Definition at line 2885 of file pval.c.

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

Referenced by pbx_load_module().

2886 {
2887 
2888 #ifdef AAL_ARGCHECK
2889  int argapp_errs =0;
2890  char *rfilename;
2891 #endif
2892  struct argapp *apps=0;
2893 
2894  if (!item)
2895  return; /* don't check an empty tree */
2896 #ifdef AAL_ARGCHECK
2897  rfilename = ast_alloca(10 + strlen(ast_config_AST_VAR_DIR));
2898  sprintf(rfilename, "%s/applist", ast_config_AST_VAR_DIR);
2899 
2900  apps = argdesc_parse(rfilename, &argapp_errs); /* giveth */
2901 #endif
2902  current_db = item;
2903  errs = warns = notes = 0;
2904 
2906  check_pval(item, apps, 0);
2907 
2908 #ifdef AAL_ARGCHECK
2909  argdesc_destroy(apps); /* taketh away */
2910 #endif
2911  current_db = 0;
2912 
2913  *arg_errs = errs;
2914  *arg_warns = warns;
2915  *arg_notes = notes;
2916 }
static int errs
Definition: pval.c:65
Registered applications container.
Definition: pbx_app.c:67
static struct aco_type item
Definition: test_config.c:1463
Definition: pval.h:110
static int notes
Definition: pval.c:66
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int warns
Definition: pval.c:65
const char * ast_config_AST_VAR_DIR
Definition: options.c:157
static pval * current_db
Definition: pval.c:72
static void check_context_names(void)
Definition: pval.c:2310
void check_pval(pval *item, struct argapp *apps, int in_globals)
Definition: pval.c:2865

◆ ast_compile_ael2()

int ast_compile_ael2 ( struct ast_context **  local_contexts,
struct ast_hashtab local_table,
struct pval root 
)

Definition at line 4413 of file pval.c.

References add_extensions(), AEL_APPCALL, AEL_LABEL, ael_priority::app, ael_priority::appargs, pval::arglist, ARRAY_LEN, 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(), buf, buf2, c, ael_extension::cidmatch, ael_extension::context, context, context_used(), control_statement_count, destroy_extensions(), ael_priority::exten, 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, NULL, ael_priority::origin, pbx_builtin_setvar(), ael_extension::plist_last, priority, 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, registrar, 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().

4414 {
4415  pval *p,*p2;
4416  struct ast_context *context;
4417  char buf[2000];
4418  struct ael_extension *exten;
4419  struct ael_extension *exten_list = 0;
4420 
4421  /* Reset the counter so that we get consistent labels between reloads */
4423 
4424  for (p=root; p; p=p->next ) { /* do the globals first, so they'll be there
4425  when we try to eval them */
4426  switch (p->type) {
4427  case PV_GLOBALS:
4428  /* just VARDEC elements */
4429  for (p2=p->u1.list; p2; p2=p2->next) {
4430  char buf2[2000];
4431  snprintf(buf2,sizeof(buf2),"%s=%s", p2->u1.str, p2->u2.val);
4432  pbx_builtin_setvar(NULL, buf2);
4433  }
4434  break;
4435  default:
4436  break;
4437  }
4438  }
4439 
4440  for (p=root; p; p=p->next ) {
4441  pval *lp;
4442  int argc;
4443 
4444  switch (p->type) {
4445  case PV_MACRO:
4446 
4447  context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar);
4448 
4449  exten = new_exten();
4450  exten->context = context;
4451  exten->name = strdup("~~s~~");
4452  argc = 1;
4453  for (lp=p->u2.arglist; lp; lp=lp->next) {
4454  /* for each arg, set up a "Set" command */
4455  struct ael_priority *np2 = new_prio();
4456  np2->type = AEL_APPCALL;
4457  np2->app = strdup("MSet");
4458  snprintf(buf,sizeof(buf),"LOCAL(%s)=${ARG%d}", lp->u1.str, argc++);
4460  np2->appargs = strdup(buf);
4461  linkprio(exten, np2, NULL);
4462  }
4463 
4464  /* CONTAINS APPCALLS, CATCH, just like extensions... */
4465  if (gen_prios(exten, p->u1.str, p->u3.macro_statements, 0, context)) {
4466  return -1;
4467  }
4468  if (exten->return_needed) { /* most likely, this will go away */
4469  struct ael_priority *np2 = new_prio();
4470  np2->type = AEL_APPCALL;
4471  np2->app = strdup("NoOp");
4472  snprintf(buf,sizeof(buf),"End of Macro %s-%s",p->u1.str, exten->name);
4473  np2->appargs = strdup(buf);
4474  linkprio(exten, np2, NULL);
4475  exten-> return_target = np2;
4476  }
4477 
4478  set_priorities(exten);
4479  attach_exten(&exten_list, exten);
4480  break;
4481 
4482  case PV_GLOBALS:
4483  /* already done */
4484  break;
4485 
4486  case PV_CONTEXT:
4487  context = ast_context_find_or_create(local_contexts, local_table, p->u1.str, registrar);
4488 
4489  /* contexts contain: ignorepat, includes, switches, eswitches, extensions, */
4490  for (p2=p->u2.statements; p2; p2=p2->next) {
4491  pval *p3;
4492  char *s3;
4493 
4494  switch (p2->type) {
4495  case PV_EXTENSION:
4496  exten = new_exten();
4497  exten->name = strdup(p2->u1.str);
4498  exten->context = context;
4499 
4500  if( (s3=strchr(exten->name, '/') ) != 0 )
4501  {
4502  *s3 = 0;
4503  exten->cidmatch = s3+1;
4504  }
4505 
4506  if ( p2->u3.hints )
4507  exten->hints = strdup(p2->u3.hints);
4508  exten->regexten = p2->u4.regexten;
4509  if (gen_prios(exten, p->u1.str, p2->u2.statements, 0, context)) {
4510  return -1;
4511  }
4512  if (exten->return_needed) { /* returns don't generate a goto eoe (end of extension) any more, just a Return() app call) */
4513  struct ael_priority *np2 = new_prio();
4514  np2->type = AEL_APPCALL;
4515  np2->app = strdup("NoOp");
4516  snprintf(buf,sizeof(buf),"End of Extension %s", exten->name);
4517  np2->appargs = strdup(buf);
4518  linkprio(exten, np2, NULL);
4519  exten-> return_target = np2;
4520  }
4521  /* is the last priority in the extension a label? Then add a trailing no-op */
4522  if ( exten->plist_last && exten->plist_last->type == AEL_LABEL ) {
4523  struct ael_priority *np2 = new_prio();
4524  np2->type = AEL_APPCALL;
4525  np2->app = strdup("NoOp");
4526  snprintf(buf,sizeof(buf),"A NoOp to follow a trailing label %s", exten->plist_last->origin->u1.str);
4527  np2->appargs = strdup(buf);
4528  linkprio(exten, np2, NULL);
4529  }
4530 
4531  set_priorities(exten);
4532  attach_exten(&exten_list, exten);
4533  break;
4534 
4535  case PV_IGNOREPAT:
4536  ast_context_add_ignorepat2(context, p2->u1.str, registrar);
4537  break;
4538 
4539  case PV_INCLUDES:
4540  for (p3 = p2->u1.list; p3 ;p3=p3->next) {
4541  if ( p3->u2.arglist ) {
4542  snprintf(buf,sizeof(buf), "%s,%s,%s,%s,%s",
4543  p3->u1.str,
4544  p3->u2.arglist->u1.str,
4545  p3->u2.arglist->next->u1.str,
4546  p3->u2.arglist->next->next->u1.str,
4547  p3->u2.arglist->next->next->next->u1.str);
4548  ast_context_add_include2(context, buf, registrar);
4549  } else
4550  ast_context_add_include2(context, p3->u1.str, registrar);
4551  }
4552  break;
4553 
4554  case PV_SWITCHES:
4555  for (p3 = p2->u1.list; p3 ;p3=p3->next) {
4556  char *c = strchr(p3->u1.str, '/');
4557  if (c) {
4558  *c = '\0';
4559  c++;
4560  } else
4561  c = "";
4562 
4563  ast_context_add_switch2(context, p3->u1.str, c, 0, registrar);
4564  }
4565  break;
4566 
4567  case PV_ESWITCHES:
4568  for (p3 = p2->u1.list; p3 ;p3=p3->next) {
4569  char *c = strchr(p3->u1.str, '/');
4570  if (c) {
4571  *c = '\0';
4572  c++;
4573  } else
4574  c = "";
4575 
4576  ast_context_add_switch2(context, p3->u1.str, c, 1, registrar);
4577  }
4578  break;
4579  default:
4580  break;
4581  }
4582  }
4583 
4584  break;
4585 
4586  default:
4587  /* huh? what? */
4588  break;
4589 
4590  }
4591  }
4592 
4593  /* Create default "h" bubble context */
4594  if (ast_custom_function_find("DIALPLAN_EXISTS") && ast_custom_function_find("STACK_PEEK")) {
4595  int i;
4596  const char *h_context = "ael-builtin-h-bubble";
4597  struct ael_priority *np;
4598  struct {
4599  int priority;
4600  const char *app;
4601  const char *arg;
4602  } steps[] = {
4603  /* Start high, to avoid conflict with existing h extensions */
4604  { 1, "Goto", "9991" },
4605  /* Save the context, because after the StackPop, it disappears */
4606  { 9991, "Set", "~~parentcxt~~=${STACK_PEEK(1,c,1)}" },
4607  /* If we're not in a Gosub frame, exit */
4608  { 9992, "GotoIf", "$[\"${~~parentcxt~~}\"=\"\"]?9996" },
4609  /* Check for an "h" extension in that context */
4610  { 9993, "GotoIf", "${DIALPLAN_EXISTS(${~~parentcxt~~},h,1)}?9994:9996" },
4611  /* Pop off the stack frame to prevent an infinite loop */
4612  { 9994, "StackPop", "" },
4613  /* Finally, go there. */
4614  { 9995, "Goto", "${~~parentcxt~~},h,1" },
4615  /* Just an empty priority for jumping out early */
4616  { 9996, "NoOp", "" }
4617  };
4618  context = ast_context_find_or_create(local_contexts, local_table, h_context, registrar);
4619  if (context_used(exten_list, context)) {
4620  int found = 0;
4621  while (!found) {
4622  /* Pick a new context name that is not used. */
4623  char h_context_template[] = "/tmp/ael-builtin-h-bubble-XXXXXX";
4624  int fd = mkstemp(h_context_template);
4625  unlink(h_context_template);
4626  close(fd);
4627  context = ast_context_find_or_create(local_contexts, local_table, h_context_template + 5, registrar);
4628  found = !context_used(exten_list, context);
4629  }
4630  h_context = ast_get_context_name(context);
4631  }
4632  exten = new_exten();
4633  exten->context = context;
4634  exten->name = strdup("h");
4635 
4636  for (i = 0; i < ARRAY_LEN(steps); i++) {
4637  np = new_prio();
4638  np->type = AEL_APPCALL;
4639  np->priority_num = steps[i].priority;
4640  np->app = strdup(steps[i].app);
4641  np->appargs = strdup(steps[i].arg);
4642  linkprio(exten, np, NULL);
4643  }
4644  attach_exten(&exten_list, exten);
4645 
4646  /* Include the default "h" bubble context in each macro context */
4647  for (exten = exten_list; exten; exten = exten->next_exten) {
4648  /* All macros contain a "~~s~~" extension, and it's the first created. If
4649  * we perchance get a non-macro context, it's no big deal; the logic is
4650  * designed to exit out smoothly if not called from within a Gosub. */
4651  if (!strcmp(exten->name, "~~s~~")) {
4652  ast_context_add_include2(exten->context, h_context, registrar);
4653  }
4654  }
4655  }
4656 
4657  /* moved these from being done after a macro or extension were processed,
4658  to after all processing is done, for the sake of fixing gotos to labels inside cases... */
4659  /* I guess this would be considered 2nd pass of compiler now... */
4660  fix_gotos_in_extensions(exten_list); /* find and fix extension ref in gotos to labels that are in case statements */
4661  add_extensions(exten_list); /* actually makes calls to create priorities in ast_contexts -- feeds dialplan to asterisk */
4662  destroy_extensions(exten_list); /* all that remains is an empty husk, discard of it as is proper */
4663 
4664  return 0;
4665 }
static int context_used(struct ael_extension *exten_list, struct ast_context *context)
Definition: pval.c:4398
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
int regexten
Definition: pval.h:90
static int control_statement_count
Definition: pval.c:2922
union pval::@285 u1
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
struct pval * origin
Definition: ael_structs.h:95
const char * ast_get_context_name(struct ast_context *con)
Definition: ael_main.c:421
struct pval * list
Definition: pval.h:60
void set_priorities(struct ael_extension *exten)
Definition: pval.c:4187
static void fix_gotos_in_extensions(struct ael_extension *exten)
Definition: pval.c:4355
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
struct ael_extension * new_exten(void)
Definition: pval.c:2930
struct ael_priority * plist_last
Definition: ael_structs.h:116
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: ael_main.c:370
struct pval * statements
Definition: pval.h:61
static struct ast_threadstorage buf2
static struct test_val c
#define NULL
Definition: resample.c:96
char * appargs
Definition: ael_structs.h:93
static int priority
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:3341
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: pval.c:2936
struct ast_context * context
Definition: ael_structs.h:113
int ast_context_add_include2(struct ast_context *con, const char *include, const char *registrar)
Add a context include.
Definition: ael_main.c:359
char * cidmatch
Definition: ael_structs.h:106
char * val
Definition: pval.h:70
struct ael_extension * exten
Definition: ael_structs.h:96
char * str
Definition: pval.h:59
Definition: pval.h:48
struct ael_priority * new_prio(void)
Definition: pval.c:2924
void destroy_extensions(struct ael_extension *exten)
Definition: pval.c:2978
char * hints
Definition: pval.h:81
struct ast_custom_function * ast_custom_function_find(const char *name)
Definition: ael_main.c:173
char * app
Definition: ael_structs.h:92
static char * registrar
Definition: pval.c:70
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
union pval::@287 u3
pvaltype type
Definition: pval.h:50
static void attach_exten(struct ael_extension **list, struct ael_extension *newmem)
Definition: pval.c:4318
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...
int priority_num
Definition: ael_structs.h:89
static void remove_spaces_before_equals(char *str)
Definition: pval.c:3038
struct pval * next
Definition: pval.h:93
int ast_context_add_ignorepat2(struct ast_context *con, const char *ignorepat, const char *registrar)
Definition: ael_main.c:348
ael_priority_type type
Definition: ael_structs.h:90
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
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:6198
#define strdup(a)
Definition: astmm.h:165
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284
void add_extensions(struct ael_extension *exten)
Definition: pval.c:4213
struct pval * macro_statements
Definition: pval.h:79
union pval::@288 u4
union pval::@286 u2

◆ attach_exten()

static void attach_exten ( struct ael_extension **  list,
struct ael_extension newmem 
)
static

Definition at line 4318 of file pval.c.

References ael_extension::next_exten.

Referenced by ast_compile_ael2().

4319 {
4320  /* travel to the end of the list... */
4321  struct ael_extension *lptr;
4322  if( !*list ) {
4323  *list = newmem;
4324  return;
4325  }
4326  lptr = *list;
4327 
4328  while( lptr->next_exten ) {
4329  lptr = lptr->next_exten;
4330  }
4331  /* lptr should now pointing to the last element in the list; it has a null next_exten pointer */
4332  lptr->next_exten = newmem;
4333 }
struct ael_extension * next_exten
Definition: ael_structs.h:117

◆ check_abstract_reference()

static void check_abstract_reference ( pval abstract_context)
static

Definition at line 2329 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, pval::u2, and warns.

Referenced by check_pval_item().

2330 {
2331  pval *i,*j;
2332  /* find some context includes that reference this context */
2333 
2334 
2335  /* otherwise, print out a warning */
2336  for (i=current_db; i; i=i->next) {
2337  if (i->type == PV_CONTEXT) {
2338  for (j=i->u2. statements; j; j=j->next) {
2339  if ( j->type == PV_INCLUDES ) {
2340  struct pval *p4;
2341  for (p4=j->u1.list; p4; p4=p4->next) {
2342  /* for each context pointed to, find it, then find a context/label that matches the
2343  target here! */
2344  if ( !strcmp(p4->u1.str, abstract_context->u1.str) )
2345  return; /* found a match! */
2346  }
2347  }
2348  }
2349  }
2350  }
2351  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",
2352  abstract_context->filename, abstract_context->startline, abstract_context->endline, abstract_context->u1.str);
2353  warns++;
2354 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
pvaltype type
Definition: pval.h:50
static int warns
Definition: pval.c:65
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52
static pval * current_db
Definition: pval.c:72
union pval::@286 u2

◆ check_app_args()

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

Definition at line 2130 of file pval.c.

References ast_log, pval::endline, pval::filename, LOG_WARNING, pval::next, pval::startline, pval::str, pval::u1, and warns.

Referenced by check_pval_item().

2131 {
2132 #ifdef AAL_ARGCHECK
2133  struct argdesc *ad = app->args;
2134  pval *pa;
2135  int z;
2136 
2137  for (pa = arglist; pa; pa=pa->next) {
2138  if (!ad) {
2139  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Extra argument %s not in application call to %s !\n",
2140  arglist->filename, arglist->startline, arglist->endline, pa->u1.str, app->name);
2141  warns++;
2142  return 1;
2143  } else {
2144  /* find the first entry in the ad list that will match */
2145  do {
2146  if ( ad->dtype == ARGD_VARARG ) /* once we hit the VARARG, all bets are off. Discontinue the comparisons */
2147  break;
2148 
2149  z= option_matches( ad, pa, app);
2150  if (!z) {
2151  if ( !arglist )
2152  arglist=appcall;
2153 
2154  if (ad->type == ARGD_REQUIRED) {
2155  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2156  arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
2157  warns++;
2158  return 1;
2159  }
2160  } else if (z && ad->dtype == ARGD_OPTIONSET) {
2161  option_matches_j( ad, pa, app);
2162  }
2163  ad = ad->next;
2164  } while (ad && !z);
2165  }
2166  }
2167  /* any app nodes left, that are not optional? */
2168  for ( ; ad; ad=ad->next) {
2169  if (ad->type == ARGD_REQUIRED && ad->dtype != ARGD_VARARG) {
2170  if ( !arglist )
2171  arglist=appcall;
2172  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: Required argument %s not in application call to %s !\n",
2173  arglist->filename, arglist->startline, arglist->endline, ad->dtype==ARGD_OPTIONSET?"options":ad->name, app->name);
2174  warns++;
2175  return 1;
2176  }
2177  }
2178  return 0;
2179 #else
2180  return 0;
2181 #endif
2182 }
union pval::@285 u1
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
static int warns
Definition: pval.c:65
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52

◆ check_break()

static int check_break ( pval item)
static

Definition at line 1038 of file pval.c.

References ast_log, pval::dad, pval::endline, errs, pval::filename, item, 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().

1039 {
1040  pval *p = item;
1041 
1042  while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
1043  /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make
1044  no sense */
1045  if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN
1046  || p->type == PV_WHILE || p->type == PV_FOR ) {
1047  return 1;
1048  }
1049  p = p->dad;
1050  }
1051  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'break' not in switch, for, or while statement!\n",
1052  item->filename, item->startline, item->endline);
1053  errs++;
1054 
1055  return 0;
1056 }
static int errs
Definition: pval.c:65
struct pval * dad
Definition: pval.h:96
static struct aco_type item
Definition: test_config.c:1463
int startline
Definition: pval.h:51
#define ast_log
Definition: astobj2.c:42
Definition: pval.h:13
char * filename
Definition: pval.h:55
Definition: pval.h:48
#define LOG_ERROR
Definition: logger.h:285
Definition: pval.h:24
Definition: pval.h:9
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
int endline
Definition: pval.h:52

◆ check_context_names()

static void check_context_names ( void  )
static

Definition at line 2310 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, pval::u3, and warns.

Referenced by ael2_semantic_check().

2311 {
2312  pval *i,*j;
2313  for (i=current_db; i; i=i->next) {
2314  if (i->type == PV_CONTEXT || i->type == PV_MACRO) {
2315  for (j=i->next; j; j=j->next) {
2316  if ( j->type == PV_CONTEXT || j->type == PV_MACRO ) {
2317  if ( !strcmp(i->u1.str, j->u1.str) && !(i->u3.abstract&2) && !(j->u3.abstract&2) )
2318  {
2319  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",
2320  i->filename, i->startline, i->endline, i->u1.str, j->filename, j->startline, j->endline);
2321  warns++;
2322  }
2323  }
2324  }
2325  }
2326  }
2327 }
union pval::@285 u1
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
int abstract
Definition: pval.h:80
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
Definition: pval.h:9
union pval::@287 u3
pvaltype type
Definition: pval.h:50
static int warns
Definition: pval.c:65
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52
static pval * current_db
Definition: pval.c:72

◆ check_continue()

static int check_continue ( pval item)
static

Definition at line 1058 of file pval.c.

References ast_log, pval::dad, pval::endline, errs, pval::filename, item, LOG_ERROR, PV_CONTEXT, PV_FOR, PV_MACRO, PV_WHILE, pval::startline, and pval::type.

Referenced by check_pval_item().

1059 {
1060  pval *p = item;
1061 
1062  while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
1063  /* a break is allowed in WHILE, FOR, CASE, DEFAULT, PATTERN; otherwise, it don't make
1064  no sense */
1065  if( p->type == PV_WHILE || p->type == PV_FOR ) {
1066  return 1;
1067  }
1068  p = p->dad;
1069  }
1070  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: 'continue' not in 'for' or 'while' statement!\n",
1071  item->filename, item->startline, item->endline);
1072  errs++;
1073 
1074  return 0;
1075 }
static int errs
Definition: pval.c:65
struct pval * dad
Definition: pval.h:96
static struct aco_type item
Definition: test_config.c:1463
int startline
Definition: pval.h:51
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
Definition: pval.h:48
#define LOG_ERROR
Definition: logger.h:285
Definition: pval.h:24
Definition: pval.h:9
Definition: pval.h:25
pvaltype type
Definition: pval.h:50
int endline
Definition: pval.h:52

◆ check_day()

static void check_day ( pval DAY)
static

Definition at line 937 of file pval.c.

References ast_log, ast_strdupa, ast_strlen_zero, c, pval::endline, pval::filename, LOG_WARNING, pval::startline, pval::str, pval::u1, and warns.

Referenced by check_pval_item().

938 {
939  char *day;
940  char *c;
941  /* The following line is coincidence, really! */
942  int s, e;
943 
944  day = ast_strdupa(DAY->u1.str);
945 
946  /* Check for all days */
947  if (ast_strlen_zero(day) || !strcmp(day, "*")) {
948  return;
949  }
950  /* Get start and ending days */
951  c = strchr(day, '-');
952  if (c) {
953  *c = '\0';
954  c++;
955  }
956  /* Find the start */
957  if (sscanf(day, "%2d", &s) != 1) {
958  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start day of month (%s) must be a number!\n",
959  DAY->filename, DAY->startline, DAY->endline, day);
960  warns++;
961  }
962  else if ((s < 1) || (s > 31)) {
963  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",
964  DAY->filename, DAY->startline, DAY->endline, day);
965  warns++;
966  }
967  s--;
968  if (c) {
969  if (sscanf(c, "%2d", &e) != 1) {
970  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end day of month (%s) must be a number!\n",
971  DAY->filename, DAY->startline, DAY->endline, c);
972  warns++;
973  }
974  else if ((e < 1) || (e > 31)) {
975  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",
976  DAY->filename, DAY->startline, DAY->endline, day);
977  warns++;
978  }
979  e--;
980  } else
981  e = s;
982 }
union pval::@285 u1
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
static struct test_val c
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * str
Definition: pval.h:59
static int warns
Definition: pval.c:65
int endline
Definition: pval.h:52

◆ check_dow()

static void check_dow ( pval DOW)
static

get_dow: Get day of week

Definition at line 898 of file pval.c.

References ast_log, ast_strdupa, ast_strlen_zero, c, days, pval::endline, pval::filename, LOG_WARNING, NULL, pval::startline, pval::str, pval::u1, and warns.

Referenced by check_pval_item().

899 {
900  char *dow;
901  char *c;
902  /* The following line is coincidence, really! */
903  int s, e;
904 
905  dow = ast_strdupa(DOW->u1.str);
906 
907  /* Check for all days */
908  if (ast_strlen_zero(dow) || !strcmp(dow, "*"))
909  return;
910  /* Get start and ending days */
911  c = strchr(dow, '-');
912  if (c) {
913  *c = '\0';
914  c++;
915  } else
916  c = NULL;
917  /* Find the start */
918  s = 0;
919  while ((s < 7) && strcasecmp(dow, days[s])) s++;
920  if (s >= 7) {
921  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",
922  DOW->filename, DOW->startline, DOW->endline, dow);
923  warns++;
924  }
925  if (c) {
926  e = 0;
927  while ((e < 7) && strcasecmp(c, days[e])) e++;
928  if (e >= 7) {
929  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",
930  DOW->filename, DOW->startline, DOW->endline, c);
931  warns++;
932  }
933  } else
934  e = s;
935 }
union pval::@285 u1
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
static struct test_val c
#define NULL
Definition: resample.c:96
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * str
Definition: pval.h:59
static char * days[]
Definition: pval.c:886
static int warns
Definition: pval.c:65
int endline
Definition: pval.h:52

◆ check_expr2_input()

static void check_expr2_input ( pval expr,
char *  str 
)
static

Definition at line 801 of file pval.c.

References ast_log, pval::endline, pval::filename, LOG_WARNING, pval::startline, and warns.

Referenced by check_pval_item().

802 {
803  int spaces = strspn(str,"\t \n");
804  if ( !strncmp(str+spaces,"$[",2) ) {
805  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The expression '%s' is redundantly wrapped in '$[ ]'. \n",
806  expr->filename, expr->startline, expr->endline, str);
807  warns++;
808  }
809 }
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
const char * str
Definition: app_jack.c:147
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
static int warns
Definition: pval.c:65
int endline
Definition: pval.h:52

◆ check_goto()

static void check_goto ( pval item)
static

Definition at line 1225 of file pval.c.

References ast_log, E_FINDLABEL, E_MATCH, pval::endline, errs, 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, NULL, 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, pval::u2, and warns.

Referenced by check_pval_item(), and find_pval_goto_item().

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

◆ check_includes()

static void check_includes ( pval includes)
static

Definition at line 811 of file pval.c.

References ast_log, pval::endline, pval::filename, find_context(), pval::list, LOG_WARNING, pval::next, pval::startline, pval::str, pval::u1, and warns.

Referenced by check_pval_item().

812 {
813  struct pval *p4;
814  for (p4=includes->u1.list; p4; p4=p4->next) {
815  /* for each context pointed to, find it, then find a context/label that matches the
816  target here! */
817  char *incl_context = p4->u1.str;
818  /* find a matching context name */
819  struct pval *that_other_context = find_context(incl_context);
820  if (!that_other_context && strcmp(incl_context, "parkedcalls") != 0) {
821  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The included context '%s' cannot be found.\n\
822  (You may ignore this warning if '%s' exists in extensions.conf, or is created by another module. I cannot check for those.)\n",
823  includes->filename, includes->startline, includes->endline, incl_context, incl_context);
824  warns++;
825  }
826  }
827 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
#define LOG_WARNING
Definition: logger.h:274
struct pval * find_context(char *name)
Definition: pval.c:1953
int startline
Definition: pval.h:51
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
static int warns
Definition: pval.c:65
struct pval * next
Definition: pval.h:93
int endline
Definition: pval.h:52

◆ check_label()

static void check_label ( pval item)
static

Definition at line 1106 of file pval.c.

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

Referenced by check_pval_item().

1107 {
1108  struct pval *curr;
1109  struct pval *x;
1110  int alright = 0;
1111 
1112  /* A label outside an extension just plain does not make sense! */
1113 
1114  curr = item;
1115 
1116  while( curr ) {
1117  if( curr->type == PV_MACRO || curr->type == PV_EXTENSION ) {
1118  alright = 1;
1119  break;
1120  }
1121  curr = curr->dad;
1122  }
1123  if( !alright )
1124  {
1125  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Label %s is not within an extension or macro!\n",
1126  item->filename, item->startline, item->endline, item->u1.str);
1127  errs++;
1128  }
1129 
1130 
1131  /* basically, ensure that a label is not repeated in a context. Period.
1132  The method: well, for each label, find the first label in the context
1133  with the same name. If it's not the current label, then throw an error. */
1134 
1135 
1136  /* printf("==== check_label: ====\n"); */
1137  if( !current_extension )
1138  curr = current_context;
1139  else
1140  curr = current_extension;
1141 
1142  x = find_first_label_in_current_context((char *)item->u1.str, curr);
1143  /* 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); */
1144  if( x && x != item )
1145  {
1146  ast_log(LOG_ERROR,"Error: file %s, line %d-%d: Duplicate label %s! Previously defined at file %s, line %d.\n",
1147  item->filename, item->startline, item->endline, item->u1.str, x->filename, x->startline);
1148  errs++;
1149  }
1150  /* printf("<<<<< check_label: ====\n"); */
1151 }
union pval::@285 u1
static int errs
Definition: pval.c:65
struct pval * dad
Definition: pval.h:96
static struct aco_type item
Definition: test_config.c:1463
int startline
Definition: pval.h:51
#define ast_log
Definition: astobj2.c:42
static pval * current_extension
Definition: pval.c:74
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
#define LOG_ERROR
Definition: logger.h:285
Definition: pval.h:9
pvaltype type
Definition: pval.h:50
static pval * current_context
Definition: pval.c:73
static struct pval * find_first_label_in_current_context(char *label, pval *curr_cont)
Definition: pval.c:1839
int endline
Definition: pval.h:52

◆ check_macro_returns()

static void check_macro_returns ( pval macro)
static

Definition at line 650 of file pval.c.

References ast_log, calloc, pval::endcol, pval::endline, pval::filename, LOG_WARNING, pval::macro_statements, pval::next, NULL, PV_RETURN, pval::startcol, pval::startline, pval::str, strdup, pval::type, pval::u1, and pval::u3.

Referenced by check_pval_item().

651 {
652  pval *i;
653  if (!macro->u3.macro_statements)
654  {
655  pval *z = calloc(1, sizeof(struct pval));
656  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s is empty! I will insert a return.\n",
657  macro->filename, macro->startline, macro->endline, macro->u1.str);
658 
659  z->type = PV_RETURN;
660  z->startline = macro->startline;
661  z->endline = macro->endline;
662  z->startcol = macro->startcol;
663  z->endcol = macro->endcol;
664  z->filename = strdup(macro->filename);
665 
666  macro->u3.macro_statements = z;
667  return;
668  }
669  for (i=macro->u3.macro_statements; i; i=i->next) {
670  /* if the last statement in the list is not return, then insert a return there */
671  if (i->next == NULL) {
672  if (i->type != PV_RETURN) {
673  pval *z = calloc(1, sizeof(struct pval));
674  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The macro %s does not end with a return; I will insert one.\n",
675  macro->filename, macro->startline, macro->endline, macro->u1.str);
676 
677  z->type = PV_RETURN;
678  z->startline = macro->startline;
679  z->endline = macro->endline;
680  z->startcol = macro->startcol;
681  z->endcol = macro->endcol;
682  z->filename = strdup(macro->filename);
683 
684  i->next = z;
685  return;
686  }
687  }
688  }
689  return;
690 }
union pval::@285 u1
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
#define NULL
Definition: resample.c:96
#define calloc(a, b)
Definition: astmm.h:157
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
char * str
Definition: pval.h:59
Definition: pval.h:48
int endcol
Definition: pval.h:54
union pval::@287 u3
pvaltype type
Definition: pval.h:50
struct pval * next
Definition: pval.h:93
Definition: pval.h:27
#define strdup(a)
Definition: astmm.h:165
int endline
Definition: pval.h:52
int startcol
Definition: pval.h:53
struct pval * macro_statements
Definition: pval.h:79

◆ check_month()

static void check_month ( pval MON)
static

Definition at line 1000 of file pval.c.

References ast_log, ast_strdupa, ast_strlen_zero, c, pval::endline, pval::filename, LOG_WARNING, months, pval::startline, pval::str, pval::u1, and warns.

Referenced by check_pval_item().

1001 {
1002  char *mon;
1003  char *c;
1004  /* The following line is coincidence, really! */
1005  int s, e;
1006 
1007  mon = ast_strdupa(MON->u1.str);
1008 
1009  /* Check for all days */
1010  if (ast_strlen_zero(mon) || !strcmp(mon, "*"))
1011  return ;
1012  /* Get start and ending days */
1013  c = strchr(mon, '-');
1014  if (c) {
1015  *c = '\0';
1016  c++;
1017  }
1018  /* Find the start */
1019  s = 0;
1020  while ((s < 12) && strcasecmp(mon, months[s])) s++;
1021  if (s >= 12) {
1022  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1023  MON->filename, MON->startline, MON->endline, mon);
1024  warns++;
1025  }
1026  if (c) {
1027  e = 0;
1028  while ((e < 12) && strcasecmp(mon, months[e])) e++;
1029  if (e >= 12) {
1030  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end month (%s) must be a one of: 'jan', 'feb', ..., 'dec'!\n",
1031  MON->filename, MON->startline, MON->endline, c);
1032  warns++;
1033  }
1034  } else
1035  e = s;
1036 }
union pval::@285 u1
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
static struct test_val c
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * str
Definition: pval.h:59
static char * months[]
Definition: pval.c:984
static int warns
Definition: pval.c:65
int endline
Definition: pval.h:52

◆ check_pval()

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

Definition at line 2865 of file pval.c.

References check_pval_item(), and pval::next.

Referenced by ael2_semantic_check(), and check_pval_item().

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

◆ check_pval_item()

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

Definition at line 2357 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, errs, expr_output, pval::filename, find_context(), find_macro(), find_pval_gotos(), pval::for_inc, pval::for_init, pval::for_statements, pval::for_test, free(), in_abstract_context, item, pval::list, localized_pbx_load_module(), LOG_ERROR, LOG_WARNING, pval::macro_statements, pval::next, argapp::next, NULL, 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, pval::val, and warns.

Referenced by check_pval().

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

◆ check_switch_expr()

void check_switch_expr ( pval item,
struct argapp apps 
)

Definition at line 2184 of file pval.c.

References a, ast_log, ast_strdupa, c, calloc, pval::endcol, pval::endline, pval::filename, item, 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, pval::u2, and warns.

Referenced by check_pval_item().

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

◆ check_timerange()

static void check_timerange ( pval p)
static

Definition at line 830 of file pval.c.

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

Referenced by check_pval_item().

831 {
832  char *times;
833  char *e;
834  int s1, s2;
835  int e1, e2;
836 
837  times = ast_strdupa(p->u1.str);
838 
839  /* Star is all times */
840  if (ast_strlen_zero(times) || !strcmp(times, "*")) {
841  return;
842  }
843  /* Otherwise expect a range */
844  e = strchr(times, '-');
845  if (!e) {
846  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",
847  p->filename, p->startline, p->endline, times);
848  warns++;
849  return;
850  }
851  *e = '\0';
852  e++;
853  while (*e && !isdigit(*e))
854  e++;
855  if (!*e) {
856  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The time range format (%s) is missing the end time!\n",
857  p->filename, p->startline, p->endline, p->u1.str);
858  warns++;
859  }
860  if (sscanf(times, "%2d:%2d", &s1, &s2) != 2) {
861  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) isn't quite right!\n",
862  p->filename, p->startline, p->endline, times);
863  warns++;
864  }
865  if (sscanf(e, "%2d:%2d", &e1, &e2) != 2) {
866  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) isn't quite right!\n",
867  p->filename, p->startline, p->endline, times);
868  warns++;
869  }
870 
871  s1 = s1 * 30 + s2/2;
872  if ((s1 < 0) || (s1 >= 24*30)) {
873  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The start time (%s) is out of range!\n",
874  p->filename, p->startline, p->endline, times);
875  warns++;
876  }
877  e1 = e1 * 30 + e2/2;
878  if ((e1 < 0) || (e1 >= 24*30)) {
879  ast_log(LOG_WARNING, "Warning: file %s, line %d-%d: The end time (%s) is out of range!\n",
880  p->filename, p->startline, p->endline, e);
881  warns++;
882  }
883  return;
884 }
union pval::@285 u1
#define LOG_WARNING
Definition: logger.h:274
int startline
Definition: pval.h:51
#define ast_strlen_zero(foo)
Definition: strings.h:52
#define ast_log
Definition: astobj2.c:42
char * filename
Definition: pval.h:55
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
char * str
Definition: pval.h:59
static int warns
Definition: pval.c:65
int endline
Definition: pval.h:52

◆ contains_switch()

int contains_switch ( pval item)

Definition at line 3329 of file pval.c.

References find_switch_item(), and pval::next.

Referenced by find_switch_item(), gen_match_to_pattern(), and gen_prios().

3330 {
3331  pval *i;
3332 
3333  for (i=item; i; i=i->next) {
3334  if (find_switch_item(i))
3335  return 1;
3336  }
3337  return 0;
3338 }
Definition: pval.h:48
int find_switch_item(pval *item)
Definition: pval.c:3090
struct pval * next
Definition: pval.h:93

◆ context_used()

static int context_used ( struct ael_extension exten_list,
struct ast_context context 
)
static

Definition at line 4398 of file pval.c.

References ast_context_ignorepats_count(), ast_context_includes_count(), ast_context_switches_count(), ast_walk_context_extensions(), ael_extension::context, exten, ael_extension::next_exten, and NULL.

Referenced by ast_compile_ael2().

4399 {
4400  struct ael_extension *exten;
4401  /* Check the simple elements first */
4403  return 1;
4404  }
4405  for (exten = exten_list; exten; exten = exten->next_exten) {
4406  if (exten->context == context) {
4407  return 1;
4408  }
4409  }
4410  return 0;
4411 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
int ast_context_switches_count(const struct ast_context *con)
Definition: pbx.c:8652
#define NULL
Definition: resample.c:96
struct ael_extension * next_exten
Definition: ael_structs.h:117
struct ast_context * context
Definition: ael_structs.h:113
int ast_context_includes_count(const struct ast_context *con)
Definition: pbx.c:8697
struct ast_exten * ast_walk_context_extensions(struct ast_context *con, struct ast_exten *priority)
Definition: ael_main.c:427
int ast_context_ignorepats_count(const struct ast_context *con)
Definition: pbx.c:8740

◆ destroy_extensions()

void destroy_extensions ( struct ael_extension exten)

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

2979 {
2980  struct ael_extension *ne, *nen;
2981  for (ne=exten; ne; ne=nen) {
2982  struct ael_priority *pe, *pen;
2983 
2984  if (ne->name)
2985  free(ne->name);
2986 
2987  /* cidmatch fields are allocated with name, and freed when
2988  the name field is freed. Don't do a free for this field,
2989  unless you LIKE to see a crash! */
2990 
2991  if (ne->hints)
2992  free(ne->hints);
2993 
2994  for (pe=ne->plist; pe; pe=pen) {
2995  pen = pe->next;
2996  if (pe->app)
2997  free(pe->app);
2998  pe->app = 0;
2999  if (pe->appargs)
3000  free(pe->appargs);
3001  pe->appargs = 0;
3002  pe->origin = 0;
3003  pe->goto_true = 0;
3004  pe->goto_false = 0;
3005  free(pe);
3006  }
3007  nen = ne->next_exten;
3008  ne->next_exten = 0;
3009  ne->plist =0;
3010  ne->plist_last = 0;
3011  ne->next_exten = 0;
3012  ne->loop_break = 0;
3013  ne->loop_continue = 0;
3014  free(ne);
3015  }
3016 }
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
void free()
struct ael_priority * loop_break
Definition: ael_structs.h:119
char * app
Definition: ael_structs.h:92
struct ael_priority * loop_continue
Definition: ael_structs.h:120
struct ael_priority * next
Definition: ael_structs.h:100

◆ destroy_pval()

void destroy_pval ( pval item)

Definition at line 4940 of file pval.c.

References destroy_pval_item(), name, and pval::next.

Referenced by destroy_pval_item(), pbx_load_module(), pvalIfTimeSetCondition(), pvalIncludesAddIncludeWithTimeConstraints(), yydestruct(), and yyparse().

4941 {
4942  pval *i,*nxt;
4943 
4944  for (i=item; i; i=nxt) {
4945  nxt = i->next;
4946 
4947  destroy_pval_item(i);
4948  }
4949 }
void destroy_pval_item(pval *item)
Definition: pval.c:4672
Definition: pval.h:48
struct pval * next
Definition: pval.h:93

◆ destroy_pval_item()

void destroy_pval_item ( pval item)

Definition at line 4672 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, NULL, 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().

4673 {
4674  if (item == NULL) {
4675  ast_log(LOG_WARNING, "null item\n");
4676  return;
4677  }
4678 
4679  if (item->filename)
4680  free(item->filename);
4681 
4682  switch (item->type) {
4683  case PV_WORD:
4684  /* fields: item->u1.str == string associated with this (word). */
4685  if (item->u1.str )
4686  free(item->u1.str);
4687  if ( item->u2.arglist )
4688  destroy_pval(item->u2.arglist);
4689  break;
4690 
4691  case PV_MACRO:
4692  /* fields: item->u1.str == name of macro
4693  item->u2.arglist == pval list of PV_WORD arguments of macro, as given by user
4694  item->u2.arglist->u1.str == argument
4695  item->u2.arglist->next == next arg
4696 
4697  item->u3.macro_statements == pval list of statements in macro body.
4698  */
4699  destroy_pval(item->u2.arglist);
4700  if (item->u1.str )
4701  free(item->u1.str);
4703  break;
4704 
4705  case PV_CONTEXT:
4706  /* fields: item->u1.str == name of context
4707  item->u2.statements == pval list of statements in context body
4708  item->u3.abstract == int 1 if an abstract keyword were present
4709  */
4710  if (item->u1.str)
4711  free(item->u1.str);
4712  destroy_pval(item->u2.statements);
4713  break;
4714 
4715  case PV_MACRO_CALL:
4716  /* fields: item->u1.str == name of macro to call
4717  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
4718  item->u2.arglist->u1.str == argument
4719  item->u2.arglist->next == next arg
4720  */
4721  if (item->u1.str)
4722  free(item->u1.str);
4723  destroy_pval(item->u2.arglist);
4724  break;
4725 
4726  case PV_APPLICATION_CALL:
4727  /* fields: item->u1.str == name of application to call
4728  item->u2.arglist == pval list of PV_WORD arguments of macro call, as given by user
4729  item->u2.arglist->u1.str == argument
4730  item->u2.arglist->next == next arg
4731  */
4732  if (item->u1.str)
4733  free(item->u1.str);
4734  destroy_pval(item->u2.arglist);
4735  break;
4736 
4737  case PV_CASE:
4738  /* fields: item->u1.str == value of case
4739  item->u2.statements == pval list of statements under the case
4740  */
4741  if (item->u1.str)
4742  free(item->u1.str);
4743  destroy_pval(item->u2.statements);
4744  break;
4745 
4746  case PV_PATTERN:
4747  /* fields: item->u1.str == value of case
4748  item->u2.statements == pval list of statements under the case
4749  */
4750  if (item->u1.str)
4751  free(item->u1.str);
4752  destroy_pval(item->u2.statements);
4753  break;
4754 
4755  case PV_DEFAULT:
4756  /* fields:
4757  item->u2.statements == pval list of statements under the case
4758  */
4759  destroy_pval(item->u2.statements);
4760  break;
4761 
4762  case PV_CATCH:
4763  /* fields: item->u1.str == name of extension to catch
4764  item->u2.statements == pval list of statements in context body
4765  */
4766  if (item->u1.str)
4767  free(item->u1.str);
4768  destroy_pval(item->u2.statements);
4769  break;
4770 
4771  case PV_SWITCHES:
4772  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
4773  */
4774  destroy_pval(item->u1.list);
4775  break;
4776 
4777  case PV_ESWITCHES:
4778  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
4779  */
4780  destroy_pval(item->u1.list);
4781  break;
4782 
4783  case PV_INCLUDES:
4784  /* fields: item->u1.list == pval list of PV_WORD elements, one per entry in the list
4785  item->u2.arglist == pval list of 4 PV_WORD elements for time values
4786  */
4787  destroy_pval(item->u1.list);
4788  break;
4789 
4790  case PV_STATEMENTBLOCK:
4791  /* fields: item->u1.list == pval list of statements in block, one per entry in the list
4792  */
4793  destroy_pval(item->u1.list);
4794  break;
4795 
4796  case PV_LOCALVARDEC:
4797  case PV_VARDEC:
4798  /* fields: item->u1.str == variable name
4799  item->u2.val == variable value to assign
4800  */
4801  if (item->u1.str)
4802  free(item->u1.str);
4803  if (item->u2.val)
4804  free(item->u2.val);
4805  break;
4806 
4807  case PV_GOTO:
4808  /* fields: item->u1.list == pval list of PV_WORD target names, up to 3, in order as given by user.
4809  item->u1.list->u1.str == where the data on a PV_WORD will always be.
4810  */
4811 
4812  destroy_pval(item->u1.list);
4813  break;
4814 
4815  case PV_LABEL:
4816  /* fields: item->u1.str == label name
4817  */
4818  if (item->u1.str)
4819  free(item->u1.str);
4820  break;
4821 
4822  case PV_FOR:
4823  /* fields: item->u1.for_init == a string containing the initalizer
4824  item->u2.for_test == a string containing the loop test
4825  item->u3.for_inc == a string containing the loop increment
4826 
4827  item->u4.for_statements == a pval list of statements in the for ()
4828  */
4829  if (item->u1.for_init)
4830  free(item->u1.for_init);
4831  if (item->u2.for_test)
4832  free(item->u2.for_test);
4833  if (item->u3.for_inc)
4834  free(item->u3.for_inc);
4836  break;
4837 
4838  case PV_WHILE:
4839  /* fields: item->u1.str == the while conditional, as supplied by user
4840 
4841  item->u2.statements == a pval list of statements in the while ()
4842  */
4843  if (item->u1.str)
4844  free(item->u1.str);
4845  destroy_pval(item->u2.statements);
4846  break;
4847 
4848  case PV_BREAK:
4849  /* fields: none
4850  */
4851  break;
4852 
4853  case PV_RETURN:
4854  /* fields: none
4855  */
4856  break;
4857 
4858  case PV_CONTINUE:
4859  /* fields: none
4860  */
4861  break;
4862 
4863  case PV_IFTIME:
4864  /* fields: item->u1.list == the 4 time values, in PV_WORD structs, linked list
4865 
4866  item->u2.statements == a pval list of statements in the if ()
4867  item->u3.else_statements == a pval list of statements in the else
4868  (could be zero)
4869  */
4870  destroy_pval(item->u1.list);
4871  destroy_pval(item->u2.statements);
4872  if (item->u3.else_statements) {
4874  }
4875  break;
4876 
4877  case PV_RANDOM:
4878  /* fields: item->u1.str == the random percentage, as supplied by user
4879 
4880  item->u2.statements == a pval list of statements in the true part ()
4881  item->u3.else_statements == a pval list of statements in the else
4882  (could be zero)
4883  fall thru to If */
4884  case PV_IF:
4885  /* fields: item->u1.str == the if conditional, as supplied by user
4886 
4887  item->u2.statements == a pval list of statements in the if ()
4888  item->u3.else_statements == a pval list of statements in the else
4889  (could be zero)
4890  */
4891  if (item->u1.str)
4892  free(item->u1.str);
4893  destroy_pval(item->u2.statements);
4894  if (item->u3.else_statements) {
4896  }
4897  break;
4898 
4899  case PV_SWITCH:
4900  /* fields: item->u1.str == the switch expression
4901 
4902  item->u2.statements == a pval list of statements in the switch,
4903  (will be case statements, most likely!)
4904  */
4905  if (item->u1.str)
4906  free(item->u1.str);
4907  destroy_pval(item->u2.statements);
4908  break;
4909 
4910  case PV_EXTENSION:
4911  /* fields: item->u1.str == the extension name, label, whatever it's called
4912 
4913  item->u2.statements == a pval list of statements in the extension
4914  item->u3.hints == a char * hint argument
4915  item->u4.regexten == an int boolean. non-zero says that regexten was specified
4916  */
4917  if (item->u1.str)
4918  free(item->u1.str);
4919  if (item->u3.hints)
4920  free(item->u3.hints);
4921  destroy_pval(item->u2.statements);
4922  break;
4923 
4924  case PV_IGNOREPAT:
4925  /* fields: item->u1.str == the ignorepat data
4926  */
4927  if (item->u1.str)
4928  free(item->u1.str);
4929  break;
4930 
4931  case PV_GLOBALS:
4932  /* fields: item->u1.statements == pval list of statements, usually vardecs
4933  */
4934  destroy_pval(item->u1.statements);
4935  break;
4936  }
4937  free(item);
4938 }
char * for_inc
Definition: pval.h:77
union pval::@285 u1
struct pval * list
Definition: pval.h:60
Definition: pval.h:32
Definition: pval.h:29
#define LOG_WARNING
Definition: logger.h:274
struct pval * statements
Definition: pval.h:61
Definition: pval.h:22
#define NULL
Definition: resample.c:96
Definition: pval.h:8
char * val
Definition: pval.h:70
#define ast_log
Definition: astobj2.c:42
void free()
Definition: pval.h:13
char * filename
Definition: pval.h:55
Definition: pval.h:21
void destroy_pval(pval *item)
Definition: pval.c:4940
char * str
Definition: pval.h:59
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
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
union pval::@287 u3
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
union pval::@288 u4
union pval::@286 u2

◆ extension_matches()

static int extension_matches ( pval here,
const char *  exten,
const char *  pattern 
)
static

Definition at line 694 of file pval.c.

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

Referenced by match_pval_item().

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

◆ find_context()

struct pval* find_context ( char *  name)

Definition at line 1953 of file pval.c.

References count_labels, match_context, match_exten, match_label, match_pval(), name, and return_on_context_match.

Referenced by check_goto(), check_includes(), check_pval_item(), find_first_label_in_current_context(), find_label_in_current_context(), find_pval_goto_item(), and get_goto_target().

1954 {
1956  count_labels = 0;
1957  match_context = name;
1958  match_exten = "*"; /* don't really need to set these, shouldn't be reached */
1959  match_label = "*";
1960  return match_pval(current_db);
1961 }
static int count_labels
Definition: pval.c:80
static const char name[]
Definition: cdr_mysql.c:74
static const char * match_exten
Definition: pval.c:77
static int return_on_context_match
Definition: pval.c:82
static pval * current_db
Definition: pval.c:72
struct pval * match_pval(pval *item)
Definition: pval.c:1811
static const char * match_context
Definition: pval.c:76
static const char * match_label
Definition: pval.c:78

◆ find_first_label_in_current_context()

struct pval * find_first_label_in_current_context ( char *  label,
pval curr_cont 
)
static

Definition at line 1839 of file pval.c.

References count_labels, find_context(), pval::list, match_context, match_exten, match_label, match_pval(), pval::next, PV_INCLUDES, return_on_context_match, pval::statements, pval::str, pval::type, pval::u1, and pval::u2.

Referenced by check_label().

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

◆ find_label_in_current_context()

struct pval * find_label_in_current_context ( char *  exten,
char *  label,
pval curr_cont 
)
static

Definition at line 1879 of file pval.c.

References count_labels, exten, find_context(), pval::list, match_context, match_exten, match_label, match_pval(), pval::next, PV_INCLUDES, return_on_context_match, pval::statements, pval::str, pval::type, pval::u1, and pval::u2.

Referenced by check_goto(), and get_goto_target().

1880 {
1881  /* printf(" --- Got args %s, %s\n", exten, label); */
1882  struct pval *ret;
1883  struct pval *p3;
1884 
1885  count_labels = 0;
1887  match_context = "*";
1888  match_exten = exten;
1889  match_label = label;
1890  ret = match_pval(curr_cont->u2.statements);
1891  if (ret)
1892  return ret;
1893 
1894  /* the target of the goto could be in an included context!! Fancy that!! */
1895  /* look for includes in the current context */
1896  for (p3=curr_cont->u2.statements; p3; p3=p3->next) {
1897  if (p3->type == PV_INCLUDES) {
1898  struct pval *p4;
1899  for (p4=p3->u1.list; p4; p4=p4->next) {
1900  /* for each context pointed to, find it, then find a context/label that matches the
1901  target here! */
1902  char *incl_context = p4->u1.str;
1903  /* find a matching context name */
1904  struct pval *that_context = find_context(incl_context);
1905  if (that_context) {
1906  struct pval *x3;
1907  x3 = find_label_in_current_context(exten, label, that_context);
1908  if (x3) {
1909  return x3;
1910  }
1911  }
1912  }
1913  }
1914  }
1915  return 0;
1916 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
union pval::@285 u1
struct pval * list
Definition: pval.h:60
struct pval * statements
Definition: pval.h:61
struct pval * find_context(char *name)
Definition: pval.c:1953
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:1879
static int count_labels
Definition: pval.c:80
pvaltype type
Definition: pval.h:50
struct pval * next
Definition: pval.h:93
static const char * match_exten
Definition: pval.c:77
static int return_on_context_match
Definition: pval.c:82
struct pval * match_pval(pval *item)
Definition: pval.c:1811
static const char * match_context
Definition: pval.c:76
static const char * match_label
Definition: pval.c:78
union pval::@286 u2

◆ find_label_in_current_db()

static struct pval * find_label_in_current_db ( const char *  context,
const char *  exten,
const char *  label 
)
static

Definition at line 1929 of file pval.c.

References context, count_labels, exten, match_context, match_exten, match_label, match_pval(), and return_on_context_match.

Referenced by check_goto(), and get_goto_target().

1930 {
1931  /* printf(" --- Got args %s, %s, %s\n", context, exten, label); */
1932  count_labels = 0;
1934 
1936  match_exten = exten;
1937  match_label = label;
1938 
1939  return match_pval(current_db);
1940 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
static int count_labels
Definition: pval.c:80
static const char * match_exten
Definition: pval.c:77
static int return_on_context_match
Definition: pval.c:82
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
static pval * current_db
Definition: pval.c:72
struct pval * match_pval(pval *item)
Definition: pval.c:1811
static const char * match_context
Definition: pval.c:76
static const char * match_label
Definition: pval.c:78

◆ find_label_in_current_extension()

static struct pval * find_label_in_current_extension ( const char *  label,
pval curr_ext 
)
static

Definition at line 1918 of file pval.c.

References count_labels, match_context, match_exten, match_label, match_pval(), and return_on_context_match.

Referenced by check_goto(), and get_goto_target().

1919 {
1920  /* printf(" --- Got args %s\n", label); */
1921  count_labels = 0;
1923  match_context = "*";
1924  match_exten = "*";
1925  match_label = label;
1926  return match_pval(curr_ext);
1927 }
static int count_labels
Definition: pval.c:80
static const char * match_exten
Definition: pval.c:77
static int return_on_context_match
Definition: pval.c:82
struct pval * match_pval(pval *item)
Definition: pval.c:1811
static const char * match_context
Definition: pval.c:76
static const char * match_label
Definition: pval.c:78

◆ find_macro()

struct pval* find_macro ( char *  name)

Definition at line 1943 of file pval.c.

References count_labels, match_context, match_exten, match_label, match_pval(), name, and return_on_context_match.

Referenced by check_pval_item().

1944 {
1946  count_labels = 0;
1947  match_context = name;
1948  match_exten = "*"; /* don't really need to set these, shouldn't be reached */
1949  match_label = "*";
1950  return match_pval(current_db);
1951 }
static int count_labels
Definition: pval.c:80
static const char name[]
Definition: cdr_mysql.c:74
static const char * match_exten
Definition: pval.c:77
static int return_on_context_match
Definition: pval.c:82
static pval * current_db
Definition: pval.c:72
struct pval * match_pval(pval *item)
Definition: pval.c:1811
static const char * match_context
Definition: pval.c:76
static const char * match_label
Definition: pval.c:78

◆ find_pval_goto_item()

static void find_pval_goto_item ( pval item,
int  lev 
)
static

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

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

◆ find_pval_gotos()

static void find_pval_gotos ( pval item,
int  lev 
)
static

Definition at line 1550 of file pval.c.

References find_pval_goto_item(), and pval::next.

Referenced by check_pval_item(), and find_pval_goto_item().

1551 {
1552  pval *i;
1553 
1554  for (i=item; i; i=i->next) {
1555  /* printf("About to call pval_goto_item, itemcount=%d, itemtype=%d\n", item_count, i->type); */
1556  find_pval_goto_item(i, lev);
1557  }
1558 }
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
static void find_pval_goto_item(pval *item, int lev)
Definition: pval.c:1379

◆ find_switch_item()

int find_switch_item ( pval item)

Definition at line 3090 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(), and gen_match_to_pattern().

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

◆ fix_gotos_in_extensions()

static void fix_gotos_in_extensions ( struct ael_extension exten)
static

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

4356 {
4357  struct ael_extension *e;
4358  for(e=exten;e;e=e->next_exten) {
4359 
4360  struct ael_priority *p;
4361  for(p=e->plist;p;p=p->next) {
4362 
4363  if( p->origin && p->origin->type == PV_GOTO && p->origin->u3.goto_target_in_case ) {
4364 
4365  /* fix the extension of the goto target to the actual extension in the post-compiled dialplan */
4366 
4367  pval *target = p->origin->u2.goto_target;
4368  struct ael_extension *z = target->u3.compiled_label;
4369  pval *pv2 = p->origin;
4370  char buf1[500];
4371  char *apparg_save = p->appargs;
4372 
4373  p->appargs = 0;
4374  if (!pv2->u1.list->next) /* just one -- it won't hurt to repeat the extension */ {
4375  snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->u1.str);
4376  p->appargs = strdup(buf1);
4377 
4378  } else if (pv2->u1.list->next && !pv2->u1.list->next->next) /* two */ {
4379  snprintf(buf1,sizeof(buf1),"%s,%s", z->name, pv2->u1.list->next->u1.str);
4380  p->appargs = strdup(buf1);
4381  } else if (pv2->u1.list->next && pv2->u1.list->next->next) {
4382  snprintf(buf1,sizeof(buf1),"%s,%s,%s", pv2->u1.list->u1.str,
4383  z->name,
4384  pv2->u1.list->next->next->u1.str);
4385  p->appargs = strdup(buf1);
4386  }
4387  else
4388  printf("WHAT? The goto doesn't fall into one of three cases for GOTO????\n");
4389 
4390  if( apparg_save ) {
4391  free(apparg_save);
4392  }
4393  }
4394  }
4395  }
4396 }
union pval::@285 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
void free()
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
static struct ast_threadstorage buf1
union pval::@287 u3
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:165
union pval::@286 u2

◆ gen_match_to_pattern()

static void gen_match_to_pattern ( char *  pattern,
char *  result 
)
static

Definition at line 3061 of file pval.c.

References contains_switch(), find_switch_item(), and result.

Referenced by gen_prios().

3062 {
3063  /* the result will be a string that will be matched by pattern */
3064  char *p=pattern, *t=result;
3065  while (*p) {
3066  if (*p == 'x' || *p == 'n' || *p == 'z' || *p == 'X' || *p == 'N' || *p == 'Z')
3067  *t++ = '9';
3068  else if (*p == '[') {
3069  char *z = p+1;
3070  while (*z != ']')
3071  z++;
3072  if (*(z+1)== ']')
3073  z++;
3074  *t++=*(p+1); /* use the first char in the set */
3075  p = z;
3076  } else {
3077  *t++ = *p;
3078  }
3079  p++;
3080  }
3081  *t++ = 0; /* cap it off */
3082 }
static PGresult * result
Definition: cel_pgsql.c:88

◆ gen_prios()

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 3341 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, buf, 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, NULL, 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, RAII_VAR, 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().

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

◆ get_contxt()

static pval * get_contxt ( pval p)
static

Definition at line 4345 of file pval.c.

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

Referenced by check_goto(), and get_goto_target().

4346 {
4347  while( p && p->type != PV_CONTEXT && p->type != PV_MACRO ) {
4348 
4349  p = p->dad;
4350  }
4351 
4352  return p;
4353 }
struct pval * dad
Definition: pval.h:96
Definition: pval.h:9
pvaltype type
Definition: pval.h:50

◆ get_extension_or_contxt()

static pval * get_extension_or_contxt ( pval p)
static

Definition at line 4335 of file pval.c.

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

Referenced by check_goto(), and get_goto_target().

4336 {
4337  while( p && p->type != PV_EXTENSION && p->type != PV_CONTEXT && p->type != PV_MACRO ) {
4338 
4339  p = p->dad;
4340  }
4341 
4342  return p;
4343 }
struct pval * dad
Definition: pval.h:96
Definition: pval.h:9
pvaltype type
Definition: pval.h:50

◆ get_goto_target()

static pval * get_goto_target ( pval item)
static

Definition at line 1153 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, NULL, PV_INCLUDES, pval::statements, pval::str, pval::type, pval::u1, and pval::u2.

Referenced by gen_prios().

1154 {
1155  /* just one item-- the label should be in the current extension */
1156  pval *curr_ext = get_extension_or_contxt(item); /* containing exten, or macro */
1157  pval *curr_cont;
1158 
1159  if (!item->u1.list) {
1160  return NULL;
1161  }
1162 
1163  if (!item->u1.list->next && !strstr((item->u1.list)->u1.str,"${")) {
1164  struct pval *x = find_label_in_current_extension((char*)((item->u1.list)->u1.str), curr_ext);
1165  return x;
1166  }
1167 
1168  curr_cont = get_contxt(item);
1169 
1170  /* TWO items */
1171  if (item->u1.list->next && !item->u1.list->next->next) {
1172  if (!strstr((item->u1.list)->u1.str,"${")
1173  && !strstr(item->u1.list->next->u1.str,"${") ) /* Don't try to match variables */ {
1174  struct pval *x = find_label_in_current_context((char *)item->u1.list->u1.str, (char *)item->u1.list->next->u1.str, curr_cont);
1175  return x;
1176  }
1177  }
1178 
1179  /* All 3 items! */
1180  if (item->u1.list->next && item->u1.list->next->next) {
1181  /* all three */
1182  pval *first = item->u1.list;
1183  pval *second = item->u1.list->next;
1184  pval *third = item->u1.list->next->next;
1185 
1186  if (!strstr((item->u1.list)->u1.str,"${")
1187  && !strstr(item->u1.list->next->u1.str,"${")
1188  && !strstr(item->u1.list->next->next->u1.str,"${")) /* Don't try to match variables */ {
1189  struct pval *x = find_label_in_current_db((char*)first->u1.str, (char*)second->u1.str, (char*)third->u1.str);
1190  if (!x) {
1191 
1192  struct pval *p3;
1193  struct pval *that_context = find_context(item->u1.list->u1.str);
1194 
1195  /* the target of the goto could be in an included context!! Fancy that!! */
1196  /* look for includes in the current context */
1197  if (that_context) {
1198  for (p3=that_context->u2.statements; p3; p3=p3->next) {
1199  if (p3->type == PV_INCLUDES) {
1200  struct pval *p4;
1201  for (p4=p3->u1.list; p4; p4=p4->next) {
1202  /* for each context pointed to, find it, then find a context/label that matches the
1203  target here! */
1204  char *incl_context = p4->u1.str;
1205  /* find a matching context name */
1206  struct pval *that_other_context = find_context(incl_context);
1207  if (that_other_context) {
1208  struct pval *x3;
1209  x3 = find_label_in_current_context((char *)item->u1.list->next->u1.str, (char *)item->u1.list->next->next->u1.str, that_other_context);
1210  if (x3) {
1211  return x3;
1212  }
1213  }
1214  }
1215  }
1216  }
1217  }
1218  }
1219  return x;
1220  }
1221  }
1222  return NULL;
1223 }
union pval::@285 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:1918
struct pval * statements
Definition: pval.h:61
struct pval * find_context(char *name)
Definition: pval.c:1953
#define NULL
Definition: resample.c:96
static pval * get_contxt(pval *p)
Definition: pval.c:4345
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:1879
struct sla_ringing_trunk * first
Definition: app_meetme.c:1092
static struct pval * find_label_in_current_db(const char *context, const char *exten, const char *label)
Definition: pval.c:1929
pvaltype type
Definition: pval.h:50
struct pval * next
Definition: pval.h:93
union pval::@286 u2
static pval * get_extension_or_contxt(pval *p)
Definition: pval.c:4335

◆ in_context()

static struct pval* in_context ( pval item)
static

Definition at line 1090 of file pval.c.

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

Referenced by check_goto().

1091 {
1092  struct pval *curr;
1093  curr = item;
1094  while( curr ) {
1095  if( curr->type == PV_MACRO || curr->type == PV_CONTEXT ) {
1096  return curr;
1097  }
1098  curr = curr->dad;
1099  }
1100  return 0;
1101 }
struct pval * dad
Definition: pval.h:96
static struct aco_type item
Definition: test_config.c:1463
Definition: pval.h:48
Definition: pval.h:9
pvaltype type
Definition: pval.h:50

◆ in_macro()

static struct pval* in_macro ( pval item)
static

Definition at line 1077 of file pval.c.

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

Referenced by check_goto().

1078 {
1079  struct pval *curr;
1080  curr = item;
1081  while( curr ) {
1082  if( curr->type == PV_MACRO ) {
1083  return curr;
1084  }
1085  curr = curr->dad;
1086  }
1087  return 0;
1088 }
struct pval * dad
Definition: pval.h:96
static struct aco_type item
Definition: test_config.c:1463
Definition: pval.h:48
Definition: pval.h:9
pvaltype type
Definition: pval.h:50

◆ is_empty()

int is_empty ( char *  arg)

Definition at line 1981 of file pval.c.

References app, ast_log, ast_strdupa, pval::endline, errs, pval::filename, is_float(), is_int(), LOG_ERROR, LOG_WARNING, argapp::next, pval::startline, pval::str, pval::u1, and warns.

1982 {
1983  if (!arg)
1984  return 1;
1985  if (*arg == 0)
1986  return 1;
1987  while (*arg) {
1988  if (*arg != ' ' && *arg != '\t')
1989  return 0;
1990  arg++;
1991  }
1992  return 1;
1993 }

◆ is_float()

int is_float ( char *  arg)

Definition at line 1963 of file pval.c.

Referenced by is_empty().

1964 {
1965  char *s;
1966  for (s=arg; *s; s++) {
1967  if (*s != '.' && (*s < '0' || *s > '9'))
1968  return 0;
1969  }
1970  return 1;
1971 }

◆ is_int()

int is_int ( char *  arg)

Definition at line 1972 of file pval.c.

Referenced by is_empty().

1973 {
1974  char *s;
1975  for (s=arg; *s; s++) {
1976  if (*s < '0' || *s > '9')
1977  return 0;
1978  }
1979  return 1;
1980 }

◆ label_inside_case()

static int label_inside_case ( pval label)
static

Definition at line 3018 of file pval.c.

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

Referenced by gen_prios().

3019 {
3020  pval *p = label;
3021 
3022  while( p && p->type != PV_MACRO && p->type != PV_CONTEXT ) /* early cutout, sort of */ {
3023  if( p->type == PV_CASE || p->type == PV_DEFAULT || p->type == PV_PATTERN ) {
3024  return 1;
3025  }
3026 
3027  p = p->dad;
3028  }
3029  return 0;
3030 }
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

◆ linkexten()

static void linkexten ( struct ael_extension exten,
struct ael_extension add 
)
static

Definition at line 3032 of file pval.c.

References ael_extension::next_exten.

Referenced by gen_prios().

3033 {
3034  add->next_exten = exten->next_exten; /* this will reverse the order. Big deal. */
3035  exten->next_exten = add;
3036 }
struct ael_extension * next_exten
Definition: ael_structs.h:117

◆ linkprio()

void linkprio ( struct ael_extension exten,
struct ael_priority prio,
struct ael_extension mother_exten 
)

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

2937 {
2938  char *p1, *p2;
2939 
2940  if (!exten->plist) {
2941  exten->plist = prio;
2942  exten->plist_last = prio;
2943  } else {
2944  exten->plist_last->next = prio;
2945  exten->plist_last = prio;
2946  }
2947  if( !prio->exten )
2948  prio->exten = exten; /* don't override the switch value */
2949  /* The following code will cause all priorities within an extension
2950  to have ${EXTEN} or ${EXTEN: replaced with ~~EXTEN~~, which is
2951  set just before the first switch in an exten. The switches
2952  will muck up the original ${EXTEN} value, so we save it away
2953  and the user accesses this copy instead. */
2954  if (prio->appargs && ((mother_exten && mother_exten->has_switch) || exten->has_switch) ) {
2955  while ((p1 = strstr(prio->appargs, "${EXTEN}"))) {
2956  p2 = malloc(strlen(prio->appargs)+5);
2957  *p1 = 0;
2958  strcpy(p2, prio->appargs);
2959  strcat(p2, "${~~EXTEN~~}");
2960  if (*(p1+8))
2961  strcat(p2, p1+8);
2962  free(prio->appargs);
2963  prio->appargs = p2;
2964  }
2965  while ((p1 = strstr(prio->appargs, "${EXTEN:"))) {
2966  p2 = malloc(strlen(prio->appargs)+5);
2967  *p1 = 0;
2968  strcpy(p2, prio->appargs);
2969  strcat(p2, "${~~EXTEN~~:");
2970  if (*(p1+8))
2971  strcat(p2, p1+8);
2972  free(prio->appargs);
2973  prio->appargs = p2;
2974  }
2975  }
2976 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
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
char * malloc()
void free()
struct ael_extension * exten
Definition: ael_structs.h:96
struct ael_priority * next
Definition: ael_structs.h:100

◆ linku1()

pval* linku1 ( pval head,
pval tail 
)

Definition at line 5922 of file pval.c.

References pval::next, pval::prev, and pval::u1_last.

Referenced by pvalAppCallAddArg(), pvalCasePatDefAddStatement(), pvalContextAddStatement(), pvalESwitchesAddSwitch(), pvalGlobalsAddStatement(), pvalIncludesAddInclude(), pvalIncludesAddIncludeWithTimeConstraints(), pvalMacroAddArg(), pvalMacroAddStatement(), pvalMacroCallAddArg(), pvalStatementBlockAddStatement(), pvalSwitchAddCase(), pvalSwitchesAddSwitch(), pvalTopLevAddObject(), and yyparse().

5923 {
5924  if (!head)
5925  return tail;
5926  if (tail) {
5927  if (!head->next) {
5928  head->next = tail;
5929  } else {
5930  head->u1_last->next = tail;
5931  }
5932  head->u1_last = tail;
5933  tail->prev = head; /* the dad link only points to containers */
5934  }
5935  return head;
5936 }
struct pval * u1_last
Definition: pval.h:64
struct pval * prev
Definition: pval.h:97
struct pval * next
Definition: pval.h:93

◆ localized_pbx_load_module()

int localized_pbx_load_module ( void  )

Definition at line 5647 of file extconf.c.

References ast_context_verify_includes(), ast_merge_contexts_and_delete(), ast_walk_contexts(), ast_context::name, NULL, and pbx_load_config().

Referenced by check_goto(), check_pval_item(), and localized_context_verify_includes().

5648 {
5649  struct ast_context *con;
5650 
5652  return -1 /* AST_MODULE_LOAD_DECLINE*/;
5653 
5654  /* pbx_load_users(); */ /* does this affect the dialplan? */
5655 
5657 
5658  for (con = NULL; (con = ast_walk_contexts(con));)
5660 
5661  printf("=== Loading extensions.conf ===\n");
5662  con = 0;
5663  while ((con = ast_walk_contexts(con)) ) {
5664  printf("Context: %s\n", con->name);
5665  }
5666  printf("=========\n");
5667 
5668  return 0;
5669 }
static char * global_registrar
Definition: extconf.c:2122
#define NULL
Definition: resample.c:96
static struct ast_context * ast_walk_contexts(struct ast_context *con)
Definition: extconf.c:4026
static char * config_filename
Definition: extconf.c:2121
static struct ast_context * local_contexts
Definition: extconf.c:3598
char name[0]
Definition: pbx.c:297
static int ast_context_verify_includes(struct ast_context *con)
Definition: extconf.c:5623
static void ast_merge_contexts_and_delete(struct ast_context **extcontexts, const char *registrar)
Definition: extconf.c:5573
ast_context: An extension context - must remain in sync with fake_context
Definition: pbx.c:284
static int pbx_load_config(const char *config_file)
Definition: extconf.c:5339

◆ match_pval()

struct pval * match_pval ( pval item)

Definition at line 1811 of file pval.c.

References count_labels, count_labels_in_current_context(), label_count, match_pval_item(), pval::next, return_on_context_match, pval::statements, and pval::u2.

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

1812 {
1813  pval *i;
1814 
1815  for (i=item; i; i=i->next) {
1816  pval *x;
1817  /* printf(" -- match pval: item %d\n", i->type); */
1818 
1819  if ((x = match_pval_item(i))) {
1820  /* printf("match_pval: returning x=%x\n", (int)x); */
1821  return x; /* cut the search short */
1822  }
1823  }
1824  return 0;
1825 }
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
static struct pval * match_pval_item(pval *item)
Definition: pval.c:1563

◆ match_pval_item()

static struct pval* match_pval_item ( pval item)
static

Definition at line 1563 of file pval.c.

References count_labels, pval::else_statements, extension_matches(), pval::for_statements, item, label_count, pval::list, pval::macro_statements, match_context, match_exten, match_label, 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, return_on_context_match, pval::statements, pval::str, pval::type, pval::u1, pval::u2, pval::u3, and pval::u4.

Referenced by match_pval().

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

◆ new_exten()

struct ael_extension* new_exten ( void  )

Definition at line 2930 of file pval.c.

References calloc.

Referenced by ast_compile_ael2(), and gen_prios().

2931 {
2932  struct ael_extension *x = (struct ael_extension *)calloc(sizeof(struct ael_extension),1);
2933  return x;
2934 }
#define calloc(a, b)
Definition: astmm.h:157

◆ new_prio()

struct ael_priority* new_prio ( void  )

Definition at line 2924 of file pval.c.

References calloc.

Referenced by ast_compile_ael2(), and gen_prios().

2925 {
2926  struct ael_priority *x = (struct ael_priority *)calloc(sizeof(struct ael_priority),1);
2927  return x;
2928 }
#define calloc(a, b)
Definition: astmm.h:157

◆ print_pval()

static void print_pval ( FILE *  fin,
pval item,
int  depth 
)
static

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

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

◆ print_pval_list()

static void print_pval_list ( FILE *  fin,
pval item,
int  depth 
)
static

Definition at line 373 of file pval.c.

References pval::next, and print_pval().

Referenced by ael2_print(), and print_pval().

374 {
375  pval *i;
376 
377  for (i=item; i; i=i->next) {
378  print_pval(fin, i, depth);
379  }
380 }
static void print_pval(FILE *fin, pval *item, int depth)
Definition: pval.c:115
Definition: pval.h:48
struct pval * next
Definition: pval.h:93

◆ pvalAppCallAddArg()

void pvalAppCallAddArg ( pval p,
pval arg 
)

Definition at line 5268 of file pval.c.

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

Referenced by main().

5269 {
5270  if (!pvalCheckType(p, "pvalAppCallAddArg", PV_APPLICATION_CALL))
5271  return;
5272  if (!p->u2.arglist)
5273  p->u2.arglist = arg;
5274  else
5275  linku1(p->u2.arglist, arg);
5276 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
struct pval * arglist
Definition: pval.h:68
union pval::@286 u2

◆ pvalAppCallGetAppName()

char* pvalAppCallGetAppName ( pval p)

Definition at line 5254 of file pval.c.

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

5255 {
5256  if (!pvalCheckType(p, "pvalAppCallGetAppName", PV_APPLICATION_CALL))
5257  return 0;
5258  return p->u1.str;
5259 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalAppCallSetAppName()

void pvalAppCallSetAppName ( pval p,
char *  name 
)

Definition at line 5247 of file pval.c.

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

Referenced by main().

5248 {
5249  if (!pvalCheckType(p, "pvalAppCallSetAppName", PV_APPLICATION_CALL))
5250  return;
5251  p->u1.str = name;
5252 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
static const char name[]
Definition: cdr_mysql.c:74

◆ pvalAppCallSetArglist()

void pvalAppCallSetArglist ( pval p,
pval arglist 
)

Definition at line 5261 of file pval.c.

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

5262 {
5263  if (!pvalCheckType(p, "pvalAppCallSetArglist", PV_APPLICATION_CALL))
5264  return;
5265  p->u2.arglist = arglist;
5266 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * arglist
Definition: pval.h:68
union pval::@286 u2

◆ pvalAppCallWalkArgs()

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

Definition at line 5278 of file pval.c.

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

5279 {
5280  if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL))
5281  return 0;
5282  if (!(*args))
5283  *args = p->u2.arglist;
5284  else {
5285  *args = (*args)->next;
5286  }
5287  return *args;
5288 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
const char * args
struct pval * arglist
Definition: pval.h:68
struct pval * next
Definition: pval.h:93
union pval::@286 u2

◆ pvalCasePatDefAddStatement()

void pvalCasePatDefAddStatement ( pval p,
pval statement 
)

Definition at line 5303 of file pval.c.

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

5304 {
5305  if (!p->u2.arglist)
5306  p->u2.statements = statement;
5307  else
5308  linku1(p->u2.statements, statement);
5309 }
struct pval * statements
Definition: pval.h:61
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
struct pval * arglist
Definition: pval.h:68
union pval::@286 u2

◆ pvalCasePatDefWalkStatements()

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

Definition at line 5311 of file pval.c.

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

5312 {
5313  if (!(*statement))
5314  *statement = p->u2.statements;
5315  else {
5316  *statement = (*statement)->next;
5317  }
5318  return *statement;
5319 }
struct pval * statements
Definition: pval.h:61
struct pval * next
Definition: pval.h:93
union pval::@286 u2

◆ pvalCasePatGetVal()

char* pvalCasePatGetVal ( pval p)

Definition at line 5298 of file pval.c.

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

5299 {
5300  return p->u1.str;
5301 }
union pval::@285 u1
char * str
Definition: pval.h:59

◆ pvalCasePatSetVal()

void pvalCasePatSetVal ( pval p,
char *  val 
)

Definition at line 5291 of file pval.c.

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

5292 {
5293  if (!pvalCheckType(p, "pvalAppCallWalkArgs", PV_APPLICATION_CALL))
5294  return;
5295  p->u1.str = val;
5296 }
union pval::@285 u1
Definition: ast_expr2.c:325
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalCatchGetExtName()

char* pvalCatchGetExtName ( pval p)

Definition at line 5329 of file pval.c.

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

5330 {
5331  if (!pvalCheckType(p, "pvalCatchGetExtName", PV_CATCH))
5332  return 0;
5333  return p->u1.str;
5334 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:16

◆ pvalCatchGetStatement()

pval* pvalCatchGetStatement ( pval p)

Definition at line 5343 of file pval.c.

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

5344 {
5345  if (!pvalCheckType(p, "pvalCatchGetStatement", PV_CATCH))
5346  return 0;
5347  return p->u2.statements;
5348 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
Definition: pval.h:16
union pval::@286 u2

◆ pvalCatchSetExtName()

void pvalCatchSetExtName ( pval p,
char *  name 
)

Definition at line 5322 of file pval.c.

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

5323 {
5324  if (!pvalCheckType(p, "pvalCatchSetExtName", PV_CATCH))
5325  return;
5326  p->u1.str = name;
5327 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
static const char name[]
Definition: cdr_mysql.c:74
Definition: pval.h:16

◆ pvalCatchSetStatement()

void pvalCatchSetStatement ( pval p,
pval statement 
)

Definition at line 5336 of file pval.c.

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

5337 {
5338  if (!pvalCheckType(p, "pvalCatchSetStatement", PV_CATCH))
5339  return;
5340  p->u2.statements = statement;
5341 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
Definition: pval.h:16
union pval::@286 u2

◆ pvalCheckType()

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

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

5032 {
5033  if (p->type != type)
5034  {
5035  ast_log(LOG_ERROR, "Func: %s the pval passed is not appropriate for this function!\n", funcname);
5036  return 0;
5037  }
5038  return 1;
5039 }
static const char type[]
Definition: chan_ooh323.c:109
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
pvaltype type
Definition: pval.h:50

◆ pvalConditionalGetElseStatement()

pval* pvalConditionalGetElseStatement ( pval p)

Definition at line 5751 of file pval.c.

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

5752 {
5753  return p->u3.else_statements;
5754 }
struct pval * else_statements
Definition: pval.h:78
union pval::@287 u3

◆ pvalConditionalGetThenStatement()

pval* pvalConditionalGetThenStatement ( pval p)

Definition at line 5746 of file pval.c.

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

5747 {
5748  return p->u2.statements;
5749 }
struct pval * statements
Definition: pval.h:61
union pval::@286 u2

◆ pvalConditionalSetElseStatement()

void pvalConditionalSetElseStatement ( pval p,
pval statement 
)

Definition at line 5741 of file pval.c.

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

5742 {
5743  p->u3.else_statements = statement;
5744 }
struct pval * else_statements
Definition: pval.h:78
union pval::@287 u3

◆ pvalConditionalSetThenStatement()

void pvalConditionalSetThenStatement ( pval p,
pval statement 
)

Definition at line 5736 of file pval.c.

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

5737 {
5738  p->u2.statements = statement;
5739 }
struct pval * statements
Definition: pval.h:61
union pval::@286 u2

◆ pvalContextAddStatement()

void pvalContextAddStatement ( pval p,
pval statement 
)

Definition at line 5180 of file pval.c.

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

Referenced by main().

5181 {
5182  if (!pvalCheckType(p, "pvalContextAddStatement", PV_CONTEXT))
5183  return;
5184  if (!p->u2.statements)
5185  p->u2.statements = statement;
5186  else
5187  linku1(p->u2.statements, statement);
5188 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
union pval::@286 u2

◆ pvalContextGetAbstract()

int pvalContextGetAbstract ( pval p)

Definition at line 5171 of file pval.c.

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

5172 {
5173  if (!pvalCheckType(p, "pvalContextGetAbstract", PV_CONTEXT))
5174  return 0;
5175  return p->u3.abstract;
5176 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
int abstract
Definition: pval.h:80
union pval::@287 u3

◆ pvalContextGetName()

char* pvalContextGetName ( pval p)

Definition at line 5150 of file pval.c.

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

5151 {
5152  if (!pvalCheckType(p, "pvalContextGetName", PV_CONTEXT))
5153  return 0;
5154  return p->u1.str;
5155 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalContextSetAbstract()

void pvalContextSetAbstract ( pval p)

Definition at line 5157 of file pval.c.

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

5158 {
5159  if (!pvalCheckType(p, "pvalContextSetAbstract", PV_CONTEXT))
5160  return;
5161  p->u3.abstract = 1;
5162 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
int abstract
Definition: pval.h:80
union pval::@287 u3

◆ pvalContextSetName()

void pvalContextSetName ( pval p,
char *  name 
)

Definition at line 5143 of file pval.c.

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

Referenced by main().

5144 {
5145  if (!pvalCheckType(p, "pvalContextSetName", PV_CONTEXT))
5146  return;
5147  p->u1.str = name;
5148 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
static const char name[]
Definition: cdr_mysql.c:74

◆ pvalContextUnsetAbstract()

void pvalContextUnsetAbstract ( pval p)

Definition at line 5164 of file pval.c.

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

5165 {
5166  if (!pvalCheckType(p, "pvalContextUnsetAbstract", PV_CONTEXT))
5167  return;
5168  p->u3.abstract = 0;
5169 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
int abstract
Definition: pval.h:80
union pval::@287 u3

◆ pvalContextWalkStatements()

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

Definition at line 5190 of file pval.c.

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

5191 {
5192  if (!pvalCheckType(p, "pvalContextWalkStatements", PV_CONTEXT))
5193  return 0;
5194  if (!(*statements))
5195  *statements = p->u2.statements;
5196  else {
5197  *statements = (*statements)->next;
5198  }
5199  return *statements;
5200 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
struct pval * next
Definition: pval.h:93
union pval::@286 u2

◆ pvalCreateNode()

pval* pvalCreateNode ( pvaltype  type)

Definition at line 5042 of file pval.c.

References calloc, pval::type, and ael_priority::type.

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

5043 {
5044  pval *p = calloc(1,sizeof(pval)); /* why, oh why, don't I use ast_calloc? Way, way, way too messy if I do! */
5045  /* remember, this can be used externally or internally to asterisk */
5046  if (p) {
5047  p->type = type;
5048  }
5049  return p;
5050 }
static const char type[]
Definition: chan_ooh323.c:109
#define calloc(a, b)
Definition: astmm.h:157
Definition: pval.h:48
pvaltype type
Definition: pval.h:50

◆ pvalESwitchesAddSwitch()

void pvalESwitchesAddSwitch ( pval p,
char *  name 
)

Definition at line 5373 of file pval.c.

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

5374 {
5375  pval *s;
5376  if (!pvalCheckType(p, "pvalESwitchesAddSwitch", PV_ESWITCHES))
5377  return;
5378  s = pvalCreateNode(PV_WORD);
5379  s->u1.str = name;
5380  p->u1.list = linku1(p->u1.list, s);
5381 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:8
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
char * str
Definition: pval.h:59
Definition: pval.h:48
static const char name[]
Definition: cdr_mysql.c:74
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5042

◆ pvalESwitchesWalkNames()

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

Definition at line 5383 of file pval.c.

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

5384 {
5385  if (!pvalCheckType(p, "pvalESwitchesWalkNames", PV_ESWITCHES))
5386  return 0;
5387  if (!(*next_item))
5388  *next_item = p->u1.list;
5389  else {
5390  *next_item = (*next_item)->next;
5391  }
5392  return (*next_item)->u1.str;
5393 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93

◆ pvalExtenGetHints()

char* pvalExtenGetHints ( pval p)

Definition at line 5837 of file pval.c.

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

5838 {
5839  if (!pvalCheckType(p, "pvalExtenGetHints", PV_EXTENSION))
5840  return 0;
5841  return p->u3.hints;
5842 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * hints
Definition: pval.h:81
union pval::@287 u3

◆ pvalExtenGetName()

char* pvalExtenGetName ( pval p)

Definition at line 5802 of file pval.c.

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

5803 {
5804  if (!pvalCheckType(p, "pvalExtenGetName", PV_EXTENSION))
5805  return 0;
5806  return p->u1.str;
5807 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalExtenGetRegexten()

int pvalExtenGetRegexten ( pval p)

Definition at line 5823 of file pval.c.

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

5824 {
5825  if (!pvalCheckType(p, "pvalExtenGetRegexten", PV_EXTENSION))
5826  return 0;
5827  return p->u4.regexten;
5828 }
int regexten
Definition: pval.h:90
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
union pval::@288 u4

◆ pvalExtenGetStatement()

pval* pvalExtenGetStatement ( pval p)

Definition at line 5851 of file pval.c.

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

5852 {
5853  if (!pvalCheckType(p, "pvalExtenGetStatement", PV_EXTENSION))
5854  return 0;
5855  return p->u2.statements;
5856 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
union pval::@286 u2

◆ pvalExtenSetHints()

void pvalExtenSetHints ( pval p,
char *  hints 
)

Definition at line 5830 of file pval.c.

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

Referenced by main().

5831 {
5832  if (!pvalCheckType(p, "pvalExtenSetHints", PV_EXTENSION))
5833  return;
5834  p->u3.hints = hints;
5835 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
static struct ao2_container * hints
Definition: pbx.c:801
char * hints
Definition: pval.h:81
union pval::@287 u3

◆ pvalExtenSetName()

void pvalExtenSetName ( pval p,
char *  name 
)

Definition at line 5795 of file pval.c.

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

Referenced by main().

5796 {
5797  if (!pvalCheckType(p, "pvalExtenSetName", PV_EXTENSION))
5798  return;
5799  p->u1.str = name;
5800 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
static const char name[]
Definition: cdr_mysql.c:74

◆ pvalExtenSetRegexten()

void pvalExtenSetRegexten ( pval p)

Definition at line 5809 of file pval.c.

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

5810 {
5811  if (!pvalCheckType(p, "pvalExtenSetRegexten", PV_EXTENSION))
5812  return;
5813  p->u4.regexten = 1;
5814 }
int regexten
Definition: pval.h:90
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
union pval::@288 u4

◆ pvalExtenSetStatement()

void pvalExtenSetStatement ( pval p,
pval statement 
)

Definition at line 5844 of file pval.c.

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

Referenced by main().

5845 {
5846  if (!pvalCheckType(p, "pvalExtenSetStatement", PV_EXTENSION))
5847  return;
5848  p->u2.statements = statement;
5849 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
union pval::@286 u2

◆ pvalExtenUnSetRegexten()

void pvalExtenUnSetRegexten ( pval p)

Definition at line 5816 of file pval.c.

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

5817 {
5818  if (!pvalCheckType(p, "pvalExtenUnSetRegexten", PV_EXTENSION))
5819  return;
5820  p->u4.regexten = 0;
5821 }
int regexten
Definition: pval.h:90
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
union pval::@288 u4

◆ pvalForGetInc()

char* pvalForGetInc ( pval p)

Definition at line 5647 of file pval.c.

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

5648 {
5649  if (!pvalCheckType(p, "pvalForGetInc", PV_FOR))
5650  return 0;
5651  return p->u3.for_inc;
5652 }
char * for_inc
Definition: pval.h:77
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:24
union pval::@287 u3

◆ pvalForGetInit()

char* pvalForGetInit ( pval p)

Definition at line 5633 of file pval.c.

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

5634 {
5635  if (!pvalCheckType(p, "pvalForGetInit", PV_FOR))
5636  return 0;
5637  return p->u1.for_init;
5638 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:24
char * for_init
Definition: pval.h:62

◆ pvalForGetStatement()

pval* pvalForGetStatement ( pval p)

Definition at line 5654 of file pval.c.

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

5655 {
5656  if (!pvalCheckType(p, "pvalForGetStatement", PV_FOR))
5657  return 0;
5658  return p->u4.for_statements;
5659 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:24
struct pval * for_statements
Definition: pval.h:89
union pval::@288 u4

◆ pvalForGetTest()

char* pvalForGetTest ( pval p)

Definition at line 5640 of file pval.c.

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

5641 {
5642  if (!pvalCheckType(p, "pvalForGetTest", PV_FOR))
5643  return 0;
5644  return p->u2.for_test;
5645 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * for_test
Definition: pval.h:71
Definition: pval.h:24
union pval::@286 u2

◆ pvalForSetInc()

void pvalForSetInc ( pval p,
char *  inc 
)

Definition at line 5619 of file pval.c.

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

5620 {
5621  if (!pvalCheckType(p, "pvalForSetInc", PV_FOR))
5622  return;
5623  p->u3.for_inc = inc;
5624 }
char * for_inc
Definition: pval.h:77
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:24
union pval::@287 u3

◆ pvalForSetInit()

void pvalForSetInit ( pval p,
char *  init 
)

Definition at line 5605 of file pval.c.

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

5606 {
5607  if (!pvalCheckType(p, "pvalForSetInit", PV_FOR))
5608  return;
5609  p->u1.for_init = init;
5610 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:24
char * for_init
Definition: pval.h:62

◆ pvalForSetStatement()

void pvalForSetStatement ( pval p,
pval statement 
)

Definition at line 5626 of file pval.c.

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

5627 {
5628  if (!pvalCheckType(p, "pvalForSetStatement", PV_FOR))
5629  return;
5630  p->u4.for_statements = statement;
5631 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:24
struct pval * for_statements
Definition: pval.h:89
union pval::@288 u4

◆ pvalForSetTest()

void pvalForSetTest ( pval p,
char *  test 
)

Definition at line 5612 of file pval.c.

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

5613 {
5614  if (!pvalCheckType(p, "pvalForSetTest", PV_FOR))
5615  return;
5616  p->u2.for_test = test;
5617 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * for_test
Definition: pval.h:71
Definition: pval.h:24
static struct ast_test * test
Definition: localtime.c:115
union pval::@286 u2

◆ pvalGlobalsAddStatement()

void pvalGlobalsAddStatement ( pval p,
pval statement 
)

Definition at line 5874 of file pval.c.

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

5875 {
5876  if (p->type != PV_GLOBALS) {
5877  ast_log(LOG_ERROR, "pvalGlobalsAddStatement called where first arg is not a Globals!\n");
5878  } else {
5879  if (!p->u1.statements) {
5880  p->u1.statements = statement;
5881  } else {
5882  p->u1.statements = linku1(p->u1.statements,statement);
5883  }
5884  }
5885 }
union pval::@285 u1
struct pval * statements
Definition: pval.h:61
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285
pvaltype type
Definition: pval.h:50

◆ pvalGlobalsWalkStatements()

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

Definition at line 5887 of file pval.c.

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

5888 {
5889  if (!pvalCheckType(p, "pvalGlobalsWalkStatements", PV_GLOBALS))
5890  return 0;
5891  if (!*next_statement) {
5892  *next_statement = p;
5893  return p;
5894  } else {
5895  *next_statement = (*next_statement)->next;
5896  return (*next_statement)->next;
5897  }
5898 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * next
Definition: pval.h:93

◆ pvalGotoGetTarget()

void pvalGotoGetTarget ( pval p,
char **  context,
char **  exten,
char **  label 
)

Definition at line 5563 of file pval.c.

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

5564 {
5565  if (!pvalCheckType(p, "pvalGotoGetTarget", PV_GOTO))
5566  return;
5567  if (p->u1.list && p->u1.list->next && p->u1.list->next->next) {
5568  *context = p->u1.list->u1.str;
5569  *exten = p->u1.list->next->u1.str;
5570  *label = p->u1.list->next->next->u1.str;
5571 
5572  } else if (p->u1.list && p->u1.list->next ) {
5573  *exten = p->u1.list->u1.str;
5574  *label = p->u1.list->next->u1.str;
5575  *context = 0;
5576 
5577  } else if (p->u1.list) {
5578  *label = p->u1.list->u1.str;
5579  *context = 0;
5580  *exten = 0;
5581 
5582  } else {
5583  *context = 0;
5584  *exten = 0;
5585  *label = 0;
5586  }
5587 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:22
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116

◆ pvalGotoSetTarget()

void pvalGotoSetTarget ( pval p,
char *  context,
char *  exten,
char *  label 
)

Definition at line 5527 of file pval.c.

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

5528 {
5529  pval *con, *ext, *pri;
5530 
5531  if (!pvalCheckType(p, "pvalGotoSetTarget", PV_GOTO))
5532  return;
5533  if (context && strlen(context)) {
5534  con = pvalCreateNode(PV_WORD);
5535  ext = pvalCreateNode(PV_WORD);
5536  pri = pvalCreateNode(PV_WORD);
5537 
5538  con->u1.str = context;
5539  ext->u1.str = exten;
5540  pri->u1.str = label;
5541 
5542  con->next = ext;
5543  ext->next = pri;
5544  p->u1.list = con;
5545  } else if (exten && strlen(exten)) {
5546  ext = pvalCreateNode(PV_WORD);
5547  pri = pvalCreateNode(PV_WORD);
5548 
5549  ext->u1.str = exten;
5550  pri->u1.str = label;
5551 
5552  ext->next = pri;
5553  p->u1.list = ext;
5554  } else {
5555  pri = pvalCreateNode(PV_WORD);
5556 
5557  pri->u1.str = label;
5558 
5559  p->u1.list = pri;
5560  }
5561 }
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:22
const char * ext
Definition: http.c:147
Definition: pval.h:8
char * str
Definition: pval.h:59
Definition: pval.h:48
struct pval * next
Definition: pval.h:93
static char context[AST_MAX_CONTEXT]
Definition: chan_alsa.c:116
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5042

◆ pvalIfGetCondition()

char* pvalIfGetCondition ( pval p)

Definition at line 5670 of file pval.c.

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

5671 {
5672  if (!pvalCheckType(p, "pvalIfGetCondition", PV_IFTIME))
5673  return 0;
5674  return p->u1.str;
5675 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:30

◆ pvalIfSetCondition()

void pvalIfSetCondition ( pval p,
char *  expr 
)

Definition at line 5663 of file pval.c.

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

5664 {
5665  if (!pvalCheckType(p, "pvalIfSetCondition", PV_IF))
5666  return;
5667  p->u1.str = expr;
5668 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:29
char * str
Definition: pval.h:59

◆ pvalIfTimeGetCondition()

void pvalIfTimeGetCondition ( pval p,
char **  hour_range,
char **  dow_range,
char **  dom_range,
char **  month_range 
)

Definition at line 5712 of file pval.c.

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

5713 {
5714  if (!pvalCheckType(p, "pvalIfTimeGetCondition", PV_IFTIME))
5715  return;
5716  *hour_range = p->u1.list->u1.str;
5717  *dow_range = p->u1.list->next->u1.str;
5718  *dom_range = p->u1.list->next->next->u1.str;
5719  *month_range = p->u1.list->next->next->next->u1.str;
5720 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:30
struct pval * next
Definition: pval.h:93

◆ pvalIfTimeSetCondition()

void pvalIfTimeSetCondition ( pval p,
char *  hour_range,
char *  dow_range,
char *  dom_range,
char *  mon_range 
)

Definition at line 5677 of file pval.c.

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

5678 {
5679  pval *hr;
5680  pval *dow;
5681  pval *dom;
5682  pval *mon;
5683 
5684  if (!pvalCheckType(p, "pvalIfTimeSetCondition", PV_IFTIME)) {
5685  return;
5686  }
5687 
5688  hr = pvalCreateNode(PV_WORD);
5689  dow = pvalCreateNode(PV_WORD);
5690  dom = pvalCreateNode(PV_WORD);
5691  mon = pvalCreateNode(PV_WORD);
5692 
5693  if (!hr || !dom || !dow || !mon) {
5694  destroy_pval(hr);
5695  destroy_pval(dom);
5696  destroy_pval(dow);
5697  destroy_pval(mon);
5698  return;
5699  }
5700 
5701  pvalWordSetString(hr, hour_range);
5702  pvalWordSetString(dow, dow_range);
5703  pvalWordSetString(dom, dom_range);
5704  pvalWordSetString(mon, mon_range);
5705  dom->next = mon;
5706  dow->next = dom;
5707  hr->next = dow;
5708  p->u1.list = hr;
5709 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:8
void destroy_pval(pval *item)
Definition: pval.c:4940
Definition: pval.h:48
Definition: pval.h:30
void pvalWordSetString(pval *p, char *str)
Definition: pval.c:5058
struct pval * next
Definition: pval.h:93
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5042

◆ pvalIgnorePatGetPattern()

char* pvalIgnorePatGetPattern ( pval p)

Definition at line 5866 of file pval.c.

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

5867 {
5868  if (!pvalCheckType(p, "pvalIgnorePatGetPattern", PV_IGNOREPAT))
5869  return 0;
5870  return p->u1.str;
5871 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalIgnorePatSetPattern()

void pvalIgnorePatSetPattern ( pval p,
char *  pat 
)

Definition at line 5859 of file pval.c.

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

Referenced by main().

5860 {
5861  if (!pvalCheckType(p, "pvalIgnorePatSetPattern", PV_IGNOREPAT))
5862  return;
5863  p->u1.str = pat;
5864 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalIncludeGetTimeConstraints()

void pvalIncludeGetTimeConstraints ( pval p,
char **  hour_range,
char **  dom_range,
char **  dow_range,
char **  month_range 
)

Definition at line 5450 of file pval.c.

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

5451 {
5452  if (!pvalCheckType(p, "pvalIncludeGetTimeConstraints", PV_WORD))
5453  return;
5454  if (p->u2.arglist) {
5455  *hour_range = p->u2.arglist->u1.str;
5456  *dom_range = p->u2.arglist->next->u1.str;
5457  *dow_range = p->u2.arglist->next->next->u1.str;
5458  *month_range = p->u2.arglist->next->next->next->u1.str;
5459  } else {
5460  *hour_range = 0;
5461  *dom_range = 0;
5462  *dow_range = 0;
5463  *month_range = 0;
5464  }
5465 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:8
char * str
Definition: pval.h:59
struct pval * arglist
Definition: pval.h:68
struct pval * next
Definition: pval.h:93
union pval::@286 u2

◆ pvalIncludesAddInclude()

void pvalIncludesAddInclude ( pval p,
const char *  include 
)

Definition at line 5396 of file pval.c.

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

Referenced by main().

5397 {
5398  pval *s;
5399  if (!pvalCheckType(p, "pvalIncludesAddSwitch", PV_INCLUDES))
5400  return;
5401  s = pvalCreateNode(PV_WORD);
5402  s->u1.str = (char *)include;
5403  p->u1.list = linku1(p->u1.list, s);
5404 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:8
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
char * str
Definition: pval.h:59
Definition: pval.h:48
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5042

◆ pvalIncludesAddIncludeWithTimeConstraints()

void pvalIncludesAddIncludeWithTimeConstraints ( pval p,
const char *  include,
char *  hour_range,
char *  dom_range,
char *  dow_range,
char *  month_range 
)

Definition at line 5407 of file pval.c.

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

Referenced by main().

5408 {
5409  pval *hr;
5410  pval *dom;
5411  pval *dow;
5412  pval *mon;
5413  pval *s;
5414 
5415  if (!pvalCheckType(p, "pvalIncludeAddIncludeWithTimeConstraints", PV_INCLUDES)) {
5416  return;
5417  }
5418 
5419  hr = pvalCreateNode(PV_WORD);
5420  dom = pvalCreateNode(PV_WORD);
5421  dow = pvalCreateNode(PV_WORD);
5422  mon = pvalCreateNode(PV_WORD);
5423  s = pvalCreateNode(PV_WORD);
5424 
5425  if (!hr || !dom || !dow || !mon || !s) {
5426  destroy_pval(hr);
5427  destroy_pval(dom);
5428  destroy_pval(dow);
5429  destroy_pval(mon);
5430  destroy_pval(s);
5431  return;
5432  }
5433 
5434  s->u1.str = (char *)include;
5435  p->u1.list = linku1(p->u1.list, s);
5436 
5437  hr->u1.str = hour_range;
5438  dom->u1.str = dom_range;
5439  dow->u1.str = dow_range;
5440  mon->u1.str = month_range;
5441 
5442  s->u2.arglist = hr;
5443 
5444  hr->next = dom;
5445  dom->next = dow;
5446  dow->next = mon;
5447  mon->next = 0;
5448 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:8
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
void destroy_pval(pval *item)
Definition: pval.c:4940
char * str
Definition: pval.h:59
Definition: pval.h:48
struct pval * arglist
Definition: pval.h:68
struct pval * next
Definition: pval.h:93
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5042
union pval::@286 u2

◆ pvalIncludesWalk()

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

Definition at line 5467 of file pval.c.

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

5468 {
5469  if (!pvalCheckType(p, "pvalIncludesWalk", PV_INCLUDES))
5470  return 0;
5471  if (!(*next_item))
5472  *next_item = p->u1.list;
5473  else {
5474  *next_item = (*next_item)->next;
5475  }
5476  return (*next_item)->u1.str;
5477 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93

◆ pvalLabelGetName()

char* pvalLabelGetName ( pval p)

Definition at line 5597 of file pval.c.

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

5598 {
5599  if (!pvalCheckType(p, "pvalLabelGetName", PV_LABEL))
5600  return 0;
5601  return p->u1.str;
5602 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:23

◆ pvalLabelSetName()

void pvalLabelSetName ( pval p,
char *  name 
)

Definition at line 5590 of file pval.c.

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

5591 {
5592  if (!pvalCheckType(p, "pvalLabelSetName", PV_LABEL))
5593  return;
5594  p->u1.str = name;
5595 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
static const char name[]
Definition: cdr_mysql.c:74
Definition: pval.h:23

◆ pvalMacroAddArg()

void pvalMacroAddArg ( pval p,
pval arg 
)

Definition at line 5094 of file pval.c.

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

5095 {
5096  if (!pvalCheckType(p, "pvalMacroAddArg", PV_MACRO))
5097  return;
5098  if (!p->u2.arglist)
5099  p->u2.arglist = arg;
5100  else
5101  linku1(p->u2.arglist, arg);
5102 
5103 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
union pval::@286 u2

◆ pvalMacroAddStatement()

void pvalMacroAddStatement ( pval p,
pval statement 
)

Definition at line 5117 of file pval.c.

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

5118 {
5119  if (!pvalCheckType(p, "pvalMacroAddStatement", PV_MACRO))
5120  return;
5121  if (!p->u3.macro_statements)
5122  p->u3.macro_statements = statement;
5123  else
5124  linku1(p->u3.macro_statements, statement);
5125 
5126 
5127 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
Definition: pval.h:9
union pval::@287 u3
struct pval * macro_statements
Definition: pval.h:79

◆ pvalMacroCallAddArg()

void pvalMacroCallAddArg ( pval p,
pval arg 
)

Definition at line 5224 of file pval.c.

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

5225 {
5226  if (!pvalCheckType(p, "pvalMacroCallGetAddArg", PV_MACRO_CALL))
5227  return;
5228  if (!p->u2.arglist)
5229  p->u2.arglist = arg;
5230  else
5231  linku1(p->u2.arglist, arg);
5232 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
struct pval * arglist
Definition: pval.h:68
union pval::@286 u2

◆ pvalMacroCallGetMacroName()

char* pvalMacroCallGetMacroName ( pval p)

Definition at line 5210 of file pval.c.

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

5211 {
5212  if (!pvalCheckType(p, "pvalMacroCallGetMacroName", PV_MACRO_CALL))
5213  return 0;
5214  return p->u1.str;
5215 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalMacroCallSetArglist()

void pvalMacroCallSetArglist ( pval p,
pval arglist 
)

Definition at line 5217 of file pval.c.

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

5218 {
5219  if (!pvalCheckType(p, "pvalMacroCallSetArglist", PV_MACRO_CALL))
5220  return;
5221  p->u2.arglist = arglist;
5222 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * arglist
Definition: pval.h:68
union pval::@286 u2

◆ pvalMacroCallSetMacroName()

void pvalMacroCallSetMacroName ( pval p,
char *  name 
)

Definition at line 5203 of file pval.c.

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

5204 {
5205  if (!pvalCheckType(p, "pvalMacroCallSetMacroName", PV_MACRO_CALL))
5206  return;
5207  p->u1.str = name;
5208 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
static const char name[]
Definition: cdr_mysql.c:74

◆ pvalMacroCallWalkArgs()

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

Definition at line 5234 of file pval.c.

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

5235 {
5236  if (!pvalCheckType(p, "pvalMacroCallWalkArgs", PV_MACRO_CALL))
5237  return 0;
5238  if (!(*args))
5239  *args = p->u2.arglist;
5240  else {
5241  *args = (*args)->next;
5242  }
5243  return *args;
5244 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
const char * args
struct pval * arglist
Definition: pval.h:68
struct pval * next
Definition: pval.h:93
union pval::@286 u2

◆ pvalMacroGetName()

char* pvalMacroGetName ( pval p)

Definition at line 5080 of file pval.c.

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

5081 {
5082  if (!pvalCheckType(p, "pvalMacroGetName", PV_MACRO))
5083  return 0;
5084  return p->u1.str;
5085 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:9

◆ pvalMacroSetArglist()

void pvalMacroSetArglist ( pval p,
pval arglist 
)

Definition at line 5087 of file pval.c.

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

5088 {
5089  if (!pvalCheckType(p, "pvalMacroSetArglist", PV_MACRO))
5090  return;
5091  p->u2.arglist = arglist;
5092 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
union pval::@286 u2

◆ pvalMacroSetName()

void pvalMacroSetName ( pval p,
char *  name 
)

Definition at line 5073 of file pval.c.

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

5074 {
5075  if (!pvalCheckType(p, "pvalMacroSetName", PV_MACRO))
5076  return;
5077  p->u1.str = name;
5078 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:9
static const char name[]
Definition: cdr_mysql.c:74

◆ pvalMacroWalkArgs()

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

Definition at line 5105 of file pval.c.

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

5106 {
5107  if (!pvalCheckType(p, "pvalMacroWalkArgs", PV_MACRO))
5108  return 0;
5109  if (!(*arg))
5110  *arg = p->u2.arglist;
5111  else {
5112  *arg = (*arg)->next;
5113  }
5114  return *arg;
5115 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * arglist
Definition: pval.h:68
Definition: pval.h:9
struct pval * next
Definition: pval.h:93
union pval::@286 u2

◆ pvalMacroWalkStatements()

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

Definition at line 5129 of file pval.c.

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

5130 {
5131  if (!pvalCheckType(p, "pvalMacroWalkStatements", PV_MACRO))
5132  return 0;
5133  if (!(*next_statement))
5134  *next_statement = p->u3.macro_statements;
5135  else {
5136  *next_statement = (*next_statement)->next;
5137  }
5138  return *next_statement;
5139 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:9
union pval::@287 u3
struct pval * next
Definition: pval.h:93
struct pval * macro_statements
Definition: pval.h:79

◆ pvalObjectGetType()

pvaltype pvalObjectGetType ( pval p)

Definition at line 5052 of file pval.c.

References pval::type.

5053 {
5054  return p->type;
5055 }
pvaltype type
Definition: pval.h:50

◆ pvalRandomGetCondition()

char* pvalRandomGetCondition ( pval p)

Definition at line 5729 of file pval.c.

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

5730 {
5731  if (!pvalCheckType(p, "pvalRandomGetCondition", PV_RANDOM))
5732  return 0;
5733  return p->u1.str;
5734 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:31

◆ pvalRandomSetCondition()

void pvalRandomSetCondition ( pval p,
char *  percent 
)

Definition at line 5722 of file pval.c.

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

5723 {
5724  if (!pvalCheckType(p, "pvalRandomSetCondition", PV_RANDOM))
5725  return;
5726  p->u1.str = percent;
5727 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
Definition: pval.h:31

◆ pvalStatementBlockAddStatement()

void pvalStatementBlockAddStatement ( pval p,
pval statement 
)

Definition at line 5480 of file pval.c.

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

Referenced by main().

5481 {
5482  if (!pvalCheckType(p, "pvalStatementBlockAddStatement", PV_STATEMENTBLOCK))
5483  return;
5484  p->u1.list = linku1(p->u1.list, statement);
5485 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922

◆ pvalStatementBlockWalkStatements()

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

Definition at line 5487 of file pval.c.

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

5488 {
5489  if (!pvalCheckType(p, "pvalStatementBlockWalkStatements", PV_STATEMENTBLOCK))
5490  return 0;
5491  if (!(*next_statement))
5492  *next_statement = p->u1.list;
5493  else {
5494  *next_statement = (*next_statement)->next;
5495  }
5496  return *next_statement;
5497 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * next
Definition: pval.h:93

◆ pvalSwitchAddCase()

void pvalSwitchAddCase ( pval p,
pval Case 
)

Definition at line 5770 of file pval.c.

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

5771 {
5772  if (!pvalCheckType(p, "pvalSwitchAddCase", PV_SWITCH))
5773  return;
5774  if (!pvalCheckType(Case, "pvalSwitchAddCase", PV_CASE))
5775  return;
5776  if (!p->u2.statements)
5777  p->u2.statements = Case;
5778  else
5779  linku1(p->u2.statements, Case);
5780 }
Definition: pval.h:32
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
Definition: pval.h:13
union pval::@286 u2

◆ pvalSwitchesAddSwitch()

void pvalSwitchesAddSwitch ( pval p,
char *  name 
)

Definition at line 5351 of file pval.c.

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

Referenced by main().

5352 {
5353  pval *s;
5354  if (!pvalCheckType(p, "pvalSwitchesAddSwitch", PV_SWITCHES))
5355  return;
5356  s = pvalCreateNode(PV_WORD);
5357  s->u1.str = name;
5358  p->u1.list = linku1(p->u1.list, s);
5359 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:8
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
char * str
Definition: pval.h:59
Definition: pval.h:48
static const char name[]
Definition: cdr_mysql.c:74
pval * pvalCreateNode(pvaltype type)
Definition: pval.c:5042

◆ pvalSwitchesWalkNames()

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

Definition at line 5361 of file pval.c.

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

5362 {
5363  if (!pvalCheckType(p, "pvalSwitchesWalkNames", PV_SWITCHES))
5364  return 0;
5365  if (!(*next_item))
5366  *next_item = p->u1.list;
5367  else {
5368  *next_item = (*next_item)->next;
5369  }
5370  return (*next_item)->u1.str;
5371 }
union pval::@285 u1
struct pval * list
Definition: pval.h:60
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59
struct pval * next
Definition: pval.h:93

◆ pvalSwitchGetTestexpr()

char* pvalSwitchGetTestexpr ( pval p)

Definition at line 5763 of file pval.c.

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

5764 {
5765  if (!pvalCheckType(p, "pvalSwitchGetTestexpr", PV_SWITCH))
5766  return 0;
5767  return p->u1.str;
5768 }
union pval::@285 u1
Definition: pval.h:32
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalSwitchSetTestexpr()

void pvalSwitchSetTestexpr ( pval p,
char *  expr 
)

Definition at line 5756 of file pval.c.

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

5757 {
5758  if (!pvalCheckType(p, "pvalSwitchSetTestexpr", PV_SWITCH))
5759  return;
5760  p->u1.str = expr;
5761 }
union pval::@285 u1
Definition: pval.h:32
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * str
Definition: pval.h:59

◆ pvalSwitchWalkCases()

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

Definition at line 5782 of file pval.c.

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

5783 {
5784  if (!pvalCheckType(p, "pvalSwitchWalkCases", PV_SWITCH))
5785  return 0;
5786  if (!(*next_case))
5787  *next_case = p->u2.statements;
5788  else {
5789  *next_case = (*next_case)->next;
5790  }
5791  return *next_case;
5792 }
Definition: pval.h:32
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
struct pval * statements
Definition: pval.h:61
struct pval * next
Definition: pval.h:93
union pval::@286 u2

◆ pvalTopLevAddObject()

void pvalTopLevAddObject ( pval p,
pval contextOrObj 
)

Definition at line 5901 of file pval.c.

References ast_log, linku1(), and LOG_ERROR.

Referenced by main().

5902 {
5903  if (p) {
5904  linku1(p,contextOrObj);
5905  } else {
5906  ast_log(LOG_ERROR, "First arg to pvalTopLevel is NULL!\n");
5907  }
5908 }
pval * linku1(pval *head, pval *tail)
Definition: pval.c:5922
#define ast_log
Definition: astobj2.c:42
#define LOG_ERROR
Definition: logger.h:285

◆ pvalTopLevWalkObjects()

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

Definition at line 5910 of file pval.c.

References pval::next.

5911 {
5912  if (!*next_obj) {
5913  *next_obj = p;
5914  return p;
5915  } else {
5916  *next_obj = (*next_obj)->next;
5917  return (*next_obj)->next;
5918  }
5919 }
struct pval * next
Definition: pval.h:93

◆ pvalVarDecGetValue()

char* pvalVarDecGetValue ( pval p)

Definition at line 5520 of file pval.c.

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

5521 {
5522  if (!pvalCheckType(p, "pvalVarDecGetValue", PV_VARDEC))
5523  return 0;
5524  return p->u2.val;
5525 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
char * val
Definition: pval.h:70
Definition: pval.h:21
union pval::@286 u2

◆ pvalVarDecGetVarname()

char* pvalVarDecGetVarname ( pval p)

Definition at line 5513 of file pval.c.

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

5514 {
5515  if (!pvalCheckType(p, "pvalVarDecGetVarname", PV_VARDEC))
5516  return 0;
5517  return p->u1.str;
5518 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:21
char * str
Definition: pval.h:59

◆ pvalVarDecSetValue()

void pvalVarDecSetValue ( pval p,
char *  value 
)

Definition at line 5506 of file pval.c.

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

5507 {
5508  if (!pvalCheckType(p, "pvalVarDecSetValue", PV_VARDEC))
5509  return;
5510  p->u2.val = value;
5511 }
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
int value
Definition: syslog.c:37
char * val
Definition: pval.h:70
Definition: pval.h:21
union pval::@286 u2

◆ pvalVarDecSetVarname()

void pvalVarDecSetVarname ( pval p,
char *  name 
)

Definition at line 5499 of file pval.c.

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

5500 {
5501  if (!pvalCheckType(p, "pvalVarDecSetVarname", PV_VARDEC))
5502  return;
5503  p->u1.str = name;
5504 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:21
char * str
Definition: pval.h:59
static const char name[]
Definition: cdr_mysql.c:74

◆ pvalWordGetString()

char* pvalWordGetString ( pval p)

Definition at line 5065 of file pval.c.

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

5066 {
5067  if (!pvalCheckType(p, "pvalWordGetString", PV_WORD))
5068  return 0;
5069  return p->u1.str;
5070 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
Definition: pval.h:8
char * str
Definition: pval.h:59

◆ pvalWordSetString()

void pvalWordSetString ( pval p,
char *  str 
)

Definition at line 5058 of file pval.c.

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

Referenced by main(), and pvalIfTimeSetCondition().

5059 {
5060  if (!pvalCheckType(p, "pvalWordSetString", PV_WORD))
5061  return;
5062  p->u1.str = str;
5063 }
union pval::@285 u1
int pvalCheckType(pval *p, char *funcname, pvaltype type)
Definition: pval.c:5031
const char * str
Definition: app_jack.c:147
Definition: pval.h:8
char * str
Definition: pval.h:59

◆ remove_spaces_before_equals()

static void remove_spaces_before_equals ( char *  str)
static

Definition at line 3038 of file pval.c.

References str.

Referenced by ast_compile_ael2(), and gen_prios().

3039 {
3040  char *p;
3041  while( str && *str && *str != '=' )
3042  {
3043  if( *str == ' ' || *str == '\n' || *str == '\r' || *str == '\t' )
3044  {
3045  p = str;
3046  while( *p )
3047  {
3048  *p = *(p+1);
3049  p++;
3050  }
3051  }
3052  else
3053  str++;
3054  }
3055 }
const char * str
Definition: app_jack.c:147

◆ set_priorities()

void set_priorities ( struct ael_extension exten)

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

4188 {
4189  int i;
4190  struct ael_priority *pr;
4191  do {
4192  if (exten->is_switch)
4193  i = 10;
4194  else if (exten->regexten)
4195  i=2;
4196  else
4197  i=1;
4198 
4199  for (pr=exten->plist; pr; pr=pr->next) {
4200  pr->priority_num = i;
4201 
4202  if (!pr->origin || (pr->origin && pr->origin->type != PV_LABEL) ) /* Labels don't show up in the dialplan,
4203  but we want them to point to the right
4204  priority, which would be the next line
4205  after the label; */
4206  i++;
4207  }
4208 
4209  exten = exten->next_exten;
4210  } while ( exten );
4211 }
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

◆ traverse_pval_item_template()

void traverse_pval_item_template ( pval item,
int  depth 
)

Definition at line 400 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 ael2_print(), and traverse_pval_template().

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

◆ traverse_pval_template()

void traverse_pval_template ( pval item,
int  depth 
)

Definition at line 634 of file pval.c.

References pval::next, and traverse_pval_item_template().

Referenced by ael2_print().

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

Variable Documentation

◆ control_statement_count

int control_statement_count
static

Definition at line 2922 of file pval.c.

Referenced by ast_compile_ael2(), and gen_prios().

◆ count_labels

int count_labels
static

◆ current_context

pval* current_context
static

Definition at line 73 of file pval.c.

Referenced by check_label().

◆ current_db

pval* current_db
static

Definition at line 72 of file pval.c.

◆ current_extension

pval* current_extension
static

Definition at line 74 of file pval.c.

Referenced by check_label().

◆ days

char* days[]
static

Definition at line 886 of file pval.c.

Referenced by check_dow().

◆ errs

int errs
static

◆ expr_output

char expr_output[2096]
static

Definition at line 60 of file pval.c.

Referenced by check_pval_item().

◆ in_abstract_context

int in_abstract_context
static

Definition at line 79 of file pval.c.

Referenced by check_pval_item().

◆ label_count

int label_count
static

Definition at line 81 of file pval.c.

Referenced by match_pval(), and match_pval_item().

◆ last_matched_label

pval* last_matched_label
static

Definition at line 83 of file pval.c.

◆ match_context

const char* match_context
static

◆ match_exten

const char* match_exten
static

◆ match_label

const char* match_label
static

◆ months

char* months[]
static

Definition at line 984 of file pval.c.

Referenced by check_month().

◆ notes

int notes
static

Definition at line 66 of file pval.c.

Referenced by ael2_semantic_check().

◆ registrar

char* registrar = "pbx_ael"
static

Definition at line 70 of file pval.c.

Referenced by add_extensions(), and ast_compile_ael2().

◆ return_on_context_match

int return_on_context_match
static

◆ warns

int warns
static