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
master
Chris Allegretta 2003-01-26 04:45:05 +00:00
parent 1939c3590b
commit 9090f2e44b
3 changed files with 47 additions and 33 deletions

View File

@ -5,6 +5,9 @@ CVS Code -
two strings that had no actual words in them that two strings that had no actual words in them that
should be translated. Suggested originally by should be translated. Suggested originally by
Christian Rose. Christian Rose.
- Fix subexpression replacement to work consistently.
Affects search.c:replace_regexp() and
utils.c:strstrwrapper() (David Benbennick).
- cut.c: - cut.c:
do_cut_text() do_cut_text()
- Fix incorrect cursor location when cutting long lines - Fix incorrect cursor location when cutting long lines

View File

@ -445,10 +445,10 @@ int replace_regexp(char *string, int create_flag)
c++; c++;
new_size++; new_size++;
} else { } else {
int num = (int)(*(c + 1) - '0'); int num = (int) *(c + 1) - (int) '0';
if (num >= 1 && num <= 9) { 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) { if (num > search_regexp.re_nsub) {
/* Ugh, they specified a subexpression that doesn't /* Ugh, they specified a subexpression that doesn't
@ -460,12 +460,15 @@ int replace_regexp(char *string, int create_flag)
c += 2; c += 2;
/* But add the length of the subexpression to new_size */ /* 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 /* And if create_flag is set, append the result of the
* subexpression match to the new line */ * subexpression match to the new line */
while (create_flag && i < regmatches[num].rm_eo) if (create_flag) {
*string++ = *(current->data + i++); strncpy(string, current->data + current_x +
regmatches[num].rm_so, i);
string += i;
}
} else { } else {
if (create_flag) if (create_flag)

64
utils.c
View File

@ -138,50 +138,58 @@ const char *stristr(const char *haystack, const char *needle)
return NULL; 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 *strstrwrapper(const char *haystack, const char *needle,
const char *rev_start, int line_pos) const char *rev_start, int line_pos)
{ {
#ifdef HAVE_REGEX_H #ifdef HAVE_REGEX_H
if (ISSET(USE_REGEXP)) { 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 #ifndef NANO_SMALL
else { if (ISSET(REVERSE_SEARCH)) {
const char *i, *j; /* 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;
/* do a quick search forward first */ /* Search forward until there is no more match. */
if (!regexec(&search_regexp, haystack, 10, regmatches, 0)) { while (!regexec(&search_regexp, retval + 1, 1, regmatches,
/* there's a match somewhere in the line - now search for it backwards, much slower */ REG_NOTBOL) &&
for (i = rev_start; i >= haystack; --i) { retval + 1 + regmatches[0].rm_so <= rev_start)
if (!regexec(&search_regexp, i, 10, regmatches, (i > haystack) ? REG_NOTBOL : 0)) { retval += 1 + regmatches[0].rm_so;
j = i + regmatches[0].rm_so; /* Finally, put the subexpression matches in global
if (j <= rev_start) * variable regmatches. The REG_NOTBOL flag doesn't
return j; * 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 NULL;
return 0;
} }
#endif #endif /* HAVE_REGEX_H */
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (ISSET(CASE_SENSITIVE)) { if (ISSET(CASE_SENSITIVE)) {
if (ISSET(REVERSE_SEARCH)) if (ISSET(REVERSE_SEARCH))
return revstrstr(haystack, needle, rev_start); return revstrstr(haystack, needle, rev_start);
else
return strstr(haystack, needle);
} else {
if (ISSET(REVERSE_SEARCH))
return revstristr(haystack, needle, rev_start);
else else
return strstr(haystack, needle);
} else if (ISSET(REVERSE_SEARCH))
return revstristr(haystack, needle, rev_start);
#endif #endif
return stristr(haystack, needle); return stristr(haystack, needle);
#ifndef NANO_SMALL
}
#endif
} }
/* This is a wrapper for the perror function. The wrapper takes care of /* This is a wrapper for the perror function. The wrapper takes care of