commit 9090f2e44b8a2429b911ba382274139de1ee9693
parent 1939c3590b74b88920e1037f18c8c8319d5cd738
Author: Chris Allegretta <chrisa@asty.org>
Date: Sun, 26 Jan 2003 04:45:05 +0000
General - Fix subexpression replacement to work consistently. Affects search.c:replace_regexp() and utils.c:strstrwrapper() (David Benbennick)
git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1393 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Diffstat:
M | ChangeLog | | | 3 | +++ |
M | search.c | | | 13 | ++++++++----- |
M | utils.c | | | 66 | +++++++++++++++++++++++++++++++++++++----------------------------- |
3 files changed, 48 insertions(+), 34 deletions(-)
diff --git 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
diff --git 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
@@ -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