OSSP CVS Repository

ossp - Difference in ossp-pkg/var/var.c versions 1.84 and 1.85
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/var/var.c 1.84 -> 1.85

--- var.c        2002/03/07 09:08:11     1.84
+++ var.c        2002/03/07 09:14:05     1.85
@@ -845,6 +845,7 @@
     tokenbuf_t tmp;
     const char *p;
     int case_insensitive = 0;
+    int multiline = 0;
     int global = 0;
     int no_regex = 0;
     int rc;
@@ -852,19 +853,22 @@
     if (search->begin == search->end)
         return VAR_ERR_EMPTY_SEARCH_STRING;
 
-    for (p = flags->begin; p != flags->end; ++p) {
+    for (p = flags->begin; p != flags->end; p++) {
         switch (tolower(*p)) {
-        case 'i':
-            case_insensitive = 1;
-            break;
-        case 'g':
-            global = 1;
-            break;
-        case 't':
-            no_regex = 1;
-            break;
-        default:
-            return VAR_ERR_UNKNOWN_REPLACE_FLAG;
+            case 'm':
+                multiline = 1;
+                break;
+            case 'i':
+                case_insensitive = 1;
+                break;
+            case 'g':
+                global = 1;
+                break;
+            case 't':
+                no_regex = 1;
+                break;
+            default:
+                return VAR_ERR_UNKNOWN_REPLACE_FLAG;
         }
     }
 
@@ -916,7 +920,10 @@
         }
 
         /* compile the pattern. */
-        rc = regcomp(&preg, tmp.begin, REG_NEWLINE|REG_EXTENDED|((case_insensitive)?REG_ICASE:0));
+        rc = regcomp(&preg, tmp.begin, 
+                     (  REG_EXTENDED
+                      | (multiline ? REG_NEWLINE : 0)
+                      | (case_insensitive ? REG_ICASE : 0)));
         tokenbuf_free(&tmp);
         if (rc != 0) {
             tokenbuf_free(&mydata);
@@ -925,31 +932,41 @@
 
         /* match the pattern and create the result string in the tmp buffer */
         tokenbuf_append(&tmp, "", 0);
-        for (p = mydata.begin; p != mydata.end; ) {
+        for (p = mydata.begin; p < mydata.end; ) {
             if (p == mydata.begin || p[-1] == '\n')
                 regexec_flag = 0;
             else
                 regexec_flag = REG_NOTBOL;
             rc = regexec(&preg, p, sizeof(pmatch) / sizeof(regmatch_t), pmatch, regexec_flag);
-            if (rc != 0 || p + pmatch[0].rm_so == mydata.end) {
+            /* XXX */
+            if (rc != 0) {
+                /* no (more) matching */
                 tokenbuf_append(&tmp, p, mydata.end - p);
                 break;
-            } else {
-                /* create replace string */
-                rc = parse_regex_replace(var, ctx, p, replace, pmatch, &myreplace);
-                if (rc != VAR_OK) {
+            }
+            else if (   multiline 
+                     && (p + pmatch[0].rm_so) == mydata.end 
+                     && (pmatch[0].rm_eo - pmatch[0].rm_so) == 0) {
+                /* special case: found empty pattern (usually /^/ or /$/ only)
+                   in multi-line at end of data (after the last newline) */
+                tokenbuf_append(&tmp, p, mydata.end - p);
+                break;
+            }
+            else {
+                /* append prolog string */
+                if (!tokenbuf_append(&tmp, p, pmatch[0].rm_so)) {
                     regfree(&preg);
                     tokenbuf_free(&tmp);
                     tokenbuf_free(&mydata);
-                    return rc;
+                    return VAR_ERR_OUT_OF_MEMORY;
                 }
-                /* append prolog string */
-                if (!tokenbuf_append(&tmp, p, pmatch[0].rm_so)) {
+                /* create replace string */
+                rc = parse_regex_replace(var, ctx, p, replace, pmatch, &myreplace);
+                if (rc != VAR_OK) {
                     regfree(&preg);
                     tokenbuf_free(&tmp);
                     tokenbuf_free(&mydata);
-                    tokenbuf_free(&myreplace);
-                    return VAR_ERR_OUT_OF_MEMORY;
+                    return rc;
                 }
                 /* append replace string */
                 if (!tokenbuf_append(&tmp, myreplace.begin, myreplace.end - myreplace.begin)) {
@@ -959,19 +976,26 @@
                     tokenbuf_free(&myreplace);
                     return VAR_ERR_OUT_OF_MEMORY;
                 }
+                tokenbuf_free(&myreplace);
+                /* skip now processed data */
                 p += pmatch[0].rm_eo;
-                /* XXX??? */
+                /* if pattern matched an empty part (think about
+                   anchor-only regular expressions like /^/ or /$/) we
+                   skip the next character to make sure we do not enter
+                   an infinitive loop in matching */
                 if ((pmatch[0].rm_eo - pmatch[0].rm_so) == 0) {
+                    if (p >= mydata.end)
+                        break;
                     if (!tokenbuf_append(&tmp, p, 1)) {
                         regfree(&preg);
                         tokenbuf_free(&tmp);
                         tokenbuf_free(&mydata);
-                        tokenbuf_free(&myreplace);
                         return VAR_ERR_OUT_OF_MEMORY;
                     }
                     p++;
                 }
-                tokenbuf_free(&myreplace);
+                /* append prolog string and stop processing if we 
+                   do not perform the search & replace globally */
                 if (!global) {
                     if (!tokenbuf_append(&tmp, p, mydata.end - p)) {
                         regfree(&preg);

CVSTrac 2.0.1