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-d3aeb78583b8master
parent
27fbc69ec4
commit
9819ed031b
12
ChangeLog
12
ChangeLog
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
57
src/search.c
57
src/search.c
|
@ -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++;
|
||||
|
|
Loading…
Reference in New Issue