From e190ff30f22db2ff9a4297eb8040d136880c7807 Mon Sep 17 00:00:00 2001
From: David Lawrence Ramsey <pooka109@gmail.com>
Date: Sat, 3 Jan 2004 21:42:25 +0000
Subject: [PATCH] find all beginning-of-line and/or end-of-line regexes once
 per line, not just the zero-length ones; this fixes multiple replaces
 occurring with them in conjunction with "*"

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1608 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog    | 16 ++++++++--------
 src/color.c  |  2 +-
 src/search.c | 29 ++++++++++++++---------------
 src/utils.c  | 10 +++++-----
 4 files changed, 28 insertions(+), 29 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5c0559f2..1be17c38 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -80,14 +80,14 @@ CVS code -
 - search.c:
   findnextstr(), do_replace_loop()
 	- Fix potential infinite loops and other misbehavior when doing
-	  certain zero-length regex replacements ("^", "$", and "^$").
-	  Add a no_sameline parameter to findnextstr(), and set it in
-	  the calls in do_replace_loop() when such regexes are found, so
-	  that such regexes are only found once per line.  Also change
-	  length_change from a long to an int; size_t is unsuitable due
-	  to its being unsigned. (DLR; found by Mike Frysinger and DLR)
-	  David Benbennick: Add a few minor cleanups to
-	  do_replace_loop().
+	  beginning-of-line or end-of-line regex replacements ("^", "$",
+	  and "^$").  Add a no_sameline parameter to findnextstr(), and
+	  set it in the calls in do_replace_loop() when such regexes are
+	  found, so that such regexes are only found once per line.
+	  Also change length_change from a long to an int; size_t is
+	  unsuitable due to its being unsigned. (DLR; found by Mike
+	  Frysinger and DLR)  David Benbennick: Add a few minor cleanups
+	  to do_replace_loop().
 - winio.c:
   get_kbinput(), get_accepted_kbinput()
 	- Don't pass in the value of the REBIND_DELETE flag anymore.
diff --git a/src/color.c b/src/color.c
index 759f1444..630cace2 100644
--- a/src/color.c
+++ b/src/color.c
@@ -109,7 +109,7 @@ void update_color(void)
 
 	for (e = tmpsyntax->extensions; e != NULL; e = e->next) {
 	    /* Set colorstrings if we matched the extension regex */
-	    if (!regexec(&e->val, filename, 0, NULL, 0))
+	    if (regexec(&e->val, filename, 0, NULL, 0) == 0)
 		colorstrings = tmpsyntax->color;
 
 	    if (colorstrings != NULL)
diff --git a/src/search.c b/src/search.c
index 53c05208..778ee3ab 100644
--- a/src/search.c
+++ b/src/search.c
@@ -618,8 +618,8 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
 {
     int replaceall = 0, numreplaced = -1;
 #ifdef HAVE_REGEX_H
-    /* The starting-line match and zero-length regex flags. */
-    int beginline = 0, caretdollar = 0;
+    /* The starting-line match and bol/eol regex flags. */
+    int beginline = 0, bol_eol = 0;
 #endif
     filestruct *fileptr = NULL;
 
@@ -649,31 +649,30 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
 	fileptr = findnextstr(fileptr || replaceall || search_last_line,
 		FALSE, begin, *beginx, prevanswer,
 #ifdef HAVE_REGEX_H
-		/* We should find a zero-length regex only once per
-		 * line.  If the caretdollar flag is set, it means that
-		 * the last search found one on the beginning line, so we
+		/* We should find a bol and/or eol regex only once per
+		 * line.  If the bol_eol flag is set, it means that the
+		 * last search found one on the beginning line, so we
 		 * should skip over the beginning line when doing this
 		 * search. */
-		caretdollar
+		bol_eol
 #else
 		0
 #endif
 		);
 
 #ifdef HAVE_REGEX_H
-	/* If the caretdollar flag is set, we've found a match on the
+	/* If the bol_eol flag is set, we've found a match on the
 	 * beginning line already, and we're still on the beginning line
 	 * after the search, it means that we've wrapped around, so
 	 * we're done. */
-	if (caretdollar && beginline && fileptr == begin)
+	if (bol_eol && beginline && fileptr == begin)
 	    fileptr = NULL;
 	/* Otherwise, set the beginline flag if we've found a match on
-	 * the beginning line, reset the caretdollar flag, and
-	 * continue. */
+	 * the beginning line, reset the bol_eol flag, and continue. */
 	else {
 	    if (fileptr == begin)
 		beginline = 1;
-	    caretdollar = 0;
+	    bol_eol = 0;
 	}
 #endif
 
@@ -721,10 +720,10 @@ int do_replace_loop(const char *prevanswer, const filestruct *begin,
 	}
 
 #ifdef HAVE_REGEX_H
-	/* Set the caretdollar flag if we're doing a zero-length regex
-	 * replace (such as "^", "$", or "^$"). */
-	if (ISSET(USE_REGEXP) && match_len == 0)
-	    caretdollar = 1;
+	/* Set the bol_eol flag if we're doing a bol and/or eol regex
+	 * replace ("^", "$", or "^$"). */
+	if (ISSET(USE_REGEXP) && regexec(&search_regexp, prevanswer, 1, NULL, REG_NOTBOL | REG_NOTEOL) == REG_NOMATCH)
+	    bol_eol = 1;
 #endif
 
 	if (*i > 0 || replaceall) {	/* Yes, replace it!!!! */
diff --git a/src/utils.c b/src/utils.c
index a1d84c91..93d3a221 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -197,13 +197,13 @@ const char *strstrwrapper(const char *haystack, const char *needle,
 #ifndef NANO_SMALL
 	if (ISSET(REVERSE_SEARCH)) {
 		/* When doing a backwards search, haystack is a whole line. */
-	    if (!regexec(&search_regexp, haystack, 1, regmatches, 0) &&
+	    if (regexec(&search_regexp, haystack, 1, regmatches, 0) == 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) &&
+		while (regexec(&search_regexp, retval + 1, 1, regmatches,
+			    REG_NOTBOL) == 0 &&
 			retval + 1 + regmatches[0].rm_so <= rev_start)
 		    retval += 1 + regmatches[0].rm_so;
 		/* Finally, put the subexpression matches in global
@@ -214,8 +214,8 @@ const char *strstrwrapper(const char *haystack, const char *needle,
 	    }
 	} else
 #endif /* !NANO_SMALL */
-	if (!regexec(&search_regexp, haystack, 10, regmatches,
-			line_pos > 0 ? REG_NOTBOL : 0)) {
+	if (regexec(&search_regexp, haystack, 10, regmatches,
+			line_pos > 0 ? REG_NOTBOL : 0) == 0) {
 	    const char *retval = haystack + regmatches[0].rm_so;
 
 	    regexec(&search_regexp, retval, 10, regmatches, 0);
-- 
GitLab