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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [readline/] [isearch.c] - Blame information for rev 1779

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 106 markom
/* **************************************************************** */
2
/*                                                                  */
3
/*                      I-Search and Searching                      */
4
/*                                                                  */
5
/* **************************************************************** */
6
 
7
/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
8
 
9
   This file contains the Readline Library (the Library), a set of
10
   routines for providing Emacs style line input to programs that ask
11
   for it.
12
 
13
   The Library is free software; you can redistribute it and/or modify
14
   it under the terms of the GNU General Public License as published by
15
   the Free Software Foundation; either version 1, or (at your option)
16
   any later version.
17
 
18
   The Library is distributed in the hope that it will be useful, but
19
   WITHOUT ANY WARRANTY; without even the implied warranty of
20
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
21
   General Public License for more details.
22
 
23
   The GNU General Public License is often shipped with GNU software, and
24
   is generally kept in a file called COPYING or LICENSE.  If you do not
25
   have a copy of the license, write to the Free Software Foundation,
26
   675 Mass Ave, Cambridge, MA 02139, USA. */
27
#define READLINE_LIBRARY
28
 
29
#if defined (HAVE_CONFIG_H)
30
#  include <config.h>
31
#endif
32
 
33
#include <sys/types.h>
34
 
35
#include <stdio.h>
36
 
37
#if defined (HAVE_UNISTD_H)
38
#  include <unistd.h>
39
#endif
40
 
41
#if defined (HAVE_STDLIB_H)
42
#  include <stdlib.h>
43
#else
44
#  include "ansi_stdlib.h"
45
#endif
46
 
47
#include "rldefs.h"
48
#include "readline.h"
49
#include "history.h"
50
 
51
/* Variables exported to other files in the readline library. */
52
unsigned char *_rl_isearch_terminators = (unsigned char *)NULL;
53
 
54
/* Variables imported from other files in the readline library. */
55
extern Keymap _rl_keymap;
56
extern HIST_ENTRY *saved_line_for_history;
57
extern int rl_line_buffer_len;
58
extern int rl_point, rl_end;
59
extern char *rl_line_buffer;
60
 
61
extern int rl_execute_next ();
62
extern void rl_extend_line_buffer ();
63
 
64
extern int _rl_input_available ();
65
 
66
extern char *xmalloc (), *xrealloc ();
67
 
68
static int rl_search_history ();
69
 
70
/* Last line found by the current incremental search, so we don't `find'
71
   identical lines many times in a row. */
72
static char *prev_line_found;
73
 
74
/* Search backwards through the history looking for a string which is typed
75
   interactively.  Start with the current line. */
76
int
77
rl_reverse_search_history (sign, key)
78
     int sign, key;
79
{
80
  return (rl_search_history (-sign, key));
81
}
82
 
83
/* Search forwards through the history looking for a string which is typed
84
   interactively.  Start with the current line. */
85
int
86
rl_forward_search_history (sign, key)
87
     int sign, key;
88
{
89
  return (rl_search_history (sign, key));
90
}
91
 
92
/* Display the current state of the search in the echo-area.
93
   SEARCH_STRING contains the string that is being searched for,
94
   DIRECTION is zero for forward, or 1 for reverse,
95
   WHERE is the history list number of the current line.  If it is
96
   -1, then this line is the starting one. */
97
static void
98
rl_display_search (search_string, reverse_p, where)
99
     char *search_string;
100
     int reverse_p, where;
101
{
102
  char *message;
103
  int msglen, searchlen;
104
 
105
  searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
106
 
107
  message = xmalloc (searchlen + 33);
108
  msglen = 0;
109
 
110
#if defined (NOTDEF)
111
  if (where != -1)
112
    {
113
      sprintf (message, "[%d]", where + history_base);
114
      msglen = strlen (message);
115
    }
116
#endif /* NOTDEF */
117
 
118
  message[msglen++] = '(';
119
 
120
  if (reverse_p)
121
    {
122
      strcpy (message + msglen, "reverse-");
123
      msglen += 8;
124
    }
125
 
126
  strcpy (message + msglen, "i-search)`");
127
  msglen += 10;
128
 
129
  if (search_string)
130
    {
131
      strcpy (message + msglen, search_string);
132
      msglen += searchlen;
133
    }
134
 
135
  strcpy (message + msglen, "': ");
136
 
137
  rl_message ("%s", message, 0);
138
  free (message);
139
  (*rl_redisplay_function) ();
140
}
141
 
142
/* Search through the history looking for an interactively typed string.
143
   This is analogous to i-search.  We start the search in the current line.
144
   DIRECTION is which direction to search; >= 0 means forward, < 0 means
145
   backwards. */
146
static int
147
rl_search_history (direction, invoking_key)
148
     int direction, invoking_key;
