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
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

View File

@ -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)

64
utils.c
View File

@ -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;
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;
/* 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;
}
}
/* 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