]> git.ipfire.org Git - thirdparty/bash.git/blame - lib/readline/isearch.c
Imported from ../bash-3.2.48.tar.gz.
[thirdparty/bash.git] / lib / readline / isearch.c
CommitLineData
726f6388
JA
1/* **************************************************************** */
2/* */
3/* I-Search and Searching */
4/* */
5/* **************************************************************** */
6
95732b49 7/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
726f6388
JA
8
9 This file contains the Readline Library (the Library), a set of
10 routines for providing Emacs style line input to programs that ask
11 for it.
12
13 The Library is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
bb70624e 15 the Free Software Foundation; either version 2, or (at your option)
726f6388
JA
16 any later version.
17
18 The Library is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 General Public License for more details.
22
23 The GNU General Public License is often shipped with GNU software, and
24 is generally kept in a file called COPYING or LICENSE. If you do not
25 have a copy of the license, write to the Free Software Foundation,
bb70624e 26 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
726f6388
JA
27#define READLINE_LIBRARY
28
ccc6cda3
JA
29#if defined (HAVE_CONFIG_H)
30# include <config.h>
31#endif
32
d166f048
JA
33#include <sys/types.h>
34
726f6388
JA
35#include <stdio.h>
36
37#if defined (HAVE_UNISTD_H)
38# include <unistd.h>
39#endif
40
d166f048
JA
41#if defined (HAVE_STDLIB_H)
42# include <stdlib.h>
43#else
44# include "ansi_stdlib.h"
45#endif
ccc6cda3
JA
46
47#include "rldefs.h"
7117c2d2
JA
48#include "rlmbutil.h"
49
726f6388
JA
50#include "readline.h"
51#include "history.h"
52
bb70624e
JA
53#include "rlprivate.h"
54#include "xmalloc.h"
55
b72432fd 56/* Variables exported to other files in the readline library. */
f73dda09 57char *_rl_isearch_terminators = (char *)NULL;
b72432fd 58
95732b49
JA
59_rl_search_cxt *_rl_iscxt = 0;
60
726f6388 61/* Variables imported from other files in the readline library. */
28ef6c31 62extern HIST_ENTRY *_rl_saved_line_for_history;
726f6388 63
f73dda09 64static int rl_search_history PARAMS((int, int));
726f6388 65
95732b49
JA
66static _rl_search_cxt *_rl_isearch_init PARAMS((int));
67static void _rl_isearch_fini PARAMS((_rl_search_cxt *));
68static int _rl_isearch_cleanup PARAMS((_rl_search_cxt *, int));
69
726f6388 70/* Last line found by the current incremental search, so we don't `find'
0628567a
JA
71 identical lines many times in a row. Now part of isearch context. */
72/* static char *prev_line_found; */
726f6388 73
f73dda09
JA
74/* Last search string and its length. */
75static char *last_isearch_string;
76static int last_isearch_string_len;
77
78static char *default_isearch_terminators = "\033\012";
28ef6c31 79
95732b49
JA
80_rl_search_cxt *
81_rl_scxt_alloc (type, flags)
82 int type, flags;
83{
84 _rl_search_cxt *cxt;
85
86 cxt = (_rl_search_cxt *)xmalloc (sizeof (_rl_search_cxt));
87
88 cxt->type = type;
89 cxt->sflags = flags;
90
91 cxt->search_string = 0;
92 cxt->search_string_size = cxt->search_string_index = 0;
93
94 cxt->lines = 0;
95 cxt->allocated_line = 0;
96 cxt->hlen = cxt->hindex = 0;
97
98 cxt->save_point = rl_point;
99 cxt->save_mark = rl_mark;
100 cxt->save_line = where_history ();
101 cxt->last_found_line = cxt->save_line;
102 cxt->prev_line_found = 0;
103
104 cxt->save_undo_list = 0;
105
106 cxt->history_pos = 0;
107 cxt->direction = 0;
108
109 cxt->lastc = 0;
110
111 cxt->sline = 0;
112 cxt->sline_len = cxt->sline_index = 0;
113
114 cxt->search_terminators = 0;
115
116 return cxt;
117}
118
119void
120_rl_scxt_dispose (cxt, flags)
121 _rl_search_cxt *cxt;
122 int flags;
123{
124 FREE (cxt->search_string);
125 FREE (cxt->allocated_line);
126 FREE (cxt->lines);
127
128 free (cxt);
129}
130
726f6388
JA
131/* Search backwards through the history looking for a string which is typed
132 interactively. Start with the current line. */
ccc6cda3 133int
726f6388 134rl_reverse_search_history (sign, key)
ccc6cda3 135 int sign, key;
726f6388
JA
136{
137 return (rl_search_history (-sign, key));
138}
139
140/* Search forwards through the history looking for a string which is typed
141 interactively. Start with the current line. */
ccc6cda3 142int
726f6388 143rl_forward_search_history (sign, key)
ccc6cda3 144 int sign, key;
726f6388
JA
145{
146 return (rl_search_history (sign, key));
147}
148
149/* Display the current state of the search in the echo-area.
150 SEARCH_STRING contains the string that is being searched for,
95732b49 151 DIRECTION is zero for forward, or non-zero for reverse,
726f6388
JA
152 WHERE is the history list number of the current line. If it is
153 -1, then this line is the starting one. */
154static void
155rl_display_search (search_string, reverse_p, where)
156 char *search_string;
157 int reverse_p, where;
158{
159 char *message;
ccc6cda3
JA
160 int msglen, searchlen;
161
162 searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
726f6388 163
f73dda09 164 message = (char *)xmalloc (searchlen + 33);
ccc6cda3 165 msglen = 0;
726f6388
JA
166
167#if defined (NOTDEF)
168 if (where != -1)
ccc6cda3
JA
169 {
170 sprintf (message, "[%d]", where + history_base);
171 msglen = strlen (message);
172 }
726f6388
JA
173#endif /* NOTDEF */
174
ccc6cda3 175 message[msglen++] = '(';
726f6388
JA
176
177 if (reverse_p)
ccc6cda3
JA
178 {
179 strcpy (message + msglen, "reverse-");
180 msglen += 8;
181 }
726f6388 182
ccc6cda3
JA
183 strcpy (message + msglen, "i-search)`");
184 msglen += 10;
726f6388
JA
185
186 if (search_string)
ccc6cda3
JA
187 {
188 strcpy (message + msglen, search_string);
189 msglen += searchlen;
190 }
191
192 strcpy (message + msglen, "': ");
726f6388 193
f73dda09 194 rl_message ("%s", message);
726f6388 195 free (message);
ccc6cda3 196 (*rl_redisplay_function) ();
726f6388
JA
197}
198
95732b49
JA
199static _rl_search_cxt *
200_rl_isearch_init (direction)
201 int direction;
726f6388 202{
95732b49 203 _rl_search_cxt *cxt;
ccc6cda3 204 register int i;
95732b49 205 HIST_ENTRY **hlist;
ccc6cda3 206
95732b49
JA
207 cxt = _rl_scxt_alloc (RL_SEARCH_ISEARCH, 0);
208 if (direction < 0)
209 cxt->sflags |= SF_REVERSE;
b72432fd 210
95732b49 211 cxt->search_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
28ef6c31 212 : default_isearch_terminators;
b72432fd 213
726f6388 214 /* Create an arrary of pointers to the lines that we want to search. */
95732b49 215 hlist = history_list ();
28ef6c31 216 rl_maybe_replace_line ();
ccc6cda3 217 i = 0;
726f6388
JA
218 if (hlist)
219 for (i = 0; hlist[i]; i++);
220
221 /* Allocate space for this many lines, +1 for the current input line,
222 and remember those lines. */
95732b49
JA
223 cxt->lines = (char **)xmalloc ((1 + (cxt->hlen = i)) * sizeof (char *));
224 for (i = 0; i < cxt->hlen; i++)
225 cxt->lines[i] = hlist[i]->line;
726f6388 226
28ef6c31 227 if (_rl_saved_line_for_history)
95732b49 228 cxt->lines[i] = _rl_saved_line_for_history->line;
726f6388
JA
229 else
230 {
231 /* Keep track of this so we can free it. */
95732b49
JA
232 cxt->allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
233 strcpy (cxt->allocated_line, &rl_line_buffer[0]);
234 cxt->lines[i] = cxt->allocated_line;
726f6388
JA
235 }
236
95732b49 237 cxt->hlen++;
726f6388
JA
238
239 /* The line where we start the search. */
95732b49 240 cxt->history_pos = cxt->save_line;
726f6388 241
b72432fd 242 rl_save_prompt ();
ccc6cda3 243
726f6388 244 /* Initialize search parameters. */
95732b49
JA
245 cxt->search_string = (char *)xmalloc (cxt->search_string_size = 128);
246 cxt->search_string[cxt->search_string_index = 0] = '\0';
726f6388
JA
247
248 /* Normalize DIRECTION into 1 or -1. */
95732b49 249 cxt->direction = (direction >= 0) ? 1 : -1;
726f6388 250
95732b49
JA
251 cxt->sline = rl_line_buffer;
252 cxt->sline_len = strlen (cxt->sline);
253 cxt->sline_index = rl_point;
726f6388 254
95732b49 255 _rl_iscxt = cxt; /* save globally */
726f6388 256
95732b49
JA
257 return cxt;
258}
259
260static void
261_rl_isearch_fini (cxt)
262 _rl_search_cxt *cxt;
263{
264 /* First put back the original state. */
265 strcpy (rl_line_buffer, cxt->lines[cxt->save_line]);
266
267 rl_restore_prompt ();
268
269 /* Save the search string for possible later use. */
270 FREE (last_isearch_string);
271 last_isearch_string = cxt->search_string;
272 last_isearch_string_len = cxt->search_string_index;
273 cxt->search_string = 0;
274
275 if (cxt->last_found_line < cxt->save_line)
276 rl_get_previous_history (cxt->save_line - cxt->last_found_line, 0);
277 else
278 rl_get_next_history (cxt->last_found_line - cxt->save_line, 0);
279
280 /* If the string was not found, put point at the end of the last matching
281 line. If last_found_line == orig_line, we didn't find any matching
282 history lines at all, so put point back in its original position. */
283 if (cxt->sline_index < 0)
726f6388 284 {
95732b49
JA
285 if (cxt->last_found_line == cxt->save_line)
286 cxt->sline_index = cxt->save_point;
287 else
288 cxt->sline_index = strlen (rl_line_buffer);
289 rl_mark = cxt->save_mark;
290 }
726f6388 291
95732b49
JA
292 rl_point = cxt->sline_index;
293 /* Don't worry about where to put the mark here; rl_get_previous_history
294 and rl_get_next_history take care of it. */
295
296 rl_clear_message ();
297}
298
299int
300_rl_search_getchar (cxt)
301 _rl_search_cxt *cxt;
302{
303 int c;
304
305 /* Read a key and decide how to proceed. */
306 RL_SETSTATE(RL_STATE_MOREINPUT);
307 c = cxt->lastc = rl_read_key ();
308 RL_UNSETSTATE(RL_STATE_MOREINPUT);
726f6388 309
7117c2d2 310#if defined (HANDLE_MULTIBYTE)
95732b49
JA
311 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
312 c = cxt->lastc = _rl_read_mbstring (cxt->lastc, cxt->mb, MB_LEN_MAX);
7117c2d2
JA
313#endif
314
95732b49
JA
315 return c;
316}
726f6388 317
95732b49
JA
318/* Process just-read character C according to isearch context CXT. Return
319 -1 if the caller should just free the context and return, 0 if we should
320 break out of the loop, and 1 if we should continue to read characters. */
321int
322_rl_isearch_dispatch (cxt, c)
323 _rl_search_cxt *cxt;
324 int c;
325{
326 int n, wstart, wlen, limit, cval;
327 rl_command_func_t *f;
328
329 f = (rl_command_func_t *)NULL;
f1be666c
JA
330
331 if (c < 0)
332 {
333 cxt->sflags |= SF_FAILED;
334 cxt->history_pos = cxt->last_found_line;
335 return -1;
336 }
337
338 /* Translate the keys we do something with to opcodes. */
95732b49
JA
339 if (c >= 0 && _rl_keymap[c].type == ISFUNC)
340 {
341 f = _rl_keymap[c].function;
342
343 if (f == rl_reverse_search_history)
344 cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
345 else if (f == rl_forward_search_history)
346 cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
347 else if (f == rl_rubout)
348 cxt->lastc = -3;
349 else if (c == CTRL ('G'))
350 cxt->lastc = -4;
351 else if (c == CTRL ('W')) /* XXX */
352 cxt->lastc = -5;
353 else if (c == CTRL ('Y')) /* XXX */
354 cxt->lastc = -6;
355 }
356
357 /* The characters in isearch_terminators (set from the user-settable
358 variable isearch-terminators) are used to terminate the search but
359 not subsequently execute the character as a command. The default
360 value is "\033\012" (ESC and C-J). */
361 if (strchr (cxt->search_terminators, cxt->lastc))
362 {
363 /* ESC still terminates the search, but if there is pending
364 input or if input arrives within 0.1 seconds (on systems
365 with select(2)) it is used as a prefix character
366 with rl_execute_next. WATCH OUT FOR THIS! This is intended
367 to allow the arrow keys to be used like ^F and ^B are used
368 to terminate the search and execute the movement command.
369 XXX - since _rl_input_available depends on the application-
370 settable keyboard timeout value, this could alternatively
371 use _rl_input_queued(100000) */
372 if (cxt->lastc == ESC && _rl_input_available ())
373 rl_execute_next (ESC);
374 return (0);
375 }
ccc6cda3 376
7117c2d2
JA
377#define ENDSRCH_CHAR(c) \
378 ((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
379
380#if defined (HANDLE_MULTIBYTE)
95732b49
JA
381 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
382 {
383 if (cxt->lastc >= 0 && (cxt->mb[0] && cxt->mb[1] == '\0') && ENDSRCH_CHAR (cxt->lastc))
384 {
385 /* This sets rl_pending_input to c; it will be picked up the next
386 time rl_read_key is called. */
387 rl_execute_next (cxt->lastc);
388 return (0);
389 }
390 }
391 else
392#endif
393 if (cxt->lastc >= 0 && ENDSRCH_CHAR (cxt->lastc))
394 {
395 /* This sets rl_pending_input to LASTC; it will be picked up the next
396 time rl_read_key is called. */
397 rl_execute_next (cxt->lastc);
398 return (0);
399 }
400
401 /* Now dispatch on the character. `Opcodes' affect the search string or
402 state. Other characters are added to the string. */
403 switch (cxt->lastc)
404 {
405 /* search again */
406 case -1:
407 if (cxt->search_string_index == 0)
7117c2d2 408 {
95732b49 409 if (last_isearch_string)
7117c2d2 410 {
95732b49
JA
411 cxt->search_string_size = 64 + last_isearch_string_len;
412 cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
413 strcpy (cxt->search_string, last_isearch_string);
414 cxt->search_string_index = last_isearch_string_len;
415 rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
7117c2d2
JA
416 break;
417 }
95732b49 418 return (1);
7117c2d2 419 }
95732b49
JA
420 else if (cxt->sflags & SF_REVERSE)
421 cxt->sline_index--;
422 else if (cxt->sline_index != cxt->sline_len)
423 cxt->sline_index++;
7117c2d2 424 else
95732b49
JA
425 rl_ding ();
426 break;
427
428 /* switch directions */
429 case -2:
430 cxt->direction = -cxt->direction;
431 if (cxt->direction < 0)
432 cxt->sflags |= SF_REVERSE;
433 else
434 cxt->sflags &= ~SF_REVERSE;
435 break;
436
437 /* delete character from search string. */
438 case -3: /* C-H, DEL */
439 /* This is tricky. To do this right, we need to keep a
440 stack of search positions for the current search, with
441 sentinels marking the beginning and end. But this will
442 do until we have a real isearch-undo. */
443 if (cxt->search_string_index == 0)
444 rl_ding ();
445 else
446 cxt->search_string[--cxt->search_string_index] = '\0';
447 break;
448
449 case -4: /* C-G, abort */
450 rl_replace_line (cxt->lines[cxt->save_line], 0);
451 rl_point = cxt->save_point;
452 rl_mark = cxt->save_mark;
453 rl_restore_prompt();
454 rl_clear_message ();
455
456 return -1;
457
458 case -5: /* C-W */
459 /* skip over portion of line we already matched and yank word */
460 wstart = rl_point + cxt->search_string_index;
461 if (wstart >= rl_end)
726f6388 462 {
95732b49 463 rl_ding ();
ccc6cda3
JA
464 break;
465 }
726f6388 466
95732b49
JA
467 /* if not in a word, move to one. */
468 cval = _rl_char_value (rl_line_buffer, wstart);
469 if (_rl_walphabetic (cval) == 0)
ccc6cda3 470 {
95732b49 471 rl_ding ();
726f6388 472 break;
95732b49
JA
473 }
474 n = MB_NEXTCHAR (rl_line_buffer, wstart, 1, MB_FIND_NONZERO);;
475 while (n < rl_end)
476 {
477 cval = _rl_char_value (rl_line_buffer, n);
478 if (_rl_walphabetic (cval) == 0)
479 break;
480 n = MB_NEXTCHAR (rl_line_buffer, n, 1, MB_FIND_NONZERO);;
481 }
482 wlen = n - wstart + 1;
483 if (cxt->search_string_index + wlen + 1 >= cxt->search_string_size)
484 {
485 cxt->search_string_size += wlen + 1;
486 cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
487 }
488 for (; wstart < n; wstart++)
489 cxt->search_string[cxt->search_string_index++] = rl_line_buffer[wstart];
490 cxt->search_string[cxt->search_string_index] = '\0';
491 break;
492
493 case -6: /* C-Y */
494 /* skip over portion of line we already matched and yank rest */
495 wstart = rl_point + cxt->search_string_index;
496 if (wstart >= rl_end)
497 {
498 rl_ding ();
726f6388 499 break;
95732b49
JA
500 }
501 n = rl_end - wstart + 1;
502 if (cxt->search_string_index + n + 1 >= cxt->search_string_size)
503 {
504 cxt->search_string_size += n + 1;
505 cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
506 }
507 for (n = wstart; n < rl_end; n++)
508 cxt->search_string[cxt->search_string_index++] = rl_line_buffer[n];
509 cxt->search_string[cxt->search_string_index] = '\0';
510 break;
511
512 /* Add character to search string and continue search. */
513 default:
514 if (cxt->search_string_index + 2 >= cxt->search_string_size)
515 {
516 cxt->search_string_size += 128;
517 cxt->search_string = (char *)xrealloc (cxt->search_string, cxt->search_string_size);
518 }
519#if defined (HANDLE_MULTIBYTE)
520 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
521 {
522 int j, l;
523 for (j = 0, l = strlen (cxt->mb); j < l; )
524 cxt->search_string[cxt->search_string_index++] = cxt->mb[j++];
525 }
526 else
527#endif
528 cxt->search_string[cxt->search_string_index++] = c;
529 cxt->search_string[cxt->search_string_index] = '\0';
530 break;
531 }
726f6388 532
95732b49
JA
533 for (cxt->sflags &= ~(SF_FOUND|SF_FAILED);; )
534 {
535 limit = cxt->sline_len - cxt->search_string_index + 1;
7117c2d2 536
95732b49
JA
537 /* Search the current line. */
538 while ((cxt->sflags & SF_REVERSE) ? (cxt->sline_index >= 0) : (cxt->sline_index < limit))
539 {
540 if (STREQN (cxt->search_string, cxt->sline + cxt->sline_index, cxt->search_string_index))
7117c2d2 541 {
95732b49 542 cxt->sflags |= SF_FOUND;
7117c2d2
JA
543 break;
544 }
95732b49
JA
545 else
546 cxt->sline_index += cxt->direction;
547 }
548 if (cxt->sflags & SF_FOUND)
549 break;
7117c2d2 550
95732b49
JA
551 /* Move to the next line, but skip new copies of the line
552 we just found and lines shorter than the string we're
553 searching for. */
554 do
555 {
556 /* Move to the next line. */
557 cxt->history_pos += cxt->direction;
7117c2d2 558
95732b49
JA
559 /* At limit for direction? */
560 if ((cxt->sflags & SF_REVERSE) ? (cxt->history_pos < 0) : (cxt->history_pos == cxt->hlen))
7117c2d2 561 {
95732b49 562 cxt->sflags |= SF_FAILED;
7117c2d2
JA
563 break;
564 }
cce855bc 565
95732b49
JA
566 /* We will need these later. */
567 cxt->sline = cxt->lines[cxt->history_pos];
568 cxt->sline_len = strlen (cxt->sline);
726f6388 569 }
95732b49
JA
570 while ((cxt->prev_line_found && STREQ (cxt->prev_line_found, cxt->lines[cxt->history_pos])) ||
571 (cxt->search_string_index > cxt->sline_len));
726f6388 572
95732b49
JA
573 if (cxt->sflags & SF_FAILED)
574 break;
726f6388 575
95732b49
JA
576 /* Now set up the line for searching... */
577 cxt->sline_index = (cxt->sflags & SF_REVERSE) ? cxt->sline_len - cxt->search_string_index : 0;
578 }
726f6388 579
95732b49
JA
580 if (cxt->sflags & SF_FAILED)
581 {
582 /* We cannot find the search string. Ding the bell. */
583 rl_ding ();
584 cxt->history_pos = cxt->last_found_line;
585 return 1;
586 }
726f6388 587
95732b49
JA
588 /* We have found the search string. Just display it. But don't
589 actually move there in the history list until the user accepts
590 the location. */
591 if (cxt->sflags & SF_FOUND)
592 {
593 cxt->prev_line_found = cxt->lines[cxt->history_pos];
594 rl_replace_line (cxt->lines[cxt->history_pos], 0);
595 rl_point = cxt->sline_index;
596 cxt->last_found_line = cxt->history_pos;
597 rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), (cxt->history_pos == cxt->save_line) ? -1 : cxt->history_pos);
598 }
726f6388 599
95732b49
JA
600 return 1;
601}
726f6388 602
95732b49
JA
603static int
604_rl_isearch_cleanup (cxt, r)
605 _rl_search_cxt *cxt;
606 int r;
607{
608 if (r >= 0)
609 _rl_isearch_fini (cxt);
610 _rl_scxt_dispose (cxt, 0);
611 _rl_iscxt = 0;
726f6388 612
95732b49 613 RL_UNSETSTATE(RL_STATE_ISEARCH);
726f6388 614
95732b49
JA
615 return (r != 0);
616}
726f6388 617
95732b49
JA
618/* Search through the history looking for an interactively typed string.
619 This is analogous to i-search. We start the search in the current line.
620 DIRECTION is which direction to search; >= 0 means forward, < 0 means
621 backwards. */
622static int
623rl_search_history (direction, invoking_key)
624 int direction, invoking_key;
625{
626 _rl_search_cxt *cxt; /* local for now, but saved globally */
627 int c, r;
726f6388 628
95732b49
JA
629 RL_SETSTATE(RL_STATE_ISEARCH);
630 cxt = _rl_isearch_init (direction);
ccc6cda3 631
95732b49 632 rl_display_search (cxt->search_string, (cxt->sflags & SF_REVERSE), -1);
726f6388 633
95732b49
JA
634 /* If we are using the callback interface, all we do is set up here and
635 return. The key is that we leave RL_STATE_ISEARCH set. */
636 if (RL_ISSTATE (RL_STATE_CALLBACK))
637 return (0);
726f6388 638
95732b49
JA
639 r = -1;
640 for (;;)
7117c2d2 641 {
95732b49
JA
642 c = _rl_search_getchar (cxt);
643 /* We might want to handle EOF here (c == 0) */
644 r = _rl_isearch_dispatch (cxt, cxt->lastc);
645 if (r <= 0)
646 break;
7117c2d2
JA
647 }
648
95732b49
JA
649 /* The searching is over. The user may have found the string that she
650 was looking for, or else she may have exited a failing search. If
651 LINE_INDEX is -1, then that shows that the string searched for was
652 not found. We use this to determine where to place rl_point. */
653 return (_rl_isearch_cleanup (cxt, r));
654}
726f6388 655
95732b49
JA
656#if defined (READLINE_CALLBACKS)
657/* Called from the callback functions when we are ready to read a key. The
658 callback functions know to call this because RL_ISSTATE(RL_STATE_ISEARCH).
659 If _rl_isearch_dispatch finishes searching, this function is responsible
660 for turning off RL_STATE_ISEARCH, which it does using _rl_isearch_cleanup. */
661int
662_rl_isearch_callback (cxt)
663 _rl_search_cxt *cxt;
664{
665 int c, r;
726f6388 666
95732b49
JA
667 c = _rl_search_getchar (cxt);
668 /* We might want to handle EOF here */
669 r = _rl_isearch_dispatch (cxt, cxt->lastc);
28ef6c31 670
95732b49 671 return (r <= 0) ? _rl_isearch_cleanup (cxt, r) : 0;
726f6388 672}
95732b49 673#endif