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