]> git.wh0rd.org Git - nano.git/commitdiff
General - Fix subexpression replacement to work consistently. Affects search.c:repla...
authorChris Allegretta <chrisa@asty.org>
Sun, 26 Jan 2003 04:45:05 +0000 (04:45 +0000)
committerChris Allegretta <chrisa@asty.org>
Sun, 26 Jan 2003 04:45:05 +0000 (04:45 +0000)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1393 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
search.c
utils.c

index fe783bc6640f1f2ee341566a1112b405f492d9f0..adf50d6db7c76f7a3fe102fe073a0e250b5e664f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -5,6 +5,9 @@ CVS Code -
          two strings that had no actual words in them that
          should be translated.  Suggested originally by
          Christian Rose.
+       - Fix subexpression replacement to work consistently.
+         Affects search.c:replace_regexp() and 
+         utils.c:strstrwrapper() (David Benbennick).
 - cut.c:
   do_cut_text()
        - Fix incorrect cursor location when cutting long lines
index 71415649caffab06a3f6538dc25f99aad6545b85..c6c42a7ea636d2e1bfea67aca1036a4a36378068 100644 (file)
--- a/search.c
+++ b/search.c
@@ -445,10 +445,10 @@ int replace_regexp(char *string, int create_flag)
            c++;
            new_size++;
        } else {
-           int num = (int)(*(c + 1) - '0');
+           int num = (int) *(c + 1) - (int) '0';
            if (num >= 1 && num <= 9) {
 
-               int i = regmatches[num].rm_so;
+               int i = regmatches[num].rm_eo - regmatches[num].rm_so;
 
                if (num > search_regexp.re_nsub) {
                    /* Ugh, they specified a subexpression that doesn't
@@ -460,12 +460,15 @@ int replace_regexp(char *string, int create_flag)
                c += 2;
 
                /* But add the length of the subexpression to new_size */
-               new_size += regmatches[num].rm_eo - regmatches[num].rm_so;
+               new_size += i;
 
                /* And if create_flag is set, append the result of the
                 * subexpression match to the new line */
-               while (create_flag && i < regmatches[num].rm_eo)
-                   *string++ = *(current->data + i++);
+               if (create_flag) {
+                   strncpy(string, current->data + current_x +
+                           regmatches[num].rm_so, i);
+                   string += i;
+               }
 
            } else {
                if (create_flag)
diff --git a/utils.c b/utils.c
index 557624b7e43aea8d39231d6aa36229b2181caaf2..6d3f8f1190cc578bd3f63dc9c0a4fc63d9728851 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -138,50 +138,58 @@ const char *stristr(const char *haystack, const char *needle)
     return NULL;
 }
 
+/* If we are searching backwards, we will find the last match
+ * that starts no later than rev_start.  If we are doing a regexp search,
+ * then line_pos should be 0 if haystack starts at the beginning of a
+ * line, and positive otherwise.  In the regexp case, we fill in the
+ * global variable regmatches with at most 9 subexpression matches.  Also,
+ * all .rm_so elements are relative to the start of the whole match, so
+ * regmatches[0].rm_so == 0. */
 const char *strstrwrapper(const char *haystack, const char *needle,
                        const char *rev_start, int line_pos)
 {
 #ifdef HAVE_REGEX_H
     if (ISSET(USE_REGEXP)) {
-       if (!ISSET(REVERSE_SEARCH)) {
-           if (!regexec(&search_regexp, haystack, 10, regmatches, (line_pos > 0) ? REG_NOTBOL : 0))
-               return haystack + regmatches[0].rm_so;
-       }
 #ifndef NANO_SMALL
-       else {
-           const char *i, *j;
-
-           /* do a quick search forward first */
-           if (!regexec(&search_regexp, haystack, 10, regmatches, 0)) {
-               /* there's a match somewhere in the line - now search for it backwards, much slower */
-               for (i = rev_start; i >= haystack; --i) {
-                   if (!regexec(&search_regexp, i, 10, regmatches, (i > haystack) ? REG_NOTBOL : 0)) {
-                       j = i + regmatches[0].rm_so;
-                       if (j <= rev_start)
-                           return j;
-                   }
-               }
+       if (ISSET(REVERSE_SEARCH)) {
+               /* When doing a backwards search, haystack is a whole line. */
+           if (!regexec(&search_regexp, haystack, 1, regmatches, 0) &&
+                   haystack + regmatches[0].rm_so <= rev_start) {
+               const char *retval = haystack + regmatches[0].rm_so;
+
+               /* Search forward until there is no more match. */
+               while (!regexec(&search_regexp, retval + 1, 1, regmatches,
+                           REG_NOTBOL) &&
+                       retval + 1 + regmatches[0].rm_so <= rev_start)
+                   retval += 1 + regmatches[0].rm_so;
+               /* Finally, put the subexpression matches in global
+                * variable regmatches.  The REG_NOTBOL flag doesn't
+                * matter now. */
+               regexec(&search_regexp, retval, 10, regmatches, 0);
+               return retval;
            }
+       } else
+#endif /* !NANO_SMALL */
+       if (!regexec(&search_regexp, haystack, 10, regmatches,
+                       line_pos > 0 ? REG_NOTBOL : 0)) {
+           const char *retval = haystack + regmatches[0].rm_so;
+
+           regexec(&search_regexp, retval, 10, regmatches, 0);
+           return retval;
        }
-#endif
-       return 0;
+       return NULL;
     }
-#endif
+#endif /* HAVE_REGEX_H */
 #ifndef NANO_SMALL
     if (ISSET(CASE_SENSITIVE)) {
        if (ISSET(REVERSE_SEARCH))
            return revstrstr(haystack, needle, rev_start);
-        else
-           return strstr(haystack, needle);
-    } else {
-       if (ISSET(REVERSE_SEARCH))
-           return revstristr(haystack, needle, rev_start);
        else
+           return strstr(haystack, needle);
+    } else if (ISSET(REVERSE_SEARCH))
+       return revstristr(haystack, needle, rev_start);
 #endif
-           return stristr(haystack, needle);
-#ifndef NANO_SMALL
-    }
-#endif
+    return stristr(haystack, needle);
 }
 
 /* This is a wrapper for the perror function.  The wrapper takes care of