Merge expression handling into variable handling

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@870 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Spencer 2003-04-18 16:57:48 +00:00
parent f2245eff85
commit 53eabdf513
1 changed files with 77 additions and 183 deletions

260
pbx.c
View File

@ -859,7 +859,7 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp
int length;
char workspace[256];
char ltmp[256], var[256];
char *nextpos;
char *nextvar, *nextexp;
char *vars, *vare;
int pos, brackets, needsub, len;
@ -872,11 +872,22 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp
pos = strlen(whereweare);
/* Look for a variable */
nextpos = strstr(whereweare, "${");
nextvar = strstr(whereweare, "${");
nextexp = strstr(whereweare, "$[");
if (nextvar && nextexp) {
if (nextvar < nextexp)
nextexp = NULL;
else
nextvar = NULL;
}
/* If there is one, we only go that far */
if (nextpos)
pos = nextpos - whereweare;
if (nextvar)
pos = nextvar - whereweare;
else if (nextexp)
pos = nextexp - whereweare;
/* Can't copy more than 'count' bytes */
if (pos > count)
@ -889,11 +900,11 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp
cp2 += pos;
whereweare += pos;
if (nextpos) {
if (nextvar) {
/* We have a variable. Find the start and end, and determine
if we are going to have to recursively call ourselves on the
contents */
vars = vare = nextpos + 2;
vars = vare = nextvar + 2;
brackets = 1;
needsub = 0;
@ -904,7 +915,7 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp
brackets++;
} else if (vare[0] == '}') {
brackets--;
} else if (vare[0] == '[')
} else if ((vare[0] == '$') && (vare[1] == '['))
needsub++;
vare++;
}
@ -940,18 +951,70 @@ static void pbx_substitute_variables_helper(struct ast_channel *c,const char *cp
cp2 += length;
}
} else if (nextexp) {
/* We have an expression. Find the start and end, and determine
if we are going to have to recursively call ourselves on the
contents */
vars = vare = nextexp + 2;
brackets = 1;
needsub = 0;
/* Find the end of it */
while(brackets && *vare) {
if ((vare[0] == '$') && (vare[1] == '[')) {
needsub++;
brackets++;
} else if (vare[0] == ']') {
brackets--;
} else if ((vare[0] == '$') && (vare[1] == '{'))
needsub++;
vare++;
}
if (brackets)
ast_log(LOG_NOTICE, "Error in extension logic (missing ']')\n");
len = vare - vars - 1;
/* Skip totally over variable name */
whereweare += ( len + 3);
/* Store variable name (and truncate) */
memset(var, 0, sizeof(var));
strncpy(var, vars, sizeof(var) - 1);
var[len] = '\0';
/* Substitute if necessary */
if (needsub) {
memset(ltmp, 0, sizeof(ltmp));
pbx_substitute_variables_helper(c, var, ltmp, sizeof(ltmp) - 1);
vars = ltmp;
} else {
vars = var;
}
/* Evaluate expression */
cp4 = ast_expr(vars);
printf("Expression is '%s'\n", cp4);
if (cp4) {
length = strlen(cp4);
if (length > count)
length = count;
memcpy(cp2, cp4, length);
count -= length;
cp2 += length;
free(cp4);
}
} else
break;
}
}
static void pbx_substitute_variables(char *passdata, int datalen, struct ast_channel *c, struct ast_exten *e) {
char *cp1,*cp3,*cp4;
char cp2[256] = "";
char c1,c2;
int m,mve,origlen,quoted,dolsign,docopy;
char cp5[256]="";
memset(passdata, 0, datalen);
/* No variables or expressions in e->data, so why scan it? */
if (!strstr(e->data,"${") && !strstr(e->data,"$[")) {
strncpy(passdata, e->data, datalen - 1);
@ -959,177 +1022,8 @@ static void pbx_substitute_variables(char *passdata, int datalen, struct ast_cha
return;
}
pbx_substitute_variables_helper(c,e->data,cp2, sizeof(cp2) - 1);
/* Second stage, expression evaluation */
if ((strstr(cp2,"$[")==NULL)) {
strncpy(passdata, cp2, datalen - 1);
passdata[datalen-1] = '\0';
return;
}
/* else, do expression evaluation */
dolsign=0;
docopy=1;
origlen=strlen(cp2)+1;
cp4=NULL;
cp1=cp2;
quoted=0;
do {
c1=*cp1;
mve=0;
switch (c1) {
case '$' :
dolsign=1;
docopy=0;
break;
case '[' :
if (dolsign==0) {
docopy=1;
dolsign=0;
break;
}
dolsign=0;
docopy=0;
m=0;
mve=1;
cp1++;
while (((c2=*(cp1+m))!=']') && (c2!='\0')) {
m++;
}
cp3=malloc(m+2);
strncpy(cp3,cp1,m);
cp3[m]='\0';
cp1+=m;
/* Now we have the expression to evaluate on cp3 */
cp4=ast_expr(cp3);
free(cp3);
break;
default :
if (dolsign==1) {
strncat((char *)cp5,"$",1);
}
dolsign=0;
docopy=1;
mve=0;
break;
}
if (cp1!='\0') {
if (mve==0) {
if (docopy==1) {
strncat((char *)cp5,&c1,1);
}
} else {
if (cp4!=NULL) {
strncat((char *)cp5,cp4,strlen(cp4));
} else {
ast_log(LOG_WARNING,"mve!=0 and cp4=NULL, something gone astray\n");
}
}
}
} while (*cp1++!='\0');
strncpy(passdata, cp5, datalen - 1);
}
#if 0
static void *pbx_substitute_variables(struct ast_channel *c, struct ast_exten *e) {
char *cp1,*cp3,*cp4,*cp5;
char *cp2;
char c1,c2;
int m,mve,origlen,quoted,dolsign,docopy;
/* No variables or expressions in e->data, so why scan it? */
if (!strstr(e->data,"${") && !strstr(e->data,"$[")) {
return strndup(e->data,strlen(e->data)+1);
}
cp1=e->data;
cp2=malloc(sizeof(char)*256);
pbx_substitute_variables_helper(c,cp1,(char **)&cp2,0);
/* Second stage, expression evaluation */
if ((strstr(cp2,"$[")==NULL)) {
/* No expressions in cp2, return it */
return(cp2);
}
/* else, do expression evaluation */
dolsign=0;
docopy=1;
origlen=strlen(cp2)+1;
cp5=malloc(origlen);
memset(cp5,0,origlen);
cp4=NULL;
cp1=cp2;
quoted=0;
do {
c1=*cp1;
mve=0;
switch (c1) {
case '$' :
dolsign=1;
docopy=0;
break;
case '[' :
if (dolsign==0) {
docopy=1;
dolsign=0;
break;
}
dolsign=0;
docopy=0;
m=0;
mve=1;
cp1++;
while (((c2=*(cp1+m))!=']') && (c2!='\0')) {
m++;
}
cp3=malloc(m+2);
strncpy(cp3,cp1,m);
cp3[m]='\0';
cp1+=m;
/* Now we have the expression to evaluate on cp3 */
cp4=ast_expr(cp3);
free(cp3);
break;
default :
if (dolsign==1) {
strncat((char *)cp5,"$",1);
}
dolsign=0;
docopy=1;
mve=0;
break;
}
if (cp1!='\0') {
if (mve==0) {
if (docopy==1) {
strncat((char *)cp5,&c1,1);
}
} else {
if (cp4!=NULL) {
cp5=realloc(cp5,origlen+strlen(cp4)+1);
strncat((char *)cp5,cp4,strlen(cp4));
free(cp4);
} else {
ast_log(LOG_WARNING,"mve!=0 and cp4=NULL, something gone astray\n");
}
}
}
} while (*cp1++!='\0');
free(cp2);
return(cp5);
}
#endif
pbx_substitute_variables_helper(c,e->data,passdata, datalen - 1);
}
static int pbx_extension_helper(struct ast_channel *c, char *context, char *exten, int priority, char *callerid, int action)
{