~ubuntu-branches/ubuntu/oneiric/ecasound2.2/oneiric

« back to all changes in this revision

Viewing changes to readline-4.0/search.c

  • Committer: Bazaar Package Importer
  • Author(s): Junichi Uekawa
  • Date: 2008-03-23 21:42:49 UTC
  • mfrom: (3.1.6 hardy)
  • Revision ID: james.westby@ubuntu.com-20080323214249-evlfv3y1o8q747la
Tags: 2.4.6.1-2
* Bug fix: "FTBFS with GCC 4.3: missing #includes", thanks to Martin
  Michlmayr (Closes: #454890).
- 13_gcc4: updated

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 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
 
#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
 
#ifdef abs
47
 
#  undef abs
48
 
#endif
49
 
#define abs(x)          (((x) >= 0) ? (x) : -(x))
50
 
 
51
 
extern char *xmalloc (), *xrealloc ();
52
 
 
53
 
/* Variables imported from readline.c */
54
 
extern int rl_point, rl_end, rl_line_buffer_len;
55
 
extern int rl_editing_mode;
56
 
extern char *rl_prompt;
57
 
extern char *rl_line_buffer;
58
 
extern HIST_ENTRY *saved_line_for_history;
59
 
extern Function *rl_last_func;
60
 
 
61
 
/* Functions imported from the rest of the library. */
62
 
extern int _rl_free_history_entry ();
63
 
extern char *_rl_make_prompt_for_search ();
64
 
extern void rl_extend_line_buffer ();
65
 
 
66
 
static char *noninc_search_string = (char *) NULL;
67
 
static int noninc_history_pos;
68
 
static char *prev_line_found = (char *) NULL;
69
 
 
70
 
/* Search the history list for STRING starting at absolute history position
71
 
   POS.  If STRING begins with `^', the search must match STRING at the
72
 
   beginning of a history line, otherwise a full substring match is performed
73
 
   for STRING.  DIR < 0 means to search backwards through the history list,
74
 
   DIR >= 0 means to search forward. */
75
 
static int
76
 
noninc_search_from_pos (string, pos, dir)
77
 
     char *string;
78
 
     int pos, dir;
79
 
{
80
 
  int ret, old;
81
 
 
82
 
  old = where_history ();
83
 
  history_set_pos (pos);
84
 
 
85
 
  if (*string == '^')
86
 
    ret = history_search_prefix (string + 1, dir);
87
 
  else
88
 
    ret = history_search (string, dir);
89
 
 
90
 
  if (ret != -1)
91
 
    ret = where_history ();
92
 
 
93
 
  history_set_pos (old);
94
 
  return (ret);
95
 
}
96
 
 
97
 
/* Search for a line in the history containing STRING.  If DIR is < 0, the
98
 
   search is backwards through previous entries, else through subsequent
99
 
   entries. */
100
 
static void
101
 
noninc_dosearch (string, dir)
102
 
     char *string;
103
 
     int dir;
104
 
{
105
 
  int oldpos, pos, line_len;
106
 
  HIST_ENTRY *entry;
107
 
 
108
 
  if (string == 0 || *string == '\0' || noninc_history_pos < 0)
109
 
    {
110
 
      ding ();
111
 
      return;
112
 
    }
113
 
 
114
 
  pos = noninc_search_from_pos (string, noninc_history_pos + dir, dir);
115
 
  if (pos == -1)
116
 
    {
117
 
      /* Search failed, current history position unchanged. */
118
 
      maybe_unsave_line ();
119
 
      rl_clear_message ();
120
 
      rl_point = 0;
121
 
      ding ();
122
 
      return;
123
 
    }
124
 
 
125
 
  noninc_history_pos = pos;
126
 
 
127
 
  oldpos = where_history ();
128
 
  history_set_pos (noninc_history_pos);
129
 
  entry = current_history ();
130
 
#if defined (VI_MODE)
131
 
  if (rl_editing_mode != vi_mode)
132
 
#endif
133
 
  history_set_pos (oldpos);
134
 
 
135
 
  line_len = strlen (entry->line);
136
 
  if (line_len >= rl_line_buffer_len)
137
 
    rl_extend_line_buffer (line_len);
138
 
  strcpy (rl_line_buffer, entry->line);
139
 
 
140
 
  rl_undo_list = (UNDO_LIST *)entry->data;
141
 
  rl_end = strlen (rl_line_buffer);
142
 
  rl_point = 0;
143
 
  rl_clear_message ();
144
 
 
145
 
  if (saved_line_for_history)
146
 
    _rl_free_history_entry (saved_line_for_history);
147
 
  saved_line_for_history = (HIST_ENTRY *)NULL;
148
 
}
149
 
 
150
 
/* Search non-interactively through the history list.  DIR < 0 means to
151
 
   search backwards through the history of previous commands; otherwise
152
 
   the search is for commands subsequent to the current position in the
153
 
   history list.  PCHAR is the character to use for prompting when reading
154
 
   the search string; if not specified (0), it defaults to `:'. */
155
 
static void
156
 
noninc_search (dir, pchar)
157
 
     int dir;
158
 
     int pchar;
159
 
{
160
 
  int saved_point, c;
161
 
  char *p;
162
 
 
163
 
  maybe_save_line ();
164
 
  saved_point = rl_point;
165
 
 
166
 
  /* Use the line buffer to read the search string. */
167
 
  rl_line_buffer[0] = 0;
168
 
  rl_end = rl_point = 0;
169
 
 
170
 
  p = _rl_make_prompt_for_search (pchar ? pchar : ':');
171
 
  rl_message (p, 0, 0);
172
 
  free (p);
173
 
 
174
 
#define SEARCH_RETURN rl_restore_prompt (); return
175
 
 
176
 
  /* Read the search string. */
177
 
  while (c = rl_read_key ())
178
 
    {
179
 
      switch (c)
180
 
        {
181
 
        case CTRL('H'):
182
 
        case RUBOUT:
183
 
          if (rl_point == 0)
184
 
            {
185
 
              maybe_unsave_line ();
186
 
              rl_clear_message ();
187
 
              rl_point = saved_point;
188
 
              SEARCH_RETURN;
189
 
            }
190
 
          rl_rubout (1, c);
191
 
          break;
192
 
 
193
 
        case CTRL('W'):
194
 
          rl_unix_word_rubout (1, c);
195
 
          break;
196
 
 
197
 
        case CTRL('U'):
198
 
          rl_unix_line_discard (1, c);
199
 
          break;
200
 
 
201
 
        case RETURN:
202
 
        case NEWLINE:
203
 
          goto dosearch;
204
 
          /* NOTREACHED */
205
 
          break;
206
 
 
207
 
        case CTRL('C'):
208
 
        case CTRL('G'):
209
 
          maybe_unsave_line ();
210
 
          rl_clear_message ();
211
 
          rl_point = saved_point;
212
 
          ding ();
213
 
          SEARCH_RETURN;
214
 
 
215
 
        default:
216
 
          rl_insert (1, c);
217
 
          break;
218
 
        }
219
 
      (*rl_redisplay_function) ();
220
 
    }
221
 
 
222
 
 dosearch:
223
 
  /* If rl_point == 0, we want to re-use the previous search string and
224
 
     start from the saved history position.  If there's no previous search
225
 
     string, punt. */
226
 
  if (rl_point == 0)
227
 
    {
228
 
      if (!noninc_search_string)
229
 
        {
230
 
          ding ();
231
 
          SEARCH_RETURN;
232
 
        }
233
 
    }
234
 
  else
235
 
    {
236
 
      /* We want to start the search from the current history position. */
237
 
      noninc_history_pos = where_history ();
238
 
      if (noninc_search_string)
239
 
        free (noninc_search_string);
240
 
      noninc_search_string = savestring (rl_line_buffer);
241
 
    }
242
 
 
243
 
  rl_restore_prompt ();
244
 
  noninc_dosearch (noninc_search_string, dir);
245
 
}
246
 
 
247
 
/* Search forward through the history list for a string.  If the vi-mode
248
 
   code calls this, KEY will be `?'. */
249
 
int
250
 
rl_noninc_forward_search (count, key)
251
 
     int count, key;
252
 
{
253
 
  noninc_search (1, (key == '?') ? '?' : 0);
254
 
  return 0;
255
 
}
256
 
 
257
 
/* Reverse search the history list for a string.  If the vi-mode code
258
 
   calls this, KEY will be `/'. */
259
 
int
260
 
rl_noninc_reverse_search (count, key)
261
 
     int count, key;
262
 
{
263
 
  noninc_search (-1, (key == '/') ? '/' : 0);
264
 
  return 0;
265
 
}
266
 
 
267
 
/* Search forward through the history list for the last string searched
268
 
   for.  If there is no saved search string, abort. */
269
 
int
270
 
rl_noninc_forward_search_again (count, key)
271
 
     int count, key;
272
 
{
273
 
  if (!noninc_search_string)
274
 
    {
275
 
      ding ();
276
 
      return (-1);
277
 
    }
278
 
  noninc_dosearch (noninc_search_string, 1);
279
 
  return 0;
280
 
}
281
 
 
282
 
/* Reverse search in the history list for the last string searched
283
 
   for.  If there is no saved search string, abort. */
284
 
int
285
 
rl_noninc_reverse_search_again (count, key)
286
 
     int count, key;
287
 
{
288
 
  if (!noninc_search_string)
289
 
    {
290
 
      ding ();
291
 
      return (-1);
292
 
    }
293
 
  noninc_dosearch (noninc_search_string, -1);
294
 
  return 0;
295
 
}
296
 
 
297
 
static int
298
 
rl_history_search_internal (count, direction)
299
 
     int count, direction;
300
 
{
301
 
  HIST_ENTRY *temp, *old_temp;
302
 
  int line_len;
303
 
 
304
 
  maybe_save_line ();
305
 
 
306
 
  temp = old_temp = (HIST_ENTRY *)NULL;
307
 
  while (count)
308
 
    {
309
 
      temp = (direction < 0) ? previous_history () : next_history ();
310
 
      if (temp == 0)
311
 
        break;
312
 
      /* On an empty prefix, make this the same as previous-history. */
313
 
      if (rl_point == 0)
314
 
        {
315
 
          count--;
316
 
          continue;
317
 
        }
318
 
      if (STREQN (rl_line_buffer, temp->line, rl_point))
319
 
        {
320
 
          /* Don't find multiple instances of the same line. */
321
 
          if (prev_line_found && STREQ (prev_line_found, temp->line))
322
 
            continue;
323
 
          if (direction < 0)
324
 
            old_temp = temp;
325
 
          prev_line_found = temp->line;
326
 
          count--;
327
 
        }
328
 
    }
329
 
 
330
 
  if (temp == 0)
331
 
    {
332
 
      if (direction < 0 && old_temp)
333
 
        temp = old_temp;
334
 
      else
335
 
        {
336
 
          maybe_unsave_line ();
337
 
          ding ();
338
 
          return 1;
339
 
        }
340
 
    }
341
 
 
342
 
  line_len = strlen (temp->line);
343
 
  if (line_len >= rl_line_buffer_len)
344
 
    rl_extend_line_buffer (line_len);
345
 
  strcpy (rl_line_buffer, temp->line);
346
 
  rl_undo_list = (UNDO_LIST *)temp->data;
347
 
  rl_end = line_len;
348
 
  return 0;
349
 
}
350
 
 
351
 
/* Search forward in the history for the string of characters
352
 
   from the start of the line to rl_point.  This is a non-incremental
353
 
   search. */
354
 
int
355
 
rl_history_search_forward (count, ignore)
356
 
     int count, ignore;
357
 
{
358
 
  if (count == 0)
359
 
    return (0);
360
 
  if (rl_last_func != rl_history_search_forward)
361
 
    prev_line_found = (char *)NULL;
362
 
  return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
363
 
}
364
 
 
365
 
/* Search backward through the history for the string of characters
366
 
   from the start of the line to rl_point.  This is a non-incremental
367
 
   search. */
368
 
int
369
 
rl_history_search_backward (count, ignore)
370
 
     int count, ignore;
371
 
{
372
 
  if (count == 0)
373
 
    return (0);
374
 
  if (rl_last_func != rl_history_search_backward)
375
 
    prev_line_found = (char *)NULL;
376
 
  return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
377
 
}