Allow nested %q<> and %<>
authorAri Johnson <ari@theari.com>
Wed, 11 May 2011 00:16:20 +0000 (20:16 -0400)
committerAri Johnson <ari@theari.com>
Wed, 11 May 2011 00:16:20 +0000 (20:16 -0400)
hdrs/parse.h
src/parse.c
src/tables.c

index 4eb7715042ca8793c83505a58f8872391ba404e4..d489c117d3732091796bb7ef6d08c932e574f32c 100644 (file)
@@ -244,6 +244,7 @@ int process_expression(char *buff, char **bp, char const **str,
 #define PT_SEMI         0x00000010
 #define PT_EQUALS       0x00000020
 #define PT_SPACE        0x00000040
+#define PT_GT          0x00000080
 
 /* These represent '\0', '}', ']', ')', ',', ';', '=', and ' ', respectively.
  * If the character corresponding to a set flag is encountered, then
index babb4e7853d69b9031049393dd2c90d1f196af3e..edd3058dc74a505ecab2dfa9a583190aba4d90a1 100644 (file)
@@ -821,6 +821,10 @@ process_expression(char *buff, char **bp, char const **str,
       if (tflags & PT_SPACE)
         goto exit_sequence;
       break;
+    case '>':
+      if (tflags & PT_GT)
+        goto exit_sequence;
+      break;
     case '\0':
       goto exit_sequence;
     }
@@ -906,19 +910,10 @@ process_expression(char *buff, char **bp, char const **str,
         safe_chr(savec, buff, bp);
         (*str)++;
         switch (savec) {
-         case '<':
-           savec = **str;
-           if (!savec)
-             goto exit_sequence;
-           for (savec = **str; savec && savec != '>'; savec = **str) {
-             safe_chr(savec, buff, bp);
-             (*str)++;
-           }
-           if(!savec)
-             goto exit_sequence;
-           safe_chr(savec, buff, bp);
-           (*str)++;
-           break;
+       case '<':
+          process_expression(buff, bp, str, executor, caller, enactor,
+                            eflags & ~PE_STRIP_BRACES, PT_GT, pe_info);
+         break;
         case 'Q':
         case 'q':
           savec = **str;
@@ -926,16 +921,11 @@ process_expression(char *buff, char **bp, char const **str,
             goto exit_sequence;
           safe_chr(savec, buff, bp);
           (*str)++;
-          if (savec == '<') {
-            for (savec = **str; savec && savec != '>'; savec = **str) {
-              safe_chr(savec, buff, bp);
-              (*str)++;
-            }
-            if(!savec)
-              goto exit_sequence;
-            safe_chr(savec, buff, bp);
+          if (savec == '<')
+            process_expression(buff, bp, str, executor, caller, enactor,
+                              eflags & ~PE_STRIP_BRACES, PT_GT, pe_info);
+          else
             (*str)++;
-          }
           break;
         case 'V':
         case 'v':
@@ -1072,27 +1062,26 @@ process_expression(char *buff, char **bp, char const **str,
             gender = get_gender(enactor);
           safe_str(poss[gender], buff, bp);
           break;
-        case '<':
+        case '<':              /* attribute value */
           if (!**str)
             goto exit_sequence;
-          {
-            const char *tmp;
+          else {
             char atrname[BUFFER_LEN];
+            char *anp = atrname;
             ATTR *atr;
 
-            for(tmp = *str; *tmp && *tmp != '>'; tmp++)
-              ;
-            if(!*tmp || tmp == *str) {
-              (*str)--;
-              goto exit_sequence;
+            if (process_expression(atrname, &anp, str, executor, caller,
+                                  enactor, eflags & ~PE_STRIP_BRACES, PT_GT,
+                                  pe_info)) {
+              retval = 1;
+              break;
             }
-            strncpy(atrname, *str, tmp - *str);
-            atrname[tmp - *str] = '\0';
-
+            *anp = '\0';
             atr = atr_get(executor, strupper(atrname));
             if(atr)
               safe_str(atr_value(atr), buff, bp);
-            *str = tmp + 1;
+            if (**str == '>')
+              (*str)++;
           }
           break;
         case 'Q':
@@ -1102,18 +1091,19 @@ process_expression(char *buff, char **bp, char const **str,
             goto exit_sequence;
           (*str)++;
           if (nextc == '<') {
-            const char *tmp;
             char regname[BUFFER_LEN];
-            for(tmp = *str; *tmp && *tmp != '>'; tmp++)
-              ;
-            if(!*tmp || tmp == *str) {
-              (*str)--;
-              goto exit_sequence;
+            char *rnp = regname;
+            if (process_expression(regname, &rnp, str, executor, caller,
+                                  enactor, eflags & ~PE_STRIP_BRACES, PT_GT,
+                                  pe_info)) {
+              retval = 1;
+              break;
             }
-            strncpy(regname, *str, tmp - *str);
-            regname[tmp - *str] = '\0';
-            safe_str(get_namedreg(&global_eval_context.namedregs, regname), buff, bp);
-            *str = tmp + 1;
+            *rnp = '\0';
+            safe_str(get_namedreg(&global_eval_context.namedregs, regname),
+                    buff, bp);
+            if (**str == '>')
+              (*str)++;
           } else {
             if ((qindex = qreg_indexes[(unsigned char) nextc]) == -1)
               break;
index e432d270a8a446245725c7748d0c4d8c9c5b1cea..9e5f3d8df10a36497644fec4e1d36fda635f1027 100644 (file)
@@ -44,7 +44,7 @@ char active_table[256] = {
   1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  0,  0,  0,
   1,  0,  0,  0,  1,  1,  0,  0,  1,  1,  0,  0,  1,  0,  0,  0,
-  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  0,  0,
+  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  0,  1,  1,  0,
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  1,  1,  1,  0,  0,
   0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,