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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gdb/] [gdb-6.8/] [readline/] [search.c] - Blame information for rev 26

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 26 jlechner
/* search.c - code for non-incremental searching in emacs and vi modes. */
2
 
3
/* Copyright (C) 1992-2005 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 "rlmbutil.h"
44
 
45
#include "readline.h"
46
#include "history.h"
47
 
48
#include "rlprivate.h"
49
#include "xmalloc.h"
50
 
51
#ifdef abs
52
#  undef abs
53
#endif
54
#define abs(x)          (((x) >= 0) ? (x) : -(x))
55
 
56
_rl_search_cxt *_rl_nscxt = 0;
57
 
58
extern HIST_ENTRY *_rl_saved_line_for_history;
59
 
60
/* Functions imported from the rest of the library. */
61
extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
62
 
63
static char *noninc_search_string = (char *) NULL;
64
static int noninc_history_pos;
65
 
66
static char *prev_line_found = (char *) NULL;
67
 
68
static int rl_history_search_len;
69
static int rl_history_search_pos;
70
static char *history_search_string;
71
static int history_string_size;
72
 
73
static UNDO_LIST *noninc_saved_undo_list;
74
static void make_history_line_current PARAMS((HIST_ENTRY *));
75
static int noninc_search_from_pos PARAMS((char *, int, int));
76
static int noninc_dosearch PARAMS((char *, int));
77
static int noninc_search PARAMS((int, int));
78
static int rl_history_search_internal PARAMS((int, int));
79
static void rl_history_search_reinit PARAMS((void));
80
 
81
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
82
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
83
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
84
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
85
 
86
/* Make the data from the history entry ENTRY be the contents of the
87
   current line.  This doesn't do anything with rl_point; the caller
88
   must set it. */
89
static void
90
make_history_line_current (entry)
91
     HIST_ENTRY *entry;
92
{
93
  _rl_replace_text (entry->line, 0, rl_end);
94
  _rl_fix_point (1);
95
#if defined (VI_MODE)
96
  if (rl_editing_mode == vi_mode)
97
    /* POSIX.2 says that the `U' command doesn't affect the copy of any
98
       command lines to the edit line.  We're going to implement that by
99
       making the undo list start after the matching line is copied to the
100
       current editing buffer. */
101
    rl_free_undo_list ();
102
#endif
103
 
104
  if (_rl_saved_line_for_history)
105
    _rl_free_history_entry (_rl_saved_line_for_history);
106
  _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
107
}
108
 
109
/* Search the history list for STRING starting at absolute history position
110
   POS.  If STRING begins with `^', the search must match STRING at the
111
   beginning of a history line, otherwise a full substring match is performed
112
   for STRING.  DIR < 0 means to search backwards through the history list,
113
   DIR >= 0 means to search forward. */
114
static int
115
noninc_search_from_pos (string, pos, dir)
116
     char *string;
117
     int pos, dir;
118
{
119
  int ret, old;
120
 
121
  if (pos < 0)
122
    return -1;
123
 
124
  old = where_history ();
125
  if (history_set_pos (pos) == 0)
126
    return -1;
127
 
128
  RL_SETSTATE(RL_STATE_SEARCH);
129
  if (*string == '^')
130
    ret = history_search_prefix (string + 1, dir);
131
  else
132
    ret = history_search (string, dir);
133
  RL_UNSETSTATE(RL_STATE_SEARCH);
134
 
135
  if (ret != -1)
136
    ret = where_history ();
137
 
138
  history_set_pos (old);
139
  return (ret);
140
}
141
 
142
/* Search for a line in the history containing STRING.  If DIR is < 0, the
143
   search is backwards through previous entries, else through subsequent
144
   entries.  Returns 1 if the search was successful, 0 otherwise. */
145
static int
146
noninc_dosearch (string, dir)
147
     char *string;
148
     int dir;
