~ubuntu-branches/ubuntu/trusty/bash/trusty-security

« back to all changes in this revision

Viewing changes to lib/readline/search.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2014-03-03 22:52:05 UTC
  • mfrom: (1.3.5) (2.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20140303225205-87ltrt5kspeq0g1b
Tags: 4.3-1ubuntu1
* Merge with Debian; remaining changes:
  - skel.bashrc:
    - Run lesspipe.
    - Enable ls aliases.
    - Set options in ll alias to -alF.
    - Define an alert alias.
    - Enabled colored grep aliases.
  - etc.bash.bashrc:
    - Add sudo hint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* search.c - code for non-incremental searching in emacs and vi modes. */
 
2
 
 
3
/* Copyright (C) 1992-2013 Free Software Foundation, Inc.
 
4
 
 
5
   This file is part of the GNU Readline Library (Readline), a library
 
6
   for reading lines of text with interactive input and history editing.      
 
7
 
 
8
   Readline is free software: you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation, either version 3 of the License, or
 
11
   (at your option) any later version.
 
12
 
 
13
   Readline is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
 
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with Readline.  If not, see <http://www.gnu.org/licenses/>.
 
20
*/
 
21
 
 
22
#define READLINE_LIBRARY
 
23
 
 
24
#if defined (HAVE_CONFIG_H)
 
25
#  include <config.h>
 
26
#endif
 
27
 
 
28
#include <sys/types.h>
 
29
#include <stdio.h>
 
30
 
 
31
#if defined (HAVE_UNISTD_H)
 
32
#  include <unistd.h>
 
33
#endif
 
34
 
 
35
#if defined (HAVE_STDLIB_H)
 
36
#  include <stdlib.h>
 
37
#else
 
38
#  include "ansi_stdlib.h"
 
39
#endif
 
40
 
 
41
#include "rldefs.h"
 
42
#include "rlmbutil.h"
 
43
 
 
44
#include "readline.h"
 
45
#include "history.h"
 
46
#include "histlib.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 int rl_history_search_flags;
 
71
 
 
72
static char *history_search_string;
 
73
static int history_string_size;
 
74
 
 
75
static void make_history_line_current PARAMS((HIST_ENTRY *));
 
76
static int noninc_search_from_pos PARAMS((char *, int, int));
 
77
static int noninc_dosearch PARAMS((char *, int));
 
78
static int noninc_search PARAMS((int, int));
 
79
static int rl_history_search_internal PARAMS((int, int));
 
80
static void rl_history_search_reinit PARAMS((int));
 
81
 
 
82
static _rl_search_cxt *_rl_nsearch_init PARAMS((int, int));
 
83
static int _rl_nsearch_cleanup PARAMS((_rl_search_cxt *, int));
 
84
static void _rl_nsearch_abort PARAMS((_rl_search_cxt *));
 
85
static int _rl_nsearch_dispatch PARAMS((_rl_search_cxt *, int));
 
86
 
 
87
/* Make the data from the history entry ENTRY be the contents of the
 
88
   current line.  This doesn't do anything with rl_point; the caller
 
89
   must set it. */
 
90
static void
 
91
make_history_line_current (entry)
 
92
     HIST_ENTRY *entry;
 
93
{
 
94
  _rl_replace_text (entry->line, 0, rl_end);
 
95
  _rl_fix_point (1);
 
96
#if defined (VI_MODE)
 
97
  if (rl_editing_mode == vi_mode)
 
98
    /* POSIX.2 says that the `U' command doesn't affect the copy of any
 
99
       command lines to the edit line.  We're going to implement that by
 
100
       making the undo list start after the matching line is copied to the
 
101
       current editing buffer. */
 
102
    rl_free_undo_list ();
 
103
#endif
 
104
 
 
105
  if (_rl_saved_line_for_history)
 
106
    _rl_free_history_entry (_rl_saved_line_for_history);
 
107
  _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
 
108
}
 
109
 
 
110
/* Search the history list for STRING starting at absolute history position
 
111
   POS.  If STRING begins with `^', the search must match STRING at the
 
112
   beginning of a history line, otherwise a full substring match is performed
 
113
   for STRING.  DIR < 0 means to search backwards through the history list,
 
114
   DIR >= 0 means to search forward. */
 
115
static int
 
116
noninc_search_from_pos (string, pos, dir)
 
117
     char *string;
 
118
     int pos, dir;
 
119
{
 
120
  int ret, old;
 
121
 
 
122
  if (pos < 0)
 
123
    return -1;
 
124
 
 
125
  old = where_history ();
 
126
  if (history_set_pos (pos) == 0)
 
127
    return -1;
 
128
 
 
129
  RL_SETSTATE(RL_STATE_SEARCH);
 
130
  if (*string == '^')
 
131
    ret = history_search_prefix (string + 1, dir);
 
132
  else
 
133
    ret = history_search (string, dir);
 
134
  RL_UNSETSTATE(RL_STATE_SEARCH);
 
135
 
 
136
  if (ret != -1)
 
137
    ret = where_history ();
 
138
 
 
139
  history_set_pos (old);
 
140
  return (ret);
 
141
}
 
142
 
 
143
/* Search for a line in the history containing STRING.  If DIR is < 0, the
 
144
   search is backwards through previous entries, else through subsequent
 
145
   entries.  Returns 1 if the search was successful, 0 otherwise. */
 
146
static int
 
147
noninc_dosearch (string, dir)
 
148
     char *string;
 
149
     int dir;
 
150
{
 
151
  int oldpos, pos;
 
152
  HIST_ENTRY *entry;
 
153
 
 
154
  if (string == 0 || *string == '\0' || noninc_history_pos < 0)
 
155
    {
 
156
      rl_ding ();
 
157
      return 0;
 
158
    }
 
159
 
 
160
  pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
 
161
  if (pos == -1)
 
162
    {
 
163
      /* Search failed, current history position unchanged. */
 
164
      rl_maybe_unsave_line ();
 
165
      rl_clear_message ();
 
166
      rl_point = 0;
 
167
      rl_ding ();
 
168
      return 0;
 
169
    }
 
170
 
 
171
  noninc_history_pos = pos;
 
172
 
 
173
  oldpos = where_history ();
 
174
  history_set_pos (noninc_history_pos);
 
175
  entry = current_history ();           /* will never be NULL after successful search */
 
176
  
 
177
#if defined (VI_MODE)
 
178
  if (rl_editing_mode != vi_mode)
 
179
#endif
 
180
    history_set_pos (oldpos);
 
181
 
 
182
  make_history_line_current (entry);
 
183
 
 
184
  rl_point = 0;
 
185
  rl_mark = rl_end;
 
186
 
 
187
  rl_clear_message ();
 
188
  return 1;
 
189
}
 
190
 
 
191
static _rl_search_cxt *
 
192
_rl_nsearch_init (dir, pchar)
 
193
     int dir, pchar;
 
194
{
 
195
  _rl_search_cxt *cxt;
 
196
  char *p;
 
197
 
 
198
  cxt = _rl_scxt_alloc (RL_SEARCH_NSEARCH, 0);
 
199
  if (dir < 0)
 
200
    cxt->sflags |= SF_REVERSE;          /* not strictly needed */
 
201
 
 
202
  cxt->direction = dir;
 
203
  cxt->history_pos = cxt->save_line;
 
204
 
 
205
  rl_maybe_save_line ();
 
206
 
 
207
  /* Clear the undo list, since reading the search string should create its
 
208
     own undo list, and the whole list will end up being freed when we
 
209
     finish reading the search string. */
 
210
  rl_undo_list = 0;
 
211
 
 
212
  /* Use the line buffer to read the search string. */
 
213
  rl_line_buffer[0] = 0;
 
214
  rl_end = rl_point = 0;
 
215
 
 
216
  p = _rl_make_prompt_for_search (pchar ? pchar : ':');
 
217
  rl_message ("%s", p);
 
218
  xfree (p);
 
219
 
 
220
  RL_SETSTATE(RL_STATE_NSEARCH);
 
221
 
 
222
  _rl_nscxt = cxt;
 
223
 
 
224
  return cxt;
 
225
}
 
226
 
 
227
static int
 
228
_rl_nsearch_cleanup (cxt, r)
 
229
     _rl_search_cxt *cxt;
 
230
     int r;
 
231
{
 
232
  _rl_scxt_dispose (cxt, 0);
 
233
  _rl_nscxt = 0;
 
234
 
 
235
  RL_UNSETSTATE(RL_STATE_NSEARCH);
 
236
 
 
237
  return (r != 1);
 
238
}
 
239
 
 
240
static void
 
241
_rl_nsearch_abort (cxt)
 
242
     _rl_search_cxt *cxt;
 
243
{
 
244
  rl_maybe_unsave_line ();
 
245
  rl_clear_message ();
 
246
  rl_point = cxt->save_point;
 
247
  rl_mark = cxt->save_mark;
 
248
  rl_restore_prompt ();
 
249
 
 
250
  RL_UNSETSTATE (RL_STATE_NSEARCH);
 
251
}
 
252
 
 
253
/* Process just-read character C according to search context CXT.  Return -1
 
254
   if the caller should abort the search, 0 if we should break out of the
 
255
   loop, and 1 if we should continue to read characters. */
 
256
static int
 
257
_rl_nsearch_dispatch (cxt, c)
 
258
     _rl_search_cxt *cxt;
 
259
     int c;
 
260
{
 
261
  switch (c)
 
262
    {
 
263
    case CTRL('W'):
 
264
      rl_unix_word_rubout (1, c);
 
265
      break;
 
266
 
 
267
    case CTRL('U'):
 
268
      rl_unix_line_discard (1, c);
 
269
      break;
 
270
 
 
271
    case RETURN:
 
272
    case NEWLINE:
 
273
      return 0;
 
274
 
 
275
    case CTRL('H'):
 
276
    case RUBOUT:
 
277
      if (rl_point == 0)
 
278
        {
 
279
          _rl_nsearch_abort (cxt);
 
280
          return -1;
 
281
        }
 
282
      _rl_rubout_char (1, c);
 
283
      break;
 
284
 
 
285
    case CTRL('C'):
 
286
    case CTRL('G'):
 
287
      rl_ding ();
 
288
      _rl_nsearch_abort (cxt);
 
289
      return -1;
 
290
 
 
291
    default:
 
292
#if defined (HANDLE_MULTIBYTE)
 
293
      if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
 
294
        rl_insert_text (cxt->mb);
 
295
      else
 
296
#endif
 
297
        _rl_insert_char (1, c);
 
298
      break;
 
299
    }
 
300
 
 
301
  (*rl_redisplay_function) ();
 
302
  return 1;
 
303
}
 
304
 
 
305
/* Perform one search according to CXT, using NONINC_SEARCH_STRING.  Return
 
306
   -1 if the search should be aborted, any other value means to clean up
 
307
   using _rl_nsearch_cleanup ().  Returns 1 if the search was successful,
 
308
   0 otherwise. */
 
309
static int
 
310
_rl_nsearch_dosearch (cxt)
 
311
     _rl_search_cxt *cxt;
 
312
{
 
313
  rl_mark = cxt->save_mark;
 
314
 
 
315
  /* If rl_point == 0, we want to re-use the previous search string and
 
316
     start from the saved history position.  If there's no previous search
 
317
     string, punt. */
 
318
  if (rl_point == 0)
 
319
    {
 
320
      if (noninc_search_string == 0)
 
321
        {
 
322
          rl_ding ();
 
323
          rl_restore_prompt ();
 
324
          RL_UNSETSTATE (RL_STATE_NSEARCH);
 
325
          return -1;
 
326
        }
 
327
    }
 
328
  else
 
329
    {
 
330
      /* We want to start the search from the current history position. */
 
331
      noninc_history_pos = cxt->save_line;
 
332
      FREE (noninc_search_string);
 
333
      noninc_search_string = savestring (rl_line_buffer);
 
334
 
 
335
      /* If we don't want the subsequent undo list generated by the search
 
336
         matching a history line to include the contents of the search string,
 
337
         we need to clear rl_line_buffer here.  For now, we just clear the
 
338
         undo list generated by reading the search string.  (If the search
 
339
         fails, the old undo list will be restored by rl_maybe_unsave_line.) */
 
340
      rl_free_undo_list ();
 
341
    }
 
342
 
 
343
  rl_restore_prompt ();
 
344
  return (noninc_dosearch (noninc_search_string, cxt->direction));
 
345
}
 
346
 
 
347
/* Search non-interactively through the history list.  DIR < 0 means to
 
348
   search backwards through the history of previous commands; otherwise
 
349
   the search is for commands subsequent to the current position in the
 
350
   history list.  PCHAR is the character to use for prompting when reading
 
351
   the search string; if not specified (0), it defaults to `:'. */
 
352
static int
 
353
noninc_search (dir, pchar)
 
354
     int dir;
 
355
     int pchar;
 
356
{
 
357
  _rl_search_cxt *cxt;
 
358
  int c, r;
 
359
 
 
360
  cxt = _rl_nsearch_init (dir, pchar);
 
361
 
 
362
  if (RL_ISSTATE (RL_STATE_CALLBACK))
 
363
    return (0);
 
364
 
 
365
  /* Read the search string. */
 
366
  r = 0;
 
367
  while (1)
 
368
    {
 
369
      c = _rl_search_getchar (cxt);
 
370
 
 
371
      if (c == 0)
 
372
        break;
 
373
 
 
374
      r = _rl_nsearch_dispatch (cxt, c);
 
375
      if (r < 0)
 
376
        return 1;
 
377
      else if (r == 0)
 
378
        break;        
 
379
    }
 
380
 
 
381
  r = _rl_nsearch_dosearch (cxt);
 
382
  return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
 
383
}
 
384
 
 
385
/* Search forward through the history list for a string.  If the vi-mode
 
386
   code calls this, KEY will be `?'. */
 
387
int
 
388
rl_noninc_forward_search (count, key)
 
389
     int count, key;
 
390
{
 
391
  return noninc_search (1, (key == '?') ? '?' : 0);
 
392
}
 
393
 
 
394
/* Reverse search the history list for a string.  If the vi-mode code
 
395
   calls this, KEY will be `/'. */
 
396
int
 
397
rl_noninc_reverse_search (count, key)
 
398
     int count, key;
 
399
{
 
400
  return noninc_search (-1, (key == '/') ? '/' : 0);
 
401
}
 
402
 
 
403
/* Search forward through the history list for the last string searched
 
404
   for.  If there is no saved search string, abort. */
 
405
int
 
406
rl_noninc_forward_search_again (count, key)
 
407
     int count, key;
 
408
{
 
409
  int r;
 
410
 
 
411
  if (!noninc_search_string)
 
412
    {
 
413
      rl_ding ();
 
414
      return (-1);
 
415
    }
 
416
  r = noninc_dosearch (noninc_search_string, 1);
 
417
  return (r != 1);
 
418
}
 
419
 
 
420
/* Reverse search in the history list for the last string searched
 
421
   for.  If there is no saved search string, abort. */
 
422
int
 
423
rl_noninc_reverse_search_again (count, key)
 
424
     int count, key;
 
425
{
 
426
  int r;
 
427
 
 
428
  if (!noninc_search_string)
 
429
    {
 
430
      rl_ding ();
 
431
      return (-1);
 
432
    }
 
433
  r = noninc_dosearch (noninc_search_string, -1);
 
434
  return (r != 1);
 
435
}
 
436
 
 
437
#if defined (READLINE_CALLBACKS)
 
438
int
 
439
_rl_nsearch_callback (cxt)
 
440
     _rl_search_cxt *cxt;
 
441
{
 
442
  int c, r;
 
443
 
 
444
  c = _rl_search_getchar (cxt);
 
445
  r = _rl_nsearch_dispatch (cxt, c);
 
446
  if (r != 0)
 
447
    return 1;
 
448
 
 
449
  r = _rl_nsearch_dosearch (cxt);
 
450
  return ((r >= 0) ? _rl_nsearch_cleanup (cxt, r) : (r != 1));
 
451
}
 
452
#endif
 
453
  
 
454
static int
 
455
rl_history_search_internal (count, dir)
 
456
     int count, dir;
 
457
{
 
458
  HIST_ENTRY *temp;
 
459
  int ret, oldpos;
 
460
  char *t;
 
461
 
 
462
  rl_maybe_save_line ();
 
463
  temp = (HIST_ENTRY *)NULL;
 
464
 
 
465
  /* Search COUNT times through the history for a line matching
 
466
     history_search_string.  If history_search_string[0] == '^', the
 
467
     line must match from the start; otherwise any substring can match.
 
468
     When this loop finishes, TEMP, if non-null, is the history line to
 
469
     copy into the line buffer. */
 
470
  while (count)
 
471
    {
 
472
      RL_CHECK_SIGNALS ();
 
473
      ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
 
474
      if (ret == -1)
 
475
        break;
 
476
 
 
477
      /* Get the history entry we found. */
 
478
      rl_history_search_pos = ret;
 
479
      oldpos = where_history ();
 
480
      history_set_pos (rl_history_search_pos);
 
481
      temp = current_history ();        /* will never be NULL after successful search */
 
482
      history_set_pos (oldpos);
 
483
 
 
484
      /* Don't find multiple instances of the same line. */
 
485
      if (prev_line_found && STREQ (prev_line_found, temp->line))
 
486
        continue;
 
487
      prev_line_found = temp->line;
 
488
      count--;
 
489
    }
 
490
 
 
491
  /* If we didn't find anything at all, return. */
 
492
  if (temp == 0)
 
493
    {
 
494
      rl_maybe_unsave_line ();
 
495
      rl_ding ();
 
496
      /* If you don't want the saved history line (last match) to show up
 
497
         in the line buffer after the search fails, change the #if 0 to
 
498
         #if 1 */
 
499
#if 0
 
500
      if (rl_point > rl_history_search_len)
 
501
        {
 
502
          rl_point = rl_end = rl_history_search_len;
 
503
          rl_line_buffer[rl_end] = '\0';
 
504
          rl_mark = 0;
 
505
        }
 
506
#else
 
507
      rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
 
508
      rl_mark = rl_end;
 
509
#endif
 
510
      return 1;
 
511
    }
 
512
 
 
513
  /* Copy the line we found into the current line buffer. */
 
514
  make_history_line_current (temp);
 
515
 
 
516
  if (rl_history_search_flags & ANCHORED_SEARCH)
 
517
    rl_point = rl_history_search_len;   /* easy case */
 
518
  else
 
519
    {
 
520
      t = strstr (rl_line_buffer, history_search_string);
 
521
      rl_point = t ? (int)(t - rl_line_buffer) + rl_history_search_len : rl_end;
 
522
    }
 
523
  rl_mark = rl_end;
 
524
 
 
525
  return 0;
 
526
}
 
527
 
 
528
static void
 
529
rl_history_search_reinit (flags)
 
530
     int flags;
 
531
{
 
532
  int sind;
 
533
 
 
534
  rl_history_search_pos = where_history ();
 
535
  rl_history_search_len = rl_point;
 
536
  rl_history_search_flags = flags;
 
537
 
 
538
  prev_line_found = (char *)NULL;
 
539
  if (rl_point)
 
540
    {
 
541
      /* Allocate enough space for anchored and non-anchored searches */
 
542
      if (rl_history_search_len >= history_string_size - 2)
 
543
        {
 
544
          history_string_size = rl_history_search_len + 2;
 
545
          history_search_string = (char *)xrealloc (history_search_string, history_string_size);
 
546
        }
 
547
      sind = 0;
 
548
      if (flags & ANCHORED_SEARCH)
 
549
        history_search_string[sind++] = '^';
 
550
      strncpy (history_search_string + sind, rl_line_buffer, rl_point);
 
551
      history_search_string[rl_point + sind] = '\0';
 
552
    }
 
553
  _rl_free_saved_history_line ();
 
554
}
 
555
 
 
556
/* Search forward in the history for the string of characters
 
557
   from the start of the line to rl_point.  This is a non-incremental
 
558
   search.  The search is anchored to the beginning of the history line. */
 
559
int
 
560
rl_history_search_forward (count, ignore)
 
561
     int count, ignore;
 
562
{
 
563
  if (count == 0)
 
564
    return (0);
 
565
 
 
566
  if (rl_last_func != rl_history_search_forward &&
 
567
      rl_last_func != rl_history_search_backward)
 
568
    rl_history_search_reinit (ANCHORED_SEARCH);
 
569
 
 
570
  if (rl_history_search_len == 0)
 
571
    return (rl_get_next_history (count, ignore));
 
572
  return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
 
573
}
 
574
 
 
575
/* Search backward through the history for the string of characters
 
576
   from the start of the line to rl_point.  This is a non-incremental
 
577
   search. */
 
578
int
 
579
rl_history_search_backward (count, ignore)
 
580
     int count, ignore;
 
581
{
 
582
  if (count == 0)
 
583
    return (0);
 
584
 
 
585
  if (rl_last_func != rl_history_search_forward &&
 
586
      rl_last_func != rl_history_search_backward)
 
587
    rl_history_search_reinit (ANCHORED_SEARCH);
 
588
 
 
589
  if (rl_history_search_len == 0)
 
590
    return (rl_get_previous_history (count, ignore));
 
591
  return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
 
592
}
 
593
 
 
594
/* Search forward in the history for the string of characters
 
595
   from the start of the line to rl_point.  This is a non-incremental
 
596
   search.  The search succeeds if the search string is present anywhere
 
597
   in the history line. */
 
598
int
 
599
rl_history_substr_search_forward (count, ignore)
 
600
     int count, ignore;
 
601
{
 
602
  if (count == 0)
 
603
    return (0);
 
604
 
 
605
  if (rl_last_func != rl_history_substr_search_forward &&
 
606
      rl_last_func != rl_history_substr_search_backward)
 
607
    rl_history_search_reinit (NON_ANCHORED_SEARCH);
 
608
 
 
609
  if (rl_history_search_len == 0)
 
610
    return (rl_get_next_history (count, ignore));
 
611
  return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
 
612
}
 
613
 
 
614
/* Search backward through the history for the string of characters
 
615
   from the start of the line to rl_point.  This is a non-incremental
 
616
   search. */
 
617
int
 
618
rl_history_substr_search_backward (count, ignore)
 
619
     int count, ignore;
 
620
{
 
621
  if (count == 0)
 
622
    return (0);
 
623
 
 
624
  if (rl_last_func != rl_history_substr_search_forward &&
 
625
      rl_last_func != rl_history_substr_search_backward)
 
626
    rl_history_search_reinit (NON_ANCHORED_SEARCH);
 
627
 
 
628
  if (rl_history_search_len == 0)
 
629
    return (rl_get_previous_history (count, ignore));
 
630
  return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
 
631
}