OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [readline/] [search.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1181 sfurman
/* 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 2, 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
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23
#define READLINE_LIBRARY
24
 
25
#if defined (HAVE_CONFIG_H)
26
#  include <config.h>
27
#endif
28
 
29
#include <sys/types.h>
30
#include <stdio.h>
31
 
32
#if defined (HAVE_UNISTD_H)
33
#  include <unistd.h>
34
#endif
35
 
36
#if defined (HAVE_STDLIB_H)
37
#  include <stdlib.h>
38
#else
39
#  include "ansi_stdlib.h"
40
#endif
41
 
42
#include "rldefs.h"
43
#include "readline.h"
44
#include "history.h"
45
 
46
#include "rlprivate.h"
47
#include "xmalloc.h"
48
 
49
#ifdef abs
50
#  undef abs
51
#endif
52
#define abs(x)          (((x) >= 0) ? (x) : -(x))
53
 
54
extern HIST_ENTRY *saved_line_for_history;
55
 
56
/* Functions imported from the rest of the library. */
57
extern int _rl_free_history_entry __P((HIST_ENTRY *));
58
 
59
static char *noninc_search_string = (char *) NULL;
60
static int noninc_history_pos;
61
 
62
static char *prev_line_found = (char *) NULL;
63
 
64
static int rl_history_search_len;
65
static int rl_history_search_pos;
66
static char *history_search_string;
67
static int history_string_size;
68
 
69
/* Make the data from the history entry ENTRY be the contents of the
70
   current line.  This doesn't do anything with rl_point; the caller
71
   must set it. */
72
static void
73
make_history_line_current (entry)
74
     HIST_ENTRY *entry;
75
{
76
  int line_len;
77
 
78
  line_len = strlen (entry->line);
79
  if (line_len >= rl_line_buffer_len)
80
    rl_extend_line_buffer (line_len);
81
  strcpy (rl_line_buffer, entry->line);
82
 
83
  rl_undo_list = (UNDO_LIST *)entry->data;
84
  rl_end = line_len;
85
 
86
  if (saved_line_for_history)
87
    _rl_free_history_entry (saved_line_for_history);
88
  saved_line_for_history = (HIST_ENTRY *)NULL;
89
}
90
 
91
/* Search the history list for STRING starting at absolute history position
92
   POS.  If STRING begins with `^', the search must match STRING at the
93
   beginning of a history line, otherwise a full substring match is performed
94
   for STRING.  DIR < 0 means to search backwards through the history list,
95
   DIR >= 0 means to search forward. */
96
static int
97
noninc_search_from_pos (string, pos, dir)
98
     char *string;
99
     int pos, dir;
100
{
101
  int ret, old;
102
 
103
  old = where_history ();
104
  history_set_pos (pos);
105
 
106
  if (*string == '^')
107
    ret = history_search_prefix (string + 1, dir);
108
  else
109
    ret = history_search (string, dir);
110
 
111
  if (ret != -1)
112
    ret = where_history ();
113
 
114
  history_set_pos (old);
115
  return (ret);
116
}
117
 
118
/* Search for a line in the history containing STRING.  If DIR is < 0, the
119
   search is backwards through previous entries, else through subsequent
120
   entries. */
121
static void
122
noninc_dosearch (string, dir)
123
     char *string;
124
     int dir;
125
{
126
  int oldpos, pos;
127
  HIST_ENTRY *entry;
128
 
129
  if (string == 0 || *string == '\0' || noninc_history_pos < 0)
130
    {
131
      ding ();
132
      return;
133
    }
134
 
135
  pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
136
  if (pos == -1)
137
    {
138
      /* Search failed, current history position unchanged. */
139
      maybe_unsave_line ();
140
      rl_clear_message ();
141
      rl_point = 0;
142
      ding ();
143
      return;
144
    }
145
 
146
  noninc_history_pos = pos;
147
 
148
  oldpos = where_history ();
149
  history_set_pos (noninc_history_pos);
150
  entry = current_history ();
151
#if defined (VI_MODE)
152
  if (rl_editing_mode != vi_mode)
153
#endif
154
  history_set_pos (oldpos);
155
 
156
  make_history_line_current (entry);
157
 
158
  rl_point = 0;
159
  rl_clear_message ();
160
}
161
 
162
/* Search non-interactively through the history list.  DIR < 0 means to
163
   search backwards through the history of previous commands; otherwise
164
   the search is for commands subsequent to the current position in the
165
   history list.  PCHAR is the character to use for prompting when reading
166
   the search string; if not specified (0), it defaults to `:'. */
167
static void
168
noninc_search (dir, pchar)
169
     int dir;
170
     int pchar;
171
{
172
  int saved_point, c;
173
  char *p;
174
 
175
  maybe_save_line ();
176
  saved_point = rl_point;
177
 
178
  /* Use the line buffer to read the search string. */
179
  rl_line_buffer[0] = 0;
180
  rl_end = rl_point = 0;
181
 
182
  p = _rl_make_prompt_for_search (pchar ? pchar : ':');
183
  rl_message (p, 0, 0);
184
  free (p);
185
 
186
#define SEARCH_RETURN rl_restore_prompt (); return
187
 
188
  /* Read the search string. */
189
  while (c = rl_read_key ())
190
    {
191
      switch (c)
192
        {
193
        case CTRL('H'):
194
        case RUBOUT:
195
          if (rl_point == 0)
196
            {
197
              maybe_unsave_line ();
198
              rl_clear_message ();
199
              rl_point = saved_point;
200
              SEARCH_RETURN;
201
            }
202
          rl_rubout (1, c);
203
          break;
204
 
205
        case CTRL('W'):
206
          rl_unix_word_rubout (1, c);
207
          break;
208
 
209
        case CTRL('U'):
210
          rl_unix_line_discard (1, c);
211
          break;
212
 
213
        case RETURN:
214
        case NEWLINE:
215
          goto dosearch;
216
          /* NOTREACHED */
217
          break;
218
 
219
        case CTRL('C'):
220
        case CTRL('G'):
221
          maybe_unsave_line ();
222
          rl_clear_message ();
223
          rl_point = saved_point;
224
          ding ();
225
          SEARCH_RETURN;
226
 
227
        default:
228
          rl_insert (1, c);
229
          break;
230
        }
231
      (*rl_redisplay_function) ();
232
    }
233
 
234
 dosearch:
235
  /* If rl_point == 0, we want to re-use the previous search string and
236
     start from the saved history position.  If there's no previous search
237
     string, punt. */
238
  if (rl_point == 0)
239
    {
240
      if (!noninc_search_string)
241
        {
242
          ding ();
243
          SEARCH_RETURN;
244
        }
245
    }
246
  else
247
    {
248
      /* We want to start the search from the current history position. */
249
      noninc_history_pos = where_history ();
250
      FREE (noninc_search_string);
251
      noninc_search_string = savestring (rl_line_buffer);
252
    }
253
 
254
  rl_restore_prompt ();
255
  noninc_dosearch (noninc_search_string, dir);
256
}
257
 
258
/* Search forward through the history list for a string.  If the vi-mode
259
   code calls this, KEY will be `?'. */
260
int
261
rl_noninc_forward_search (count, key)
262
     int count, key;
263
{
264
  noninc_search (1, (key == '?') ? '?' : 0);
265
  return 0;
266
}
267
 
268
/* Reverse search the history list for a string.  If the vi-mode code
269
   calls this, KEY will be `/'. */
270
int
271
rl_noninc_reverse_search (count, key)
272
     int count, key;
273
{
274
  noninc_search (-1, (key == '/') ? '/' : 0);
275
  return 0;
276
}
277
 
278
/* Search forward through the history list for the last string searched
279
   for.  If there is no saved search string, abort. */
280
int
281
rl_noninc_forward_search_again (count, key)
282
     int count, key;
283
{
284
  if (!noninc_search_string)
285
    {
286
      ding ();
287
      return (-1);
288
    }
289
  noninc_dosearch (noninc_search_string, 1);
290
  return 0;
291
}
292
 
293
/* Reverse search in the history list for the last string searched
294
   for.  If there is no saved search string, abort. */
295
int
296
rl_noninc_reverse_search_again (count, key)
297
     int count, key;
298
{
299
  if (!noninc_search_string)
300
    {
301
      ding ();
302
      return (-1);
303
    }
304
  noninc_dosearch (noninc_search_string, -1);
305
  return 0;
306
}
307
 
308
static int
309
rl_history_search_internal (count, dir)
310
     int count, dir;
311
{
312
  HIST_ENTRY *temp;
313
  int ret, oldpos;
314
 
315
  maybe_save_line ();
316
  temp = (HIST_ENTRY *)NULL;
317
 
318
  /* Search COUNT times through the history for a line whose prefix
319
     matches history_search_string.  When this loop finishes, TEMP,
320
     if non-null, is the history line to copy into the line buffer. */
321
  while (count)
322
    {
323
      ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
324
      if (ret == -1)
325
        break;
326
 
327
      /* Get the history entry we found. */
328
      rl_history_search_pos = ret;
329
      oldpos = where_history ();
330
      history_set_pos (rl_history_search_pos);
331
      temp = current_history ();
332
      history_set_pos (oldpos);
333
 
334
      /* Don't find multiple instances of the same line. */
335
      if (prev_line_found && STREQ (prev_line_found, temp->line))
336
        continue;
337
      prev_line_found = temp->line;
338
      count--;
339
    }
340
 
341
  /* If we didn't find anything at all, return. */
342
  if (temp == 0)
343
    {
344
      maybe_unsave_line ();
345
      ding ();
346
      /* If you don't want the saved history line (last match) to show up
347
         in the line buffer after the search fails, change the #if 0 to
348
         #if 1 */
349
#if 0
350
      if (rl_point > rl_history_search_len)
351
        {
352
          rl_point = rl_end = rl_history_search_len;
353
          rl_line_buffer[rl_end] = '\0';
354
        }
355
#else
356
      rl_point = rl_history_search_len; /* maybe_unsave_line changes it */
357
#endif
358
      return 1;
359
    }
360
 
361
  /* Copy the line we found into the current line buffer. */
362
  make_history_line_current (temp);
363
 
364
  rl_point = rl_history_search_len;
365
  return 0;
366
}
367
 
368
static void
369
rl_history_search_reinit ()
370
{
371
  rl_history_search_pos = where_history ();
372
  rl_history_search_len = rl_point;
373
  prev_line_found = (char *)NULL;
374
  if (rl_point)
375
    {
376
      if (rl_history_search_len >= history_string_size - 2)
377
        {
378
          history_string_size = rl_history_search_len + 2;
379
          history_search_string = xrealloc (history_search_string, history_string_size);
380
        }
381
      history_search_string[0] = '^';
382
      strncpy (history_search_string + 1, rl_line_buffer, rl_point);
383
      history_search_string[rl_point + 1] = '\0';
384
    }
385
}
386
 
387
/* Search forward in the history for the string of characters
388
   from the start of the line to rl_point.  This is a non-incremental
389
   search. */
390
int
391
rl_history_search_forward (count, ignore)
392
     int count, ignore;
393
{
394
  if (count == 0)
395
    return (0);
396
 
397
  if (rl_last_func != rl_history_search_forward &&
398
      rl_last_func != rl_history_search_backward)
399
    rl_history_search_reinit ();
400
 
401
  if (rl_history_search_len == 0)
402
    return (rl_get_next_history (count, ignore));
403
  return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
404
}
405
 
406
/* Search backward through the history for the string of characters
407
   from the start of the line to rl_point.  This is a non-incremental
408
   search. */
409
int
410
rl_history_search_backward (count, ignore)
411
     int count, ignore;
412
{
413
  if (count == 0)
414
    return (0);
415
 
416
  if (rl_last_func != rl_history_search_forward &&
417
      rl_last_func != rl_history_search_backward)
418
    rl_history_search_reinit ();
419
 
420
  if (rl_history_search_len == 0)
421
    return (rl_get_previous_history (count, ignore));
422
  return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
423
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.