2996
|
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 1, 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, |
3284
|
21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ |
2996
|
22 #define READLINE_LIBRARY |
|
23 |
|
24 #include "rlconf.h" |
|
25 |
|
26 #if !defined (PAREN_MATCHING) |
|
27 extern int rl_insert (); |
|
28 |
|
29 int |
|
30 rl_insert_close (count, invoking_key) |
|
31 int count, invoking_key; |
|
32 { |
|
33 return (rl_insert (count, invoking_key)); |
|
34 } |
|
35 |
|
36 #else /* PAREN_MATCHING */ |
|
37 |
|
38 #if defined (HAVE_CONFIG_H) |
|
39 # include <config.h> |
|
40 #endif |
|
41 |
|
42 #include <stdio.h> |
|
43 #include <sys/types.h> |
|
44 |
|
45 #if defined (FD_SET) && !defined (HAVE_SELECT) |
|
46 # define HAVE_SELECT |
|
47 #endif |
|
48 |
|
49 #if defined (HAVE_SELECT) |
|
50 # include <sys/time.h> |
|
51 #endif /* HAVE_SELECT */ |
|
52 #if defined (HAVE_SYS_SELECT_H) |
|
53 # include <sys/select.h> |
|
54 #endif |
|
55 |
|
56 #if defined (HAVE_STRING_H) |
|
57 # include <string.h> |
|
58 #else /* !HAVE_STRING_H */ |
|
59 # include <strings.h> |
|
60 #endif /* !HAVE_STRING_H */ |
|
61 |
|
62 #if !defined (strchr) && !defined (__STDC__) |
|
63 extern char *strchr (), *strrchr (); |
|
64 #endif /* !strchr && !__STDC__ */ |
|
65 |
|
66 #include "readline.h" |
|
67 |
|
68 extern int rl_explicit_arg; |
|
69 |
|
70 /* Non-zero means try to blink the matching open parenthesis when the |
|
71 close parenthesis is inserted. */ |
|
72 #if defined (HAVE_SELECT) |
|
73 int rl_blink_matching_paren = 1; |
|
74 #else /* !HAVE_SELECT */ |
|
75 int rl_blink_matching_paren = 0; |
|
76 #endif /* !HAVE_SELECT */ |
|
77 |
|
78 static int find_matching_open (); |
|
79 |
|
80 int |
|
81 rl_insert_close (count, invoking_key) |
|
82 int count, invoking_key; |
|
83 { |
|
84 if (rl_explicit_arg || !rl_blink_matching_paren) |
|
85 rl_insert (count, invoking_key); |
|
86 else |
|
87 { |
|
88 #if defined (HAVE_SELECT) |
|
89 int orig_point, match_point, ready; |
|
90 struct timeval timer; |
|
91 fd_set readfds; |
|
92 |
|
93 rl_insert (1, invoking_key); |
|
94 (*rl_redisplay_function) (); |
|
95 match_point = |
|
96 find_matching_open (rl_line_buffer, rl_point - 2, invoking_key); |
|
97 |
|
98 /* Emacs might message or ring the bell here, but I don't. */ |
|
99 if (match_point < 0) |
|
100 return -1; |
|
101 |
|
102 FD_ZERO (&readfds); |
|
103 FD_SET (fileno (rl_instream), &readfds); |
3162
|
104 timer.tv_sec = 0; |
|
105 timer.tv_usec = 500000; |
2996
|
106 |
|
107 orig_point = rl_point; |
|
108 rl_point = match_point; |
|
109 (*rl_redisplay_function) (); |
|
110 ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); |
|
111 rl_point = orig_point; |
|
112 #else /* !HAVE_SELECT */ |
|
113 rl_insert (count, invoking_key); |
|
114 #endif /* !HAVE_SELECT */ |
|
115 } |
|
116 return 0; |
|
117 } |
|
118 |
|
119 static int |
|
120 find_matching_open (string, from, closer) |
|
121 char *string; |
|
122 int from, closer; |
|
123 { |
|
124 register int i; |
|
125 int opener, level, delimiter; |
|
126 |
|
127 switch (closer) |
|
128 { |
|
129 case ']': opener = '['; break; |
|
130 case '}': opener = '{'; break; |
|
131 case ')': opener = '('; break; |
|
132 default: |
|
133 return (-1); |
|
134 } |
|
135 |
|
136 level = 1; /* The closer passed in counts as 1. */ |
|
137 delimiter = 0; /* Delimited state unknown. */ |
|
138 |
|
139 for (i = from; i > -1; i--) |
|
140 { |
|
141 if (delimiter && (string[i] == delimiter)) |
|
142 delimiter = 0; |
|
143 else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i])) |
|
144 delimiter = string[i]; |
|
145 else if (!delimiter && (string[i] == closer)) |
|
146 level++; |
|
147 else if (!delimiter && (string[i] == opener)) |
|
148 level--; |
|
149 |
|
150 if (!level) |
|
151 break; |
|
152 } |
|
153 return (i); |
|
154 } |
|
155 |
|
156 #endif /* PAREN_MATCHING */ |