* signals.c (_rl_block_sigwinch, _rl_release_sigwinch): Add
[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-2009 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
47 #include "rlprivate.h"
48 #include "xmalloc.h"
49
50 #ifdef abs
51 # undef abs
52 #endif
53 #define abs(x) (((x) >= 0) ? (x) : -(x))
54
55 _rl_search_cxt *_rl_nscxt = 0;
56
57 extern HIST_ENTRY *_rl_saved_line_for_history;
58
59 /* Functions imported from the rest of the library. */
60 extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
61
62 static char *noninc_search_string = (char *) NULL;
63 static int noninc_history_pos;
64
65 static char *prev_line_found = (char *) NULL;
66
67 static int rl_history_search_len;
68 static int rl_history_search_pos;
69 static char *history_search_string;
70 static int history_string_size;
71
72 static void make_history_line_current PARAMS((HIST_ENTRY *));
73 static int noninc_search_from_pos PARAMS((char *, int, int));
74 static int noninc_dosearch PARAMS((char *, int));
75 static int noninc_search PARAMS((int, int));
76 static int rl_history_search_internal PARAMS((int, int));
77 static void rl_history_search_reinit PARAMS((void));
78
79 static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
80 static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
81 static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
82 static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
83
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. */
87 static void
88 make_history_line_current (entry)
89 HIST_ENTRY *entry;
90 {
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
101
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;
105 }
106
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. */
112 static int
113 noninc_search_from_pos (string, pos, dir)
114 char *string;
115 int pos, dir;
116 {
117 int ret, old;
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 if (*string == '^')
128 ret = history_search_prefix (string + 1, dir);
129 else
130 ret = history_search (string, dir);
131 RL_UNSETSTATE(RL_STATE_SEARCH);
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
142 entries. Returns 1 if the search was successful, 0 otherwise. */
143 static int
144 noninc_dosearch (string, dir)
145 char *string;
146 int dir;
147 {
148 int oldpos, pos;
149 HIST_ENTRY *entry;
150
151 if (string == 0 || *string == '\0' || noninc_history_pos < 0)
152 {
153 rl_ding ();
154 return 0;
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. */
161 rl_maybe_unsave_line ();
162 rl_clear_message ();
163 rl_point = 0;
164 rl_ding ();
165 return 0;
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
176 history_set_pos (oldpos);
177
178 make_history_line_current (entry);
179
180 rl_point = 0;
181 rl_mark = rl_end;
182
183 rl_clear_message ();
184 return 1;
185 }
186
187 static _rl_search_cxt *
188 _rl_nsearch_init (dir, pchar)
189 int dir, pchar;
190 {
191 _rl_search_cxt *cxt;
192 char *p;
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;
200
201 rl_maybe_save_line ();
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;
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 : ':');
213 rl_message ("%s", p, 0);
214 xfree (p);
215
216 RL_SETSTATE(RL_STATE_NSEARCH);
217
218 _rl_nscxt = cxt;
219
220 return cxt;
221 }
222
223 static 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
236 static 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. */
252 static int
253 _rl_nsearch_dispatch (cxt, c)
254 _rl_search_cxt *cxt;
255 int c;
256 {
257 switch (c)
258 {
259 case CTRL('W'):
260 rl_unix_word_rubout (1, c);
261 break;
262
263 case CTRL('U'):
264 rl_unix_line_discard (1, c);
265 break;
266
267 case RETURN:
268 case NEWLINE:
269 return 0;
270
271 case CTRL('H'):
272 case RUBOUT:
273 if (rl_point == 0)
274 {
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;
286
287 default:
288 #if defined (HANDLE_MULTIBYTE)
289 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
290 rl_insert_text (cxt->mb);
291 else
292 #endif
293 _rl_insert_char (1, c);
294 break;
295 }
296
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. */
305 static int
306 _rl_nsearch_dosearch (cxt)
307 _rl_search_cxt *cxt;
308 {
309 rl_mark = cxt->save_mark;
310
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 {
316 if (noninc_search_string == 0)
317 {
318 rl_ding ();
319 rl_restore_prompt ();
320 RL_UNSETSTATE (RL_STATE_NSEARCH);
321 return -1;
322 }
323 }
324 else
325 {
326 /* We want to start the search from the current history position. */
327 noninc_history_pos = cxt->save_line;
328 FREE (noninc_search_string);
329 noninc_search_string = savestring (rl_line_buffer);
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 ();
337 }
338
339 rl_restore_prompt ();
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 `:'. */
348 static int
349 noninc_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));
379 }
380
381 /* Search forward through the history list for a string. If the vi-mode
382 code calls this, KEY will be `?'. */
383 int
384 rl_noninc_forward_search (count, key)
385 int count, key;
386 {
387 return noninc_search (1, (key == '?') ? '?' : 0);
388 }
389
390 /* Reverse search the history list for a string. If the vi-mode code
391 calls this, KEY will be `/'. */
392 int
393 rl_noninc_reverse_search (count, key)
394 int count, key;
395 {
396 return noninc_search (-1, (key == '/') ? '/' : 0);
397 }
398
399 /* Search forward through the history list for the last string searched
400 for. If there is no saved search string, abort. */
401 int
402 rl_noninc_forward_search_again (count, key)
403 int count, key;
404 {
405 int r;
406
407 if (!noninc_search_string)
408 {
409 rl_ding ();
410 return (-1);
411 }
412 r = noninc_dosearch (noninc_search_string, 1);
413 return (r != 1);
414 }
415
416 /* Reverse search in the history list for the last string searched
417 for. If there is no saved search string, abort. */
418 int
419 rl_noninc_reverse_search_again (count, key)
420 int count, key;
421 {
422 int r;
423
424 if (!noninc_search_string)
425 {
426 rl_ding ();
427 return (-1);
428 }
429 r = noninc_dosearch (noninc_search_string, -1);
430 return (r != 1);
431 }
432
433 #if defined (READLINE_CALLBACKS)
434 int
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
450 static int
451 rl_history_search_internal (count, dir)
452 int count, dir;
453 {
454 HIST_ENTRY *temp;
455 int ret, oldpos;
456
457 rl_maybe_save_line ();
458 temp = (HIST_ENTRY *)NULL;
459
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. */
463 while (count)
464 {
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--;
481 }
482
483 /* If we didn't find anything at all, return. */
484 if (temp == 0)
485 {
486 rl_maybe_unsave_line ();
487 rl_ding ();
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';
496 rl_mark = 0;
497 }
498 #else
499 rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
500 rl_mark = rl_end;
501 #endif
502 return 1;
503 }
504
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;
509 rl_mark = rl_end;
510
511 return 0;
512 }
513
514 static void
515 rl_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;
525 history_search_string = (char *)xrealloc (history_search_string, history_string_size);
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 }
531 _rl_free_saved_history_line ();
532 }
533
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. */
537 int
538 rl_history_search_forward (count, ignore)
539 int count, ignore;
540 {
541 if (count == 0)
542 return (0);
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));
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. */
556 int
557 rl_history_search_backward (count, ignore)
558 int count, ignore;
559 {
560 if (count == 0)
561 return (0);
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));
569 return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
570 }
This page took 0.041009 seconds and 4 git commands to generate.