Changes to search commands ('/', '?', 'n' and 'N'):

- Rewrite to be smaller and (possibly) clearer.

- Issue a warning when a repeat search is requested without a
  previous search having been made.

Vim and BusyBox vi support a repetition count for searches though
the original vi doesn't.  If the count exceeds the number of
occurrences of the search string the search may loop through the
file multiple times.

function                                             old     new   delta
.rodata                                           105135  105119     -16
do_cmd                                              4898    4860     -38
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 0/2 up/down: 0/-54)             Total: -54 bytes

Signed-off-by; Ron Yorston <r...@pobox.com>
---
 editors/vi.c | 85 ++++++++++++++++++++++------------------------------
 1 file changed, 36 insertions(+), 49 deletions(-)

diff --git a/editors/vi.c b/editors/vi.c
index 04d584fec..7ead92a53 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -3463,70 +3463,57 @@ static void do_cmd(int c)
                break;
 #endif
 #if ENABLE_FEATURE_VI_SEARCH
-       case '?':                       // /- search for a pattern
-       case '/':                       // /- search for a pattern
+       case 'N':                       // N- backward search for last pattern
+               dir = last_search_pattern[0] == '/' ? BACK : FORWARD;
+               goto dc4;               // now search for pattern
+               break;
+       case '?':                       // ?- backward search for a pattern
+       case '/':                       // /- forward search for a pattern
                buf[0] = c;
                buf[1] = '\0';
                q = get_input_line(buf);        // get input line- use "status 
line"
-               if (q[0] && !q[1]) {
+               if (!q[0])      // user changed mind and erased the "/"-  do 
nothing
+                       break;
+               if (!q[1]) {    // if no pat re-use old pat
                        if (last_search_pattern[0])
                                last_search_pattern[0] = c;
-                       goto dc3; // if no pat re-use old pat
-               }
-               if (q[0]) {       // strlen(q) > 1: new pat- save it and find
-                       // there is a new pat
+               } else {        // strlen(q) > 1: new pat- save it and find
                        free(last_search_pattern);
                        last_search_pattern = xstrdup(q);
-                       goto dc3;       // now find the pattern
                }
-               // user changed mind and erased the "/"-  do nothing
-               break;
-       case 'N':                       // N- backward search for last pattern
-               dir = BACK;             // assume BACKWARD search
-               p = dot - 1;
-               if (last_search_pattern[0] == '?') {
-                       dir = FORWARD;
-                       p = dot + 1;
-               }
-               goto dc4;               // now search for pattern
-               break;
+               // fall through
        case 'n':                       // n- repeat search for last pattern
                // search rest of text[] starting at next char
-               // if search fails return orignal "p" not the "p+1" address
-               do {
-                       const char *msg;
- dc3:
-                       dir = FORWARD;  // assume FORWARD search
-                       p = dot + 1;
-                       if (last_search_pattern[0] == '?') {
-                               dir = BACK;
-                               p = dot - 1;
-                       }
+               // if search fails "dot" is unchanged
+               dir = last_search_pattern[0] == '/' ? FORWARD : BACK;
  dc4:
-                       q = char_search(p, last_search_pattern + 1, (dir << 1) 
| FULL);
+               if (last_search_pattern[1] == '\0') {
+                       status_line_bold("No previous search");
+                       break;
+               }
+               do {
+                       q = char_search(dot + dir, last_search_pattern + 1,
+                                               (dir << 1) | FULL);
                        if (q != NULL) {
                                dot = q;        // good search, update "dot"
-                               msg = NULL;
-                               goto dc2;
-                       }
-                       // no pattern found between "dot" and "end"- continue 
at top
-                       p = text;
-                       if (dir == BACK) {
-                               p = end - 1;
-                       }
-                       q = char_search(p, last_search_pattern + 1, (dir << 1) 
| FULL);
-                       if (q != NULL) {        // found something
-                               dot = q;        // found new pattern- goto it
-                               msg = "search hit BOTTOM, continuing at TOP";
-                               if (dir == BACK) {
-                                       msg = "search hit TOP, continuing at 
BOTTOM";
-                               }
                        } else {
-                               msg = "Pattern not found";
+                               // no pattern found between "dot" and 
top/bottom of file
+                               // continue from other end of file
+                               const char *msg;
+                               q = char_search(dir == FORWARD ? text : end - 1,
+                                               last_search_pattern + 1, (dir 
<< 1) | FULL);
+                               if (q != NULL) {        // found something
+                                       dot = q;        // found new pattern- 
goto it
+                                       msg = "search hit %s, continuing at %s";
+                               } else {        // pattern is nowhere in file
+                                       cmdcnt = 0;     // force exit from loop
+                                       msg = "Pattern not found";
+                               }
+                               if (dir == FORWARD)
+                                       status_line_bold(msg, "BOTTOM", "TOP");
+                               else
+                                       status_line_bold(msg, "TOP", "BOTTOM");
                        }
- dc2:
-                       if (msg)
-                               status_line_bold("%s", msg);
                } while (--cmdcnt > 0);
                break;
        case '{':                       // {- move backward paragraph
-- 
2.30.2

_______________________________________________
busybox mailing list
busybox@busybox.net
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to