]> git.wh0rd.org Git - nano.git/commitdiff
fix findnextstr() so wholewords works properly with regular expressions
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Mon, 18 Oct 2004 22:19:22 +0000 (22:19 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Mon, 18 Oct 2004 22:19:22 +0000 (22:19 +0000)
and in conjunction with no_sameline, and add a few other minor cosmetic
fixes

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@2002 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/nano.c
src/proto.h
src/search.c

index 7415e00baa078a75f7ac2d24744bcd148a91babb..ad8659d15b9bc7e3bc400f38b17280096409f3cd 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -183,16 +183,19 @@ 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 makes marked spell
-         checking when using the internal spell checker work as
-         expected (found by Rocco Corsi), and also allows replacing
-         only marked text when the mark is on (suggested by Joseph
-         Birthisel). (DLR)
+         found inside 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
          wholewords, not after all other parameters. (DLR)
        - Maintain current_y's value when moving up or down lines so
          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)
 - utils.c:
   regexp_bol_or_eol()
        - Don't assume any longer that string will be found if
index b6a55783bac5f08ef927a23d5170b32fde3c31f5..babcddeee859e5c0a7ddfaf6c350c016c231e73b 100644 (file)
@@ -1471,7 +1471,7 @@ bool do_int_spell_fix(const char *word)
     search_last_line = FALSE;
 
     /* Find the first whole-word occurrence of word. */
-    while (findnextstr(TRUE, TRUE, FALSE, fileage, 0, word))
+    while (findnextstr(TRUE, TRUE, FALSE, fileage, 0, word, NULL)) {
        if (is_whole_word(current_x, current->data, word)) {
            edit_refresh();
 
@@ -1494,6 +1494,7 @@ bool do_int_spell_fix(const char *word)
 
            break;
        }
+    }
 
     /* Restore the search/replace strings. */
     free(last_search);
index 5f789d3fc360f8bd0ec0155e5a96f2da96cfd6e7..82d2ebb7e3cbdca808a41b9adc4424e9fdbe0839 100644 (file)
@@ -406,7 +406,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);
+       *needle, size_t *needle_len);
 void do_search(void);
 #ifndef NANO_SMALL
 void do_research(void);
@@ -416,8 +416,8 @@ void replace_abort(void);
 int replace_regexp(char *string, bool create_flag);
 #endif
 char *replace_line(const char *needle);
-int do_replace_loop(const char *needle, filestruct *real_current, size_t
-       *real_current_x, bool wholewords);
+ssize_t do_replace_loop(const char *needle, filestruct *real_current,
+       size_t *real_current_x, bool wholewords);
 void do_replace(void);
 void do_gotoline(int line, bool save_pos);
 void do_gotoline_void(void);
index 3be177367ffd44513f311cc9a46d2d9de3426061..860d14dcb4cc42284fcfa229df9703ea92fb3bf1 100644 (file)
@@ -267,15 +267,18 @@ bool is_whole_word(int curr_pos, const char *datastr, const char
  * 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. */
+ * found anything.  If we did, and needle_len isn't NULL, set it to the
+ * length of the string we found. */
 bool findnextstr(bool can_display_wrap, bool wholeword, bool
        no_sameline, const filestruct *begin, size_t beginx, const char
-       *needle)
+       *needle, size_t *needle_len)
 {
     filestruct *fileptr = current;
     const char *rev_start = NULL, *found = NULL;
+    size_t found_len;
+       /* The length of the match we found. */
     size_t current_x_find = 0;
-       /* Where needle was found. */
+       /* The location of the match we found. */
     int current_y_find = current_y;
 
     /* rev_start might end up 1 character before the start or after the
@@ -293,9 +296,37 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
     while (TRUE) {
        found = strstrwrapper(fileptr->data, needle, rev_start);
 
-       if (found != NULL && (!wholeword || is_whole_word(found -
-               fileptr->data, fileptr->data, needle))) {
-           if (!no_sameline || fileptr != current)
+       /* We've found a potential match. */
+       if (found != NULL) {
+           bool found_whole = FALSE;
+               /* Is this potential match a whole word? */
+
+           /* Set found_len to the length of the potential match. */
+           found_len =
+#ifdef HAVE_REGEX_H
+               ISSET(USE_REGEXP) ?
+               regmatches[0].rm_eo - regmatches[0].rm_so :
+#endif
+               strlen(needle);
+
+           /* If we're searching for whole words, see if this potential
+            * match is a whole word. */
+           if (wholeword) {
+               char *word = charalloc(found_len + 1);
+               strncpy(word, found, found_len);
+               word[found_len] = '\0';
+
+               found_whole = is_whole_word(found - fileptr->data,
+                       fileptr->data, word);
+               free(word);
+           }
+
+           /* If we're searching for whole words and this potential
+            * match isn't a whole word, or if we're not allowed to find
+            * a match on the same line we started on and this potential
+            * match is on that line, continue searching. */
+           if ((!wholeword || found_whole) && (!no_sameline ||
+               fileptr != current))
                break;
        }
 
@@ -371,6 +402,8 @@ bool findnextstr(bool can_display_wrap, bool wholeword, bool
     current = fileptr;
     current_x = current_x_find;
     current_y = current_y_find;
+    if (needle_len != NULL)
+       *needle_len = found_len;
 
     return TRUE;
 }
@@ -416,7 +449,8 @@ void do_search(void)
 #endif
 
     search_last_line = FALSE;
-    didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x, answer);
+    didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x,
+       answer, NULL);
 
     /* Check to see if there's only one occurrence of the string and
      * we're on it now. */
