~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to cmd-line-utils/readline/misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* misc.c -- miscellaneous bindable readline functions. */
 
2
 
 
3
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
 
4
 
 
5
   This file is part of the GNU Readline Library, a library for
 
6
   reading lines of text with interactive input and history editing.
 
7
 
 
8
   The GNU Readline Library is free software; you can redistribute it
 
9
   and/or modify it under the terms of the GNU General Public License
 
10
   as published by the Free Software Foundation; either version 2, or
 
11
   (at your option) any later version.
 
12
 
 
13
   The GNU Readline Library is distributed in the hope that it will be
 
14
   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
 
15
   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
 
 
18
   The GNU General Public License is often shipped with GNU software, and
 
19
   is generally kept in a file called COPYING or LICENSE.  If you do not
 
20
   have a copy of the license, write to the Free Software Foundation,
 
21
   59 Temple Place, Suite 330, Boston, MA 02111 USA. */
 
22
#define READLINE_LIBRARY
 
23
 
 
24
#if defined (HAVE_CONFIG_H)
 
25
#  include "config_readline.h"
 
26
#endif
 
27
 
 
28
#if defined (HAVE_UNISTD_H)
 
29
#  include <unistd.h>
 
30
#endif /* HAVE_UNISTD_H */
 
31
 
 
32
#if defined (HAVE_STDLIB_H)
 
33
#  include <stdlib.h>
 
34
#else
 
35
#  include "ansi_stdlib.h"
 
36
#endif /* HAVE_STDLIB_H */
 
37
 
 
38
#if defined (HAVE_LOCALE_H)
 
39
#  include <locale.h>
 
40
#endif
 
41
 
 
42
#include <stdio.h>
 
43
 
 
44
/* System-specific feature definitions and include files. */
 
45
#include "rldefs.h"
 
46
#include "rlmbutil.h"
 
47
 
 
48
/* Some standard library routines. */
 
49
#include "readline.h"
 
50
#include "history.h"
 
51
 
 
52
#include "rlprivate.h"
 
53
#include "rlshell.h"
 
54
#include "xmalloc.h"
 
55
 
 
56
static int rl_digit_loop PARAMS((void));
 
57
static void _rl_history_set_point PARAMS((void));
 
58
 
 
59
/* Forward declarations used in this file */
 
60
void _rl_free_history_entry PARAMS((HIST_ENTRY *));
 
61
 
 
62
/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
 
63
   to preserve the value of rl_point from line to line. */
 
64
int _rl_history_preserve_point = 0;
 
65
 
 
66
_rl_arg_cxt _rl_argcxt;
 
67
 
 
68
/* Saved target point for when _rl_history_preserve_point is set.  Special
 
69
   value of -1 means that point is at the end of the line. */
 
70
int _rl_history_saved_point = -1;
 
71
 
 
72
/* **************************************************************** */
 
73
/*                                                                  */
 
74
/*                      Numeric Arguments                           */
 
75
/*                                                                  */
 
76
/* **************************************************************** */
 
77
 
 
78
int
 
79
_rl_arg_overflow ()
 
80
{
 
81
  if (rl_numeric_arg > 1000000)
 
82
    {
 
83
      _rl_argcxt = 0;
 
84
      rl_explicit_arg = rl_numeric_arg = 0;
 
85
      rl_ding ();
 
86
      rl_restore_prompt ();
 
87
      rl_clear_message ();
 
88
      RL_UNSETSTATE(RL_STATE_NUMERICARG);
 
89
      return 1;
 
90
    }
 
91
  return 0;
 
92
}
 
93
 
 
94
void
 
95
_rl_arg_init ()
 
96
{
 
97
  rl_save_prompt ();
 
98
  _rl_argcxt = 0;
 
99
  RL_SETSTATE(RL_STATE_NUMERICARG);
 
100
}
 
101
 
 
102
int
 
103
_rl_arg_getchar ()
 
104
{
 
105
  int c;
 
106
 
 
107
  rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
 
108
  RL_SETSTATE(RL_STATE_MOREINPUT);
 
109
  c = rl_read_key ();
 
110
  RL_UNSETSTATE(RL_STATE_MOREINPUT);
 
111
 
 
112
  return c;
 
113
}
 
114
 
 
115
/* Process C as part of the current numeric argument.  Return -1 if the
 
116
   argument should be aborted, 0 if we should not read any more chars, and
 
117
   1 if we should continue to read chars. */
 
