Readline 5.1 import for HEAD.
[deliverable/binutils-gdb.git] / readline / search.c
CommitLineData
d60d9f65
SS
1/* search.c - code for non-incremental searching in emacs and vi modes. */
2
5bdf8622 3/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
d60d9f65
SS
4
5 This file is part of the Readline Library (the Library), a set of
6 routines for providing Emacs style line input to programs that ask
7 for it.
8
9 The Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
1b17e766 11 the Free Software Foundation; either version 2, or (at your option)
d60d9f65
SS
12 any later version.
13
14 The Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 The GNU General Public License is often shipped with GNU software, and
20 is generally kept in a file called COPYING or LICENSE. If you do not
21 have a copy of the license, write to the Free Software Foundation,
1b17e766 22 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
d60d9f65
SS
23#define READLINE_LIBRARY
24
25#if defined (HAVE_CONFIG_H)
26# include <config.h>
27#endif
28
29#include <sys/types.h>
30#include <stdio.h>
31
32#if defined (HAVE_UNISTD_H)
33# include <unistd.h>
34#endif
35
36#if defined (HAVE_STDLIB_H)
37# include <stdlib.h>
38#else
39# include "ansi_stdlib.h"
40#endif
41
42#include "rldefs.h"
9255ee31
EZ
43#include "rlmbutil.h"
44
d60d9f65
SS
45#include "readline.h"
46#include "history.h"
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;
70static char *history_search_string;
71static int history_string_size;
72
5bdf8622 73static UNDO_LIST *noninc_saved_undo_list;
9255ee31
EZ
74static void make_history_line_current PARAMS((HIST_ENTRY *));
75static int noninc_search_from_pos PARAMS((char *, int, int));
5bdf8622
DJ
76static int noninc_dosearch PARAMS((char *, int));
77static int noninc_search PARAMS((int, int));
9255ee31
EZ
78static int rl_history_search_internal PARAMS((int, int));
79static void rl_history_search_reinit PARAMS((void));
80
5bdf8622
DJ
81static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
82static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
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);
174 entry = current_history ();
175#if defined (VI_MODE)
176 if (rl_editing_mode != vi_mode)
177#endif
5bdf8622 178 history_set_pos (oldpos);
d60d9f65 179
1b17e766 180 make_history_line_current (entry);
d60d9f65 181
d60d9f65 182 rl_point = 0;
9255ee31
EZ
183 rl_mark = rl_end;
184
d60d9f65 185 rl_clear_message ();
5bdf8622 186 return 1;
d60d9f65
SS
187}
188
5bdf8622
DJ
189static _rl_search_cxt *
190_rl_nsearch_init (dir, pchar)
191 int dir, pchar;
d60d9f65 192{
5bdf8622 193 _rl_search_cxt *cxt;
d60d9f65 194 char *p;
5bdf8622
DJ
195
196 cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
197 if (dir < 0)
198 cxt->sflags |= SF_REVERSE; /* not strictly needed */
199
200 cxt->direction = dir;
201 cxt->history_pos = cxt->save_line;
d60d9f65 202
9255ee31 203 rl_maybe_save_line ();
5bdf8622
DJ
204
205 /* Clear the undo list, since reading the search string should create its
206 own undo list, and the whole list will end up being freed when we
207 finish reading the search string. */
208 rl_undo_list = 0;
d60d9f65
SS
209
210 /* Use the line buffer to read the search string. */
211 rl_line_buffer[0] = 0;
212 rl_end = rl_point = 0;
213
214 p = _rl_make_prompt_for_search (pchar ? pchar : ':');
215 rl_message (p, 0, 0);
216 free (p);
217
9255ee31 218 RL_SETSTATE(RL_STATE_NSEARCH);
5bdf8622
DJ
219
220 _rl_nscxt = cxt;
221
222 return cxt;
223}
224
225static int
226_rl_nsearch_cleanup (cxt, r)
227 _rl_search_cxt *cxt;
228 int r;
229{
230 _rl_scxt_dispose (cxt, 0);
231 _rl_nscxt = 0;
232
233 RL_UNSETSTATE(RL_STATE_NSEARCH);
234
235 return (r != 1);
236}
237
238static void
239_rl_nsearch_abort (cxt)
240 _rl_search_cxt *cxt;
241{
242 rl_maybe_unsave_line ();
243 rl_clear_message ();
244 rl_point = cxt->save_point;
245 rl_mark = cxt->save_mark;
246 rl_restore_prompt ();
247
248 RL_UNSETSTATE (RL_STATE_NSEARCH);
249}
250
251/* Process just-read character C according to search context CXT. Return -1
252 if the caller should abort the search, 0 if we should break out of the
253 loop, and 1 if we should continue to read characters. */
254static int
255_rl_nsearch_dispatch (cxt, c)
256 _rl_search_cxt *cxt;
257 int c;
258{
259 switch (c)
d60d9f65 260 {
5bdf8622
DJ
261 case CTRL('W'):
262 rl_unix_word_rubout (1, c);
263 break;
9255ee31 264
5bdf8622
DJ
265 case CTRL('U'):
266 rl_unix_line_discard (1, c);
267 break;
9255ee31 268
5bdf8622
DJ
269 case RETURN:
270 case NEWLINE:
271 return 0;
9255ee31 272
5bdf8622
DJ
273 case CTRL('H'):
274 case RUBOUT:
275 if (rl_point == 0)
d60d9f65 276 {
5bdf8622
DJ
277 _rl_nsearch_abort (cxt);
278 return -1;
279 }
280 _rl_rubout_char (1, c);
281 break;
282
283 case CTRL('C'):
284 case CTRL('G'):
285 rl_ding ();
286 _rl_nsearch_abort (cxt);
287 return -1;
d60d9f65 288
5bdf8622 289 default:
9255ee31 290#if defined (HANDLE_MULTIBYTE)
5bdf8622
DJ
291 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
292 rl_insert_text (cxt->mb);
293 else
9255ee31 294#endif
5bdf8622
DJ
295 _rl_insert_char (1, c);
296 break;
d60d9f65
SS
297 }
298
5bdf8622
DJ
299 (*rl_redisplay_function) ();
300 return 1;
301}
302
303/* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
304 -1 if the search should be aborted, any other value means to clean up
305 using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
306 0 otherwise. */
307static int
308_rl_nsearch_dosearch (cxt)
309 _rl_search_cxt *cxt;
310{
311 rl_mark = cxt->save_mark;
9255ee31 312
d60d9f65
SS
313 /* If rl_point == 0, we want to re-use the previous search string and
314 start from the saved history position. If there's no previous search
315 string, punt. */
316 if (rl_point == 0)
317 {
5bdf8622 318 if (noninc_search_string == 0)
d60d9f65 319 {
9255ee31 320 rl_ding ();
5bdf8622
DJ
321 rl_restore_prompt ();
322 RL_UNSETSTATE (RL_STATE_NSEARCH);
323 return -1;
d60d9f65
SS
324 }
325 }
326 else
327 {
328 /* We want to start the search from the current history position. */
5bdf8622 329 noninc_history_pos = cxt->save_line;
1b17e766 330 FREE (noninc_search_string);
d60d9f65 331 noninc_search_string = savestring (rl_line_buffer);
5bdf8622
DJ
332
333 /* If we don't want the subsequent undo list generated by the search
334 matching a history line to include the contents of the search string,
335 we need to clear rl_line_buffer here. For now, we just clear the
336 undo list generated by reading the search string. (If the search
337 fails, the old undo list will be restored by rl_maybe_unsave_line.) */
338 rl_free_undo_list ();
d60d9f65
SS
339 }
340
c862e87b 341 rl_restore_prompt ();
5bdf8622
DJ
342 return (noninc_dosearch (noninc_search_string, cxt->direction));
343}
344
345/* Search non-interactively through the history list. DIR < 0 means to
346 search backwards through the history of previous commands; otherwise
347 the search is for commands subsequent to the current position in the
348 history list. PCHAR is the character to use for prompting when reading
349 the search string; if not specified (0), it defaults to `:'. */
350static int
351noninc_search (dir, pchar)
352 int dir;
353 int pchar;
354{
355 _rl_search_cxt *cxt;
356 int c, r;
357
358 cxt = _rl_nsearch_init (dir, pchar);
359
360 if (RL_ISSTATE (RL_STATE_CALLBACK))
361 return (0);
362
363 /* Read the search string. */
364 r = 0;
365 while (1)
366 {
367 c = _rl_search_getchar (cxt);
368
369 if (c == 0)
370 break;
371
372 r = _rl_nsearch_dispatch (cxt, c);
373 if (r < 0)
374 return 1;
375 else if (r == 0)
376 break;
377 }
378
379 r = _rl_nsearch_dosearch (cxt);
380 return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
d60d9f65
SS
381}
382
383/* Search forward through the history list for a string. If the vi-mode
384 code calls this, KEY will be `?'. */
385int
386rl_noninc_forward_search (count, key)
387 int count, key;
388{
5bdf8622 389 return noninc_search (1, (key == '?') ? '?' : 0);
d60d9f65
SS
390}
391
392/* Reverse search the history list for a string. If the vi-mode code
393 calls this, KEY will be `/'. */
394int
395rl_noninc_reverse_search (count, key)
396 int count, key;
397{
5bdf8622 398 return noninc_search (-1, (key == '/') ? '/' : 0);
d60d9f65
SS
399}
400
401/* Search forward through the history list for the last string searched
402 for. If there is no saved search string, abort. */
403int
404rl_noninc_forward_search_again (count, key)
405 int count, key;
406{
5bdf8622
DJ
407 int r;
408
d60d9f65
SS
409 if (!noninc_search_string)
410 {
9255ee31 411 rl_ding ();
d60d9f65
SS
412 return (-1);
413 }
5bdf8622
DJ
414 r = noninc_dosearch (noninc_search_string, 1);
415 return (r != 1);
d60d9f65
SS
416}
417
418/* Reverse search in the history list for the last string searched
419 for. If there is no saved search string, abort. */
420int
421rl_noninc_reverse_search_again (count, key)
422 int count, key;
423{
5bdf8622
DJ
424 int r;
425
d60d9f65
SS
426 if (!noninc_search_string)
427 {
9255ee31 428 rl_ding ();
d60d9f65
SS
429 return (-1);
430 }
5bdf8622
DJ
431 r = noninc_dosearch (noninc_search_string, -1);
432 return (r != 1);
d60d9f65
SS
433}
434
5bdf8622
DJ
435#if defined (READLINE_CALLBACKS)
436int
437_rl_nsearch_callback (cxt)
438 _rl_search_cxt *cxt;
439{
440 int c, r;
441
442 c = _rl_search_getchar (cxt);
443 r = _rl_nsearch_dispatch (cxt, c);
444 if (r != 0)
445 return 1;
446
447 r = _rl_nsearch_dosearch (cxt);
448 return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
449}
450#endif
451
d60d9f65 452static int
1b17e766
EZ
453rl_history_search_internal (count, dir)
454 int count, dir;
d60d9f65 455{
1b17e766
EZ
456 HIST_ENTRY *temp;
457 int ret, oldpos;
d60d9f65 458
9255ee31 459 rl_maybe_save_line ();
1b17e766 460 temp = (HIST_ENTRY *)NULL;
d60d9f65 461
1b17e766
EZ
462 /* Search COUNT times through the history for a line whose prefix
463 matches history_search_string. When this loop finishes, TEMP,
464 if non-null, is the history line to copy into the line buffer. */
d60d9f65
SS
465 while (count)
466 {
1b17e766
EZ
467 ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
468 if (ret == -1)
469 break;
470
471 /* Get the history entry we found. */
472 rl_history_search_pos = ret;
473 oldpos = where_history ();
474 history_set_pos (rl_history_search_pos);
475 temp = current_history ();
476 history_set_pos (oldpos);
477
478 /* Don't find multiple instances of the same line. */
479 if (prev_line_found && STREQ (prev_line_found, temp->line))
480 continue;
481 prev_line_found = temp->line;
482 count--;
d60d9f65
SS
483 }
484
1b17e766 485 /* If we didn't find anything at all, return. */
d60d9f65
SS
486 if (temp == 0)
487 {
9255ee31
EZ
488 rl_maybe_unsave_line ();
489 rl_ding ();
1b17e766
EZ
490 /* If you don't want the saved history line (last match) to show up
491 in the line buffer after the search fails, change the #if 0 to
492 #if 1 */
493#if 0
494 if (rl_point > rl_history_search_len)
495 {
496 rl_point = rl_end = rl_history_search_len;
497 rl_line_buffer[rl_end] = '\0';
9255ee31 498 rl_mark = 0;
1b17e766
EZ
499 }
500#else
9255ee31
EZ
501 rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
502 rl_mark = rl_end;
1b17e766
EZ
503#endif
504 return 1;
d60d9f65
SS
505 }
506
1b17e766
EZ
507 /* Copy the line we found into the current line buffer. */
508 make_history_line_current (temp);
509
510 rl_point = rl_history_search_len;
9255ee31
EZ
511 rl_mark = rl_end;
512
d60d9f65
SS
513 return 0;
514}
515
1b17e766
EZ
516static void
517rl_history_search_reinit ()
518{
519 rl_history_search_pos = where_history ();
520 rl_history_search_len = rl_point;
521 prev_line_found = (char *)NULL;
522 if (rl_point)
523 {
524 if (rl_history_search_len >= history_string_size - 2)
525 {
526 history_string_size = rl_history_search_len + 2;
9255ee31 527 history_search_string = (char *)xrealloc (history_search_string, history_string_size);
1b17e766
EZ
528 }
529 history_search_string[0] = '^';
530 strncpy (history_search_string + 1, rl_line_buffer, rl_point);
531 history_search_string[rl_point + 1] = '\0';
532 }
9255ee31 533 _rl_free_saved_history_line ();
1b17e766
EZ
534}
535
d60d9f65
SS
536/* Search forward in the history for the string of characters
537 from the start of the line to rl_point. This is a non-incremental
538 search. */
539int
540rl_history_search_forward (count, ignore)
541 int count, ignore;
542{
543 if (count == 0)
544 return (0);
1b17e766
EZ
545
546 if (rl_last_func != rl_history_search_forward &&
547 rl_last_func != rl_history_search_backward)
548 rl_history_search_reinit ();
549
550 if (rl_history_search_len == 0)
551 return (rl_get_next_history (count, ignore));
d60d9f65
SS
552 return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
553}
554
555/* Search backward through the history for the string of characters
556 from the start of the line to rl_point. This is a non-incremental
557 search. */
558int
559rl_history_search_backward (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)
567 rl_history_search_reinit ();
568
569 if (rl_history_search_len == 0)
570 return (rl_get_previous_history (count, ignore));
d60d9f65
SS
571 return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
572}
This page took 0.518292 seconds and 4 git commands to generate.