1
/* histsearch.c -- searching the history list. */
3
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
5
This file contains the GNU History Library (the Library), a set of
6
routines for managing the text of previously typed lines.
8
The Library 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 1, or (at your option)
13
The Library is distributed in the hope that it will be useful, but
14
WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16
General Public License for more details.
18
The GNU General Public License is often shipped with GNU software, and
19
is generally kept in a file called COPYING or LICENSE. If you do not
20
have a copy of the license, write to the Free Software Foundation,
21
675 Mass Ave, Cambridge, MA 02139, USA. */
23
#define READLINE_LIBRARY
25
#if defined (HAVE_CONFIG_H)
30
#if defined (HAVE_STDLIB_H)
33
# include "ansi_stdlib.h"
34
#endif /* HAVE_STDLIB_H */
35
#if defined (HAVE_UNISTD_H)
37
# include <sys/types.h>
41
#if defined (HAVE_STRING_H)
45
#endif /* !HAVE_STRING_H */
50
/* Variables imported from other history library files. */
51
extern int history_offset;
53
/* The list of alternate characters that can delimit a history search
55
char *history_search_delimiter_chars = (char *)NULL;
57
/* Search the history for STRING, starting at history_offset.
58
If DIRECTION < 0, then the search is through previous entries, else
59
through subsequent. If ANCHORED is non-zero, the string must
60
appear at the beginning of a history line, otherwise, the string
61
may appear anywhere in the line. If the string is found, then
62
current_history () is the history entry, and the value of this
63
function is the offset in the line of that history entry that the
64
string was found in. Otherwise, nothing is changed, and a -1 is
68
history_search_internal (string, direction, anchored)
70
int direction, anchored;
72
register int i, reverse;
74
register int line_index;
76
HIST_ENTRY **the_history; /* local */
79
reverse = (direction < 0);
81
/* Take care of trivial cases first. */
82
if (string == 0 || *string == '\0')
85
if (!history_length || ((i == history_length) && !reverse))
88
if (reverse && (i == history_length))
91
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
93
the_history = history_list ();
94
string_len = strlen (string);
97
/* Search each line in the history list for STRING. */
99
/* At limit for direction? */
100
if ((reverse && i < 0) || (!reverse && i == history_length))
103
line = the_history[i]->line;
104
line_index = strlen (line);
106
/* If STRING is longer than line, no match. */
107
if (string_len > line_index)
113
/* Handle anchored searches first. */
114
if (anchored == ANCHORED_SEARCH)
116
if (STREQN (string, line, string_len))
126
/* Do substring search. */
129
line_index -= string_len;
131
while (line_index >= 0)
133
if (STREQN (string, line + line_index, string_len))
145
limit = line_index - string_len + 1;
148
while (line_index < limit)
150
if (STREQN (string, line + line_index, string_len))
162
/* Do a non-anchored search for STRING through the history in DIRECTION. */
164
history_search (string, direction)
168
return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
171
/* Do an anchored search for string through the history in DIRECTION. */
173
history_search_prefix (string, direction)
177
return (history_search_internal (string, direction, ANCHORED_SEARCH));
180
/* Search for STRING in the history list. DIR is < 0 for searching
181
backwards. POS is an absolute index into the history list at
182
which point to begin searching. */
184
history_search_pos (string, dir, pos)
190
old = where_history ();
191
history_set_pos (pos);
192
if (history_search (string, dir) == -1)
194
history_set_pos (old);
197
ret = where_history ();
198
history_set_pos (old);