118
int
 
119
_rl_arg_dispatch (cxt, c)
 
120
     _rl_arg_cxt cxt;
 
121
     int c;
 
122
{
 
123
  int key, r;
 
124
 
 
125
  key = c;
 
126
 
 
127
  /* If we see a key bound to `universal-argument' after seeing digits,
 
128
      it ends the argument but is otherwise ignored. */
 
129
  if (_rl_keymap[c].type == ISFUNC && _rl_keymap[c].function == rl_universal_argument)
 
130
    {
 
131
      if ((cxt & NUM_SAWDIGITS) == 0)
 
132
        {
 
133
          rl_numeric_arg *= 4;
 
134
          return 1;
 
135
        }
 
136
      else if (RL_ISSTATE (RL_STATE_CALLBACK))
 
137
        {
 
138
          _rl_argcxt |= NUM_READONE;
 
139
          return 0;     /* XXX */
 
140
        }
 
141
      else
 
142
        {
 
143
          RL_SETSTATE(RL_STATE_MOREINPUT);
 
144
          key = rl_read_key ();
 
145
          RL_UNSETSTATE(RL_STATE_MOREINPUT);
 
146
          rl_restore_prompt ();
 
147
          rl_clear_message ();
 
148
          RL_UNSETSTATE(RL_STATE_NUMERICARG);
 
149
          return (_rl_dispatch (key, _rl_keymap));
 
150
        }
 
151
    }
 
152
 
 
153
  c = UNMETA (c);
 
154
 
 
155
  if (_rl_digit_p (c))
 
156
    {
 
157
      r = _rl_digit_value (c);          
 
158
      rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) +  r : r;
 
159
      rl_explicit_arg = 1;
 
160
      _rl_argcxt |= NUM_SAWDIGITS;
 
161
    }
 
162
  else if (c == '-' && rl_explicit_arg == 0)
 
163
    {
 
164
      rl_numeric_arg = 1;
 
165
      _rl_argcxt |= NUM_SAWMINUS;
 
166
      rl_arg_sign = -1;
 
167
    }
 
168
  else
 
169
    {
 
170
      /* Make M-- command equivalent to M--1 command. */
 
171
      if ((_rl_argcxt & NUM_SAWMINUS) && rl_numeric_arg == 1 && rl_explicit_arg == 0)
 
172
        rl_explicit_arg = 1;
 
173
      rl_restore_prompt ();
 
174
      rl_clear_message ();
 
175
      RL_UNSETSTATE(RL_STATE_NUMERICARG);
 
176
 
 
177
      r = _rl_dispatch (key, _rl_keymap);
 
178
      if (RL_ISSTATE (RL_STATE_CALLBACK))
 
179
        {
 
180
          /* At worst, this will cause an extra redisplay.  Otherwise,
 
181
             we have to wait until the next character comes in. */
 
182
          if (rl_done == 0)
 
183
            (*rl_redisplay_function) ();
 
184
          r = 0;
 
185
        }
 
186
      return r;
 
187
    }
 
188
 
 
189
  return 1;
 
190
}
 
191
 
 
192
/* Handle C-u style numeric args, as well as M--, and M-digits. */
 
193
static int
 
194
rl_digit_loop ()
 
