1
1

fix infinite loop when we're doing a replace of marked text and the only

matches found are outside the marked text


git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2004 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
Этот коммит содержится в:
David Lawrence Ramsey 2004-10-21 15:32:11 +00:00
родитель 27fbc69ec4
Коммит 9819ed031b
4 изменённых файлов: 53 добавлений и 21 удалений

Просмотреть файл

@ -187,9 +187,10 @@ CVS code -
edit_refresh() if the mark was originally on, and make edit_refresh() if the mark was originally on, and make
length_change a ssize_t. (DLR) length_change a ssize_t. (DLR)
- If the mark is on when we start, skip over all matches not - If the mark is on when we start, skip over all matches not
found inside the marked text. This allows replacing found inside the marked text, and break out if the only
only marked text when the mark is on. (DLR, suggested by matches found are outside the marked text. This allows
Joseph Birthisel) replacing only marked text when the mark is on. (DLR,
suggested by Joseph Birthisel)
- Return ssize_t instead of int. (DLR) - Return ssize_t instead of int. (DLR)
findnextstr() findnextstr()
- Take the no_sameline parameter after can_display_wrap and - Take the no_sameline parameter after can_display_wrap and
@ -198,8 +199,9 @@ CVS code -
that smooth scrolling works correctly. (DLR) that smooth scrolling works correctly. (DLR)
- Fix handling of the wholewords flag so that it works with - Fix handling of the wholewords flag so that it works with
regular expressions and in conjunction with the no_sameline regular expressions and in conjunction with the no_sameline
flag, and add a new parameter needle_len to return the length flag, and add new parameters wrapped (used to return the value
of the match in. (DLR) of search_last_line) and needle_len (used to return the length
of the match). (DLR)
- utils.c: - utils.c:
regexp_bol_or_eol() regexp_bol_or_eol()
- Don't assume any longer that string will be found if - Don't assume any longer that string will be found if

Просмотреть файл