149
{
150
  /* The string that the user types in to search for. */
151
  char *search_string;
152
 
153
  /* The current length of SEARCH_STRING. */
154
  int search_string_index;
155
 
156
  /* The amount of space that SEARCH_STRING has allocated to it. */
157
  int search_string_size;
158
 
159
  /* The list of lines to search through. */
160
  char **lines, *allocated_line;
161
 
162
  /* The length of LINES. */
163
  int hlen;
164
 
165
  /* Where we get LINES from. */
166
  HIST_ENTRY **hlist;
167
 
168
  register int i;
169
  int orig_point, orig_line, last_found_line;
170
  int c, found, failed, sline_len;
171
 
172
  /* The line currently being searched. */
173
  char *sline;
174
 
175
  /* Offset in that line. */
176
  int line_index;
177
 
178
  /* Non-zero if we are doing a reverse search. */
179
  int reverse;
180
 
181
  /* The list of characters which terminate the search, but are not
182
     subsequently executed.  If the variable isearch-terminators has
183
     been set, we use that value, otherwise we use ESC and C-J. */
184
  unsigned char *isearch_terminators;
185
 
186
  orig_point = rl_point;
187
  last_found_line = orig_line = where_history ();
188
  reverse = direction < 0;
189
  hlist = history_list ();
190
  allocated_line = (char *)NULL;
191
 
192
  isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
193
                                                : (unsigned char *)"\033\012";
194
 
195
  /* Create an arrary of pointers to the lines that we want to search. */
196
  maybe_replace_line ();
197
  i = 0;
198
  if (hlist)
199
    for (i = 0; hlist[i]; i++);
200
 
201
  /* Allocate space for this many lines, +1 for the current input line,
202
     and remember those lines. */
203
  lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *));
204
  for (i = 0; i < hlen; i++)
205
    lines[i] = hlist[i]->line;
206
 
207
  if (saved_line_for_history)
208
    lines[i] = saved_line_for_history->line;
209
  else
210
    {
211
      /* Keep track of this so we can free it. */
212
      allocated_line = xmalloc (1 + strlen (rl_line_buffer));
213
      strcpy (allocated_line, &rl_line_buffer[0]);
214
      lines[i] = allocated_line;
215
    }
216
 
217
  hlen++;
218
 
219
  /* The line where we start the search. */
220
  i = orig_line;
221
 
222
  rl_save_prompt ();
223
 
224
  /* Initialize search parameters. */
225
  search_string = xmalloc (search_string_size = 128);
226
  *search_string = '\0';
227
  search_string_index = 0;
228
  prev_line_found = (char *)0;           /* XXX */
229
 
230
  /* Normalize DIRECTION into 1 or -1. */
231
  direction = (direction >= 0) ? 1 : -1;
232
 
233
  rl_display_search (search_string, reverse, -1);
234
 
235
  sline = rl_line_buffer;
236
  sline_len = strlen (sline);
237
  line_index = rl_point;
238
 
239
  found = failed = 0;
240
  for (;;)