195
{
 
196
  int c, r;
 
197
 
 
198
  while (1)
 
199
    {
 
200
      if (_rl_arg_overflow ())
 
201
        return 1;
 
202
 
 
203
      c = _rl_arg_getchar ();
 
204
 
 
205
      if (c < 0)
 
206
        {
 
207
          _rl_abort_internal ();
 
208
          return -1;
 
209
        }
 
210
 
 
211
      r = _rl_arg_dispatch (_rl_argcxt, c);
 
212
      if (r <= 0 || (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
 
213
        break;
 
214
    }
 
215
 
 
216
  return r;
 
217
}
 
218
 
 
219
/* Create a default argument. */
 
220
void
 
221
_rl_reset_argument ()
 
222
{
 
223
  rl_numeric_arg = rl_arg_sign = 1;
 
224
  rl_explicit_arg = 0;
 
225
  _rl_argcxt = 0;
 
226
}
 
227
 
 
228
/* Start a numeric argument with initial value KEY */
 
229
int
 
230
rl_digit_argument (ignore, key)
 
231
     int ignore __attribute__((unused)), key;
 
232
{
 
233
  _rl_arg_init ();
 
234
  if (RL_ISSTATE (RL_STATE_CALLBACK))
 
235
    {
 
236
      _rl_arg_dispatch (_rl_argcxt, key);
 
237
      rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
 
238
      return 0;
 
239
    }
 
240
  else
 
241
    {
 
242
      rl_execute_next (key);
 
243
      return (rl_digit_loop ());
 
244
    }
 
245
}
 
246
 
 
247
/* C-u, universal argument.  Multiply the current argument by 4.
 
248
   Read a key.  If the key has nothing to do with arguments, then
 
249
   dispatch on it.  If the key is the abort character then abort. */
 
250
int
 
251
rl_universal_argument (count, key)
 
252
     int count __attribute__((unused)), key __attribute__((unused));
 
253
{
 
254
  _rl_arg_init ();
 
255
  rl_numeric_arg *= 4;
 
256
 
 
257
  return (RL_ISSTATE (RL_STATE_CALLBACK) ? 0 : rl_digit_loop ());
 
258
}
 
259
 
 
260
int
 
261
_rl_arg_callback (cxt)
 
262
     _rl_arg_cxt cxt;
 
263
{
 
264
  int c, r;
 
265
 
 
266
  c = _rl_arg_getchar ();
 
267
 
 
268
  if (_rl_argcxt & NUM_READONE)
 
269
    {
 
270
      _rl_argcxt &= ~NUM_READONE;
 
271
      rl_restore_prompt ();
 
272
      rl_clear_message ();
 
273
      RL_UNSETSTATE(RL_STATE_NUMERICARG);
 
274
      rl_execute_next (c);
 
275
      return 0;
 
276
    }
 
277
 
 
278
  r = _rl_arg_dispatch (cxt, c);
 
279
  return (r != 1);
 
280
}
 
281
 
 
282
/* What to do when you abort reading an argument. */
 
283
int
 
284
rl_discard_argument ()
 
285
{
 
286
  rl_ding ();
 
287
  rl_clear_message ();
 
288
  _rl_reset_argument ();
 
289
 
 
290
  return 0;
 
291
}
 
292
 
 
293
/* **************************************************************** */
 
294
/*                                                                  */
 
295
/*                      History Utilities                           */
 
296
/*                                                                  */
 
297
/* **************************************************************** */
 
298
 
 
299
/* We already have a history library, and that is what we use to control
 
300
   the history features of readline.  This is our local interface to
 
301
   the history mechanism. */
 
302
 
 
303
/* While we are editing the history, this is the saved
 
304
   version of the original line. */
 
305
HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
 
306
 
 
307
/* Set the history pointer back to the last entry in the history. */
 
308
void
 
309
_rl_start_using_history ()
 
310
{
 
311
  using_history ();
 
312
  if (_rl_saved_line_for_history)
 
313
    _rl_free_history_entry (_rl_saved_line_for_history);
 
314
 
 
315
  _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
 
316
}
 
317
 
 
318
/* Free the contents (and containing structure) of a HIST_ENTRY. */
 
319
void
 
320
_rl_free_history_entry (entry)
 
321
     HIST_ENTRY *entry;
 
322
{
 
323
  if (entry == 0)
 
324
    return;
 
325
 
 
326
  FREE (entry->line);
 
327
  FREE (entry->timestamp);
 
328
 
 
329
  free (entry);
 
330
}
 
331
 
 
332
/* Perhaps put back the current line if it has changed. */
 
333
int
 
334
rl_maybe_replace_line ()
 
335
{
 
336
  HIST_ENTRY *temp;
 
337
 
 
338
  temp = current_history ();
 
339
  /* If the current line has changed, save the changes. */
 
340
  if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
 
341
    {
 
342
      temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
 
343
      free (temp->line);
 
344
      FREE (temp->timestamp);
 
345
      free (temp);
 
346
    }
 
347
  return 0;
 
348
}
 
349
 
 
350
/* Restore the _rl_saved_line_for_history if there is one. */
 
351
int
 
352
rl_maybe_unsave_line ()
 
353
{
 
354
  if (_rl_saved_line_for_history)
 
355
    {
 
356
      /* Can't call with `1' because rl_undo_list might point to an undo
 
357
         list from a history entry, as in rl_replace_from_history() below. */
 
358
      rl_replace_line (_rl_saved_line_for_history->line, 0);
 
359
      rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
 
360
      _rl_free_history_entry (_rl_saved_line_for_history);
 
361
      _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
 
362
      rl_point = rl_end;        /* rl_replace_line sets rl_end */
 
363
    }
 
364
  else
 
365
    rl_ding ();
 
366
  return 0;
 
367
}
 
368
 
 
369
/* Save the current line in _rl_saved_line_for_history. */
 
370
int
 
371
rl_maybe_save_line ()
 
372
{
 
373
  if (_rl_saved_line_for_history == 0)
 
374
    {
 
375
      _rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
 
376
      _rl_saved_line_for_history->line = savestring (rl_line_buffer);
 
377
      _rl_saved_line_for_history->timestamp = (char *)NULL;
 
378
      _rl_saved_line_for_history->data = (char *)rl_undo_list;
 
379
    }
 
380
 
 
381
  return 0;
 
382
}
 
383
 
 
384
int
 
385
_rl_free_saved_history_line ()
 
386
{
 
387
  if (_rl_saved_line_for_history)
 
388
    {
 
389
      _rl_free_history_entry (_rl_saved_line_for_history);
 
390
      _rl_saved_line_for_history = (HIST_ENTRY *)NULL;
 
391
    }
 
392
  return 0;
 
393
}
 
394
 
 
395
static void
 
396
_rl_history_set_point ()
 
397
{
 
398
  rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
 
399
                ? _rl_history_saved_point
 
400
                : rl_end;
 
401
  if (rl_point > rl_end)
 
402
    rl_point = rl_end;
 
403
 
 
404
#if defined (VI_MODE)
 
405
  if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
 
406
    rl_point = 0;
 
407
#endif /* VI_MODE */
 
408
 
 
409
  if (rl_editing_mode == emacs_mode)
 
410
    rl_mark = (rl_point == rl_end ? 0 : rl_end);
 
411
}
 
412
 
 
413
void
 
414
rl_replace_from_history (entry, flags)
 
415
     HIST_ENTRY *entry;
 
416
     int flags __attribute__((unused)); /* currently unused */
 
417
{
 
418
  /* Can't call with `1' because rl_undo_list might point to an undo list
 
419
     from a history entry, just like we're setting up here. */
 
420
  rl_replace_line (entry->line, 0);
 
421
  rl_undo_list = (UNDO_LIST *)entry->data;
 
422
  rl_point = rl_end;
 
423
  rl_mark = 0;
 
424
 
 
425
#if defined (VI_MODE)
 
426
  if (rl_editing_mode == vi_mode)
 
427
    {
 
428
      rl_point = 0;
 
429
      rl_mark = rl_end;
 
430
    }
 
431
#endif
 
432
}  
 
433
 
 
434
/* **************************************************************** */
 
435
/*                                                                  */
 
436
/*                      History Commands                            */
 
437
/*                                                                  */
 
438
/* **************************************************************** */
 
439
 
 
440
/* Meta-< goes to the start of the history. */
 
441
int
 
442
rl_beginning_of_history (count, key)
 
443
     int count __attribute__((unused)), key;
 
444
{
 
445
  return (rl_get_previous_history (1 + where_history (), key));
 
446
}
 
447
 
 
448
/* Meta-> goes to the end of the history.  (The current line). */
 
449
int
 
450
rl_end_of_history (count, key)
 
451
     int count __attribute__((unused)), key __attribute__((unused));
 
452
{
 
453
  rl_maybe_replace_line ();
 
454
  using_history ();
 
455
  rl_maybe_unsave_line ();
 
456
  return 0;
 
457
}
 
458
 
 
459
/* Move down to the next history line. */
 
460
int
 
461
rl_get_next_history (count, key)
 
462
     int count, key;
 
463
{
 
464
  HIST_ENTRY *temp;
 
465
 
 
466
  if (count < 0)
 
467
    return (rl_get_previous_history (-count, key));
 
468
 
 
469
  if (count == 0)
 
470
    return 0;
 
471
 
 
472
  rl_maybe_replace_line ();
 
473
 
 
474
  /* either not saved by rl_newline or at end of line, so set appropriately. */
 
475
  if (_rl_history_saved_point == -1 && (rl_point || rl_end))
 
476
    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
 
477
 
 
478
  temp = (HIST_ENTRY *)NULL;
 
479
  while (count)
 
480
    {
 
481
      temp = next_history ();
 
482
      if (!temp)
 
483
        break;
 
484
      --count;
 
485
    }
 
486
 
 
487
  if (temp == 0)
 
488
    rl_maybe_unsave_line ();
 
489
  else
 
490
    {
 
491
      rl_replace_from_history (temp, 0);
 
492
      _rl_history_set_point ();
 
493
    }
 
494
  return 0;
 
495
}
 
496
 
 
497
/* Get the previous item out of our interactive history, making it the current
 
498
   line.  If there is no previous history, just ding. */
 
499
int
 
500
rl_get_previous_history (count, key)
 
501
     int count, key;
 
502
{
 
503
  HIST_ENTRY *old_temp, *temp;
 
504
 
 
505
  if (count < 0)
 
506
    return (rl_get_next_history (-count, key));
 
507
 
 
508
  if (count == 0)
 
509
    return 0;
 
510
 
 
511
  /* either not saved by rl_newline or at end of line, so set appropriately. */
 
512
  if (_rl_history_saved_point == -1 && (rl_point || rl_end))
 
513
    _rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
 
514
 
 
515
  /* If we don't have a line saved, then save this one. */
 
516
  rl_maybe_save_line ();
 
517
 
 
518
  /* If the current line has changed, save the changes. */
 
519
  rl_maybe_replace_line ();
 
520
 
 
521
  temp = old_temp = (HIST_ENTRY *)NULL;
 
522
  while (count)
 
523
    {
 
524
      temp = previous_history ();
 
525
      if (temp == 0)
 
526
        break;
 
527
 
 
528
      old_temp = temp;
 
529
      --count;
 
530
    }
 
531
 
 
532
  /* If there was a large argument, and we moved back to the start of the
 
533
     history, that is not an error.  So use the last value found. */
 
534
  if (!temp && old_temp)
 
535
    temp = old_temp;
 
536
 
 
537
  if (temp == 0)
 
538
    rl_ding ();
 
539
  else
 
540
    {
 
541
      rl_replace_from_history (temp, 0);
 
542
      _rl_history_set_point ();
 
543
    }
 
544
 
 
545
  return 0;
 
546
}
 
547
 
 
548
/* **************************************************************** */
 
549
/*                                                                  */
 
550
/*                          Editing Modes                           */
 
551
/*                                                                  */
 
552
/* **************************************************************** */
 
553
/* How to toggle back and forth between editing modes. */
 
554
int
 
555
rl_vi_editing_mode (count, key)
 
556
     int count __attribute__((unused)), key;
 
557
{
 
558
#if defined (VI_MODE)
 
559
  _rl_set_insert_mode (RL_IM_INSERT, 1);        /* vi mode ignores insert mode */
 
560
  rl_editing_mode = vi_mode;
 
561
  rl_vi_insertion_mode (1, key);
 
562
#endif /* VI_MODE */
 
563
 
 
564
  return 0;
 
565
}
 
566
 
 
567
int
 
568
rl_emacs_editing_mode (count, key)
 
569
     int count __attribute__((unused)), key __attribute__((unused));
 
570
{
 
571
  rl_editing_mode = emacs_mode;
 
572
  _rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
 
573
  _rl_keymap = emacs_standard_keymap;
 
574
  return 0;
 
575
}
 
576
 
 
577
/* Function for the rest of the library to use to set insert/overwrite mode. */
 
578
void
 
579
_rl_set_insert_mode (im, force)
 
580
     int im, force __attribute__((unused));
 
581
{
 
582
#ifdef CURSOR_MODE
 
583
  _rl_set_cursor (im, force);
 
584
#endif
 
585
 
 
586
  rl_insert_mode = im;
 
587
}
 
588
 
 
589
/* Toggle overwrite mode.  A positive explicit argument selects overwrite
 
590
   mode.  A negative or zero explicit argument selects insert mode. */
 
591
int
 
592
rl_overwrite_mode (count, key)
 
593
     int count, key __attribute__((unused));
 
594
{
 
595
  if (rl_explicit_arg == 0)
 
596
    _rl_set_insert_mode (rl_insert_mode ^ 1, 0);
 
597
  else if (count > 0)
 
598
    _rl_set_insert_mode (RL_IM_OVERWRITE, 0);
 
599
  else
 
600
    _rl_set_insert_mode (RL_IM_INSERT, 0);
 
601
 
 
602
  return 0;
 
603
}