Don't build readline's shared libs by default
[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-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 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 (entry)
91 HIST_ENTRY *entry;
92 {
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
103
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;
107 }
108
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. */
114 static int
115 noninc_search_from_pos (string, pos, dir)
116 char *string;
117 int pos, dir;
118 {
119 int ret, old;
120
121 if (pos < 0)
122 return -1;
123
124 old = where_history ();
125 if (history_set_pos (pos) == 0)
126 return -1;
127
128 RL_SETSTATE(RL_STATE_SEARCH);
129 if (*string == '^')
130 ret = history_search_prefix (string + 1, dir);
131 else
132 ret = history_search (string, dir);
133 RL_UNSETSTATE(RL_STATE_SEARCH);
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
144 entries. Returns 1 if the search was successful, 0 otherwise. */
145 static int
146 noninc_dosearch (string, dir)
147 char *string;
148 int dir;
149 {
150 int oldpos, pos;
151 HIST_ENTRY *entry;
152
153 if (string == 0 || *string == '\0' || noninc_history_pos < 0)
154 {
155 rl_ding ();
156 return 0;
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. */
163 rl_maybe_unsave_line ();
164 rl_clear_message ();
165 rl_point = 0;
166 rl_ding ();
167 return 0;
168 }
169
170 noninc_history_pos = pos;
171
172 oldpos = where_history ();
173 history_set_pos (noninc_history_pos);
174 entry = current_history (); /* will never be NULL after successful search */
175
176 #if defined (VI_MODE)
177 if (rl_editing_mode != vi_mode)
178 #endif
179 history_set_pos (oldpos);
180
181 make_history_line_current (entry);
182
183 rl_point = 0;
184 rl_mark = rl_end;
185
186 rl_clear_message ();
187 return 1;
188 }
189
190 static _rl_search_cxt *
191 _rl_nsearch_init (dir, pchar)
192 int dir, pchar;
193 {
194 _rl_search_cxt *cxt;
195 char *p;
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;
203
204 rl_maybe_save_line ();
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;
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 : ':');
216 rl_message ("%s", p);
217 xfree (p);
218
219 RL_SETSTATE(RL_STATE_NSEARCH);
220
221 _rl_nscxt = cxt;
222
223 return cxt;
224 }
225
226 int
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
239 static 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. */
255 static int
256 _rl_nsearch_dispatch (cxt, c)
257 _rl_search_cxt *cxt;
258 int c;
259 {
260 switch (c)
261 {
262 case CTRL('W'):
263 rl_unix_word_rubout (1, c);
264 break;
265
266 case CTRL('U'):
267 rl_unix_line_discard (1, c);
268 break;
269
270 case RETURN:
271 case NEWLINE:
272 return 0;
273
274 case CTRL('H'):
275 case RUBOUT:
276 if (rl_point == 0)
277 {
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;
289
290 default:
291 #if defined (HANDLE_MULTIBYTE)
292 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
293 rl_insert_text (cxt->mb);
294 else
295 #endif
296 _rl_insert_char (1, c);
297 break;
298 }
299
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. */
308 static int
309 _rl_nsearch_dosearch (cxt)
310 _rl_search_cxt *cxt;
311 {
312 rl_mark = cxt->save_mark;
313
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 {
319 if (noninc_search_string == 0)
320 {
321 rl_ding ();
322 rl_restore_prompt ();
323 RL_UNSETSTATE (RL_STATE_NSEARCH);
324 return -1;
325 }
326 }
327 else
328 {
329 /* We want to start the search from the current history position. */
330 noninc_history_pos = cxt->save_line;
331 FREE (noninc_search_string);
332 noninc_search_string = savestring (rl_line_buffer);
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 ();
340 }
341
342 rl_restore_prompt ();
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 `:'. */
351 static int
352 noninc_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));
382 }
383
384 /* Search forward through the history list for a string. If the vi-mode
385 code calls this, KEY will be `?'. */
386 int
387 rl_noninc_forward_search (count, key)
388 int count, key;
389 {
390 return noninc_search (1, (key == '?') ? '?' : 0);
391 }
392
393 /* Reverse search the history list for a string. If the vi-mode code
394 calls this, KEY will be `/'. */
395 int
396 rl_noninc_reverse_search (count, key)
397 int count, key;
398 {
399 return noninc_search (-1, (key == '/') ? '/' : 0);
400 }
401
402 /* Search forward through the history list for the last string searched
403 for. If there is no saved search string, abort. */
404 int
405 rl_noninc_forward_search_again (count, key)
406 int count, key;
407 {
408 int r;
409
410 if (!noninc_search_string)
411 {
412 rl_ding ();
413 return (1);
414 }
415 r = noninc_dosearch (noninc_search_string, 1);
416 return (r != 1);
417 }
418
419 /* Reverse search in the history list for the last string searched
420 for. If there is no saved search string, abort. */
421 int
422 rl_noninc_reverse_search_again (count, key)
423 int count, key;
424 {
425 int r;
426
427 if (!noninc_search_string)
428 {
429 rl_ding ();
430 return (1);
431 }
432 r = noninc_dosearch (noninc_search_string, -1);
433 return (r != 1);
434 }
435
436 #if defined (READLINE_CALLBACKS)
437 int
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
453 static int
454 rl_history_search_internal (count, dir)
455 int count, dir;
456 {
457 HIST_ENTRY *temp;
458 int ret, oldpos;
459 char *t;
460
461 rl_maybe_save_line ();
462 temp = (HIST_ENTRY *)NULL;
463
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. */
469 while (count)
470 {
471 RL_CHECK_SIGNALS ();
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);
480 temp = current_history (); /* will never be NULL after successful search */
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--;
488 }
489
490 /* If we didn't find anything at all, return. */
491 if (temp == 0)
492 {
493 rl_maybe_unsave_line ();
494 rl_ding ();
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';
503 rl_mark = 0;
504 }
505 #else
506 rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
507 rl_mark = rl_end;
508 #endif
509 return 1;
510 }
511
512 /* Copy the line we found into the current line buffer. */
513 make_history_line_current (temp);
514
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 }
522 rl_mark = rl_end;
523
524 return 0;
525 }
526
527 static void
528 rl_history_search_reinit (flags)
529 int flags;
530 {
531 int sind;
532
533 rl_history_search_pos = where_history ();
534 rl_history_search_len = rl_point;
535 rl_history_search_flags = flags;
536
537 prev_line_found = (char *)NULL;
538 if (rl_point)
539 {
540 /* Allocate enough space for anchored and non-anchored searches */
541 if (rl_history_search_len >= history_string_size - 2)
542 {
543 history_string_size = rl_history_search_len + 2;
544 history_search_string = (char *)xrealloc (history_search_string, history_string_size);
545 }
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';
551 }
552 _rl_free_saved_history_line ();
553 }
554
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
557 search. The search is anchored to the beginning of the history line. */
558 int
559 rl_history_search_forward (count, ignore)
560 int count, ignore;
561 {
562 if (count == 0)
563 return (0);
564
565 if (rl_last_func != rl_history_search_forward &&
566 rl_last_func != rl_history_search_backward)
567 rl_history_search_reinit (ANCHORED_SEARCH);
568
569 if (rl_history_search_len == 0)
570 return (rl_get_next_history (count, ignore));
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. */
577 int
578 rl_history_search_backward (count, ignore)
579 int count, ignore;
580 {
581 if (count == 0)
582 return (0);
583
584 if (rl_last_func != rl_history_search_forward &&
585 rl_last_func != rl_history_search_backward)
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. */
597 int
598 rl_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. */
616 int
617 rl_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);
626
627 if (rl_history_search_len == 0)
628 return (rl_get_previous_history (count, ignore));
629 return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
630 }
This page took 0.043958 seconds and 4 git commands to generate.