This commit closes bug 7605, and half-closes 7638. The AEL code has been redistributed/repartitioned to allow code re-use both inside and outside of Asterisk. This commit introduces the utils/conf2ael program, and an external config-file reader, for both normal config files, and for extensions.conf (context, exten, prio); It provides an API for programs outside of asterisk to use to play with the dialplan and config files.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@79595 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Steve Murphy
2007-08-15 19:21:27 +00:00
parent 5fbd7ebd24
commit 9836efb5fb
32 changed files with 6028 additions and 3339 deletions

View File

@@ -25,6 +25,8 @@
#ifndef _ASTERISK_AEL_STRUCTS_H
#define _ASTERISK_AEL_STRUCTS_H
#include "pval.h"
#if !defined(SOLARIS) && !defined(__CYGWIN__)
/* #include <err.h> */
#else
@@ -46,118 +48,15 @@
# endif
typedef enum {
PV_WORD, /* an ident, string, name, label, etc. A user-supplied string. */ /* 0 */
PV_MACRO, /* 1 */
PV_CONTEXT, /* 2 */
PV_MACRO_CALL, /* 3 */
PV_APPLICATION_CALL, /* 4 */
PV_CASE, /* 5 */
PV_PATTERN, /* 6 */
PV_DEFAULT, /* 7 */
PV_CATCH, /* 8 */
PV_SWITCHES, /* 9 */
PV_ESWITCHES, /* 10 */
PV_INCLUDES, /* 11 */
PV_STATEMENTBLOCK, /* 12 */
PV_VARDEC, /* you know, var=val; */ /* 13 */
PV_GOTO, /* 14 */
PV_LABEL, /* 15 */
PV_FOR, /* 16 */
PV_WHILE, /* 17 */
PV_BREAK, /* 18 */
PV_RETURN, /* 19 */
PV_CONTINUE, /* 20 */
PV_IF, /* 21 */
PV_IFTIME, /* 22 */
PV_RANDOM, /* 23 */
PV_SWITCH, /* 24 */
PV_EXTENSION, /* 25 */
PV_IGNOREPAT, /* 26 */
PV_GLOBALS, /* 27 */
PV_LOCALVARDEC, /* you know, local var=val; */ /* 28 */
} pvaltype;
/* why this horrible mess? It's always been a tradeoff-- tons of structs,
each storing it's specific lists of goodies, or a 'simple' single struct,
with lots of fields, that catches all uses at once. Either you have a long
list of struct names and subnames, or you have a long list of field names,
and where/how they are used. I'm going with a single struct, using unions
to reduce storage. Some simple generalizations, and a long list of types,
and a book about what is used with what types.... Sorry!
*/
struct pval
{
pvaltype type;
int startline;
int endline;
int startcol;
int endcol;
char *filename;
union
{
char *str; /* wow, used almost everywhere! */
struct pval *list; /* used in SWITCHES, ESWITCHES, INCLUDES, STATEMENTBLOCK, GOTO */
struct pval *statements;/* used in EXTENSION */
char *for_init; /* used in FOR */
} u1;
struct pval *u1_last; /* to build in-order lists -- looks like we only need one */
union
{
struct pval *arglist; /* used in macro_call, application_call, MACRO def, also attached to PWORD, the 4 timevals for includes */
struct pval *statements; /* used in case, default, catch, while's statement, CONTEXT elements, GLOBALS */
char *val; /* used in VARDEC */
char *for_test; /* used in FOR */
int label_in_case; /* a boolean for LABELs */
struct pval *goto_target; /* used in GOTO */
} u2;
union
{
char *for_inc; /* used in FOR */
struct pval *else_statements; /* used in IF */
struct pval *macro_statements; /* used in MACRO */
int abstract; /* used for context */
char *hints; /* used in EXTENSION */
int goto_target_in_case; /* used in GOTO */
struct ael_extension *compiled_label;
} u3;
union
{
struct pval *for_statements; /* used in PV_FOR */
int regexten; /* used in EXTENSION */
} u4;
struct pval *next; /* the pval at the end of this ptr will ALWAYS be of the same type as this one!
EXCEPT for objects of the different types, that are in the same list, like contexts & macros, etc */
struct pval *dad; /* the 'container' of this struct instance */
struct pval *prev; /* the opposite of the 'next' pointer */
} ;
typedef struct pval pval;
#if 0
pval *npval(pvaltype type, int first_line, int last_line, int first_column, int last_column);
void linku1(pval *head, pval *tail);
void print_pval_list(FILE *f, pval *item, int depth);
void print_pval(FILE *f, pval *item, int depth);
void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes);
struct pval *find_label_in_current_context(char *exten, char *label);
struct pval *find_label_in_current_extension(char *label);
int count_labels_in_current_context(char *label);
struct pval *find_label_in_current_db(char *context, char *exten, char *label);
void ael2_print(char *fname, pval *tree);
#endif
void ael2_semantic_check(pval *item, int *errs, int *warns, int *notes);
pval *npval(pvaltype type, int first_line, int last_line, int first_column, int last_column);
pval *linku1(pval *head, pval *tail);
void ael2_print(char *fname, pval *tree);
struct pval *ael2_parse(char *fname, int *errs); /* in ael.flex */
void destroy_pval(pval *item);
extern char *prev_word; /* in ael.flex */
#ifndef YY_TYPEDEF_YY_SCANNER_T

View File

@@ -19,7 +19,6 @@
#ifndef _ASTERISK_EXPR_H
#define _ASTERISK_EXPR_H
#ifndef STANDALONE
#include "asterisk/channel.h"
#endif
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {

View File

@@ -904,6 +904,52 @@ int ast_func_read(struct ast_channel *chan, const char *function, char *workspac
*/
int ast_func_write(struct ast_channel *chan, const char *function, const char *value);
/*!
* When looking up extensions, we can have different requests
* identified by the 'action' argument, as follows.
* Note that the coding is such that the low 4 bits are the
* third argument to extension_match_core.
*/
enum ext_match_t {
E_MATCHMORE = 0x00, /* extension can match but only with more 'digits' */
E_CANMATCH = 0x01, /* extension can match with or without more 'digits' */
E_MATCH = 0x02, /* extension is an exact match */
E_MATCH_MASK = 0x03, /* mask for the argument to extension_match_core() */
E_SPAWN = 0x12, /* want to spawn an extension. Requires exact match */
E_FINDLABEL = 0x22 /* returns the priority for a given label. Requires exact match */
};
#define STATUS_NO_CONTEXT 1
#define STATUS_NO_EXTENSION 2
#define STATUS_NO_PRIORITY 3
#define STATUS_NO_LABEL 4
#define STATUS_SUCCESS 5
#define AST_PBX_MAX_STACK 128
/* request and result for pbx_find_extension */
struct pbx_find_info {
#if 0
const char *context;
const char *exten;
int priority;
#endif
char *incstack[AST_PBX_MAX_STACK]; /* filled during the search */
int stacklen; /* modified during the search */
int status; /* set on return */
struct ast_switch *swo; /* set on return */
const char *data; /* set on return */
const char *foundcontext; /* set on return */
};
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);
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif