Sat Sep 16 07:28:19 2006

Asterisk developer's documentation


pbx_ael.c File Reference

Compile symbolic Asterisk Extension Logic into Asterisk extensions. More...

#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "asterisk.h"
#include "asterisk/pbx.h"
#include "asterisk/config.h"
#include "asterisk/module.h"
#include "asterisk/logger.h"
#include "asterisk/cli.h"
#include "asterisk/callerid.h"

Go to the source code of this file.

Data Structures

struct  fillin
struct  stringlink

Defines

#define DEBUG_CONTEXTS   (1 << 3)
#define DEBUG_MACROS   (1 << 2)
#define DEBUG_READ   (1 << 0)
#define DEBUG_TOKENS   (1 << 1)
#define FILLIN_BREAK   1
#define FILLIN_CONTINUE   2
#define FREE   free

Functions

static int __build_step (const char *what, const char *name, const char *filename, int lineno, struct ast_context *con, char *exten, int *pos, char *data, struct fillin **fillout, char **label)
static char * __grab_token (char *src, const char *filename, int lineno, int link)
static int ael_debug_contexts (int fd, int argc, char *argv[])
static int ael_debug_macros (int fd, int argc, char *argv[])
static int ael_debug_read (int fd, int argc, char *argv[])
static int ael_debug_tokens (int fd, int argc, char *argv[])
static int ael_no_debug (int fd, int argc, char *argv[])
static int ael_reload (int fd, int argc, char *argv[])
static void arg_free (struct stringlink *cur)
static struct stringlinkarg_parse (char *args, const char *filename, int lineno)
static char * argument_end (char *str)
static int ast_ael_compile (struct ast_context **local_contexts, const char *filename)
static int build_step (const char *what, const char *name, const char *filename, int lineno, struct ast_context *con, char *exten, int *pos, char *data, struct fillin **fillout, char **label)
char * description (void)
 Provides a description of the module.
static void fillin_free (struct fillin *fillin)
static void fillin_process (struct ast_context *con, struct fillin *fillin, const char *filename, int lineno, const char *breakexten, int breakprio, const char *contexten, int contprio)
static const char * get_case (char *s, char **restout, int *pattern)
static char * grab_else (char *args, const char *filename, int lineno)
static char * grab_token (char *src, const char *filename, int lineno)
static void handle_context (struct ast_context **local_contexts, struct stringlink *vars, const char *filename, int lineno)
static void handle_globals (struct stringlink *vars)
static void handle_macro (struct ast_context **local_contexts, struct stringlink *vars, const char *filename, int lineno)
static int handle_root_token (struct ast_context **local_contexts, char *token, int level, const char *filename, int lineno)
char * key (void)
 Returns the ASTERISK_GPL_KEY.
int load_module (void)
 Initialize the module.
static int match_assignment (char *variable, char **value)
static int matches_extension (char *exten, char **extout)
static int matches_keyword (const char *data, const char *keyword)
static int matches_label (char *data, char **rest)
static struct stringlinkparam_parse (char *parms, const char *macro, const char *filename, int lineno)
static int parse_catch (char *data, char **catch, char **rest)
static void parse_keyword (char *s, char **o)
static int pbx_load_module (void)
int reload (void)
 Reload stuff.
static struct stringlinksplit_params (char *token, const char *filename, int lineno)
static struct stringlinksplit_token (char *token, const char *filename, int lineno)
int unload_module (void)
 Cleanup all module structures, sockets, etc.
int usecount (void)
 Provides a usecount.

Variables

static struct ast_cli_entry ael_cli []
static int aeldebug = 0
static char * config = "extensions.ael"
static char * dtext = "Asterisk Extension Language Compiler"
static char * registrar = "pbx_ael"


Detailed Description

Compile symbolic Asterisk Extension Logic into Asterisk extensions.

Definition in file pbx_ael.c.


Define Documentation

#define DEBUG_CONTEXTS   (1 << 3)

Definition at line 70 of file pbx_ael.c.

Referenced by ael_debug_contexts(), and handle_context().

#define DEBUG_MACROS   (1 << 2)

Definition at line 69 of file pbx_ael.c.

Referenced by ael_debug_macros(), and handle_macro().

#define DEBUG_READ   (1 << 0)

Definition at line 67 of file pbx_ael.c.

#define DEBUG_TOKENS   (1 << 1)

Definition at line 68 of file pbx_ael.c.

Referenced by __build_step(), __grab_token(), ael_debug_tokens(), arg_parse(), get_case(), grab_else(), and handle_root_token().

#define FILLIN_BREAK   1

Definition at line 48 of file pbx_ael.c.

Referenced by __build_step(), and fillin_process().

#define FILLIN_CONTINUE   2

Definition at line 49 of file pbx_ael.c.

Referenced by __build_step(), and fillin_process().

#define FREE   free

Definition at line 64 of file pbx_ael.c.


Function Documentation

static int __build_step ( const char *  what,
const char *  name,
const char *  filename,
int  lineno,
struct ast_context con,
char *  exten,
int *  pos,
char *  data,
struct fillin **  fillout,
char **  label 
) [static]

Definition at line 478 of file pbx_ael.c.

References app, arg_free(), arg_parse(), argument_end(), ast_add_extension2(), ast_log(), ast_process_quotes_and_slashes(), ast_strlen_zero(), ast_verbose(), build_step(), stringlink::data, DEBUG_TOKENS, FILLIN_BREAK, FILLIN_CONTINUE, fillin_free(), fillin_process(), FREE, get_case(), grab_else(), ifend, LOG_NOTICE, LOG_WARNING, malloc, match_assignment(), matches_keyword(), matches_label(), stringlink::next, and strdup.

Referenced by build_step().

00479 {
00480    char *app;
00481    char *args;
00482    char *c;
00483    char *margs=NULL;
00484    char *oargs;
00485    char *rest;
00486    const char *curcase, *newcase;
00487    struct stringlink *swargs, *cur;
00488    int cpos;
00489    int mlen;
00490    int pattern = 0;
00491    struct fillin *fillin;
00492    
00493    data = ast_skip_blanks(data);
00494    if (matches_label(data, &c)) {
00495       *label = data;
00496       data = c;
00497       data = ast_skip_blanks(data);
00498    }
00499    if (ast_strlen_zero(data))
00500       return 0;
00501    if (matches_keyword(data, "switch")) {
00502       fillin = NULL;
00503       /* Switch */
00504       args = data + strlen("switch");
00505       while ((*args < 33) && (*args != '(')) args++;
00506       if ((*args == '(') && (c = argument_end(args))) {
00507          args++;
00508          *c = '\0';
00509          c++;
00510          if (aeldebug & DEBUG_TOKENS)
00511             ast_verbose("--SWITCH on : %s\n", args);
00512          mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
00513          margs = alloca(mlen);
00514          app = "Goto";
00515          sprintf(margs, "sw-%d-%s|1", *pos, args);
00516          ast_process_quotes_and_slashes(margs, ',', '|');
00517          oargs = args;
00518          args = margs;
00519          if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(args), FREE, registrar))
00520             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00521          else {
00522             *label = NULL;
00523             (*pos)++;
00524          }
00525          app = "NoOp";
00526          sprintf(margs, "Finish switch-%d", *pos - 1);
00527          if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(args), FREE, registrar))
00528             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00529          else {
00530             *label = NULL;
00531             (*pos)++;
00532          }
00533          c = ast_skip_blanks(c);
00534          if (aeldebug & DEBUG_TOKENS)
00535             ast_verbose("ARG Parsing '%s'\n", c);
00536          swargs = arg_parse(c, filename, lineno);
00537          cur = swargs;
00538          curcase = NULL;
00539          while(cur) {
00540             if ((newcase = get_case(cur->data, &rest, &pattern))) {
00541                if (aeldebug & DEBUG_TOKENS)
00542                   ast_verbose("--NEWCASE: '%s'!\n", newcase);
00543                if (curcase) {
00544                   /* Handle fall through */
00545                   char tmp[strlen(newcase) + strlen(name) + 40];
00546                   sprintf(tmp, "sw-%d-%s|%d", *pos - 2, newcase, 1);
00547                   ast_add_extension2(con, 0, margs, cpos, NULL, NULL, "Goto", strdup(tmp), FREE, registrar);
00548                }
00549                curcase = newcase;
00550                cpos = 1;
00551                if (pattern)
00552                   snprintf(margs, mlen, "_sw-%d-%s", *pos - 2, curcase);
00553                else
00554                   snprintf(margs, mlen, "sw-%d-%s", *pos - 2, curcase);
00555                if (!strcasecmp(rest, "break")) {
00556                   char tmp[strlen(exten) + 10];
00557                   sprintf(tmp, "%s|%d", exten, *pos - 1);
00558                   ast_add_extension2(con, 0, exten, cpos, *label, NULL, "Goto", strdup(tmp), FREE, registrar);
00559                   curcase = NULL;
00560                   *label = NULL;
00561                } else
00562                   build_step("switch", margs, filename, lineno, con, margs, &cpos, rest, &fillin, label);
00563             } else if (curcase) {
00564                if (aeldebug & DEBUG_TOKENS)
00565                   ast_verbose("Building statement from '%s'\n", rest);
00566                if (!strcasecmp(rest, "break")) {
00567                   char tmp[strlen(exten) + 10];
00568                   sprintf(tmp, "%s|%d", exten, *pos - 1);
00569                   ast_add_extension2(con, 0, margs, cpos, *label, NULL, "Goto", strdup(tmp), FREE, registrar);
00570                   curcase = NULL;
00571                   *label = NULL;
00572                } else
00573                   build_step("switch", margs, filename, lineno, con, margs, &cpos, rest, &fillin, label);
00574             } else 
00575                ast_log(LOG_WARNING, "Unreachable code in switch at about line %d of %s\n", lineno, filename);
00576             if (aeldebug & DEBUG_TOKENS)
00577                ast_verbose("--SWARG: %s\n", cur->data);
00578             cur = cur->next;
00579          }
00580          /* Can't do anything with these */
00581          fillin_process(con, fillin, filename, lineno, NULL, 0, NULL, 0);
00582          fillin_free(fillin);
00583          arg_free(swargs);
00584       } else
00585          ast_log(LOG_WARNING, "Syntax error in switch declaration in %s around line %d!\n", filename, lineno); 
00586          
00587    } else if (matches_keyword(data, "if")) {
00588       /* If... */
00589       args = data + strlen("if");
00590       while ((*args < 33) && (*args != '(')) args++;
00591       if ((*args == '(') && (c = argument_end(args))) {
00592          int ifblock;
00593          int ifstart;
00594          int elsestart;
00595          int ifend;
00596          int ifskip;
00597          char *elses;
00598          char *iflabel;
00599          args++;
00600          *c = '\0';
00601          c++;
00602          c = ast_skip_blanks(c);
00603          if (aeldebug & DEBUG_TOKENS)
00604             ast_verbose("--IF on : '%s' : '%s'\n", args, c);
00605          mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
00606          margs = alloca(mlen);
00607          /* Remember where the ifblock starts, and skip over */
00608          ifblock = (*pos)++;
00609          iflabel = *label;
00610          *label = NULL;
00611          /* Remember where the start of the ifblock is */
00612          ifstart = *pos;
00613          snprintf(margs, mlen, "if-%s-%d", name, ifblock);
00614          /* Now process the block of the if */
00615          if (aeldebug & DEBUG_TOKENS)
00616             ast_verbose("Searching for elses in '%s'\n", c);
00617          elses = grab_else(c, filename, lineno);
00618          build_step("if", margs, filename, lineno, con, exten, pos, c, fillout, label);
00619          if (elses) {
00620             /* Reserve a goto to exit the if */
00621             ifskip = *pos;
00622             (*pos)++;
00623             elsestart = *pos;
00624             build_step("else", margs, filename, lineno, con, exten, pos, elses, fillout, label);
00625          } else {
00626             elsestart = *pos;
00627             ifskip = 0;
00628          }
00629          ifend = *pos;
00630          (*pos)++;
00631          app = "NoOp";
00632          snprintf(margs, mlen, "Finish if-%s-%d", name, ifblock);
00633          if (ast_add_extension2(con, 0, exten, ifend, *label, NULL, app, strdup(margs), FREE, registrar))
00634             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00635          *label = NULL;
00636          app = "GotoIf";
00637          snprintf(margs, mlen, "$[ %s ]?%d:%d", args, ifstart, elsestart);
00638          if (ast_add_extension2(con, 0, exten, ifblock, iflabel, NULL, app, strdup(margs), FREE, registrar))
00639             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00640          if (ifskip) {
00641             /* Skip as appropriate around else clause */
00642             snprintf(margs, mlen, "%d", ifend);
00643             if (ast_add_extension2(con, 0, exten, ifskip, NULL, NULL, "Goto", strdup(margs), FREE, registrar))
00644                ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00645          }
00646       } else
00647          ast_log(LOG_WARNING, "Syntax error in if declaration in %s around line %d!\n", filename, lineno); 
00648    } else if (matches_keyword(data, "while")) {
00649       /* While... */
00650       fillin = NULL;
00651       args = data + strlen("while");
00652       while ((*args < 33) && (*args != '(')) args++;
00653       if ((*args == '(') && (c = argument_end(args))) {
00654          int whileblock;
00655          int whilestart;
00656          int whileend;
00657          char *whilelabel;
00658          args++;
00659          *c = '\0';
00660          c++;
00661          c = ast_skip_blanks(c);
00662          if (aeldebug & DEBUG_TOKENS)
00663             ast_verbose("--WHILE on : '%s' : '%s'\n", args, c);
00664          mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
00665          margs = alloca(mlen);
00666          /* Remember where to put the conditional, and keep its position */
00667          whilestart = (*pos);
00668          whilelabel = *label;
00669          *label = NULL;
00670          (*pos)++;
00671          /* Remember where the whileblock starts */
00672          whileblock = (*pos);
00673          snprintf(margs, mlen, "while-%s-%d", name, whilestart);
00674          build_step("while", margs, filename, lineno, con, exten, pos, c, &fillin, label);
00675          /* Close the loop */
00676          app = "Goto";
00677          snprintf(margs, mlen, "%d", whilestart);
00678          if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
00679             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00680          *label = NULL;
00681          whileend = (*pos);
00682          /* Place trailer */
00683          app = "NoOp";
00684          snprintf(margs, mlen, "Finish while-%s-%d", name, whilestart);
00685          if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
00686             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00687          *label = NULL;
00688          app = "GotoIf";
00689          snprintf(margs, mlen, "$[ %s ]?%d:%d", args, whileblock, whileend);
00690          if (ast_add_extension2(con, 0, exten, whilestart, whilelabel, NULL, app, strdup(margs), FREE, registrar))
00691             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00692          fillin_process(con, fillin, filename, lineno, exten, whileend, exten, whilestart);
00693          fillin_free(fillin);
00694       } else
00695          ast_log(LOG_WARNING, "Syntax error in while declaration in %s around line %d!\n", filename, lineno); 
00696    } else if (matches_keyword(data, "jump")) {
00697       char *p;
00698       /* Jump... */
00699       fillin = NULL;
00700       args = data + strlen("jump");
00701       args = ast_skip_blanks(args);
00702       if (aeldebug & DEBUG_TOKENS)
00703          ast_verbose("--JUMP to : '%s'\n", args);
00704       p = strchr(args, ',');
00705       if (p) {
00706          *p = '\0';
00707          p++;
00708       } else
00709          p = "1";
00710       c = strchr(args, '@');
00711       if (c) {
00712          *c = '\0';
00713          c++;
00714       }
00715       mlen = strlen(exten) + 128 + strlen(args) + strlen(name) + (c ? strlen(c) : 0);
00716       margs = alloca(mlen);
00717       if (c) 
00718          snprintf(margs, mlen, "%s|%s|%s", c,args, p);
00719       else
00720          snprintf(margs, mlen, "%s|%s", args, p);
00721       app = "Goto";
00722       if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
00723          ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00724       *label = NULL;
00725    } else if (matches_keyword(data, "goto")) {
00726       /* Jump... */
00727       fillin = NULL;
00728       args = data + strlen("goto");
00729       args = ast_skip_blanks(args);
00730       if (aeldebug & DEBUG_TOKENS)
00731          ast_verbose("--GOTO to : '%s'\n", args);
00732       app = "Goto";
00733       if (args[0] == '(' && args[strlen(args) - 1] == ')') {
00734          args[0] = '\0';
00735          args++;
00736          args[strlen(args) - 1] = '\0';
00737       }
00738       if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(args), FREE, registrar))
00739          ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00740       *label = NULL;
00741    } else if (matches_keyword(data, "for")) {
00742       /* While... */
00743       fillin = NULL;
00744       args = data + strlen("for");
00745       while ((*args < 33) && (*args != '(')) args++;
00746       if ((*args == '(') && (c = argument_end(args))) {
00747          int forblock;
00748          int forprep;
00749          int forstart;
00750          int forend;
00751          struct stringlink *fields;
00752          char *tmp;
00753          char *forlabel = NULL;
00754          args++;
00755          *c = '\0';
00756          c++;
00757          c = ast_skip_blanks(c);
00758          /* Parse arguments first */
00759          tmp = alloca(strlen(args) + 10);
00760          if (tmp) {
00761             snprintf(tmp, strlen(args) + 10, "{%s;}", args);
00762             fields = arg_parse(tmp, filename, lineno);
00763          } else
00764             fields = NULL;
00765          if (fields && fields->next && fields->next->next) {
00766             if (aeldebug & DEBUG_TOKENS)
00767                ast_verbose("--FOR ('%s' ; '%s' ; '%s') : '%s'\n", fields->data, fields->next->data, fields->next->next->data, c);
00768             mlen = strlen(exten) + 128 + strlen(args) + strlen(name);
00769             margs = alloca(mlen);
00770             forprep = *pos;
00771             snprintf(margs, mlen, "for-%s-%d", name, forprep);
00772             fillin = NULL;
00773             build_step("while", margs, filename, lineno, con, exten, pos, fields->data, &fillin, label);
00774             /* Remember where to put the conditional, and keep its position */
00775             forstart = (*pos);
00776             forlabel = *label;
00777             (*pos)++;
00778             *label = NULL;
00779             /* Remember where the whileblock starts */
00780             forblock = (*pos);
00781             build_step("for", margs, filename, lineno, con, exten, pos, c, &fillin, label);
00782             build_step("for", margs, filename, lineno, con, exten, pos, fields->next->next->data, &fillin, label);
00783             /* Close the loop */
00784             app = "Goto";
00785             snprintf(margs, mlen, "%d", forstart);
00786             if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
00787                ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00788             *label = NULL;
00789             forend = (*pos);
00790             /* Place trailer */
00791             app = "NoOp";
00792             snprintf(margs, mlen, "Finish for-%s-%d", name, forprep);
00793             if (ast_add_extension2(con, 0, exten, (*pos)++, *label, NULL, app, strdup(margs), FREE, registrar))
00794                ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00795             *label = NULL;
00796             app = "GotoIf";
00797             snprintf(margs, mlen, "$[ %s ]?%d:%d", fields->next->data, forblock, forend);
00798             if (ast_add_extension2(con, 0, exten, forstart, forlabel, NULL, app, strdup(margs), FREE, registrar))
00799                ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", forstart, what, name);
00800             fillin_process(con, fillin, filename, lineno, exten, forend, exten, forstart);
00801             fillin_free(fillin);
00802          } else
00803             ast_log(LOG_NOTICE, "Improper for declaration in %s around line %d!\n", filename, lineno); 
00804          arg_free(fields);
00805       } else
00806          ast_log(LOG_WARNING, "Syntax error in for declaration in %s around line %d!\n", filename, lineno); 
00807          
00808    } else if (!strcasecmp(data, "break") || !strcasecmp(data, "continue")) {
00809       struct fillin *fi;
00810       fi = malloc(sizeof(struct fillin));
00811       if (fi) {
00812          memset(fi, 0, sizeof(struct fillin));
00813          if (!strcasecmp(data, "break"))
00814             fi->type = FILLIN_BREAK;
00815          else
00816             fi->type = FILLIN_CONTINUE;
00817          ast_copy_string(fi->exten, exten, sizeof(fi->exten));
00818          fi->priority = (*pos)++;
00819          fi->next = *fillout;
00820          *fillout = fi;
00821       }
00822    } else if (match_assignment(data, &rest)) {
00823       if (aeldebug & DEBUG_TOKENS)
00824          ast_verbose("ASSIGN  '%s' = '%s'\n", data, rest);
00825       mlen = strlen(rest) + strlen(data) + 20;
00826       margs = alloca(mlen);
00827       snprintf(margs, mlen, "%s=$[ %s ]", data, rest);
00828       app = "Set";
00829       if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(margs), FREE, registrar))
00830          ast_log(LOG_WARNING, "Unable to add assignment at priority '%d' of %s '%s'\n", *pos, what, name);
00831       else {
00832          *label = NULL;
00833          (*pos)++;
00834       }
00835    } else {
00836       app = data;
00837       args = app;
00838       while (*args && (*args > 32) && (*args != '(')) args++;
00839          if (*args != '(') {
00840          while(*args && (*args != '(')) { *args = '\0'; args++; };
00841       }
00842       if (*args == '(') {
00843          *args = '\0';
00844          args++;
00845          /* Got arguments, trim trailing ')' */
00846          c = args + strlen(args) - 1;
00847          while((c >= args) && (*c < 33) && (*c != ')')) { *c = '\0'; c--; };
00848          if ((c >= args) && (*c == ')')) *c = '\0';
00849       } else
00850          args = "";
00851       ast_process_quotes_and_slashes(args, ',', '|');
00852       if (app[0] == '&') {
00853          app++;
00854          margs = alloca(strlen(args) + strlen(app) + 10);
00855          sprintf(margs, "%s|%s", app, args);
00856          args = margs;
00857          app = "Macro";
00858       }
00859       if (aeldebug & DEBUG_TOKENS)
00860          ast_verbose("-- APP: '%s', ARGS: '%s'\n", app, args);
00861       if (ast_add_extension2(con, 0, exten, *pos, *label, NULL, app, strdup(args), FREE, registrar))
00862          ast_log(LOG_WARNING, "Unable to add step at priority '%d' of %s '%s'\n", *pos, what, name);
00863       else {
00864          (*pos)++;
00865          *label = NULL;
00866       }
00867    }
00868    return 0;
00869 }

static char* __grab_token ( char *  src,
const char *  filename,
int  lineno,
int  link 
) [static]

Definition at line 78 of file pbx_ael.c.

References ast_log(), ast_verbose(), DEBUG_TOKENS, LOG_WARNING, malloc, and strdup.

Referenced by arg_parse(), and grab_token().

00079 {
00080    char *c;
00081    char *b;
00082    char *a;
00083    int level = 0;
00084    char *ret;
00085 #if 0
00086    if (aeldebug || DEBUG_TOKENS) 
00087       ast_verbose("Searching for token in '%s'!\n", src);
00088 #endif
00089    c = src;
00090    while(*c) {
00091       if ((*c == '\\')) {
00092          c++;
00093          if (!*c)
00094             c--;
00095       } else {
00096          if ((*c == '{') || (*c == '(')) {
00097             level++;
00098          } else if ((*c == '}') || (*c == ')')) {
00099             if (level)
00100                level--;
00101             else
00102                ast_log(LOG_WARNING, "Syntax error at line %d of '%s', too many closing braces!\n", lineno, filename);
00103          } else if ((*c == ';') && !level) {
00104             /* Got a token! */
00105             *c = '\0';
00106             b = c;
00107             b--;
00108             c++;
00109             while((b > src) && (*b < 33)) { 
00110                *b = '\0'; 
00111                b--; 
00112             }
00113             a = ast_skip_blanks(src);
00114             if (link) {
00115                ret = malloc(strlen(a) + sizeof(struct stringlink) + 1);
00116                if (ret)
00117                   strcpy(ret + sizeof(struct stringlink), a);
00118             } else
00119                ret = strdup(a);
00120             /* Save remainder */
00121             memmove(src, c, strlen(c) + 1);
00122             return ret;
00123          }
00124       }
00125       c++;
00126    }
00127    return NULL;      
00128 }

static int ael_debug_contexts ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1221 of file pbx_ael.c.

References DEBUG_CONTEXTS.

01222 {
01223    aeldebug |= DEBUG_CONTEXTS;
01224    return 0;
01225 }

static int ael_debug_macros ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1215 of file pbx_ael.c.

References DEBUG_MACROS.

01216 {
01217    aeldebug |= DEBUG_MACROS;
01218    return 0;
01219 }

static int ael_debug_read ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1203 of file pbx_ael.c.

References DEBUG_READ.

01204 {
01205    aeldebug |= DEBUG_READ;
01206    return 0;
01207 }

static int ael_debug_tokens ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1209 of file pbx_ael.c.

References DEBUG_TOKENS.

01210 {
01211    aeldebug |= DEBUG_TOKENS;
01212    return 0;
01213 }

static int ael_no_debug ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1227 of file pbx_ael.c.

01228 {
01229    aeldebug = 0;
01230    return 0;
01231 }

static int ael_reload ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 1233 of file pbx_ael.c.

References ast_context_destroy(), and pbx_load_module().

01234 {
01235    ast_context_destroy(NULL, registrar);
01236    return (pbx_load_module());
01237 }

static void arg_free ( struct stringlink cur  )  [static]

Definition at line 241 of file pbx_ael.c.

References free, last, and stringlink::next.

Referenced by __build_step(), build_step(), handle_context(), handle_macro(), and handle_root_token().

00242 {
00243    struct stringlink *last;
00244    while(cur) {
00245       last = cur;
00246       cur = cur->next;
00247       free(last);
00248    }
00249 }

static struct stringlink* arg_parse ( char *  args,
const char *  filename,
int  lineno 
) [static]

Definition at line 135 of file pbx_ael.c.

References __grab_token(), ast_verbose(), DEBUG_TOKENS, malloc, and stringlink::next.

Referenced by __build_step(), build_step(), handle_context(), and split_token().

00136 {
00137    struct stringlink *cur, *prev=NULL, *root=NULL;
00138    if (args) {
00139       if (aeldebug & DEBUG_TOKENS) 
00140          ast_verbose("Parsing args '%s'!\n", args);
00141       if (args[0] == '{') {
00142          /* Strip mandatory '}' from end */
00143          args[strlen(args) - 1] = '\0';
00144          while ((cur = (struct stringlink *)__grab_token(args + 1, filename, lineno, 1))) {
00145             cur->next = NULL;
00146             if (prev)
00147                prev->next = cur;
00148             else
00149                root = cur;
00150             prev = cur;
00151          }
00152       } else if (*args) {
00153          root = malloc(sizeof(struct stringlink) + strlen(args) + 1);
00154          if (root) {
00155             strcpy(root->data, args);
00156             root->next = NULL;
00157          }
00158       }
00159    }
00160    return root;
00161 }

static char* argument_end ( char *  str  )  [static]

Definition at line 456 of file pbx_ael.c.

Referenced by __build_step().

00457 {
00458    int level=0;
00459    while(*++str) {
00460       switch(*str) {
00461       case '(':
00462          level++;
00463          break;
00464       case ')':
00465          if(level)
00466             level--;
00467          else
00468             return str;
00469          break;
00470       default:
00471          break;
00472       }
00473    }
00474    return NULL;
00475 }

static int ast_ael_compile ( struct ast_context **  local_contexts,
const char *  filename 
) [static]

Definition at line 1127 of file pbx_ael.c.

References ast_config_AST_CONFIG_DIR, ast_log(), ast_verbose(), DEBUG_READ, free, grab_token(), handle_root_token(), local_contexts, LOG_WARNING, malloc, and realloc.

Referenced by pbx_load_module().

