Annotation of embedaddon/readline/search.c, revision 1.1.1.2
1.1 misho 1: /* search.c - code for non-incremental searching in emacs and vi modes. */
2:
1.1.1.2 ! misho 3: /* Copyright (C) 1992-2020 Free Software Foundation, Inc.
1.1 misho 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. */
1.1.1.2 ! misho 61: extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
1.1 misho 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 *));
1.1.1.2 ! misho 76: static int noninc_search_from_pos PARAMS((char *, int, int, int, int *));
! 77: static int noninc_dosearch PARAMS((char *, int, int));
1.1 misho 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
1.1.1.2 ! misho 90: make_history_line_current (HIST_ENTRY *entry)
1.1 misho 91: {
92: _rl_replace_text (entry->line, 0, rl_end);
93: _rl_fix_point (1);
94: #if defined (VI_MODE)
95: if (rl_editing_mode == vi_mode)
96: /* POSIX.2 says that the `U' command doesn't affect the copy of any
97: command lines to the edit line. We're going to implement that by
98: making the undo list start after the matching line is copied to the
99: current editing buffer. */
100: rl_free_undo_list ();
101: #endif
102:
103: if (_rl_saved_line_for_history)
104: _rl_free_history_entry (_rl_saved_line_for_history);
105: _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
106: }
107:
108: /* Search the history list for STRING starting at absolute history position
109: POS. If STRING begins with `^', the search must match STRING at the
110: beginning of a history line, otherwise a full substring match is performed
111: for STRING. DIR < 0 means to search backwards through the history list,
112: DIR >= 0 means to search forward. */
113: static int
1.1.1.2 ! misho 114: noninc_search_from_pos (char *string, int pos, int dir, int flags, int *ncp)
1.1 misho 115: {
1.1.1.2 ! misho 116: int ret, old, sflags;
! 117: char *s;
1.1 misho 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);
1.1.1.2 ! misho 127: /* These functions return the match offset in the line; history_offset gives
! 128: the matching line in the history list */
! 129: if (flags & SF_PATTERN)
! 130: {
! 131: s = string;
! 132: sflags = 0; /* Non-anchored search */
! 133: if (*s == '^')
! 134: {
! 135: sflags |= ANCHORED_SEARCH;
! 136: s++;
! 137: }
! 138: ret = _hs_history_patsearch (s, dir, sflags);
! 139: }
! 140: else if (*string == '^')
1.1 misho 141: ret = history_search_prefix (string + 1, dir);
142: else
143: ret = history_search (string, dir);
144: RL_UNSETSTATE(RL_STATE_SEARCH);
145:
1.1.1.2 ! misho 146: if (ncp)
! 147: *ncp = ret; /* caller will catch -1 to indicate no-op */
! 148:
1.1 misho 149: if (ret != -1)
150: ret = where_history ();
151:
152: history_set_pos (old);
153: return (ret);
154: }
155:
156: /* Search for a line in the history containing STRING. If DIR is < 0, the
157: search is backwards through previous entries, else through subsequent
158: entries. Returns 1 if the search was successful, 0 otherwise. */
159: static int
1.1.1.2 ! misho 160: noninc_dosearch (char *string, int dir, int flags)
1.1 misho 161: {
1.1.1.2 ! misho 162: int oldpos, pos, ind;
1.1 misho 163: HIST_ENTRY *entry;
164:
165: if (string == 0 || *string == '\0' || noninc_history_pos < 0)
166: {
167: rl_ding ();
168: return 0;
169: }
170:
1.1.1.2 ! misho 171: pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir, flags, &ind);
1.1 misho 172: if (pos == -1)
173: {
174: /* Search failed, current history position unchanged. */
175: rl_maybe_unsave_line ();
176: rl_clear_message ();
177: rl_point = 0;
178: rl_ding ();
179: return 0;
180: }
181:
182: noninc_history_pos = pos;
183:
184: oldpos = where_history ();
185: history_set_pos (noninc_history_pos);
186: entry = current_history (); /* will never be NULL after successful search */
187:
188: #if defined (VI_MODE)
189: if (rl_editing_mode != vi_mode)
190: #endif
191: history_set_pos (oldpos);
192:
193: make_history_line_current (entry);
194:
1.1.1.2 ! misho 195: if (_rl_enable_active_region && ((flags & SF_PATTERN) == 0) && ind > 0 && ind < rl_end)
! 196: {
! 197: rl_point = ind;
! 198: rl_mark = ind + strlen (string);
! 199: if (rl_mark > rl_end)
! 200: rl_mark = rl_end; /* can't happen? */
! 201: rl_activate_mark ();
! 202: }
! 203: else
! 204: {
! 205: rl_point = 0;
! 206: rl_mark = rl_end;
! 207: }
1.1 misho 208:
209: rl_clear_message ();
210: return 1;
211: }
212:
213: static _rl_search_cxt *
1.1.1.2 ! misho 214: _rl_nsearch_init (int dir, int pchar)
1.1 misho 215: {
216: _rl_search_cxt *cxt;
217: char *p;
218:
219: cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
220: if (dir < 0)
221: cxt->sflags |= SF_REVERSE; /* not strictly needed */
1.1.1.2 ! misho 222: #if defined (VI_MODE)
! 223: if (VI_COMMAND_MODE() && (pchar == '?' || pchar == '/'))
! 224: cxt->sflags |= SF_PATTERN;
! 225: #endif
1.1 misho 226:
227: cxt->direction = dir;
228: cxt->history_pos = cxt->save_line;
229:
230: rl_maybe_save_line ();
231:
232: /* Clear the undo list, since reading the search string should create its
233: own undo list, and the whole list will end up being freed when we
234: finish reading the search string. */
235: rl_undo_list = 0;
236:
237: /* Use the line buffer to read the search string. */
238: rl_line_buffer[0] = 0;
239: rl_end = rl_point = 0;
240:
241: p = _rl_make_prompt_for_search (pchar ? pchar : ':');
242: rl_message ("%s", p);
243: xfree (p);
244:
245: RL_SETSTATE(RL_STATE_NSEARCH);
246:
247: _rl_nscxt = cxt;
248:
249: return cxt;
250: }
251:
1.1.1.2 ! misho 252: int
! 253: _rl_nsearch_cleanup (_rl_search_cxt *cxt, int r)
1.1 misho 254: {
255: _rl_scxt_dispose (cxt, 0);
256: _rl_nscxt = 0;
257:
258: RL_UNSETSTATE(RL_STATE_NSEARCH);
259:
260: return (r != 1);
261: }
262:
263: static void
1.1.1.2 ! misho 264: _rl_nsearch_abort (_rl_search_cxt *cxt)
1.1 misho 265: {
266: rl_maybe_unsave_line ();
267: rl_clear_message ();
268: rl_point = cxt->save_point;
269: rl_mark = cxt->save_mark;
1.1.1.2 ! misho 270: _rl_fix_point (1);
1.1 misho 271: rl_restore_prompt ();
272:
273: RL_UNSETSTATE (RL_STATE_NSEARCH);
274: }
275:
276: /* Process just-read character C according to search context CXT. Return -1
277: if the caller should abort the search, 0 if we should break out of the
278: loop, and 1 if we should continue to read characters. */
279: static int
1.1.1.2 ! misho 280: _rl_nsearch_dispatch (_rl_search_cxt *cxt, int c)
1.1 misho 281: {
1.1.1.2 ! misho 282: int n;
! 283:
! 284: if (c < 0)
! 285: c = CTRL ('C');
! 286:
1.1 misho 287: switch (c)
288: {
289: case CTRL('W'):
290: rl_unix_word_rubout (1, c);
291: break;
292:
293: case CTRL('U'):
294: rl_unix_line_discard (1, c);
295: break;
296:
297: case RETURN:
298: case NEWLINE:
299: return 0;
300:
301: case CTRL('H'):
302: case RUBOUT:
303: if (rl_point == 0)
304: {
305: _rl_nsearch_abort (cxt);
306: return -1;
307: }
308: _rl_rubout_char (1, c);
309: break;
310:
311: case CTRL('C'):
312: case CTRL('G'):
313: rl_ding ();
314: _rl_nsearch_abort (cxt);
315: return -1;
316:
1.1.1.2 ! misho 317: case ESC:
! 318: /* XXX - experimental code to allow users to bracketed-paste into the
! 319: search string. Similar code is in isearch.c:_rl_isearch_dispatch().
! 320: The difference here is that the bracketed paste sometimes doesn't
! 321: paste everything, so checking for the prefix and the suffix in the
! 322: input queue doesn't work well. We just have to check to see if the
! 323: number of chars in the input queue is enough for the bracketed paste
! 324: prefix and hope for the best. */
! 325: if (_rl_enable_bracketed_paste && ((n = _rl_nchars_available ()) >= (BRACK_PASTE_SLEN-1)))
! 326: {
! 327: if (_rl_read_bracketed_paste_prefix (c) == 1)
! 328: rl_bracketed_paste_begin (1, c);
! 329: else
! 330: {
! 331: c = rl_read_key (); /* get the ESC that got pushed back */
! 332: _rl_insert_char (1, c);
! 333: }
! 334: }
! 335: else
! 336: _rl_insert_char (1, c);
! 337: break;
! 338:
1.1 misho 339: default:
340: #if defined (HANDLE_MULTIBYTE)
341: if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
342: rl_insert_text (cxt->mb);
343: else
344: #endif
345: _rl_insert_char (1, c);
346: break;
347: }
348:
349: (*rl_redisplay_function) ();
1.1.1.2 ! misho 350: rl_deactivate_mark ();
1.1 misho 351: return 1;
352: }
353:
354: /* Perform one search according to CXT, using NONINC_SEARCH_STRING. Return
355: -1 if the search should be aborted, any other value means to clean up
356: using _rl_nsearch_cleanup (). Returns 1 if the search was successful,
357: 0 otherwise. */
358: static int
1.1.1.2 ! misho 359: _rl_nsearch_dosearch (_rl_search_cxt *cxt)
1.1 misho 360: {
361: rl_mark = cxt->save_mark;
362:
363: /* If rl_point == 0, we want to re-use the previous search string and
364: start from the saved history position. If there's no previous search
365: string, punt. */
366: if (rl_point == 0)
367: {
368: if (noninc_search_string == 0)
369: {
370: rl_ding ();
371: rl_restore_prompt ();
372: RL_UNSETSTATE (RL_STATE_NSEARCH);
373: return -1;
374: }
375: }
376: else
377: {
378: /* We want to start the search from the current history position. */
379: noninc_history_pos = cxt->save_line;
380: FREE (noninc_search_string);
381: noninc_search_string = savestring (rl_line_buffer);
382:
383: /* If we don't want the subsequent undo list generated by the search
384: matching a history line to include the contents of the search string,
385: we need to clear rl_line_buffer here. For now, we just clear the
386: undo list generated by reading the search string. (If the search
387: fails, the old undo list will be restored by rl_maybe_unsave_line.) */
388: rl_free_undo_list ();
389: }
390:
391: rl_restore_prompt ();
1.1.1.2 ! misho 392: return (noninc_dosearch (noninc_search_string, cxt->direction, cxt->sflags&SF_PATTERN));
1.1 misho 393: }
394:
395: /* Search non-interactively through the history list. DIR < 0 means to
396: search backwards through the history of previous commands; otherwise
397: the search is for commands subsequent to the current position in the
398: history list. PCHAR is the character to use for prompting when reading
399: the search string; if not specified (0), it defaults to `:'. */
400: static int
1.1.1.2 ! misho 401: noninc_search (int dir, int pchar)
1.1 misho 402: {
403: _rl_search_cxt *cxt;
404: int c, r;
405:
406: cxt = _rl_nsearch_init (dir, pchar);
407:
408: if (RL_ISSTATE (RL_STATE_CALLBACK))
409: return (0);
410:
411: /* Read the search string. */
412: r = 0;
413: while (1)
414: {
415: c = _rl_search_getchar (cxt);
416:
1.1.1.2 ! misho 417: if (c < 0)
! 418: {
! 419: _rl_nsearch_abort (cxt);
! 420: return 1;
! 421: }
! 422:
1.1 misho 423: if (c == 0)
424: break;
425:
426: r = _rl_nsearch_dispatch (cxt, c);
427: if (r < 0)
428: return 1;
429: else if (r == 0)
430: break;
431: }
432:
433: r = _rl_nsearch_dosearch (cxt);
434: return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
435: }
436:
437: /* Search forward through the history list for a string. If the vi-mode
438: code calls this, KEY will be `?'. */
439: int
1.1.1.2 ! misho 440: rl_noninc_forward_search (int count, int key)
1.1 misho 441: {
442: return noninc_search (1, (key == '?') ? '?' : 0);
443: }
444:
445: /* Reverse search the history list for a string. If the vi-mode code
446: calls this, KEY will be `/'. */
447: int
1.1.1.2 ! misho 448: rl_noninc_reverse_search (int count, int key)
1.1 misho 449: {
450: return noninc_search (-1, (key == '/') ? '/' : 0);
451: }
452:
453: /* Search forward through the history list for the last string searched
1.1.1.2 ! misho 454: for. If there is no saved search string, abort. If the vi-mode code
! 455: calls this, KEY will be `N'. */
1.1 misho 456: int
1.1.1.2 ! misho 457: rl_noninc_forward_search_again (int count, int key)
1.1 misho 458: {
459: int r;
460:
461: if (!noninc_search_string)
462: {
463: rl_ding ();
1.1.1.2 ! misho 464: return (1);
1.1 misho 465: }
1.1.1.2 ! misho 466: #if defined (VI_MODE)
! 467: if (VI_COMMAND_MODE() && key == 'N')
! 468: r = noninc_dosearch (noninc_search_string, 1, SF_PATTERN);
! 469: else
! 470: #endif
! 471: r = noninc_dosearch (noninc_search_string, 1, 0);
1.1 misho 472: return (r != 1);
473: }
474:
475: /* Reverse search in the history list for the last string searched
1.1.1.2 ! misho 476: for. If there is no saved search string, abort. If the vi-mode code
! 477: calls this, KEY will be `n'. */
1.1 misho 478: int
1.1.1.2 ! misho 479: rl_noninc_reverse_search_again (int count, int key)
1.1 misho 480: {
481: int r;
482:
483: if (!noninc_search_string)
484: {
485: rl_ding ();
1.1.1.2 ! misho 486: return (1);
1.1 misho 487: }
1.1.1.2 ! misho 488: #if defined (VI_MODE)
! 489: if (VI_COMMAND_MODE() && key == 'n')
! 490: r = noninc_dosearch (noninc_search_string, -1, SF_PATTERN);
! 491: else
! 492: #endif
! 493: r = noninc_dosearch (noninc_search_string, -1, 0);
1.1 misho 494: return (r != 1);
495: }
496:
497: #if defined (READLINE_CALLBACKS)
498: int
1.1.1.2 ! misho 499: _rl_nsearch_callback (_rl_search_cxt *cxt)
1.1 misho 500: {
501: int c, r;
502:
503: c = _rl_search_getchar (cxt);
1.1.1.2 ! misho 504: if (c <= 0)
! 505: {
! 506: if (c < 0)
! 507: _rl_nsearch_abort (cxt);
! 508: return 1;
! 509: }
1.1 misho 510: r = _rl_nsearch_dispatch (cxt, c);
511: if (r != 0)
512: return 1;
513:
514: r = _rl_nsearch_dosearch (cxt);
515: return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
516: }
517: #endif
518:
519: static int
1.1.1.2 ! misho 520: rl_history_search_internal (int count, int dir)
1.1 misho 521: {
522: HIST_ENTRY *temp;
1.1.1.2 ! misho 523: int ret, oldpos, newcol;
1.1 misho 524: char *t;
525:
526: rl_maybe_save_line ();
527: temp = (HIST_ENTRY *)NULL;
528:
529: /* Search COUNT times through the history for a line matching
530: history_search_string. If history_search_string[0] == '^', the
531: line must match from the start; otherwise any substring can match.
532: When this loop finishes, TEMP, if non-null, is the history line to
533: copy into the line buffer. */
534: while (count)
535: {
536: RL_CHECK_SIGNALS ();
1.1.1.2 ! misho 537: ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir, 0, &newcol);
1.1 misho 538: if (ret == -1)
539: break;
540:
541: /* Get the history entry we found. */
542: rl_history_search_pos = ret;
543: oldpos = where_history ();
544: history_set_pos (rl_history_search_pos);
545: temp = current_history (); /* will never be NULL after successful search */
546: history_set_pos (oldpos);
547:
548: /* Don't find multiple instances of the same line. */
549: if (prev_line_found && STREQ (prev_line_found, temp->line))
550: continue;
551: prev_line_found = temp->line;
552: count--;
553: }
554:
555: /* If we didn't find anything at all, return. */
556: if (temp == 0)
557: {
558: rl_maybe_unsave_line ();
559: rl_ding ();
560: /* If you don't want the saved history line (last match) to show up
561: in the line buffer after the search fails, change the #if 0 to
562: #if 1 */
563: #if 0
564: if (rl_point > rl_history_search_len)
565: {
566: rl_point = rl_end = rl_history_search_len;
567: rl_line_buffer[rl_end] = '\0';
568: rl_mark = 0;
569: }
570: #else
571: rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
572: rl_mark = rl_end;
573: #endif
574: return 1;
575: }
576:
577: /* Copy the line we found into the current line buffer. */
578: make_history_line_current (temp);
579:
1.1.1.2 ! misho 580: /* decide where to put rl_point -- need to change this for pattern search */
1.1 misho 581: if (rl_history_search_flags & ANCHORED_SEARCH)
582: rl_point = rl_history_search_len; /* easy case */
583: else
584: {
1.1.1.2 ! misho 585: #if 0
! 586: t = strstr (rl_line_buffer, history_search_string); /* XXX */
1.1 misho 587: rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end;
1.1.1.2 ! misho 588: #else
! 589: rl_point = (newcol >= 0) ? newcol : rl_end;
! 590: #endif
1.1 misho 591: }
592: rl_mark = rl_end;
593:
594: return 0;
595: }
596:
597: static void
1.1.1.2 ! misho 598: rl_history_search_reinit (int flags)
1.1 misho 599: {
600: int sind;
601:
602: rl_history_search_pos = where_history ();
603: rl_history_search_len = rl_point;
604: rl_history_search_flags = flags;
605:
606: prev_line_found = (char *)NULL;
607: if (rl_point)
608: {
609: /* Allocate enough space for anchored and non-anchored searches */
610: if (rl_history_search_len >= history_string_size - 2)
611: {
612: history_string_size = rl_history_search_len + 2;
613: history_search_string = (char *)xrealloc (history_search_string, history_string_size);
614: }
615: sind = 0;
616: if (flags & ANCHORED_SEARCH)
617: history_search_string[sind++] = '^';
618: strncpy (history_search_string + sind, rl_line_buffer, rl_point);
619: history_search_string[rl_point + sind] = '\0';
620: }
621: _rl_free_saved_history_line ();
622: }
623:
624: /* Search forward in the history for the string of characters
625: from the start of the line to rl_point. This is a non-incremental
626: search. The search is anchored to the beginning of the history line. */
627: int
1.1.1.2 ! misho 628: rl_history_search_forward (int count, int ignore)
1.1 misho 629: {
630: if (count == 0)
631: return (0);
632:
633: if (rl_last_func != rl_history_search_forward &&
634: rl_last_func != rl_history_search_backward)
635: rl_history_search_reinit (ANCHORED_SEARCH);
636:
637: if (rl_history_search_len == 0)
638: return (rl_get_next_history (count, ignore));
639: return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
640: }
641:
642: /* Search backward through the history for the string of characters
643: from the start of the line to rl_point. This is a non-incremental
644: search. */
645: int
1.1.1.2 ! misho 646: rl_history_search_backward (int count, int ignore)
1.1 misho 647: {
648: if (count == 0)
649: return (0);
650:
651: if (rl_last_func != rl_history_search_forward &&
652: rl_last_func != rl_history_search_backward)
653: rl_history_search_reinit (ANCHORED_SEARCH);
654:
655: if (rl_history_search_len == 0)
656: return (rl_get_previous_history (count, ignore));
657: return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
658: }
659:
660: /* Search forward in the history for the string of characters
661: from the start of the line to rl_point. This is a non-incremental
662: search. The search succeeds if the search string is present anywhere
663: in the history line. */
664: int
1.1.1.2 ! misho 665: rl_history_substr_search_forward (int count, int ignore)
1.1 misho 666: {
667: if (count == 0)
668: return (0);
669:
670: if (rl_last_func != rl_history_substr_search_forward &&
671: rl_last_func != rl_history_substr_search_backward)
672: rl_history_search_reinit (NON_ANCHORED_SEARCH);
673:
674: if (rl_history_search_len == 0)
675: return (rl_get_next_history (count, ignore));
676: return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
677: }
678:
679: /* Search backward through the history for the string of characters
680: from the start of the line to rl_point. This is a non-incremental
681: search. */
682: int
1.1.1.2 ! misho 683: rl_history_substr_search_backward (int count, int ignore)
1.1 misho 684: {
685: if (count == 0)
686: return (0);
687:
688: if (rl_last_func != rl_history_substr_search_forward &&
689: rl_last_func != rl_history_substr_search_backward)
690: rl_history_search_reinit (NON_ANCHORED_SEARCH);
691:
692: if (rl_history_search_len == 0)
693: return (rl_get_previous_history (count, ignore));
694: return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
695: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>