241
    {
242
      Function *f = (Function *)NULL;
243
 
244
      /* Read a key and decide how to proceed. */
245
      c = rl_read_key ();
246
 
247
      if (_rl_keymap[c].type == ISFUNC)
248
        {
249
          f = _rl_keymap[c].function;
250
 
251
          if (f == rl_reverse_search_history)
252
            c = reverse ? -1 : -2;
253
          else if (f == rl_forward_search_history)
254
            c =  !reverse ? -1 : -2;
255
        }
256
 
257
#if 0
258
      /* Let NEWLINE (^J) terminate the search for people who don't like
259
         using ESC.  ^M can still be used to terminate the search and
260
         immediately execute the command. */
261
      if (c == ESC || c == NEWLINE)
262
#else
263
      /* The characters in isearch_terminators (set from the user-settable
264
         variable isearch-terminators) are used to terminate the search but
265
         not subsequently execute the character as a command.  The default
266
         value is "\033\012" (ESC and C-J). */
267
      if (strchr (isearch_terminators, c))
268
#endif
269
        {
270
          /* ESC still terminates the search, but if there is pending
271
             input or if input arrives within 0.1 seconds (on systems
272
             with select(2)) it is used as a prefix character
273
             with rl_execute_next.  WATCH OUT FOR THIS!  This is intended
274
             to allow the arrow keys to be used like ^F and ^B are used
275
             to terminate the search and execute the movement command. */
276
          if (c == ESC && _rl_input_available ())       /* XXX */
277
            rl_execute_next (ESC);
278
          break;
279
        }
280
 
281
      if (c >= 0 && (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT) && c != CTRL ('G'))
282
        {
283
          rl_execute_next (c);
284
          break;
285
        }
286
 
287
      switch (c)
288
        {
289
        case -1:
290
          if (search_string_index == 0)
291
            continue;
292
          else if (reverse)
293
            --line_index;
294
          else if (line_index != sline_len)
295
            ++line_index;
296
          else
297
            ding ();
298
          break;
299
 
300
          /* switch directions */
301
        case -2:
302
          direction = -direction;
303
          reverse = direction < 0;
304
          break;
305
 
306
        case CTRL ('G'):
307
          strcpy (rl_line_buffer, lines[orig_line]);
308
          rl_point = orig_point;
309
          rl_end = strlen (rl_line_buffer);
310
          rl_restore_prompt();
311
          rl_clear_message ();
312
          if (allocated_line)
313
            free (allocated_line);
314
          free (lines);
315
          return 0;
316
 
317
#if 0
318
        /* delete character from search string. */
319
        case -3:
320
          if (search_string_index == 0)
321
            ding ();
322
          else
323
            {
324
              search_string[--search_string_index] = '\0';
325
              /* This is tricky.  To do this right, we need to keep a
326
                 stack of search positions for the current search, with
327
                 sentinels marking the beginning and end. */
328
            }
329
          break;
330
#endif
331
 
332
        default:
333
          /* Add character to search string and continue search. */
334
          if (search_string_index + 2 >= search_string_size)
335
            {
336
              search_string_size += 128;
337
              search_string = xrealloc (search_string, search_string_size);
338
            }
339
          search_string[search_string_index++] = c;
340
          search_string[search_string_index] = '\0';
341
          break;
342
        }
343
 
344
      for (found = failed = 0;;)
345
        {
346
          int limit = sline_len - search_string_index + 1;
347
 
348
          /* Search the current line. */
349
          while (reverse ? (line_index >= 0) : (line_index < limit))
350
            {
351
              if (STREQN (search_string, sline + line_index, search_string_index))
352
                {
353
                  found++;
354
                  break;
355
                }
356
              else
357
                line_index += direction;
358
            }
359
          if (found)
360
            break;
361
 
362
          /* Move to the next line, but skip new copies of the line
363
             we just found and lines shorter than the string we're
364
             searching for. */
365
          do
366
            {
367
              /* Move to the next line. */
368
              i += direction;
369
 
370
              /* At limit for direction? */
371
              if (reverse ? (i < 0) : (i == hlen))
372
                {
373
                  failed++;
374
                  break;
375
                }
376
 
377
              /* We will need these later. */
378
              sline = lines[i];
379
              sline_len = strlen (sline);
380
            }
381
          while ((prev_line_found && STREQ (prev_line_found, lines[i])) ||
382
                 (search_string_index > sline_len));
383
 
384
          if (failed)
385
            break;
386
 
387
          /* Now set up the line for searching... */
388
          line_index = reverse ? sline_len - search_string_index : 0;
389
        }
390
 
391
      if (failed)
392
        {
393
          /* We cannot find the search string.  Ding the bell. */
394
          ding ();
395
          i = last_found_line;
396
          continue;             /* XXX - was break */
397
        }
398
 
399
      /* We have found the search string.  Just display it.  But don't
400
         actually move there in the history list until the user accepts
401
         the location. */
402
      if (found)
403
        {
404
          int line_len;
405
 
406
          prev_line_found = lines[i];
407
          line_len = strlen (lines[i]);
408
 
409
          if (line_len >= rl_line_buffer_len)
410
            rl_extend_line_buffer (line_len);
411
 
412
          strcpy (rl_line_buffer, lines[i]);
413
          rl_point = line_index;
414
          rl_end = line_len;
415
          last_found_line = i;
416
          rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
417
        }
418
    }
419
 
420
  /* The searching is over.  The user may have found the string that she
421
     was looking for, or else she may have exited a failing search.  If
422
     LINE_INDEX is -1, then that shows that the string searched for was
423
     not found.  We use this to determine where to place rl_point. */
424
 
425
  /* First put back the original state. */
426
  strcpy (rl_line_buffer, lines[orig_line]);
427
 
428
  rl_restore_prompt ();
429
 
430
  /* Free the search string. */
431
  free (search_string);
432
 
433
  if (last_found_line < orig_line)
434
    rl_get_previous_history (orig_line - last_found_line, 0);
435
  else
436
    rl_get_next_history (last_found_line - orig_line, 0);
437
 
438
  /* If the string was not found, put point at the end of the line. */
439
  if (line_index < 0)
440
    line_index = strlen (rl_line_buffer);
441
  rl_point = line_index;
442
  rl_clear_message ();
443
 
444
  if (allocated_line)
445
    free (allocated_line);
446
  free (lines);
447
 
448
  return 0;
449
}

powered by: WebSVN 2.1.0

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