01128 {
01129    char *rfilename;
01130    char *buf, *tbuf;
01131    int bufsiz;
01132    FILE *f;
01133    char *c;
01134    char *token;
01135    int lineno=0;
01136 
01137    if (filename[0] == '/')
01138       rfilename = (char *)filename;
01139    else {
01140       rfilename = alloca(strlen(filename) + strlen(ast_config_AST_CONFIG_DIR) + 2);
01141       sprintf(rfilename, "%s/%s", ast_config_AST_CONFIG_DIR, filename);
01142    }
01143    
01144    f = fopen(rfilename, "r");
01145    if (!f) {
01146       ast_log(LOG_WARNING, "Unable to open '%s': %s\n", rfilename, strerror(errno));
01147       return -1;
01148    }
01149    buf = malloc(4096);
01150    if (!buf) {
01151       ast_log(LOG_WARNING, "Out of memory!\n");
01152       fclose(f);
01153       return -1;
01154    }
01155    buf[0] = 0;
01156    bufsiz = 4096;
01157    while(!feof(f)) {
01158       if (bufsiz - strlen(buf) < 2048) {
01159          bufsiz += 4096;
01160          tbuf = realloc(buf, bufsiz);
01161          if (tbuf) {
01162             buf = tbuf;
01163          } else {
01164             free(buf);
01165             ast_log(LOG_WARNING, "Out of memory!\n");
01166             fclose(f);
01167          }
01168       }
01169       if (fgets(buf + strlen(buf), bufsiz - strlen(buf), f)) {
01170          lineno++;
01171          while(*buf && buf[strlen(buf) - 1] < 33)
01172             buf[strlen(buf) - 1] = '\0';
01173          c = strstr(buf, "//");
01174          if (c)
01175             *c = '\0';
01176          if (*buf) {
01177             if (aeldebug & DEBUG_READ)
01178                ast_verbose("Newly composed line '%s'\n", buf);
01179             while((token = grab_token(buf, filename, lineno))) {
01180                handle_root_token(local_contexts, token, 0, filename, lineno);
01181                free(token);
01182             }
01183          }
01184       }
01185    };
01186    free(buf);
01187    fclose(f);
01188    return 0;
01189 }

static int build_step ( const char *  what,
const char *  name,
const char *  filename,
int  lineno,
struct ast_context con,
char *  exten,
int *  pos,
char *  data,
struct fillin **  fillout,
char **  label 
) [static]

Definition at line 871 of file pbx_ael.c.

References __build_step(), arg_free(), arg_parse(), stringlink::data, fillin_free(), fillin_process(), and stringlink::next.

Referenced by __build_step(), handle_context(), and handle_macro().

00872 {
00873    struct stringlink *args, *cur;
00874    int res=0;
00875    struct fillin *fillin=NULL;
00876    int dropfill = 0;
00877    char *labelin = NULL;
00878    if (!fillout) {
00879       fillout = &fillin;
00880       dropfill = 1;
00881    }
00882    if (!label) {
00883       label = &labelin;
00884    };
00885    args = arg_parse(data, filename, lineno);
00886    cur = args;
00887    while(cur) {
00888       res |= __build_step(what, name, filename, lineno, con, exten, pos, cur->data, fillout, label);
00889       cur = cur->next;
00890    }
00891    arg_free(args);
00892    if (dropfill) {
00893       fillin_process(con, fillin, filename, lineno, NULL, 0, NULL, 0);
00894       fillin_free(fillin);
00895    }
00896    return res;
00897 }

char* description ( void   ) 

Provides a description of the module.

Returns:
a short description of your module

Definition at line 1276 of file pbx_ael.c.

01277 {
01278    return dtext;
01279 }

static void fillin_free ( struct fillin fillin  )  [static]

Definition at line 356 of file pbx_ael.c.

References free, and fillin::next.

Referenced by __build_step(), and build_step().

00357 {
00358    struct fillin *cur, *next;
00359    cur =  fillin;
00360    while(cur) {
00361       next = cur->next;
00362       free(cur);
00363       cur = next;
00364    }
00365 }

static void fillin_process ( struct ast_context con,
struct fillin fillin,
const char *  filename,
int  lineno,
const char *  breakexten,
int  breakprio,
const char *  contexten,
int  contprio 
) [static]

Definition at line 367 of file pbx_ael.c.

References app, ast_add_extension2(), ast_log(), AST_MAX_EXTENSION, fillin::exten, FILLIN_BREAK, FILLIN_CONTINUE, FREE, LOG_NOTICE, LOG_WARNING, fillin::next, fillin::priority, strdup, and fillin::type.

Referenced by __build_step(), and build_step().

00368 {
00369    struct fillin *cur;
00370    char *app;
00371    char mdata[AST_MAX_EXTENSION + 20];
00372    cur = fillin;
00373    while(cur) {
00374       if (cur->type == FILLIN_BREAK) {
00375          if (breakexten && breakprio) {
00376             app = "Goto";
00377             snprintf(mdata, sizeof(mdata), "%s|%d", breakexten, breakprio);
00378          } else {
00379             app = "NoOp";
00380             snprintf(mdata, sizeof(mdata), "Invalid break");
00381             ast_log(LOG_NOTICE, "Ignoring inappropriate break around line %d of %s\n", lineno, filename);
00382          }
00383          if (ast_add_extension2(con, 0, cur->exten, cur->priority, NULL, NULL, app, strdup(mdata), FREE, registrar))
00384             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of break '%s'\n", cur->priority, cur->exten);
00385       } else if (cur->type == FILLIN_CONTINUE) {
00386          if (contexten && contprio) {
00387             app = "Goto";
00388             snprintf(mdata, sizeof(mdata), "%s|%d", contexten, contprio);
00389          } else {
00390             app = "NoOp";
00391             snprintf(mdata, sizeof(mdata), "Invalid continue");
00392             ast_log(LOG_NOTICE, "Ignoring inappropriate continue around line %d of %s\n", lineno, filename);
00393          }
00394          if (ast_add_extension2(con, 0, cur->exten, cur->priority, NULL, NULL, app, strdup(mdata), FREE, registrar))
00395             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of continue '%s'\n", cur->priority, cur->exten);
00396       } else {
00397          ast_log(LOG_WARNING, "Whoa, unknown fillin type '%d'\n", cur->type);
00398       }
00399       cur = cur->next;
00400    }
00401 }

static const char* get_case ( char *  s,
char **  restout,
int *  pattern 
) [static]

Definition at line 318 of file pbx_ael.c.

References ast_verbose(), and DEBUG_TOKENS.

Referenced by __build_step().

00319 {
00320    char *newcase=NULL;
00321    char *rest=NULL;
00322    if (!strncasecmp(s, "case", 4) && s[4] && ((s[4] < 33) || (s[4] == ':'))) {
00323       newcase = s + 4;
00324       newcase = ast_skip_blanks(newcase);
00325       rest = newcase;
00326       *pattern = 0;
00327    } else if (!strncasecmp(s, "pattern", 7) && s[7] && ((s[7] < 33) || (s[7] == ':'))) {
00328       newcase = s + 8;
00329       newcase = ast_skip_blanks(newcase);
00330       rest = newcase;
00331       *pattern = 1;
00332    } else if (!strncasecmp(s, "default", 7) && ((s[7] < 33) || (s[7] == ':'))) {
00333       newcase = ".";
00334       rest = s + 7;
00335       rest = ast_skip_blanks(rest);
00336       *pattern = 1;
00337    }
00338 
00339    if (rest) {
00340       while (*rest && (*rest > 32) && (*rest != ':')) rest++;
00341       if (*rest) {
00342          *rest = 0;
00343          rest++;
00344          while (*rest && ((*rest == ':') || (*rest < 33))) rest++;
00345          *restout = rest;
00346       } else {
00347          *restout = "";
00348       }
00349    } else
00350       *restout = s;
00351    if (aeldebug & DEBUG_TOKENS)
00352       ast_verbose("GETCASE: newcase is '%s', rest = '%s'\n", newcase, *restout);
00353    return newcase;
00354 }