149
{
150
  int oldpos, pos;
151
  HIST_ENTRY *entry;
152
 
153
  if (string == 0 || *string == '\0' || noninc_history_pos < 0)
154
    {
155
      rl_ding ();
156
      return 0;
157
    }
158
 
159
  pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
160
  if (pos == -1)
161
    {
162
      /* Search failed, current history position unchanged. */
163
      rl_maybe_unsave_line ();
164
      rl_clear_message ();
165
      rl_point = 0;
166
      rl_ding ();
167
      return 0;
168
    }
169
 
170
  noninc_history_pos = pos;
171
 
172
  oldpos = where_history ();
173
  history_set_pos (noninc_history_pos);
174
  entry = current_history ();
175
#if defined (VI_MODE)
176
  if (rl_editing_mode != vi_mode)
177
#endif
178
    history_set_pos (oldpos);
179
 
180
  make_history_line_current (entry);
181
 
182
  rl_point = 0;
183
  rl_mark = rl_end;
184
 
185
  rl_clear_message ();
186
  return 1;
187
}
188
 
189
static _rl_search_cxt *
190
_rl_nsearch_init (dir, pchar)
191
     int dir, pchar;
192
{
193
  _rl_search_cxt *cxt;
194
  char *p;
195
 
196
  cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
197
  if (dir < 0)
198
    cxt->sflags |= SF_REVERSE;          /* not strictly needed */
199
 
200
  cxt->direction = dir;
201
  cxt->history_pos = cxt->save_line;
202
 
203
  rl_maybe_save_line ();
204
 
205
  /* Clear the undo list, since reading the search string should create its
206
     own undo list, and the whole list will end up being freed when we
207
     finish reading the search string. */
208
  rl_undo_list = 0;
209
 
210
  /* Use the line buffer to read the search string. */
211
  rl_line_buffer[0] = 0;
212
  rl_end = rl_point = 0;
213
 
214
  p = _rl_make_prompt_for_search (pchar ? pchar : ':');
215
  rl_message (p, 0, 0);
216
  free (p);
217
 
218
  RL_SETSTATE(RL_STATE_NSEARCH);
219
 
220
  _rl_nscxt = cxt;
221
 
222
  return cxt;
223
}
224
 
225
static int
226
_rl_nsearch_cleanup (cxt, r)
227
     _rl_search_cxt *cxt;
228
     int r;
229
{
230
  _rl_scxt_dispose (cxt, 0);
231
  _rl_nscxt = 0;
232
 
233
  RL_UNSETSTATE(RL_STATE_NSEARCH);
234
 
235
  return (r != 1);
236
}
237
 
238
static void
239
_rl_nsearch_abort (cxt)
240
     _rl_search_cxt *cxt;
241
{
242
  rl_maybe_unsave_line ();
243
  rl_clear_message ();
244
  rl_point = cxt->save_point;
245
  rl_mark = cxt->save_mark;
246
  rl_restore_prompt ();
247
 
248
  RL_UNSETSTATE (RL_STATE_NSEARCH);
249
}
250
 
251
/* Process just-read character C according to search context CXT.  Return -1
252
   if the caller should abort the search, 0 if we should break out of the
253
   loop, and 1 if we should continue to read characters. */
254
static int
255
_rl_nsearch_dispatch (cxt, c)
256
     _rl_search_cxt *cxt;
257
     int c;
258
{
259
  switch (c)
260
    {
261
    case CTRL('W'):
262
      rl_unix_word_rubout (1, c);
263
      break;
264
 
265
    case CTRL('U'):
266
      rl_unix_line_discard (1, c);
267
      break;
268
 
269
    case RETURN:
270
    case NEWLINE:
271
      return 0;
272
 
273
    case CTRL('H'):
274
    case RUBOUT:
275
      if (rl_point == 0)
276
        {
277
          _rl_nsearch_abort (cxt);
278
          return -1;
279
        }
280
      _rl_rubout_char (1, c);
281
      break;
282
 
283
    case CTRL('C'):
284
    case CTRL('G'):
285
      rl_ding ();
286
      _rl_nsearch_abort (cxt);
287
      return -1;
288
 
289
    default:
290
#if defined (HANDLE_MULTIBYTE)
291
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
292
        rl_insert_text (cxt->mb);
293
      else
294
#endif
295
        _rl_insert_char (1, c);
296
      break;
297
    }
298
 
299
  (*rl_redisplay_function) ();
300
  return 1;
301
}
302
 
