xref: /dflybsd-src/contrib/gdb-7/readline/histsearch.c (revision 16003dcfd2baa152f5dd24794ec9f36e139eaeb8)
1*6b445a62SJohn Marino /* histsearch.c -- searching the history list. */
2*6b445a62SJohn Marino 
3*6b445a62SJohn Marino /* Copyright (C) 1989, 1992-2009 Free Software Foundation, Inc.
4*6b445a62SJohn Marino 
5*6b445a62SJohn Marino    This file contains the GNU History Library (History), a set of
6*6b445a62SJohn Marino    routines for managing the text of previously typed lines.
7*6b445a62SJohn Marino 
8*6b445a62SJohn Marino    History is free software: you can redistribute it and/or modify
9*6b445a62SJohn Marino    it under the terms of the GNU General Public License as published by
10*6b445a62SJohn Marino    the Free Software Foundation, either version 3 of the License, or
11*6b445a62SJohn Marino    (at your option) any later version.
12*6b445a62SJohn Marino 
13*6b445a62SJohn Marino    History is distributed in the hope that it will be useful,
14*6b445a62SJohn Marino    but WITHOUT ANY WARRANTY; without even the implied warranty of
15*6b445a62SJohn Marino    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16*6b445a62SJohn Marino    GNU General Public License for more details.
17*6b445a62SJohn Marino 
18*6b445a62SJohn Marino    You should have received a copy of the GNU General Public License
19*6b445a62SJohn Marino    along with History.  If not, see <http://www.gnu.org/licenses/>.
20*6b445a62SJohn Marino */
21*6b445a62SJohn Marino 
22*6b445a62SJohn Marino #define READLINE_LIBRARY
23*6b445a62SJohn Marino 
24*6b445a62SJohn Marino #if defined (HAVE_CONFIG_H)
25*6b445a62SJohn Marino #  include <config.h>
26*6b445a62SJohn Marino #endif
27*6b445a62SJohn Marino 
28*6b445a62SJohn Marino #include <stdio.h>
29*6b445a62SJohn Marino #if defined (HAVE_STDLIB_H)
30*6b445a62SJohn Marino #  include <stdlib.h>
31*6b445a62SJohn Marino #else
32*6b445a62SJohn Marino #  include "ansi_stdlib.h"
33*6b445a62SJohn Marino #endif /* HAVE_STDLIB_H */
34*6b445a62SJohn Marino 
35*6b445a62SJohn Marino #if defined (HAVE_UNISTD_H)
36*6b445a62SJohn Marino #  ifdef _MINIX
37*6b445a62SJohn Marino #    include <sys/types.h>
38*6b445a62SJohn Marino #  endif
39*6b445a62SJohn Marino #  include <unistd.h>
40*6b445a62SJohn Marino #endif
41*6b445a62SJohn Marino 
42*6b445a62SJohn Marino #include "history.h"
43*6b445a62SJohn Marino #include "histlib.h"
44*6b445a62SJohn Marino 
45*6b445a62SJohn Marino /* The list of alternate characters that can delimit a history search
46*6b445a62SJohn Marino    string. */
47*6b445a62SJohn Marino char *history_search_delimiter_chars = (char *)NULL;
48*6b445a62SJohn Marino 
49*6b445a62SJohn Marino static int history_search_internal PARAMS((const char *, int, int));
50*6b445a62SJohn Marino 
51*6b445a62SJohn Marino /* Search the history for STRING, starting at history_offset.
52*6b445a62SJohn Marino    If DIRECTION < 0, then the search is through previous entries, else
53*6b445a62SJohn Marino    through subsequent.  If ANCHORED is non-zero, the string must
54*6b445a62SJohn Marino    appear at the beginning of a history line, otherwise, the string
55*6b445a62SJohn Marino    may appear anywhere in the line.  If the string is found, then
56*6b445a62SJohn Marino    current_history () is the history entry, and the value of this
57*6b445a62SJohn Marino    function is the offset in the line of that history entry that the
58*6b445a62SJohn Marino    string was found in.  Otherwise, nothing is changed, and a -1 is
59*6b445a62SJohn Marino    returned. */
60*6b445a62SJohn Marino 
61*6b445a62SJohn Marino static int
history_search_internal(string,direction,anchored)62*6b445a62SJohn Marino history_search_internal (string, direction, anchored)
63*6b445a62SJohn Marino      const char *string;
64*6b445a62SJohn Marino      int direction, anchored;
65*6b445a62SJohn Marino {
66*6b445a62SJohn Marino   register int i, reverse;
67*6b445a62SJohn Marino   register char *line;
68*6b445a62SJohn Marino   register int line_index;
69*6b445a62SJohn Marino   int string_len;
70*6b445a62SJohn Marino   HIST_ENTRY **the_history; 	/* local */
71*6b445a62SJohn Marino 
72*6b445a62SJohn Marino   i = history_offset;
73*6b445a62SJohn Marino   reverse = (direction < 0);
74*6b445a62SJohn Marino 
75*6b445a62SJohn Marino   /* Take care of trivial cases first. */
76*6b445a62SJohn Marino   if (string == 0 || *string == '\0')
77*6b445a62SJohn Marino     return (-1);
78*6b445a62SJohn Marino 
79*6b445a62SJohn Marino   if (!history_length || ((i >= history_length) && !reverse))
80*6b445a62SJohn Marino     return (-1);
81*6b445a62SJohn Marino 
82*6b445a62SJohn Marino   if (reverse && (i >= history_length))
83*6b445a62SJohn Marino     i = history_length - 1;
84*6b445a62SJohn Marino 
85*6b445a62SJohn Marino #define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
86*6b445a62SJohn Marino 
87*6b445a62SJohn Marino   the_history = history_list ();
88*6b445a62SJohn Marino   string_len = strlen (string);
89*6b445a62SJohn Marino   while (1)
90*6b445a62SJohn Marino     {
91*6b445a62SJohn Marino       /* Search each line in the history list for STRING. */
92*6b445a62SJohn Marino 
93*6b445a62SJohn Marino       /* At limit for direction? */
94*6b445a62SJohn Marino       if ((reverse && i < 0) || (!reverse && i == history_length))
95*6b445a62SJohn Marino 	return (-1);
96*6b445a62SJohn Marino 
97*6b445a62SJohn Marino       line = the_history[i]->line;
98*6b445a62SJohn Marino       line_index = strlen (line);
99*6b445a62SJohn Marino 
100*6b445a62SJohn Marino       /* If STRING is longer than line, no match. */
101*6b445a62SJohn Marino       if (string_len > line_index)
102*6b445a62SJohn Marino 	{
103*6b445a62SJohn Marino 	  NEXT_LINE ();
104*6b445a62SJohn Marino 	  continue;
105*6b445a62SJohn Marino 	}
106*6b445a62SJohn Marino 
107*6b445a62SJohn Marino       /* Handle anchored searches first. */
108*6b445a62SJohn Marino       if (anchored == ANCHORED_SEARCH)
109*6b445a62SJohn Marino 	{
110*6b445a62SJohn Marino 	  if (STREQN (string, line, string_len))
111*6b445a62SJohn Marino 	    {
112*6b445a62SJohn Marino 	      history_offset = i;
113*6b445a62SJohn Marino 	      return (0);
114*6b445a62SJohn Marino 	    }
115*6b445a62SJohn Marino 
116*6b445a62SJohn Marino 	  NEXT_LINE ();
117*6b445a62SJohn Marino 	  continue;
118*6b445a62SJohn Marino 	}
119*6b445a62SJohn Marino 
120*6b445a62SJohn Marino       /* Do substring search. */
121*6b445a62SJohn Marino       if (reverse)
122*6b445a62SJohn Marino 	{
123*6b445a62SJohn Marino 	  line_index -= string_len;
124*6b445a62SJohn Marino 
125*6b445a62SJohn Marino 	  while (line_index >= 0)
126*6b445a62SJohn Marino 	    {
127*6b445a62SJohn Marino 	      if (STREQN (string, line + line_index, string_len))
128*6b445a62SJohn Marino 		{
129*6b445a62SJohn Marino 		  history_offset = i;
130*6b445a62SJohn Marino 		  return (line_index);
131*6b445a62SJohn Marino 		}
132*6b445a62SJohn Marino 	      line_index--;
133*6b445a62SJohn Marino 	    }
134*6b445a62SJohn Marino 	}
135*6b445a62SJohn Marino       else
136*6b445a62SJohn Marino 	{
137*6b445a62SJohn Marino 	  register int limit;
138*6b445a62SJohn Marino 
139*6b445a62SJohn Marino 	  limit = line_index - string_len + 1;
140*6b445a62SJohn Marino 	  line_index = 0;
141*6b445a62SJohn Marino 
142*6b445a62SJohn Marino 	  while (line_index < limit)
143*6b445a62SJohn Marino 	    {
144*6b445a62SJohn Marino 	      if (STREQN (string, line + line_index, string_len))
145*6b445a62SJohn Marino 		{
146*6b445a62SJohn Marino 		  history_offset = i;
147*6b445a62SJohn Marino 		  return (line_index);
148*6b445a62SJohn Marino 		}
149*6b445a62SJohn Marino 	      line_index++;
150*6b445a62SJohn Marino 	    }
151*6b445a62SJohn Marino 	}
152*6b445a62SJohn Marino       NEXT_LINE ();
153*6b445a62SJohn Marino     }
154*6b445a62SJohn Marino }
155*6b445a62SJohn Marino 
156*6b445a62SJohn Marino /* Do a non-anchored search for STRING through the history in DIRECTION. */
157*6b445a62SJohn Marino int
history_search(string,direction)158*6b445a62SJohn Marino history_search (string, direction)
159*6b445a62SJohn Marino      const char *string;
160*6b445a62SJohn Marino      int direction;
161*6b445a62SJohn Marino {
162*6b445a62SJohn Marino   return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
163*6b445a62SJohn Marino }
164*6b445a62SJohn Marino 
165*6b445a62SJohn Marino /* Do an anchored search for string through the history in DIRECTION. */
166*6b445a62SJohn Marino int
history_search_prefix(string,direction)167*6b445a62SJohn Marino history_search_prefix (string, direction)
168*6b445a62SJohn Marino      const char *string;
169*6b445a62SJohn Marino      int direction;
170*6b445a62SJohn Marino {
171*6b445a62SJohn Marino   return (history_search_internal (string, direction, ANCHORED_SEARCH));
172*6b445a62SJohn Marino }
173*6b445a62SJohn Marino 
174*6b445a62SJohn Marino /* Search for STRING in the history list.  DIR is < 0 for searching
175*6b445a62SJohn Marino    backwards.  POS is an absolute index into the history list at
176*6b445a62SJohn Marino    which point to begin searching. */
177*6b445a62SJohn Marino int
history_search_pos(string,dir,pos)178*6b445a62SJohn Marino history_search_pos (string, dir, pos)
179*6b445a62SJohn Marino      const char *string;
180*6b445a62SJohn Marino      int dir, pos;
181*6b445a62SJohn Marino {
182*6b445a62SJohn Marino   int ret, old;
183*6b445a62SJohn Marino 
184*6b445a62SJohn Marino   old = where_history ();
185*6b445a62SJohn Marino   history_set_pos (pos);
186*6b445a62SJohn Marino   if (history_search (string, dir) == -1)
187*6b445a62SJohn Marino     {
188*6b445a62SJohn Marino       history_set_pos (old);
189*6b445a62SJohn Marino       return (-1);
190*6b445a62SJohn Marino     }
191*6b445a62SJohn Marino   ret = where_history ();
192*6b445a62SJohn Marino   history_set_pos (old);
193*6b445a62SJohn Marino   return ret;
194*6b445a62SJohn Marino }
195