static char* grab_else ( char *  args,
const char *  filename,
int  lineno 
) [static]

Definition at line 163 of file pbx_ael.c.

References ast_verbose(), and DEBUG_TOKENS.

Referenced by __build_step().

00164 {
00165    char *ret = NULL;
00166    int level=0;
00167    char *c;
00168    if (args) {
00169       if (args[0] == '{') {
00170          c = args;
00171          while(*c) {
00172             if (*c == '{')
00173                level++;
00174             else if (*c == '}') {
00175                level--;
00176                if (!level) {
00177                   c++;
00178                   while(*c && (*c < 33)) { *c = '\0'; c++; };
00179                   if (!strncasecmp(c, "else", 4) && 
00180                      ((c[4] == '{') || (c[4] < 33))) {
00181                         /* Ladies and gentlemen, we have an else clause */
00182                      *c = '\0';
00183                      c += 4;
00184                      c = ast_skip_blanks(c);
00185                      ret = c;
00186                      if (aeldebug & DEBUG_TOKENS)
00187                         ast_verbose("Returning else clause '%s'\n", c);
00188                   }
00189                   break;
00190                }
00191             }
00192             c++;
00193          }
00194       }
00195    }
00196    return ret;
00197 }

static char* grab_token ( char *  src,
const char *  filename,
int  lineno 
) [static]

Definition at line 130 of file pbx_ael.c.

References __grab_token().

Referenced by ast_ael_compile().

00131 {
00132    return __grab_token(src, filename, lineno, 0);
00133 }

static void handle_context ( struct ast_context **  local_contexts,
struct stringlink vars,
const char *  filename,
int  lineno 
) [static]

Definition at line 1019 of file pbx_ael.c.

References arg_free(), arg_parse(), ast_context_add_ignorepat2(), ast_context_add_include2(), ast_context_add_switch2(), ast_context_create(), ast_log(), ast_verbose(), build_step(), stringlink::data, DEBUG_CONTEXTS, local_contexts, LOG_NOTICE, LOG_WARNING, matches_extension(), matches_keyword(), name, stringlink::next, parse_keyword(), and split_token().

Referenced by handle_root_token().

01020 {
01021    struct stringlink *argv;
01022    struct stringlink *cur2;
01023    struct stringlink *argv2;
01024    struct stringlink *cur;
01025    struct ast_context *con;
01026    char *rest;
01027    char *c;
01028    char name[256];
01029    int pos;
01030 
01031    if (aeldebug & DEBUG_CONTEXTS)
01032       ast_verbose("Root context def is '%s'\n", vars->data);
01033    argv = split_token(vars->data, filename, lineno);
01034    if (aeldebug & DEBUG_CONTEXTS) 
01035       ast_verbose("Found context '%s'\n", vars->data);
01036    snprintf(name, sizeof(name), "%s", vars->data);
01037    con = ast_context_create(local_contexts, name, registrar);
01038    if (con) {
01039       cur = argv;
01040       while(cur) {
01041          if (matches_keyword(cur->data, "includes")) {
01042             if (aeldebug & DEBUG_CONTEXTS)
01043                ast_verbose("--INCLUDES: '%s'\n", cur->data);
01044             parse_keyword(cur->data, &rest);
01045             if (rest) {
01046                argv2 = arg_parse(rest, filename, lineno);
01047                cur2 = argv2;
01048                while(cur2) {
01049                   ast_context_add_include2(con, cur2->data, registrar);
01050                   cur2 = cur2->next;
01051                }
01052                arg_free(argv2);
01053             }
01054          } else if (matches_keyword(cur->data, "ignorepat")) {
01055             if (aeldebug & DEBUG_CONTEXTS)
01056                ast_verbose("--IGNOREPAT: '%s'\n", cur->data);
01057             parse_keyword(cur->data, &rest);
01058             if (rest) {
01059                argv2 = arg_parse(rest, filename, lineno);
01060                cur2 = argv2;
01061                while(cur2) {
01062                   ast_context_add_ignorepat2(con, cur2->data, registrar);
01063                   cur2 = cur2->next;
01064                }
01065                arg_free(argv2);
01066             }
01067          } else if (matches_keyword(cur->data, "switches") || matches_keyword(cur->data, "eswitches")) {
01068             if (aeldebug & DEBUG_CONTEXTS)
01069                ast_verbose("--[E]SWITCH: '%s'\n", cur->data);
01070             parse_keyword(cur->data, &rest);
01071             if (rest) {
01072                argv2 = arg_parse(rest, filename, lineno);
01073                cur2 = argv2;
01074                while(cur2) {
01075                   c = strchr(cur2->data, '/');
01076                   if (c) {
01077                      *c = '\0';
01078                      c++;
01079                   } else
01080                      c = "";
01081                   ast_context_add_switch2(con, cur2->data, c, (cur->data[0] == 'e'), registrar);
01082                   cur2 = cur2->next;
01083                }
01084                arg_free(argv2);
01085             }
01086          } else if (matches_extension(cur->data, &rest)) {
01087             if (aeldebug & DEBUG_CONTEXTS)
01088                ast_verbose("Extension: '%s' => '%s'\n", cur->data, rest);
01089             pos = 1;
01090             build_step("extension", cur->data, filename, lineno, con, cur->data, &pos, rest, NULL, NULL);
01091          }
01092          cur = cur->next;
01093       }
01094    } else
01095          ast_log(LOG_WARNING, "Unable to create context '%s'\n", name);
01096    arg_free(argv);
01097    if (vars->next)
01098       ast_log(LOG_NOTICE, "Ignoring excess tokens in macro definition around line %d of %s!\n", lineno, filename);
01099 }

static void handle_globals ( struct stringlink vars  )  [static]

Definition at line 251 of file pbx_ael.c.

References stringlink::data, stringlink::next, and pbx_builtin_setvar().

Referenced by handle_root_token().

00252 {
00253    while(vars) {
00254       pbx_builtin_setvar(NULL, vars->data);
00255       vars = vars->next;
00256    }
00257 }

static void handle_macro ( struct ast_context **  local_contexts,
struct stringlink vars,
const char *  filename,
int  lineno 
) [static]

Definition at line 921 of file pbx_ael.c.

References arg_free(), ast_add_extension2(), ast_context_create(), ast_log(), ast_verbose(), build_step(), stringlink::data, DEBUG_MACROS, FREE, local_contexts, LOG_NOTICE, LOG_WARNING, matches_keyword(), name, stringlink::next, parse_catch(), split_params(), split_token(), and strdup.

Referenced by handle_root_token().