303
/* Perform one search according to CXT, using NONINC_SEARCH_STRING.  Return
304
   -1 if the search should be aborted, any other value means to clean up
305
   using _rl_nsearch_cleanup ().  Returns 1 if the search was successful,
306
 
307
static int
308
_rl_nsearch_dosearch (cxt)
309
     _rl_search_cxt *cxt;
310
{
311
  rl_mark = cxt->save_mark;
312
 
313
  /* If rl_point == 0, we want to re-use the previous search string and
314
     start from the saved history position.  If there's no previous search
315
     string, punt. */
316
  if (rl_point == 0)
317
    {
318
      if (noninc_search_string == 0)
319
        {
320
          rl_ding ();
321
          rl_restore_prompt ();
322
          RL_UNSETSTATE (RL_STATE_NSEARCH);
323
          return -1;
324
        }
325
    }
326
  else
327
    {
328
      /* We want to start the search from the current history position. */
329
      noninc_history_pos = cxt->save_line;
330
      FREE (noninc_search_string);
331
      noninc_search_string = savestring (rl_line_buffer);
332
 
333
      /* If we don't want the subsequent undo list generated by the search
334
         matching a history line to include the contents of the search string,
335
         we need to clear rl_line_buffer here.  For now, we just clear the
336
         undo list generated by reading the search string.  (If the search
337
         fails, the old undo list will be restored by rl_maybe_unsave_line.) */
338
      rl_free_undo_list ();
339
    }
340
 
341
  rl_restore_prompt ();
342
  return (noninc_dosearch (noninc_search_string, cxt->direction));
343
}
344
 
345
/* Search non-interactively through the history list.  DIR < 0 means to
346
   search backwards through the history of previous commands; otherwise
347
   the search is for commands subsequent to the current position in the
348
   history list.  PCHAR is the character to use for prompting when reading
349
   the search string; if not specified (0), it defaults to `:'. */
350
static int
351
noninc_search (dir, pchar)
352
     int dir;
353
     int pchar;
354
{
355
  _rl_search_cxt *cxt;
356
  int c, r;
357
 
358
  cxt = _rl_nsearch_init (dir, pchar);
359
 
360
  if (RL_ISSTATE (RL_STATE_CALLBACK))
361
    return (0);
362
 
363
  /* Read the search string. */
364
  r = 0;
365
  while (1)
366
    {
367
      c = _rl_search_getchar (cxt);
368
 
369
      if (c == 0)
370
        break;
371
 
372
      r = _rl_nsearch_dispatch (cxt, c);
373
      if (r < 0)
374
        return 1;
375
      else if (r == 0)
376
        break;
377
    }
378
 
379
  r = _rl_nsearch_dosearch (cxt);
380
  return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
381
}
382
 
383
/* Search forward through the history list for a string.  If the vi-mode
384
   code calls this, KEY will be `?'. */
385
int
386
rl_noninc_forward_search (count, key)
387
     int count, key;
388
{
389
  return noninc_search (1, (key == '?') ? '?' : 0);
390
}
391
 
392
/* Reverse search the history list for a string.  If the vi-mode code
393
   calls this, KEY will be `/'. */
394
int
395
rl_noninc_reverse_search (count, key)
396
     int count, key;
397
{
398
  return noninc_search (-1, (key == '/') ? '/' : 0);
399
}
400
 
401
/* Search forward through the history list for the last string searched
402
   for.  If there is no saved search string, abort. */
403
int
404
rl_noninc_forward_search_again (count, key)
405
     int count, key;
406
{
407
  int r;
408
 
409
  if (!noninc_search_string)
410
    {
411
      rl_ding ();
412
      return (-1);
413
    }
414
  r = noninc_dosearch (noninc_search_string, 1);
415
  return (r != 1);
416
}
417
 
418
/* Reverse search in the history list for the last string searched
419
   for.  If there is no saved search string, abort. */
420
int
421
rl_noninc_reverse_search_again (count, key)
422
     int count, key;
423
{
424
  int r;
425
 
426
  if (!noninc_search_string)
427
    {
428
      rl_ding ();
429
      return (-1);
430
    }
431
  r = noninc_dosearch (noninc_search_string, -1);
432
  return (r != 1);
433
}
434
 
435
#if defined (READLINE_CALLBACKS)
436
int
437
_rl_nsearch_callback (cxt)
438
     _rl_search_cxt *cxt;
