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);