Bash-4.3 distribution sources and documentation
[platform/upstream/bash.git] / lib / readline / search.c
1 /* search.c - code for non-incremental searching in emacs and vi modes. */
2
3 /* Copyright (C) 1992-2013 Free Software Foundation, Inc.
4
5    This file is part of the GNU Readline Library (Readline), a library
6    for reading lines of text with interactive input and history editing.      
7
8    Readline is free software: you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation, either version 3 of the License, or
11    (at your option) any later version.
12
13    Readline is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #define READLINE_LIBRARY
23
24 #if defined (HAVE_CONFIG_H)
25 #  include <config.h>
26 #endif
27
28 #include <sys/types.h>
29 #include <stdio.h>
30
31 #if defined (HAVE_UNISTD_H)
32 #  include <unistd.h>
33 #endif
34
35 #if defined (HAVE_STDLIB_H)
36 #  include <stdlib.h>
37 #else
38 #  include "ansi_stdlib.h"
39 #endif
40
41 #include "rldefs.h"
42 #include "rlmbutil.h"
43
44 #include "readline.h"
45 #include "history.h"
46 #include "histlib.h"
47
48 #include "rlprivate.h"
49 #include "xmalloc.h"
50
51 #ifdef abs
52 #  undef abs
53 #endif
54 #define abs(x)          (((x) >= 0) ? (x) : -(x))
55
56 _rl_search_cxt *_rl_nscxt = 0;
57
58 extern HIST_ENTRY *_rl_saved_line_for_history;
59
60 /* Functions imported from the rest of the library. */
61 extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
62
63 static char *noninc_search_string = (char *) NULL;
64 static int noninc_history_pos;
65
66 static char *prev_line_found = (char *) NULL;
67
68 static int rl_history_search_len;
69 static int rl_history_search_pos;
70 static int rl_history_search_flags;
71
72 static char *history_search_string;
73 static int history_string_size;
74
75 static void make_history_line_current PARAMS((HIST_ENTRY *));
76 static int noninc_search_from_pos PARAMS((char *, int, int));
77 static int noninc_dosearch PARAMS((char *, int));
78 static int noninc_search PARAMS((int, int));
79 static int rl_history_search_internal PARAMS((int, int));
80 static void rl_history_search_reinit PARAMS((int));
81
82 static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
83 static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
84 static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
85 static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
86
87 /* Make the data from the history entry ENTRY be the contents of the
88    current line.  This doesn't do anything with rl_point; the caller
89    must set it. */
90 static void
91 make_history_line_current (entry)
92      HIST_ENTRY *entry;
93 {
94   _rl_replace_text (entry->line, 0, rl_end);
95   _rl_fix_point (1);
96 #if defined (VI_MODE)
97   if (rl_editing_mode == vi_mode)
98     /* POSIX.2 says that the `U' command doesn't affect the copy of any
99        command lines to the edit line.  We're going to implement that by
100        making the undo list start after the matching line is copied to the
101        current editing buffer. */
102     rl_free_undo_list ();
103 #endif
104
105   if (_rl_saved_line_for_history)
106     _rl_free_history_entry (_rl_saved_line_for_history);
107   _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
108 }
109
110 /* Search the history list for STRING starting at absolute history position
111    POS.  If STRING begins with `^', the search must match STRING at the
112    beginning of a history line, otherwise a full substring match is performed
113    for STRING.  DIR < 0 means to search backwards through the history list,
114    DIR >= 0 means to search forward. */
115 static int
116 noninc_search_from_pos (string, pos, dir)
117      char *string;
118      int pos, dir;
119 {
120   int ret, old;
121
122   if (pos < 0)
123     return -1;
124
125   old = where_history ();
126   if (history_set_pos (pos) == 0)
127     return -1;
128
129   RL_SETSTATE(RL_STATE_SEARCH);
130   if (*string == '^')
131     ret = history_search_prefix (string + 1, dir);
132   else
133     ret = history_search (string, dir);
134   RL_UNSETSTATE(RL_STATE_SEARCH);
135
136   if (ret != -1)
137     ret = where_history ();
138
139   history_set_pos (old);
140   return (ret);
141 }
142
143 /* Search for a line in the history containing STRING.  If DIR is < 0, the
144    search is backwards through previous entries, else through subsequent
145    entries.  Returns 1 if the search was successful, 0 otherwise. */
146 static int
147 noninc_dosearch (string, dir)
148      char *string;
149      int dir;
150 {
151   int oldpos, pos;
152   HIST_ENTRY *entry;
153
154   if (string == 0 || *string == '\0' || noninc_history_pos < 0)
155     {
156       rl_ding ();
157       return 0;
158     }
159
160   pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
161   if (pos == -1)
162     {
163       /* Search failed, current history position unchanged. */
164       rl_maybe_unsave_line ();
165       rl_clear_message ();
166       rl_point = 0;
167       rl_ding ();
168       return 0;
169     }
170
171   noninc_history_pos = pos;
172
173   oldpos = where_history ();
174   history_set_pos (noninc_history_pos);
175   entry = current_history ();           /* will never be NULL after successful search */
176   
177 #if defined (VI_MODE)
178   if (rl_editing_mode != vi_mode)
179 #endif
180     history_set_pos (oldpos);
181
182   make_history_line_current (entry);
183
184   rl_point = 0;
185   rl_mark = rl_end;
186
187   rl_clear_message ();
188   return 1;
189 }
190
191 static _rl_search_cxt *
192 _rl_nsearch_init (dir, pchar)
193      int dir, pchar;
194 {
195   _rl_search_cxt *cxt;
196   char *p;
197
198   cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
199   if (dir < 0)
200     cxt->sflags |= SF_REVERSE;          /* not strictly needed */
201
202   cxt->direction = dir;
203   cxt->history_pos = cxt->save_line;
204
205   rl_maybe_save_line ();
206
207   /* Clear the undo list, since reading the search string should create its
208      own undo list, and the whole list will end up being freed when we
209      finish reading the search string. */
210   rl_undo_list = 0;
211
212   /* Use the line buffer to read the search string. */
213   rl_line_buffer[0] = 0;
214   rl_end = rl_point = 0;
215
216   p = _rl_make_prompt_for_search (pchar ? pchar : ':');
217   rl_message ("%s", p);
218   xfree (p);
219
220   RL_SETSTATE(RL_STATE_NSEARCH);
221
222   _rl_nscxt = cxt;
223
224   return cxt;
225 }
226
227 static int
228 _rl_nsearch_cleanup (cxt, r)
229      _rl_search_cxt *cxt;
230      int r;
231 {
232   _rl_scxt_dispose (cxt, 0);
233   _rl_nscxt = 0;
234
235   RL_UNSETSTATE(RL_STATE_NSEARCH);
236
237   return (r != 1);
238 }
239
240 static void
241 _rl_nsearch_abort (cxt)
242      _rl_search_cxt *cxt;
243 {
244   rl_maybe_unsave_line ();
245   rl_clear_message ();
246   rl_point = cxt->save_point;
247   rl_mark = cxt->save_mark;
248   rl_restore_prompt ();
249
250   RL_UNSETSTATE (RL_STATE_NSEARCH);
251 }
252
253 /* Process just-read character C according to search context CXT.  Return -1
254    if the caller should abort the search, 0 if we should break out of the
255    loop, and 1 if we should continue to read characters. */
256 static int
257 _rl_nsearch_dispatch (cxt, c)
258      _rl_search_cxt *cxt;
259      int c;
260 {
261   switch (c)
262     {
263     case CTRL('W'):
264       rl_unix_word_rubout (1, c);
265       break;
266
267     case CTRL('U'):
268       rl_unix_line_discard (1, c);
269       break;
270
271     case RETURN:
272     case NEWLINE:
273       return 0;
274
275     case CTRL('H'):
276     case RUBOUT:
277       if (rl_point == 0)
278         {
279           _rl_nsearch_abort (cxt);
280           return -1;
281         }
282       _rl_rubout_char (1, c);
283       break;
284
285     case CTRL('C'):
286     case CTRL('G'):
287       rl_ding ();
288       _rl_nsearch_abort (cxt);
289       return -1;
290
291     default:
292 #if defined (HANDLE_MULTIBYTE)
293       if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
294         rl_insert_text (cxt->mb);
295       else
296 #endif
297         _rl_insert_char (1, c);
298       break;
299     }
300
301   (*rl_redisplay_function) ();
302   return 1;
303 }
304
305 /* Perform one search according to CXT, using NONINC_SEARCH_STRING.  Return
306    -1 if the search should be aborted, any other value means to clean up
307    using _rl_nsearch_cleanup ().  Returns 1 if the search was successful,
308    0 otherwise. */
309 static int
310 _rl_nsearch_dosearch (cxt)
311      _rl_search_cxt *cxt;
312 {
313   rl_mark = cxt->save_mark;
314
315   /* If rl_point == 0, we want to re-use the previous search string and
316      start from the saved history position.  If there's no previous search
317      string, punt. */
318   if (rl_point == 0)
319     {
320       if (noninc_search_string == 0)
321         {
322           rl_ding ();
323           rl_restore_prompt ();
324           RL_UNSETSTATE (RL_STATE_NSEARCH);
325           return -1;
326         }
327     }
328   else
329     {
330       /* We want to start the search from the current history position. */
331       noninc_history_pos = cxt->save_line;
332       FREE (noninc_search_string);
333       noninc_search_string = savestring (rl_line_buffer);
334
335       /* If we don't want the subsequent undo list generated by the search
336          matching a history line to include the contents of the search string,
337          we need to clear rl_line_buffer here.  For now, we just clear the
338          undo list generated by reading the search string.  (If the search
339          fails, the old undo list will be restored by rl_maybe_unsave_line.) */
340       rl_free_undo_list ();
341     }
342
343   rl_restore_prompt ();
344   return (noninc_dosearch (noninc_search_string, cxt->direction));
345 }
346
347 /* Search non-interactively through the history list.  DIR < 0 means to
348    search backwards through the history of previous commands; otherwise
349    the search is for commands subsequent to the current position in the
350    history list.  PCHAR is the character to use for prompting when reading
351    the search string; if not specified (0), it defaults to `:'. */
352 static int
353 noninc_search (dir, pchar)
354      int dir;
355      int pchar;
356 {
357   _rl_search_cxt *cxt;
358   int c, r;
359
360   cxt = _rl_nsearch_init (dir, pchar);
361
362   if (RL_ISSTATE (RL_STATE_CALLBACK))
363     return (0);
364
365   /* Read the search string. */
366   r = 0;
367   while (1)
368     {
369       c = _rl_search_getchar (cxt);
370
371       if (c == 0)
372         break;
373
374       r = _rl_nsearch_dispatch (cxt, c);
375       if (r < 0)
376         return 1;
377       else if (r == 0)
378         break;        
379     }
380
381   r = _rl_nsearch_dosearch (cxt);
382   return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
383 }
384
385 /* Search forward through the history list for a string.  If the vi-mode
386    code calls this, KEY will be `?'. */
387 int
388 rl_noninc_forward_search (count, key)
389      int count, key;
390 {
391   return noninc_search (1, (key == '?') ? '?' : 0);
392 }
393
394 /* Reverse search the history list for a string.  If the vi-mode code
395    calls this, KEY will be `/'. */
396 int
397 rl_noninc_reverse_search (count, key)
398      int count, key;
399 {
400   return noninc_search (-1, (key == '/') ? '/' : 0);
401 }
402
403 /* Search forward through the history list for the last string searched
404    for.  If there is no saved search string, abort. */
405 int
406 rl_noninc_forward_search_again (count, key)
407      int count, key;
408 {
409   int r;
410
411   if (!noninc_search_string)
412     {
413       rl_ding ();
414       return (-1);
415     }
416   r = noninc_dosearch (noninc_search_string, 1);
417   return (r != 1);
418 }
419
420 /* Reverse search in the history list for the last string searched
421    for.  If there is no saved search string, abort. */
422 int
423 rl_noninc_reverse_search_again (count, key)
424      int count, key;
425 {
426   int r;
427
428   if (!noninc_search_string)
429     {
430       rl_ding ();
431       return (-1);
432     }
433   r = noninc_dosearch (noninc_search_string, -1);
434   return (r != 1);
435 }
436
437 #if defined (READLINE_CALLBACKS)
438 int
439 _rl_nsearch_callback (cxt)
440      _rl_search_cxt *cxt;
441 {
442   int c, r;
443
444   c = _rl_search_getchar (cxt);
445   r = _rl_nsearch_dispatch (cxt, c);
446   if (r != 0)
447     return 1;
448
449   r = _rl_nsearch_dosearch (cxt);
450   return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
451 }
452 #endif
453   
454 static int
455 rl_history_search_internal (count, dir)
456      int count, dir;
457 {
458   HIST_ENTRY *temp;
459   int ret, oldpos;
460   char *t;
461
462   rl_maybe_save_line ();
463   temp = (HIST_ENTRY *)NULL;
464
465   /* Search COUNT times through the history for a line matching
466      history_search_string.  If history_search_string[0] == '^', the
467      line must match from the start; otherwise any substring can match.
468      When this loop finishes, TEMP, if non-null, is the history line to
469      copy into the line buffer. */
470   while (count)
471     {
472       RL_CHECK_SIGNALS ();
473       ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
474       if (ret == -1)
475         break;
476
477       /* Get the history entry we found. */
478       rl_history_search_pos = ret;
479       oldpos = where_history ();
480       history_set_pos (rl_history_search_pos);
481       temp = current_history ();        /* will never be NULL after successful search */
482       history_set_pos (oldpos);
483
484       /* Don't find multiple instances of the same line. */
485       if (prev_line_found && STREQ (prev_line_found, temp->line))
486         continue;
487       prev_line_found = temp->line;
488       count--;
489     }
490
491   /* If we didn't find anything at all, return. */
492   if (temp == 0)
493     {
494       rl_maybe_unsave_line ();
495       rl_ding ();
496       /* If you don't want the saved history line (last match) to show up
497          in the line buffer after the search fails, change the #if 0 to
498          #if 1 */
499 #if 0
500       if (rl_point > rl_history_search_len)
501         {
502           rl_point = rl_end = rl_history_search_len;
503           rl_line_buffer[rl_end] = '\0';
504           rl_mark = 0;
505         }
506 #else
507       rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
508       rl_mark = rl_end;
509 #endif
510       return 1;
511     }
512
513   /* Copy the line we found into the current line buffer. */
514   make_history_line_current (temp);
515
516   if (rl_history_search_flags & ANCHORED_SEARCH)
517     rl_point = rl_history_search_len;   /* easy case */
518   else
519     {
520       t = strstr (rl_line_buffer, history_search_string);
521       rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end;
522     }
523   rl_mark = rl_end;
524
525   return 0;
526 }
527
528 static void
529 rl_history_search_reinit (flags)
530      int flags;
531 {
532   int sind;
533
534   rl_history_search_pos = where_history ();
535   rl_history_search_len = rl_point;
536   rl_history_search_flags = flags;
537
538   prev_line_found = (char *)NULL;
539   if (rl_point)
540     {
541       /* Allocate enough space for anchored and non-anchored searches */
542       if (rl_history_search_len >= history_string_size - 2)
543         {
544           history_string_size = rl_history_search_len + 2;
545           history_search_string = (char *)xrealloc (history_search_string, history_string_size);
546         }
547       sind = 0;
548       if (flags & ANCHORED_SEARCH)
549         history_search_string[sind++] = '^';
550       strncpy (history_search_string + sind, rl_line_buffer, rl_point);
551       history_search_string[rl_point + sind] = '\0';
552     }
553   _rl_free_saved_history_line ();
554 }
555
556 /* Search forward in the history for the string of characters
557    from the start of the line to rl_point.  This is a non-incremental
558    search.  The search is anchored to the beginning of the history line. */
559 int
560 rl_history_search_forward (count, ignore)
561      int count, ignore;
562 {
563   if (count == 0)
564     return (0);
565
566   if (rl_last_func != rl_history_search_forward &&
567       rl_last_func != rl_history_search_backward)
568     rl_history_search_reinit (ANCHORED_SEARCH);
569
570   if (rl_history_search_len == 0)
571     return (rl_get_next_history (count, ignore));
572   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
573 }
574
575 /* Search backward through the history for the string of characters
576    from the start of the line to rl_point.  This is a non-incremental
577    search. */
578 int
579 rl_history_search_backward (count, ignore)
580      int count, ignore;
581 {
582   if (count == 0)
583     return (0);
584
585   if (rl_last_func != rl_history_search_forward &&
586       rl_last_func != rl_history_search_backward)
587     rl_history_search_reinit (ANCHORED_SEARCH);
588
589   if (rl_history_search_len == 0)
590     return (rl_get_previous_history (count, ignore));
591   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
592 }
593
594 /* Search forward in the history for the string of characters
595    from the start of the line to rl_point.  This is a non-incremental
596    search.  The search succeeds if the search string is present anywhere
597    in the history line. */
598 int
599 rl_history_substr_search_forward (count, ignore)
600      int count, ignore;
601 {
602   if (count == 0)
603     return (0);
604
605   if (rl_last_func != rl_history_substr_search_forward &&
606       rl_last_func != rl_history_substr_search_backward)
607     rl_history_search_reinit (NON_ANCHORED_SEARCH);
608
609   if (rl_history_search_len == 0)
610     return (rl_get_next_history (count, ignore));
611   return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
612 }
613
614 /* Search backward through the history for the string of characters
615    from the start of the line to rl_point.  This is a non-incremental
616    search. */
617 int
618 rl_history_substr_search_backward (count, ignore)
619      int count, ignore;
620 {
621   if (count == 0)
622     return (0);
623
624   if (rl_last_func != rl_history_substr_search_forward &&
625       rl_last_func != rl_history_substr_search_backward)
626     rl_history_search_reinit (NON_ANCHORED_SEARCH);
627
628   if (rl_history_search_len == 0)
629     return (rl_get_previous_history (count, ignore));
630   return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
631 }