Annotation of embedaddon/readline/histsearch.c, revision 1.1.1.1
1.1 misho 1: /* histsearch.c -- searching the history list. */
2:
3: /* Copyright (C) 1989, 1992-2009 Free Software Foundation, Inc.
4:
5: This file contains the GNU History Library (History), a set of
6: routines for managing the text of previously typed lines.
7:
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.
12:
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.
17:
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/>.
20: */
21:
22: #define READLINE_LIBRARY
23:
24: #if defined (HAVE_CONFIG_H)
25: # include <config.h>
26: #endif
27:
28: #include <stdio.h>
29: #if defined (HAVE_STDLIB_H)
30: # include <stdlib.h>
31: #else
32: # include "ansi_stdlib.h"
33: #endif /* HAVE_STDLIB_H */
34:
35: #if defined (HAVE_UNISTD_H)
36: # ifdef _MINIX
37: # include <sys/types.h>
38: # endif
39: # include <unistd.h>
40: #endif
41:
42: #include "history.h"
43: #include "histlib.h"
44:
45: /* The list of alternate characters that can delimit a history search
46: string. */
47: char *history_search_delimiter_chars = (char *)NULL;
48:
49: static int history_search_internal PARAMS((const char *, int, int));
50:
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
59: returned. */
60:
61: static int
62: history_search_internal (string, direction, anchored)
63: const char *string;
64: int direction, anchored;
65: {
66: register int i, reverse;
67: register char *line;
68: register int line_index;
69: int string_len;
70: HIST_ENTRY **the_history; /* local */
71:
72: i = history_offset;
73: reverse = (direction < 0);
74:
75: /* Take care of trivial cases first. */
76: if (string == 0 || *string == '\0')
77: return (-1);
78:
79: if (!history_length || ((i >= history_length) && !reverse))
80: return (-1);
81:
82: if (reverse && (i >= history_length))
83: i = history_length - 1;
84:
85: #define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
86:
87: the_history = history_list ();
88: string_len = strlen (string);
89: while (1)
90: {
91: /* Search each line in the history list for STRING. */
92:
93: /* At limit for direction? */
94: if ((reverse && i < 0) || (!reverse && i == history_length))
95: return (-1);
96:
97: line = the_history[i]->line;
98: line_index = strlen (line);
99:
100: /* If STRING is longer than line, no match. */
101: if (string_len > line_index)
102: {
103: NEXT_LINE ();
104: continue;
105: }
106:
107: /* Handle anchored searches first. */
108: if (anchored == ANCHORED_SEARCH)
109: {
110: if (STREQN (string, line, string_len))
111: {
112: history_offset = i;
113: return (0);
114: }
115:
116: NEXT_LINE ();
117: continue;
118: }
119:
120: /* Do substring search. */
121: if (reverse)
122: {
123: line_index -= string_len;
124:
125: while (line_index >= 0)
126: {
127: if (STREQN (string, line + line_index, string_len))
128: {
129: history_offset = i;
130: return (line_index);
131: }
132: line_index--;
133: }
134: }
135: else
136: {
137: register int limit;
138:
139: limit = line_index - string_len + 1;
140: line_index = 0;
141:
142: while (line_index < limit)
143: {
144: if (STREQN (string, line + line_index, string_len))
145: {
146: history_offset = i;
147: return (line_index);
148: }
149: line_index++;
150: }
151: }
152: NEXT_LINE ();
153: }
154: }
155:
156: /* Do a non-anchored search for STRING through the history in DIRECTION. */
157: int
158: history_search (string, direction)
159: const char *string;
160: int direction;
161: {
162: return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
163: }
164:
165: /* Do an anchored search for string through the history in DIRECTION. */
166: int
167: history_search_prefix (string, direction)
168: const char *string;
169: int direction;
170: {
171: return (history_search_internal (string, direction, ANCHORED_SEARCH));
172: }
173:
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. */
177: int
178: history_search_pos (string, dir, pos)
179: const char *string;
180: int dir, pos;
181: {
182: int ret, old;
183:
184: old = where_history ();
185: history_set_pos (pos);
186: if (history_search (string, dir) == -1)
187: {
188: history_set_pos (old);
189: return (-1);
190: }
191: ret = where_history ();
192: history_set_pos (old);
193: return ret;
194: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>