@ -1468,7 +1468,8 @@ bool do_int_spell_fix(const char *word)
current_x = -1; current_x = -1;
/* Find the first whole-word occurrence of word. */ /* Find the first whole-word occurrence of word. */
while (findnextstr(TRUE, TRUE, FALSE, fileage, 0, word, NULL)) { while (findnextstr(TRUE, TRUE, FALSE, fileage, 0, word, NULL,
NULL)) {
if (is_whole_word(current_x, current->data, word)) { if (is_whole_word(current_x, current->data, word)) {
edit_refresh(); edit_refresh();

Просмотреть файл

@ -405,7 +405,7 @@ bool is_whole_word(int curr_pos, const char *datastr, const char
*searchword); *searchword);
bool findnextstr(bool can_display_wrap, bool wholeword, bool bool findnextstr(bool can_display_wrap, bool wholeword, bool
no_sameline, const filestruct *begin, size_t beginx, const char no_sameline, const filestruct *begin, size_t beginx, const char
*needle, size_t *needle_len); *needle, bool *wrapped, size_t *needle_len);
void do_search(void); void do_search(void);
#ifndef NANO_SMALL #ifndef NANO_SMALL
void do_research(void); void do_research(void);

Просмотреть файл

@ -266,13 +266,13 @@ bool is_whole_word(int curr_pos, const char *datastr, const char
/* Look for needle, starting at current, column current_x. If /* Look for needle, starting at current, column current_x. If
* no_sameline is TRUE, skip over begin when looking for needle. begin * no_sameline is TRUE, skip over begin when looking for needle. begin
* is the line where we first started searching, at column beginx. If * is the line where we first started searching, at column beginx. If
* can_display_wrap is TRUE, we put messages on the statusbar, and wrap * can_display_wrap is TRUE, we put messages on the statusbar, wrap
* around the file boundaries. The return value specifies whether we * around the file boundaries, and set wrapped to TRUE if it isn't NULL.
* found anything. If we did, and needle_len isn't NULL, set it to the * The return value specifies whether we found anything. If we did, set
* length of the string we found. */ * needle_len to the length of the string we found if it isn't NULL. */
bool findnextstr(bool can_display_wrap, bool wholeword, bool bool findnextstr(bool can_display_wrap, bool wholeword, bool
no_sameline, const filestruct *begin, size_t beginx, const char no_sameline, const filestruct *begin, size_t beginx, const char
*needle, size_t *needle_len) *needle, bool *wrapped, size_t *needle_len)
{ {
filestruct *fileptr = current; filestruct *fileptr = current;
const char *rev_start = NULL, *found = NULL; const char *rev_start = NULL, *found = NULL;
@ -284,6 +284,10 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
bool search_last_line = FALSE; bool search_last_line = FALSE;
/* Have we gone past the last line while searching? */ /* Have we gone past the last line while searching? */
/* wrapped holds the value of search_last_line. */
if (wrapped != NULL)
*wrapped = FALSE;
/* rev_start might end up 1 character before the start or after the /* rev_start might end up 1 character before the start or after the
* end of the line. This won't be a problem because strstrwrapper() * end of the line. This won't be a problem because strstrwrapper()
* will return immediately and say that no match was found, and * will return immediately and say that no match was found, and
@ -374,8 +378,11 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
} }
/* Original start line reached. */ /* Original start line reached. */
if (fileptr == begin) if (fileptr == begin) {
search_last_line = TRUE; search_last_line = TRUE;
if (wrapped != NULL)
*wrapped = TRUE;
}
rev_start = fileptr->data; rev_start = fileptr->data;
#ifndef NANO_SMALL #ifndef NANO_SMALL
if (ISSET(REVERSE_SEARCH)) if (ISSET(REVERSE_SEARCH))
@ -405,6 +412,8 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
current = fileptr; current = fileptr;
current_x = current_x_find; current_x = current_x_find;
current_y = current_y_find; current_y = current_y_find;
/* needle_len holds the length of needle. */
if (needle_len != NULL) if (needle_len != NULL)
*needle_len = found_len; *needle_len = found_len;
@ -452,7 +461,7 @@ void do_search(void)
#endif #endif
didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x, didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x,
answer, NULL); answer, NULL, NULL);
/* Check to see if there's only one occurrence of the string and /* Check to see if there's only one occurrence of the string and
* we're on it now. */ * we're on it now. */
@ -466,7 +475,7 @@ void do_search(void)
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp, if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
last_search)) { last_search)) {
didfind = findnextstr(TRUE, FALSE, TRUE, current, current_x, didfind = findnextstr(TRUE, FALSE, TRUE, current, current_x,
answer, NULL); answer, NULL, NULL);
if (fileptr == current && fileptr_x == current_x && !didfind) if (fileptr == current && fileptr_x == current_x && !didfind)
statusbar(_("This is the only occurrence")); statusbar(_("This is the only occurrence"));
} else { } else {
@ -505,7 +514,7 @@ void do_research(void)
#endif #endif
didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x, didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x,
last_search, NULL); last_search, NULL, NULL);
/* Check to see if there's only one occurrence of the string and /* Check to see if there's only one occurrence of the string and
* we're on it now. */ * we're on it now. */
@ -519,7 +528,7 @@ void do_research(void)
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp, if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
last_search)) { last_search)) {
didfind = findnextstr(TRUE, FALSE, TRUE, current, didfind = findnextstr(TRUE, FALSE, TRUE, current,
current_x, answer, NULL); current_x, answer, NULL, NULL);
if (fileptr == current && fileptr_x == current_x && !didfind) if (fileptr == current && fileptr_x == current_x && !didfind)
statusbar(_("This is the only occurrence")); statusbar(_("This is the only occurrence"));
} else { } else {
@ -656,9 +665,10 @@ ssize_t do_replace_loop(const char *needle, filestruct *real_current,
bool begin_line = FALSE, bol_or_eol = FALSE; bool begin_line = FALSE, bol_or_eol = FALSE;
#endif #endif
#ifndef NANO_SMALL #ifndef NANO_SMALL
bool old_mark_set = ISSET(MARK_ISSET); bool old_mark_set = ISSET(MARK_ISSET), wrapped;
const filestruct *top, *bot; const filestruct *top, *bot;
size_t top_x, bot_x; size_t top_x, bot_x;
int wraps = 0;
if (old_mark_set) { if (old_mark_set) {
/* Save the locations where the mark begins and ends. */ /* Save the locations where the mark begins and ends. */
@ -686,7 +696,16 @@ ssize_t do_replace_loop(const char *needle, filestruct *real_current,
#else #else
FALSE FALSE
#endif #endif
, current_save, current_x_save, needle, &match_len)) { , current_save, current_x_save, needle,
#ifndef NANO_SMALL
/* If we're replacing marked text, we should take note of when
* the search wraps. If the wrapped flag is set, it means that
* we've wrapped since the last search. */
&wrapped
#else
NULL
#endif
, &match_len)) {
int i = 0; int i = 0;
@ -697,8 +716,18 @@ ssize_t do_replace_loop(const char *needle, filestruct *real_current,
if (current->lineno < top->lineno || current->lineno > if (current->lineno < top->lineno || current->lineno >
bot->lineno || (current == top && current_x < top_x) || bot->lineno || (current == top && current_x < top_x) ||
(current == bot && (current_x > bot_x || current_x + (current == bot && (current_x > bot_x || current_x +
match_len > bot_x))) match_len > bot_x))) {
/* Keep track of how many times the search has wrapped.
* If it's wrapped more than once, it means that the
* only matches left are those outside the marked text,
* so we're done. */
if (wrapped) {
wraps++;
if (wraps > 1)
break;
}
continue; continue;
}
} }
#endif #endif
@ -1056,7 +1085,7 @@ void do_find_bracket(void)
while (TRUE) { while (TRUE) {
if (findnextstr(FALSE, FALSE, FALSE, current, current_x, if (findnextstr(FALSE, FALSE, FALSE, current, current_x,
regexp_pat, NULL)) { regexp_pat, NULL, NULL)) {
/* Found identical bracket. */ /* Found identical bracket. */
if (current->data[current_x] == ch_under_cursor) if (current->data[current_x] == ch_under_cursor)
count++; count++;