OSSP CVS Repository

ossp - Check-in [1317]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 1317
Date: 2001-Nov-13 15:36:55 (local)
2001-Nov-13 14:36:55 (UTC)
User:simons
Branch:
Comment: Implemented submatching in regular expressions and added the appropriate test cases.
Tickets:
Inspections:
Files:
ossp-pkg/var/var.c      1.6 -> 1.7     84 inserted, 14 deleted
ossp-pkg/var/var.h      1.3 -> 1.4     2 inserted, 0 deleted
ossp-pkg/var/var_test.c      1.5 -> 1.6     7 inserted, 15 deleted

ossp-pkg/var/var.c 1.6 -> 1.7

--- var.c        2001/11/13 13:32:58     1.6
+++ var.c        2001/11/13 14:36:55     1.7
@@ -340,6 +340,13 @@
                 return VAR_INCOMPLETE_NAMED_CHARACTER;
             switch (*src)
                 {
+                case '\\':
+                    if (!unescape_all)
+                        {
+                        *dst++ = '\\';
+                        }
+                    *dst++ = '\\';
+                    break;
                 case 'n':
                     *dst++ = '\n';
                     break;
@@ -925,6 +932,67 @@
     return VAR_OK;
     }
 
+static int expand_regex_replace(const char* data, tokenbuf* orig, regmatch_t* pmatch, tokenbuf* expanded)
+    {
+    const char* p = orig->begin;
+    size_t i;
+
+    init_tokenbuf(expanded);
+
+    while(p != orig->end)
+        {
+        if (*p == '\\')
+            {
+            if (orig->end - p <= 1)
+                {
+                free_tokenbuf(expanded);
+                return VAR_INCOMPLETE_QUOTED_PAIR;
+                }
+            else
+                ++p;
+            if (*p == '\\')
+                {
+                if (!append_to_tokenbuf(expanded, p, 1))
+                    {
+                    free_tokenbuf(expanded);
+                    return VAR_OUT_OF_MEMORY;
+                    }
+                ++p;
+                continue;
+                }
+            if (!isdigit(*p))
+                {
+                free_tokenbuf(expanded);
+                return VAR_UNKNOWN_QUOTED_PAIR_IN_REPLACE;
+                }
+            i = *p - '0';
+            ++p;
+            if (pmatch[i].rm_so == -1)
+                {
+                free_tokenbuf(expanded);
+                return VAR_SUBMATCH_OUT_OF_RANGE;
+                }
+            if (!append_to_tokenbuf(expanded, data + pmatch[i].rm_so,
+                                    pmatch[i].rm_eo - pmatch[i].rm_so))
+                {
+                free_tokenbuf(expanded);
+                return VAR_OUT_OF_MEMORY;
+                }
+            }
+        else
+            {
+            if (!append_to_tokenbuf(expanded, p, 1))
+                {
+                free_tokenbuf(expanded);
+                return VAR_OUT_OF_MEMORY;
+                }
+            ++p;
+            }
+        }
+
+    return VAR_OK;
+    }
+
 static int search_and_replace(tokenbuf* data, tokenbuf* search, tokenbuf* replace, tokenbuf* flags)
     {
     const char* p;
@@ -936,24 +1004,18 @@
     if (search->begin == search->end)
         return VAR_EMPTY_SEARCH_STRING;
 
-    printf("Search '%s' in '%s' and replace it with '%s'.\n",
-           search->begin, data->begin, replace->begin);
-
     for (p = flags->begin; p != flags->end; ++p)
         {
         switch (tolower(*p))
             {
             case 'i':
                 case_insensitive = 1;
-                printf("case_insensitive = 1;\n");
                 break;
             case 'g':
                 global = 1;
-                printf("global = 1;\n");
                 break;
             case 't':
                 no_regex = 1;
-                printf("no_regex = 1;\n");
                 break;
             default:
                 return VAR_UNKNOWN_REPLACE_FLAG;
@@ -1003,8 +1065,9 @@
         {
         tokenbuf tmp;
         tokenbuf mydata;
+        tokenbuf myreplace;
         regex_t preg;
-        regmatch_t pmatch[33];
+        regmatch_t pmatch[10];
         int regexec_flag;
 
         /* Copy the pattern and the data to our own buffer to make
@@ -1020,9 +1083,6 @@
 
         /* Compile the pattern. */
 
-        printf("data is.................: '%s'\n", mydata.begin);
-        printf("regex search pattern is.: '%s'\n", tmp.begin);
-        printf("regex replace pattern is: '%s'\n", replace->begin);
         rc = regcomp(&preg, tmp.begin, REG_EXTENDED | ((case_insensitive) ? REG_ICASE : 0));
         free_tokenbuf(&tmp);
         if (rc != 0)
@@ -1030,7 +1090,6 @@
             free_tokenbuf(&mydata);
             return VAR_INVALID_REGEX_IN_REPLACE;
             }
-        printf("Subexpression in pattern: '%d'\n", preg.re_nsub);
 
         /* Match the pattern and create the result string in the tmp
            buffer. */
@@ -1043,22 +1102,33 @@
                 regexec_flag = REG_NOTBOL;
             if (regexec(&preg, p, sizeof(pmatch) / sizeof(regmatch_t), pmatch, regexec_flag) == REG_NOMATCH)
                 {
-                printf("No match; appending remainder ('%s') to output string.\n", p);
                 append_to_tokenbuf(&tmp, p, mydata.end - p);
                 break;
                 }
             else
                 {
+                rc = expand_regex_replace(p, replace, pmatch, &myreplace);
+                if (rc != VAR_OK)
+                    {
+                    regfree(&preg);
+                    free_tokenbuf(&tmp);
+                    free_tokenbuf(&mydata);
+                    return rc;
+                    }
                 if (!append_to_tokenbuf(&tmp, p, pmatch[0].rm_so) ||
-                    !append_to_tokenbuf(&tmp, replace->begin, replace->end - replace->begin))
+                    !append_to_tokenbuf(&tmp, myreplace.begin, myreplace.end - myreplace.begin))
                     {
                     regfree(&preg);
                     free_tokenbuf(&tmp);
                     free_tokenbuf(&mydata);
+                    free_tokenbuf(&myreplace);
                     return VAR_OUT_OF_MEMORY;
                     }
                 else
-                    p += pmatch[0].rm_eo;
+                    {
+                    p += (pmatch[0].rm_eo > 0) ? pmatch[0].rm_eo : 1;
+                    free_tokenbuf(&myreplace);
+                    }
                 if (!global)
                     {
                     append_to_tokenbuf(&tmp, p, mydata.end - p);


ossp-pkg/var/var.h 1.3 -> 1.4

--- var.h        2001/11/13 12:46:24     1.3
+++ var.h        2001/11/13 14:36:55     1.4
@@ -37,6 +37,8 @@
 typedef enum
     {
     VAR_CALLBACK_ERROR                 = -64,
+    VAR_SUBMATCH_OUT_OF_RANGE          = -34,
+    VAR_UNKNOWN_QUOTED_PAIR_IN_REPLACE = -33,
     VAR_EMPTY_PADDING_FILL_STRING      = -32,
     VAR_MISSING_PADDING_WIDTH          = -31,
     VAR_MALFORMATTED_PADDING           = -30,


ossp-pkg/var/var_test.c 1.5 -> 1.6

--- var_test.c   2001/11/13 13:33:28     1.5
+++ var_test.c   2001/11/13 14:36:55     1.6
@@ -3,7 +3,7 @@
 #include <errno.h>
 #include "var.h"
 
-int env_lookup(void* context,
+static int env_lookup(void* context,
                const char* varname, size_t name_len,
                const char** data, size_t* data_len, size_t* buffer_size)
     {
@@ -81,12 +81,13 @@
         { "${FOO:p/15/../c}",            "......os......."                 },
         { "${FOO:p/15/12345/c}",         "123451os1234512"                 },
         { "${FOO:s/os/\\x{4F}\\123/g}",  "OS"                              },
-        { "${FOO:s/os/\\1\\x4F\\123/t}", "\\1OS"                           }
+        { "${FOO:s/os/\\1\\x4F\\123/t}", "\\1OS"                           },
+        { "${HOME:s/g(res)s/x\\1x/g}",   "/home/rexresxion-tests"          },
+        { "${HOME:s/(s+)/_\\1_/g}",      "/home/regre_ss_ion-te_s_t_s_"    },
+        { "${HOME:s/\\x65/\\x45/g}",     "/homE/rEgrEssion-tEsts"          },
+        { "${HOME:s/(s*)/x\\1X/g}",      "xXxXxXxXxXxXxXxXxXxXxXxssXxXxXxXxXxXxXxsXxXxsX" },
+        { "${HOME:s/./\\\\/g}",          "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\" }
         };
-    /*
-        { "${HOME:s/g(res)s/x\\\\1x/g}","/homE/rEgrEssion-tEsts"          }
-        { "${HOME:s/\\x65/\\x45/g}",    "/home/regression-tests"          }
-    */
     char*    tmp;
     size_t   tmp_len;
     var_rc_t rc;
@@ -135,15 +136,6 @@
             printf("Test case #%d: Expected result '%s' but got '%s'.\n", i, tests[i].expected, tmp);
             return 1;
             }
-        rc = var_unescape(tests[i].input, strlen(tests[i].input), buffer, 1);
-        if (rc != VAR_OK)
-            {
-            printf("Test case #%d: Second var_unescape() failed with return code %d.\n", i, rc);
-            return 1;
-            }
-#ifdef DEBUG
-        printf("Test case #%02d: Unescaped output is '%s'.\n\n", i, tmp);
-#endif
         free(tmp);
         }
 

CVSTrac 2.0.1