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