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
master
David Lawrence Ramsey 2004-10-21 15:32:11 +00:00
parent 27fbc69ec4
commit 9819ed031b
4 changed files with 53 additions and 21 deletions

View File

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

View File

@ -1468,7 +1468,8 @@ bool do_int_spell_fix(const char *word)
current_x = -1;
/* 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)) {
edit_refresh();

View File

@ -405,7 +405,7 @@ bool is_whole_word(int curr_pos, const char *datastr, const char
*searchword);
bool findnextstr(bool can_display_wrap, bool wholeword, bool
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);
#ifndef NANO_SMALL
void do_research(void);

View File

@ -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
* no_sameline is TRUE, skip over begin when looking for needle. begin
* 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
* around the file boundaries. The return value specifies whether we
* found anything. If we did, and needle_len isn't NULL, set it to the
* length of the string we found. */
* can_display_wrap is TRUE, we put messages on the statusbar, wrap
* around the file boundaries, and set wrapped to TRUE if it isn't NULL.
* The return value specifies whether we found anything. If we did, set
* needle_len to the length of the string we found if it isn't NULL. */
bool findnextstr(bool can_display_wrap, bool wholeword, bool
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;
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;
/* 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
* end of the line. This won't be a problem because strstrwrapper()
* 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. */
if (fileptr == begin)
if (fileptr == begin) {
search_last_line = TRUE;
if (wrapped != NULL)
*wrapped = TRUE;
}
rev_start = fileptr->data;
#ifndef NANO_SMALL
if (ISSET(REVERSE_SEARCH))
@ -405,6 +412,8 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
current = fileptr;
current_x = current_x_find;
current_y = current_y_find;
/* needle_len holds the length of needle. */
if (needle_len != NULL)
*needle_len = found_len;
@ -452,7 +461,7 @@ void do_search(void)
#endif
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
* we're on it now. */
@ -466,7 +475,7 @@ void do_search(void)
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
last_search)) {
didfind = findnextstr(TRUE, FALSE, TRUE, current, current_x,
answer, NULL);
answer, NULL, NULL);
if (fileptr == current && fileptr_x == current_x && !didfind)
statusbar(_("This is the only occurrence"));
} else {
@ -505,7 +514,7 @@ void do_research(void)
#endif
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
* we're on it now. */
@ -519,7 +528,7 @@ void do_research(void)
if (ISSET(USE_REGEXP) && regexp_bol_or_eol(&search_regexp,
last_search)) {
didfind = findnextstr(TRUE, FALSE, TRUE, current,
current_x, answer, NULL);
current_x, answer, NULL, NULL);
if (fileptr == current && fileptr_x == current_x && !didfind)
statusbar(_("This is the only occurrence"));
} else {
@ -656,9 +665,10 @@ ssize_t do_replace_loop(const char *needle, filestruct *real_current,
bool begin_line = FALSE, bol_or_eol = FALSE;
#endif
#ifndef NANO_SMALL
bool old_mark_set = ISSET(MARK_ISSET);
bool old_mark_set = ISSET(MARK_ISSET), wrapped;
const filestruct *top, *bot;
size_t top_x, bot_x;
int wraps = 0;
if (old_mark_set) {
/* 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
FALSE
#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;
@ -697,8 +716,18 @@ ssize_t do_replace_loop(const char *needle, filestruct *real_current,
if (current->lineno < top->lineno || current->lineno >
bot->lineno || (current == top && current_x < top_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;
}
}
#endif
@ -1056,7 +1085,7 @@ void do_find_bracket(void)
while (TRUE) {
if (findnextstr(FALSE, FALSE, FALSE, current, current_x,
regexp_pat, NULL)) {
regexp_pat, NULL, NULL)) {
/* Found identical bracket. */
if (current->data[current_x] == ch_under_cursor)
count++;