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