00922 {
00923    struct stringlink *argv;
00924    struct stringlink *paramv;
00925    struct stringlink *cur;
00926    struct ast_context *con;
00927    struct fillin *fillin;
00928    char *catch, *rest;
00929    char name[256];
00930    int pos;
00931    int cpos;
00932 
00933    if (aeldebug & DEBUG_MACROS)
00934       ast_verbose("Root macro def is '%s'\n", vars->data);
00935    argv = split_token(vars->data, filename, lineno);
00936    paramv = split_params(vars->data, filename, lineno);
00937    if (aeldebug & DEBUG_MACROS) 
00938       ast_verbose("Found macro '%s'\n", vars->data);
00939    snprintf(name, sizeof(name), "macro-%s", vars->data);
00940    con = ast_context_create(local_contexts, name, registrar);
00941    if (con) {
00942       pos = 1;
00943       cur = paramv;
00944       while(cur) {
00945          if (aeldebug & DEBUG_MACROS)
00946             ast_verbose("  PARAM => '%s'\n", cur->data);
00947          snprintf(name, sizeof(name), "%s=${ARG%d}", cur->data, pos);
00948          if (ast_add_extension2(con, 0, "s", pos, NULL, NULL, "Set", strdup(name), FREE, registrar))
00949             ast_log(LOG_WARNING, "Unable to add step at priority '%d' of macro '%s'\n", pos, vars->data);
00950          else
00951             pos++;
00952          cur = cur->next;
00953       }
00954       cur = argv;
00955       while(cur) {
00956          if (aeldebug & DEBUG_MACROS)
00957             ast_verbose("  STEP => '%s'\n", cur->data);
00958          if (matches_keyword(cur->data, "catch")) {
00959             if (aeldebug & DEBUG_MACROS)
00960                ast_verbose("--CATCH: '%s'\n", cur->data);
00961             if (parse_catch(cur->data, &catch, &rest)) {
00962                cpos = 1;
00963                build_step("catch", catch, filename, lineno, con, catch, &cpos, rest, NULL, NULL);
00964             } else
00965                ast_log(LOG_NOTICE, "Parse error for catch at about line %d of %s\n", lineno, filename);
00966          } else {
00967             fillin = NULL;
00968             build_step("macro", vars->data, filename, lineno, con, "s", &pos, cur->data, NULL, NULL);
00969          }
00970          cur = cur->next;
00971       }
00972    } else
00973       ast_log(LOG_WARNING, "Unable to create context '%s'\n", name);
00974    arg_free(paramv);
00975    arg_free(argv);
00976    if (vars->next)
00977       ast_log(LOG_NOTICE, "Ignoring excess tokens in macro definition around line %d of %s!\n", lineno, filename);
00978 }

static int handle_root_token ( struct ast_context **  local_contexts,
char *  token,
int  level,
const char *  filename,
int  lineno 
) [static]

Definition at line 1101 of file pbx_ael.c.

References arg_free(), ast_log(), ast_verbose(), stringlink::data, DEBUG_TOKENS, handle_context(), handle_globals(), handle_macro(), local_contexts, LOG_NOTICE, stringlink::next, and split_token().

Referenced by ast_ael_compile().

01102 {
01103    struct stringlink *argv, *cur;
01104    argv = split_token(token, filename, lineno);
01105    if (aeldebug & DEBUG_TOKENS) {
01106       ast_verbose("Found root token '%s' at level %d (%s:%d)!\n", token, level, filename, lineno);
01107       cur = argv;
01108       while(cur) {
01109          ast_verbose("   ARG => '%s'\n", cur->data);
01110          cur = cur->next;
01111       }
01112    }
01113    if (!strcasecmp(token, "globals")) {
01114       handle_globals(argv);
01115    } else if (!strcasecmp(token, "macro")) {
01116       handle_macro(local_contexts, argv, filename, lineno);
01117    } else if (!strcasecmp(token, "context")) {
01118       handle_context(local_contexts, argv, filename, lineno);
01119    } else {
01120       ast_log(LOG_NOTICE, "Unknown root token '%s'\n", token);
01121    }
01122    arg_free(argv);
01123    return 0;
01124 }

char* key ( void   ) 

Returns the ASTERISK_GPL_KEY.

This returns the ASTERISK_GPL_KEY, signifiying that you agree to the terms of the GPL stated in the ASTERISK_GPL_KEY. Your module will not load if it does not return the EXACT message:

 char *key(void) {
         return ASTERISK_GPL_KEY;
 }

Returns:
ASTERISK_GPL_KEY

Definition at line 1281 of file pbx_ael.c.

References ASTERISK_GPL_KEY.

01282 {
01283    return ASTERISK_GPL_KEY;
01284 }

int load_module ( void   ) 

Initialize the module.

Initialize the Agents module. This function is being called by Asterisk when loading the module. Among other thing it registers applications, cli commands and reads the cofiguration file.

Returns:
int Always 0.

Definition at line 1259 of file pbx_ael.c.

References ael_cli, ast_cli_register_multiple(), and pbx_load_module().

01260 {
01261    ast_cli_register_multiple(ael_cli, sizeof(ael_cli)/ sizeof(ael_cli[0]));
01262    return (pbx_load_module());
01263 }

static int match_assignment ( char *  variable,
char **  value 
) [static]

Definition at line 403 of file pbx_ael.c.

Referenced by __build_step().

00404 {
00405    char *c;
00406    char *ws;
00407    int inpar = 0;
00408    c = variable;
00409    
00410    while (*c) {
00411       if(*c == ')' && (inpar > 0)) {
00412          inpar--;
00413       } else if(*c == '(' && (inpar >= 0)) {
00414          inpar++;
00415       } else if(*c == '=' && (inpar == 0)) {
00416          break;
00417       }
00418       c++;
00419    } 
00420    ws = c;
00421    c = ast_skip_blanks(c);
00422    if (*c == '=') {
00423       *ws = '\0';
00424       *c = '\0';
00425       c++;
00426       c = ast_skip_blanks(c);
00427       *value = c;
00428       return 1;
00429    }
00430    return 0;
00431 }

static int matches_extension ( char *  exten,
char **  extout 
) [static]

Definition at line 980 of file pbx_ael.c.

Referenced by handle_context().

00981 {
00982    char *c;
00983    *extout = NULL;
00984    c = exten;
00985    while(*c && (*c > 32)) c++;
00986    if (*c) {
00987       *c = '\0';
00988       c++;
00989       c = ast_skip_blanks(c);
00990       if (*c) {
00991          if (*c == '=') {
00992             *c = '\0';
00993             c++;
00994             if (*c == '>')
00995                c++;
00996             c = ast_skip_blanks(c);
00997             *extout = c;
00998             return 1;
00999          }
01000       }
01001    }
01002    return 0;
01003 }

static int matches_keyword ( const char *  data,
const char *  keyword 
) [static]

Definition at line 286 of file pbx_ael.c.

Referenced by __build_step(), handle_context(), and handle_macro().

00287 {
00288    char c;
00289    if (!strncasecmp(data, keyword, strlen(keyword))) {
00290       c = data[strlen(keyword)];
00291       if ((c < 33) || (c == '(') || (c == '{'))
00292          return 1;
00293    }
00294    return 0;
00295 }

static int matches_label ( char *  data,
char **  rest 
) [static]

Definition at line 433 of file pbx_ael.c.

References last.

Referenced by __build_step().

00434 {
00435    char last = 0;
00436    char *start = data;
00437    while (*data > 32) {
00438       last = *data;
00439       data++;
00440    }
00441    if (last != ':') {
00442       data = ast_skip_blanks(data);
00443       last = *data;
00444       data++;
00445    }
00446    if (last == ':') {
00447       *rest = data;
00448       /* Go back and trim up the label */
00449       while(*start && ((*start > 32) && (*start != ':'))) start++;
00450       *start = '\0';
00451       return 1;
00452    }
00453    return 0;
00454 }