@@ -430,7 +464,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);
+               answer, NULL);
            if (fileptr == current && fileptr_x == current_x && !didfind)
                statusbar(_("This is the only occurrence"));
        } else {
@@ -470,7 +504,7 @@ void do_research(void)
 
        search_last_line = FALSE;
        didfind = findnextstr(TRUE, FALSE, FALSE, current, current_x,
-               last_search);
+               last_search, NULL);
 
        /* Check to see if there's only one occurrence of the string and
         * we're on it now. */
@@ -484,7 +518,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);
+                       current_x, answer, NULL);
                if (fileptr == current && fileptr_x == current_x && !didfind)
                    statusbar(_("This is the only occurrence"));
            } else {
@@ -608,10 +642,11 @@ char *replace_line(const char *needle)
  *
  * needle is the string to seek.  We replace it with answer.  Return -1
  * if needle isn't found, else the number of replacements performed. */
-int do_replace_loop(const char *needle, filestruct *real_current, size_t
-       *real_current_x, bool wholewords)
+ssize_t do_replace_loop(const char *needle, filestruct *real_current,
+       size_t *real_current_x, bool wholewords)
 {
-    int numreplaced = -1;
+    ssize_t numreplaced = -1;
+    size_t match_len;
     size_t old_pww = placewewant, current_x_save = *real_current_x;
     const filestruct *current_save = real_current;
     bool replaceall = FALSE;
@@ -650,15 +685,9 @@ int do_replace_loop(const char *needle, filestruct *real_current, size_t
 #else
        FALSE
 #endif
-       , current_save, current_x_save, needle)) {
+       , current_save, current_x_save, needle, &match_len)) {
 
        int i = 0;
-       size_t match_len =
-#ifdef HAVE_REGEX_H
-               ISSET(USE_REGEXP) ?
-               regmatches[0].rm_eo - regmatches[0].rm_so :
-#endif
-               strlen(needle);
 
 #ifndef NANO_SMALL
        /* If we've found a match outside the marked text, skip over it
@@ -809,9 +838,10 @@ int do_replace_loop(const char *needle, filestruct *real_current, size_t
 /* Replace a string. */
 void do_replace(void)
 {
-    int i, numreplaced;
+    int i;
     filestruct *edittop_save, *begin;
     size_t beginx;
+    ssize_t numreplaced;
 
     if (ISSET(VIEW_MODE)) {
        print_view_warning();
@@ -889,8 +919,8 @@ void do_replace(void)
     edit_refresh();
 
     if (numreplaced >= 0)
-       statusbar(P_("Replaced %d occurrence", "Replaced %d occurrences",
-               numreplaced), numreplaced);
+       statusbar(P_("Replaced %ld occurrence", "Replaced %ld occurrences",
+               (long)numreplaced), (long)numreplaced);
 
     replace_abort();
 }
@@ -1026,7 +1056,7 @@ void do_find_bracket(void)
     search_last_line = FALSE;
     while (TRUE) {
        if (findnextstr(FALSE, FALSE, FALSE, current, current_x,
-               regexp_pat)) {
+               regexp_pat, NULL)) {
            /* Found identical bracket. */
            if (current->data[current_x] == ch_under_cursor)
                count++;