439
{
440
  int c, r;
441
 
442
  c = _rl_search_getchar (cxt);
443
  r = _rl_nsearch_dispatch (cxt, c);
444
  if (r != 0)
445
    return 1;
446
 
447
  r = _rl_nsearch_dosearch (cxt);
448
  return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
449
}
450
#endif
451
 
452
static int
453
rl_history_search_internal (count, dir)
454
     int count, dir;
455
{
456
  HIST_ENTRY *temp;
457
  int ret, oldpos;
458
 
459
  rl_maybe_save_line ();
460
  temp = (HIST_ENTRY *)NULL;
461
 
462
  /* Search COUNT times through the history for a line whose prefix
463
     matches history_search_string.  When this loop finishes, TEMP,
464
     if non-null, is the history line to copy into the line buffer. */
465
  while (count)
466
    {
467
      ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
468
      if (ret == -1)
469
        break;
470
 
471
      /* Get the history entry we found. */
472
      rl_history_search_pos = ret;
473
      oldpos = where_history ();
474
      history_set_pos (rl_history_search_pos);
475
      temp = current_history ();
476
      history_set_pos (oldpos);
477
 
478
      /* Don't find multiple instances of the same line. */
479
      if (prev_line_found && STREQ (prev_line_found, temp->line))
480
        continue;
481
      prev_line_found = temp->line;
482
      count--;
483
    }
484
 
485
  /* If we didn't find anything at all, return. */
486
  if (temp == 0)
487
    {
488
      rl_maybe_unsave_line ();
489
      rl_ding ();
490
      /* If you don't want the saved history line (last match) to show up
491
         in the line buffer after the search fails, change the #if 0 to
492
         #if 1 */
493
#if 0
494
      if (rl_point > rl_history_search_len)
495
        {
496
          rl_point = rl_end = rl_history_search_len;
497
          rl_line_buffer[rl_end] = '\0';
498
          rl_mark = 0;
499
        }
500
#else
501
      rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
502
      rl_mark = rl_end;
503
#endif
504
      return 1;
505
    }
506
 
507
  /* Copy the line we found into the current line buffer. */
508
  make_history_line_current (temp);
509
 
510
  rl_point = rl_history_search_len;
511
  rl_mark = rl_end;
512
 
513
  return 0;
514
}
515
 
516
static void
517
rl_history_search_reinit ()
518
{
519
  rl_history_search_pos = where_history ();
520
  rl_history_search_len = rl_point;
521
  prev_line_found = (char *)NULL;
522
  if (rl_point)
523
    {
524
      if (rl_history_search_len >= history_string_size - 2)
525
        {
526
          history_string_size = rl_history_search_len + 2;
527
          history_search_string = (char *)xrealloc (history_search_string, history_string_size);
528
        }
529
      history_search_string[0] = '^';
530
      strncpy (history_search_string + 1, rl_line_buffer, rl_point);
531
      history_search_string[rl_point + 1] = '\0';
532
    }
533
  _rl_free_saved_history_line ();
534
}
535
 
536
/* Search forward in the history for the string of characters
537
   from the start of the line to rl_point.  This is a non-incremental
538
   search. */
539
int
540
rl_history_search_forward (count, ignore)
541
     int count, ignore;
542
{
543
  if (count == 0)
544
    return (0);
545
 
546
  if (rl_last_func != rl_history_search_forward &&
547
      rl_last_func != rl_history_search_backward)
548
    rl_history_search_reinit ();
549
 
550
  if (rl_history_search_len == 0)
551
    return (rl_get_next_history (count, ignore));
552
  return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
553
}
554
 
555
/* Search backward through the history for the string of characters
556
   from the start of the line to rl_point.  This is a non-incremental
557
   search. */
558
int
559
rl_history_search_backward (count, ignore)
560
     int count, ignore;
561
{
562
  if (count == 0)
563
    return (0);
564
 
565
  if (rl_last_func != rl_history_search_forward &&
566
      rl_last_func != rl_history_search_backward)
567
    rl_history_search_reinit ();
568
 
569
  if (rl_history_search_len == 0)
570
    return (rl_get_previous_history (count, ignore));
571
  return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
572
}

powered by: WebSVN 2.1.0

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