1
/* histsearch.c -- searching the history list. */
3
/* Copyright (C) 1989, 1992-2009 Free Software Foundation, Inc.
5
This file contains the GNU History Library (History), a set of
6
routines for managing the text of previously typed lines.
8
History 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.
13
History 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.
18
You should have received a copy of the GNU General Public License
19
along with History. If not, see <http://www.gnu.org/licenses/>.
22
#define READLINE_LIBRARY
24
#if defined (HAVE_CONFIG_H)
29
#if defined (HAVE_STDLIB_H)
32
# include "ansi_stdlib.h"
33
#endif /* HAVE_STDLIB_H */
35
#if defined (HAVE_UNISTD_H)
37
# include <sys/types.h>
45
/* The list of alternate characters that can delimit a history search
47
char *history_search_delimiter_chars = (char *)NULL;
49
static int history_search_internal PARAMS((const char *, int, int));
51
/* Search the history for STRING, starting at history_offset.
52
If DIRECTION < 0, then the search is through previous entries, else
53
through subsequent. If ANCHORED is non-zero, the string must
54
appear at the beginning of a history line, otherwise, the string
55
may appear anywhere in the line. If the string is found, then
56
current_history () is the history entry, and the value of this
57
function is the offset in the line of that history entry that the
58
string was found in. Otherwise, nothing is changed, and a -1 is
62
history_search_internal (string, direction, anchored)
64
int direction, anchored;
66
register int i, reverse;
68
register int line_index;
70
HIST_ENTRY **the_history; /* local */
73
reverse = (direction < 0);
75
/* Take care of trivial cases first. */
76
if (string == 0 || *string == '\0')
79
if (!history_length || ((i >= history_length) && !reverse))
82
if (reverse && (i >= history_length))
83
i = history_length - 1;
85
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
87
the_history = history_list ();
88
string_len = strlen (string);
91
/* Search each line in the history list for STRING. */
93
/* At limit for direction? */
94
if ((reverse && i < 0) || (!reverse && i == history_length))
97
line = the_history[i]->line;
98
line_index = strlen (line);
100
/* If STRING is longer than line, no match. */
101
if (string_len > line_index)
107
/* Handle anchored searches first. */
108
if (anchored == ANCHORED_SEARCH)
110
if (STREQN (string, line, string_len))
120
/* Do substring search. */
123
line_index -= string_len;
125
while (line_index >= 0)
127
if (STREQN (string, line + line_index, string_len))
139
limit = line_index - string_len + 1;
142
while (line_index < limit)
144
if (STREQN (string, line + line_index, string_len))
156
/* Do a non-anchored search for STRING through the history in DIRECTION. */
158
history_search (string, direction)
162
return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
165
/* Do an anchored search for string through the history in DIRECTION. */
167
history_search_prefix (string, direction)
171
return (history_search_internal (string, direction, ANCHORED_SEARCH));
174
/* Search for STRING in the history list. DIR is < 0 for searching
175
backwards. POS is an absolute index into the history list at
176
which point to begin searching. */
178
history_search_pos (string, dir, pos)
184
old = where_history ();
185
history_set_pos (pos);
186
if (history_search (string, dir) == -1)
188
history_set_pos (old);
191
ret = where_history ();
192
history_set_pos (old);