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

« back to all changes in this revision

Viewing changes to cmd-line-utils/readline/parens.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
/* parens.c -- Implementation of matching parentheses feature. */
 
2
 
 
3
/* Copyright (C) 1987, 1989, 1992 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 (__TANDEM)
 
25
#  include <floss.h>
 
26
#endif
 
27
 
 
28
#include "rlconf.h"
 
29
 
 
30
#if defined (HAVE_CONFIG_H)
 
31
#  include "config_readline.h"
 
32
#endif
 
33
 
 
34
#include <stdio.h>
 
35
#include <sys/types.h>
 
36
 
 
37
#if defined (HAVE_UNISTD_H)
 
38
#  include <unistd.h>
 
39
#endif
 
40
 
 
41
#if defined (FD_SET) && !defined (HAVE_SELECT)
 
42
#  define HAVE_SELECT
 
43
#endif
 
44
 
 
45
#if defined (HAVE_SELECT)
 
46
#  include <sys/time.h>
 
47
#endif /* HAVE_SELECT */
 
48
#if defined (HAVE_SYS_SELECT_H)
 
49
#  include <sys/select.h>
 
50
#endif
 
51
 
 
52
#if defined (HAVE_STRING_H)
 
53
#  include <string.h>
 
54
#else /* !HAVE_STRING_H */
 
55
#  include <strings.h>
 
56
#endif /* !HAVE_STRING_H */
 
57
 
 
58
#if !defined (strchr) && !defined (__STDC__)
 
59
extern char *strchr (), *strrchr ();
 
60
#endif /* !strchr && !__STDC__ */
 
61
 
 
62
#include "readline.h"
 
63
#include "rlprivate.h"
 
64
 
 
65
static int find_matching_open PARAMS((char *, int, int));
 
66
 
 
67
/* Non-zero means try to blink the matching open parenthesis when the
 
68
   close parenthesis is inserted. */
 
69
#if defined (HAVE_SELECT)
 
70
int rl_blink_matching_paren = 1;
 
71
#else /* !HAVE_SELECT */
 
72
int rl_blink_matching_paren = 0;
 
73
#endif /* !HAVE_SELECT */
 
74
 
 
75
static int _paren_blink_usec = 500000;
 
76
 
 
77
/* Change emacs_standard_keymap to have bindings for paren matching when
 
78
   ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
 
79
void
 
80
_rl_enable_paren_matching (on_or_off)
 
81
     int on_or_off;
 
82
{
 
83
  if (on_or_off)
 
84
    {   /* ([{ */
 
85
      rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
 
86
      rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
 
87
      rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
 
88
    }
 
89
  else
 
90
    {   /* ([{ */
 
91
      rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
 
92
      rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
 
93
      rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
 
94
    }
 
95
}
 
96
 
 
97
int
 
98
rl_set_paren_blink_timeout (u)
 
99
     int u;
 
100
{
 
101
  int o;
 
102
 
 
103
  o = _paren_blink_usec;
 
104
  if (u > 0)
 
105
    _paren_blink_usec = u;
 
106
  return (o);
 
107
}
 
108
 
 
109
int
 
110
rl_insert_close (count, invoking_key)
 
111
     int count, invoking_key;
 
112
{
 
113
  if (rl_explicit_arg || !rl_blink_matching_paren)
 
114
    _rl_insert_char (count, invoking_key);
 
115
  else
 
116
    {
 
117
#if defined (HAVE_SELECT)
 
118
      int orig_point, match_point, ready;
 
119
      struct timeval timer;
 
120
      fd_set readfds;
 
121
 
 
122
      _rl_insert_char (1, invoking_key);
 
123
      (*rl_redisplay_function) ();
 
124
      match_point =
 
125
        find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
 
126
 
 
127
      /* Emacs might message or ring the bell here, but I don't. */
 
128
      if (match_point < 0)
 
129
        return -1;
 
130
 
 
131
      FD_ZERO (&readfds);
 
132
      FD_SET (fileno (rl_instream), &readfds);
 
133
      timer.tv_sec = 0;
 
134
      timer.tv_usec = _paren_blink_usec;
 
135
 
 
136
      orig_point = rl_point;
 
137
      rl_point = match_point;
 
138
      (*rl_redisplay_function) ();
 
139
      ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
 
140
      rl_point = orig_point;
 
141
#else /* !HAVE_SELECT */
 
142
      _rl_insert_char (count, invoking_key);
 
143
#endif /* !HAVE_SELECT */
 
144
    }
 
145
  return 0;
 
146
}
 
147
 
 
148
static int
 
149
find_matching_open (string, from, closer)
 
150
     char *string;
 
151
     int from, closer;
 
152
{
 
153
  register int i;
 
154
  int opener, level, delimiter;
 
155
 
 
156
  switch (closer)
 
157
    {
 
158
    case ']': opener = '['; break;
 
159
    case '}': opener = '{'; break;
 
160
    case ')': opener = '('; break;
 
161
    default:
 
162
      return (-1);
 
163
    }
 
164
 
 
165
  level = 1;                    /* The closer passed in counts as 1. */
 
166
  delimiter = 0;                /* Delimited state unknown. */
 
167
 
 
168
  for (i = from; i > -1; i--)
 
169
    {
 
170
      if (delimiter && (string[i] == delimiter))
 
171
        delimiter = 0;
 
172
      else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
 
173
        delimiter = string[i];
 
174
      else if (!delimiter && (string[i] == closer))
 
175
        level++;
 
176
      else if (!delimiter && (string[i] == opener))
 
177
        level--;
 
178
 
 
179
      if (!level)
 
180
        break;
 
181
    }
 
182
  return (i);
 
183
}