Merge expression handling into variable handling
authorMark Spencer <markster@digium.com>
Fri, 18 Apr 2003 16:57:48 +0000 (16:57 +0000)
committerMark Spencer <markster@digium.com>
Fri, 18 Apr 2003 16:57:48 +0000 (16:57 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@870 65c4cc65-6c06-0410-ace0-fbb531ad65f3

pbx.c

diff --git a/pbx.c b/pbx.c
index dff4491..df1ca72 100755 (executable)
--- a/pbx.c
+++ b/pbx.c
@@ -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) 
 {