]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - readline/search.c
* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[thirdparty/binutils-gdb.git] / readline / search.c
CommitLineData
5e98bbab
PB
1/* search.c - code for non-incremental searching in emacs and vi modes. */
2
3/* Copyright (C) 1992 Free Software Foundation, Inc.
4
5 This file is part of the Readline Library (the Library), a set of
6 routines for providing Emacs style line input to programs that ask
7 for it.
8
9 The Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 1, or (at your option)
12 any later version.
13
14 The Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 General Public License for more details.
18
19 The GNU General Public License is often shipped with GNU software, and
20 is generally kept in a file called COPYING or LICENSE. If you do not
21 have a copy of the license, write to the Free Software Foundation,
22 675 Mass Ave, Cambridge, MA 02139, USA. */
23
24#include <stdio.h>
25
26#if defined (__GNUC__)
27# define alloca __builtin_alloca
28#else
29# if defined (sparc) || defined (HAVE_ALLOCA_H)
30# include <alloca.h>
31# endif
32#endif
33
34#include "readline.h"
35#include "history.h"
36
37extern char *xmalloc (), *xrealloc ();
38
39/* Variables imported from readline.c */
40extern int rl_point, rl_end, rl_line_buffer_len;
41extern Keymap _rl_keymap;
42extern char *rl_prompt;
43extern char *rl_line_buffer;
44extern HIST_ENTRY *saved_line_for_history;
45
46static char *noninc_search_string = (char *) NULL;
47static int noninc_history_pos = 0;
48
49/* Search the history list for STRING starting at absolute history position
50 POS. If STRING begins with `^', the search must match STRING at the
51 beginning of a history line, otherwise a full substring match is performed
52 for STRING. DIR < 0 means to search backwards through the history list,
53 DIR >= 0 means to search forward. */
54static int
55noninc_search_from_pos (string, pos, dir)
56 char *string;
57 int pos, dir;
58{
59 int ret, old;
60
61 old = where_history ();
62 history_set_pos (pos);
63
64 if (*string == '^')
65 ret = history_search_prefix (string + 1, dir);
66 else
67 ret = history_search (string, dir);
68
69 if (ret != -1)
70 ret = where_history ();
71
72 history_set_pos (old);
73 return (ret);
74}
75
76/* Search for a line in the history containing STRING. If DIR is < 0, the
77 search is backwards through previous entries, else through subsequent
78 entries. */
79static void
80noninc_dosearch (string, dir)
81 char *string;
82 int dir;
83{
84 int oldpos, pos;
85 HIST_ENTRY *entry;
86
87 if (string == 0 || *string == 0 || noninc_history_pos < 0)
88 {
89 ding ();
90 return;
91 }
92
93 pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
94 if (pos == -1)
95 {
96 /* Search failed, current history position unchanged. */
97 maybe_unsave_line ();
98 rl_clear_message ();
99 rl_point = 0;
100 ding ();
101 return;
102 }
103
104 noninc_history_pos = pos;
105
106 oldpos = where_history ();
107 history_set_pos (noninc_history_pos);
108 entry = current_history ();
109 history_set_pos (oldpos);
110
111 {
112 int line_len;
113
114 line_len = strlen (entry->line);
115 if (line_len >= rl_line_buffer_len)
116 rl_extend_line_buffer (line_len);
117 strcpy (rl_line_buffer, entry->line);
118 }
119
120 rl_undo_list = (UNDO_LIST *)entry->data;
121 rl_end = strlen (rl_line_buffer);
122 rl_point = 0;
123 rl_clear_message ();
124
125 if (saved_line_for_history)
126 free_history_entry (saved_line_for_history);
127 saved_line_for_history = (HIST_ENTRY *)NULL;
128}
129
130/* Search non-interactively through the history list. DIR < 0 means to
131 search backwards through the history of previous commands; otherwise
132 the search is for commands subsequent to the current position in the
133 history list. PCHAR is the character to use for prompting when reading
134 the search string; if not specified (0), it defaults to `:'. */
135static void
136noninc_search (dir, pchar)
137 int dir;
138 int pchar;
139{
140 int saved_point, c, pmtlen;
141 char *p;
142
143 maybe_save_line ();
144 saved_point = rl_point;
145
146 /* Use the line buffer to read the search string. */
147 rl_line_buffer[0] = 0;
148 rl_end = rl_point = 0;
149
150 pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
151 p = (char *)alloca (2 + pmtlen);
152 if (pmtlen)
153 strcpy (p, rl_prompt);
154 p[pmtlen] = pchar ? pchar : ':';
155 p[pmtlen + 1] = '\0';
156
157 rl_message (p, 0, 0);
158
159 /* Read the search string. */
160 while (c = rl_read_key ())
161 {
162 switch (c)
163 {
164 case CTRL('H'):
165 case RUBOUT:
166 if (rl_point == 0)
167 {
168 maybe_unsave_line ();
169 rl_clear_message ();
170 rl_point = saved_point;
171 return;
172 }
173 /* FALLTHROUGH */
174
175 case CTRL('W'):
176 case CTRL('U'):
177 rl_dispatch (c, _rl_keymap);
178 break;
179
180 case RETURN:
181 case NEWLINE:
182 goto dosearch;
183 /* NOTREACHED */
184 break;
185
186 case CTRL('C'):
187 case CTRL('G'):
188 maybe_unsave_line ();
189 rl_clear_message ();
190 rl_point = saved_point;
191 ding ();
192 return;
193
194 default:
195 rl_insert (1, c);
196 break;
197 }
198 rl_redisplay ();
199 }
200
201 dosearch:
202 /* If rl_point == 0, we want to re-use the previous search string and
203 start from the saved history position. If there's no previous search
204 string, punt. */
205 if (rl_point == 0)
206 {
207 if (!noninc_search_string)
208 {
209 ding ();
210 return;
211 }
212 }
213 else
214 {
215 /* We want to start the search from the current history position. */
216 noninc_history_pos = where_history ();
217 if (noninc_search_string)
218 free (noninc_search_string);
219 noninc_search_string = savestring (rl_line_buffer);
220 }
221
222 noninc_dosearch (noninc_search_string, dir);
223}
224
225/* Search forward through the history list for a string. If the vi-mode
226 code calls this, KEY will be `?'. */
227rl_noninc_forward_search (count, key)
228 int count, key;
229{
230 if (key == '?')
231 noninc_search (1, '?');
232 else
233 noninc_search (1, 0);
234}
235
236/* Reverse search the history list for a string. If the vi-mode code
237 calls this, KEY will be `/'. */
238rl_noninc_reverse_search (count, key)
239 int count, key;
240{
241 if (key == '/')
242 noninc_search (-1, '/');
243 else
244 noninc_search (-1, 0);
245}
246
247/* Search forward through the history list for the last string searched
248 for. If there is no saved search string, abort. */
249rl_noninc_forward_search_again (count, key)
250 int count, key;
251{
252 if (!noninc_search_string)
253 {
254 ding ();
255 return (-1);
256 }
257 noninc_dosearch (noninc_search_string, 1);
258}
259
260/* Reverse search in the history list for the last string searched
261 for. If there is no saved search string, abort. */
262rl_noninc_reverse_search_again (count, key)
263 int count, key;
264{
265 if (!noninc_search_string)
266 {
267 ding ();
268 return (-1);
269 }
270 noninc_dosearch (noninc_search_string, -1);
271}