static struct stringlink* param_parse ( char *  parms,
const char *  macro,
const char *  filename,
int  lineno 
) [static]

Definition at line 199 of file pbx_ael.c.

References ast_log(), LOG_NOTICE, malloc, and s.

Referenced by split_params().

00200 {
00201    char *s, *e;
00202    struct stringlink *root = NULL, *prev=NULL, *cur;
00203    if (!parms || !*parms)
00204       return NULL;
00205    if (*parms != '(') {
00206       ast_log(LOG_NOTICE, "Syntax error in parameter list for macro '%s' at about line %d of %s: Expecting '(' but got '%c'\n", macro, lineno, filename, *parms);
00207       return NULL;
00208    }
00209    s = parms + 1;
00210    while(*s) {
00211       s = ast_skip_blanks(s);
00212       e = s;
00213       while(*e &&  (*e != ')') && (*e != ',')) {
00214          if (*e < 33)
00215             *e = '\0';
00216          e++;
00217       }
00218       if (*e) {
00219          /* Strip token */
00220          *e = '\0';
00221          e++;
00222          /* Skip over whitespace */
00223          e = ast_skip_blanks(e);
00224          /* Link */
00225          cur = malloc(strlen(s) + sizeof(struct stringlink) + 1);
00226          if (cur) {
00227             cur->next = NULL;
00228             strcpy(cur->data, s);
00229             if (prev)
00230                prev->next = cur;
00231             else
00232                root = cur;
00233             prev = cur;
00234          }
00235          s = e;
00236       }
00237    }
00238    return root;
00239 }

static int parse_catch ( char *  data,
char **  catch,
char **  rest 
) [static]

Definition at line 899 of file pbx_ael.c.

Referenced by handle_macro().

00900 {
00901    /* Skip the word 'catch' */
00902    data += 5;
00903    data = ast_skip_blanks(data);
00904    /* Here's the extension */
00905    *catch = data;
00906    if (!*data)
00907       return 0;
00908    while (*data && (*data > 32)) data++;
00909    if (!*data)
00910       return 0;
00911    /* Trim any trailing spaces */
00912    *data = '\0';
00913    data++;
00914    data = ast_skip_blanks(data);
00915    if (!*data)
00916       return 0;
00917    *rest = data;
00918    return 1;
00919 }

static void parse_keyword ( char *  s,
char **  o 
) [static]

Definition at line 1005 of file pbx_ael.c.

Referenced by handle_context().

01006 {
01007    char *c;
01008    c = s;
01009    while((*c) && (*c > 32)) c++;
01010    if (*c) {
01011       *c = '\0';
01012       c++;
01013       c = ast_skip_blanks(c);
01014       *o = c;
01015    } else
01016       *o = NULL;
01017 }

static int pbx_load_module ( void   )  [static]

Definition at line 1191 of file pbx_ael.c.

References ast_ael_compile(), ast_context_verify_includes(), ast_merge_contexts_and_delete(), ast_walk_contexts(), and local_contexts.

Referenced by ael_reload(), handle_reload_extensions(), load_module(), and reload().

01192 {
01193    struct ast_context *local_contexts=NULL, *con;
01194    ast_ael_compile(&local_contexts, config);
01195    ast_merge_contexts_and_delete(&local_contexts, registrar);
01196    for (con = ast_walk_contexts(NULL); con; con = ast_walk_contexts(con))
01197       ast_context_verify_includes(con);
01198 
01199    return 0;
01200 }

int reload ( void   ) 

Reload stuff.

This function is where any reload routines take place. Re-read config files, change signalling, whatever is appropriate on a reload.

Returns:
The return value is not used.

Definition at line 1265 of file pbx_ael.c.

References ast_context_destroy(), and pbx_load_module().

01266 {
01267    ast_context_destroy(NULL, registrar);
01268    return pbx_load_module();
01269 }

static struct stringlink* split_params ( char *  token,
const char *  filename,
int  lineno 
) [static]

Definition at line 297 of file pbx_ael.c.

References param_parse().

Referenced by handle_macro().

00298 {
00299    char *params;
00300    struct stringlink *paramv;
00301    params = token;
00302    while(*params && (*params > 32) && (*params != '(')) params++;
00303    if (*params) {
00304       if (*params != '(') {
00305          *params = '\0';
00306          params++;
00307          params = ast_skip_blanks(params);
00308       }
00309       if (!*params)
00310          params = NULL;
00311    } else params = NULL;
00312    paramv = param_parse(params, token, filename, lineno);
00313    if (params)
00314       *params = '\0';
00315    return paramv;
00316 }

static struct stringlink* split_token ( char *  token,
const char *  filename,
int  lineno 
) [static]

Definition at line 259 of file pbx_ael.c.

References arg_parse().

Referenced by handle_context(), handle_macro(), and handle_root_token().

00260 {
00261    char *args, *p;
00262    struct stringlink *argv;
00263    args = token;
00264    while (*args && (*args > 32) && (*args != '{') && (*args != '(')) args++;
00265    if (*args) {
00266       p = args;
00267       args = ast_skip_blanks(args);
00268       if (*args != '(') {
00269          *p = '\0';
00270       } else {
00271          while (*args && (*args != ')')) args++;
00272          if (*args == ')') {
00273             args++;
00274             args = ast_skip_blanks(args);
00275          }
00276       }
00277       if (!*args)
00278          args = NULL;
00279    } else args = NULL;
00280    argv = arg_parse(args, filename, lineno);
00281    if (args)
00282       *args = '\0';
00283    return argv;
00284 }

int unload_module ( void   ) 

Cleanup all module structures, sockets, etc.

This is called at exit. Any registrations and memory allocations need to be unregistered and free'd here. Nothing else will do these for you (until exit).

Returns:
Zero on success, or non-zero on error.

Definition at line 1251 of file pbx_ael.c.

References ael_cli, ast_cli_unregister_multiple(), and ast_context_destroy().

01252 {
01253    ast_context_destroy(NULL, registrar);
01254    ast_cli_unregister_multiple(ael_cli, sizeof(ael_cli)/ sizeof(ael_cli[0]));
01255    return 0;
01256 }

int usecount ( void   ) 

Provides a usecount.

This function will be called by various parts of asterisk. Basically, all it has to do is to return a usecount when called. You will need to maintain your usecount within the module somewhere. The usecount should be how many channels provided by this module are in use.

Returns:
The module's usecount.

Definition at line 1271 of file pbx_ael.c.

01272 {
01273    return 0;
01274 }


Variable Documentation

struct ast_cli_entry ael_cli[] [static]

Definition at line 1239 of file pbx_ael.c.

Referenced by load_module(), and unload_module().

int aeldebug = 0 [static]

Definition at line 72 of file pbx_ael.c.

char* config = "extensions.ael" [static]

Definition at line 75 of file pbx_ael.c.

char* dtext = "Asterisk Extension Language Compiler" [static]

Definition at line 74 of file pbx_ael.c.

char* registrar = "pbx_ael" [static]

Definition at line 76 of file pbx_ael.c.

Referenced by load_config(), and park_add_hints().


Generated on Sat Sep 16 07:28:19 2006 for Asterisk - the Open Source PBX by  doxygen 1.4.7