2996
|
1 /* util.c -- readline utility functions */ |
|
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 |
3779
|
10 as published by the Free Software Foundation; either version 2, or |
2996
|
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 #if defined (HAVE_CONFIG_H) |
|
25 # include <config.h> |
|
26 #endif |
|
27 |
|
28 #include <sys/types.h> |
|
29 #include <fcntl.h> |
|
30 #include "posixjmp.h" |
|
31 |
|
32 #if defined (HAVE_UNISTD_H) |
|
33 # include <unistd.h> /* for _POSIX_VERSION */ |
|
34 #endif /* HAVE_UNISTD_H */ |
|
35 |
|
36 #if defined (HAVE_STDLIB_H) |
|
37 # include <stdlib.h> |
|
38 #else |
|
39 # include "ansi_stdlib.h" |
|
40 #endif /* HAVE_STDLIB_H */ |
|
41 |
|
42 #include <stdio.h> |
|
43 #include <ctype.h> |
|
44 |
|
45 /* System-specific feature definitions and include files. */ |
|
46 #include "rldefs.h" |
|
47 |
|
48 #if defined (TIOCSTAT_IN_SYS_IOCTL) |
|
49 # include <sys/ioctl.h> |
|
50 #endif /* TIOCSTAT_IN_SYS_IOCTL */ |
|
51 |
|
52 /* Some standard library routines. */ |
|
53 #include "readline.h" |
|
54 |
3779
|
55 #include "rlprivate.h" |
|
56 #include "xmalloc.h" |
2996
|
57 |
3779
|
58 #define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) |
2996
|
59 |
|
60 /* **************************************************************** */ |
|
61 /* */ |
|
62 /* Utility Functions */ |
|
63 /* */ |
|
64 /* **************************************************************** */ |
|
65 |
|
66 /* Return 0 if C is not a member of the class of characters that belong |
|
67 in words, or 1 if it is. */ |
|
68 |
|
69 int _rl_allow_pathname_alphabetic_chars = 0; |
3779
|
70 static const char *pathname_alphabetic_chars = "/-_=~.#$"; |
2996
|
71 |
|
72 int |
3779
|
73 rl_alphabetic (c) |
2996
|
74 int c; |
|
75 { |
|
76 if (ALPHABETIC (c)) |
|
77 return (1); |
|
78 |
|
79 return (_rl_allow_pathname_alphabetic_chars && |
|
80 strchr (pathname_alphabetic_chars, c) != NULL); |
|
81 } |
|
82 |
|
83 /* How to abort things. */ |
|
84 int |
|
85 _rl_abort_internal () |
|
86 { |
3779
|
87 rl_ding (); |
2996
|
88 rl_clear_message (); |
|
89 _rl_init_argument (); |
3779
|
90 rl_clear_pending_input (); |
2996
|
91 |
|
92 _rl_defining_kbd_macro = 0; |
3779
|
93 while (rl_executing_macro) |
2996
|
94 _rl_pop_executing_macro (); |
|
95 |
3779
|
96 rl_last_func = (rl_command_func_t *)NULL; |
2996
|
97 longjmp (readline_top_level, 1); |
|
98 return (0); |
|
99 } |
|
100 |
|
101 int |
|
102 rl_abort (count, key) |
|
103 int count, key; |
|
104 { |
|
105 return (_rl_abort_internal ()); |
|
106 } |
|
107 |
|
108 int |
|
109 rl_tty_status (count, key) |
|
110 int count, key; |
|
111 { |
|
112 #if defined (TIOCSTAT) |
|
113 ioctl (1, TIOCSTAT, (char *)0); |
3779
|
114 rl_refresh_line (count, key); |
2996
|
115 #else |
3779
|
116 rl_ding (); |
2996
|
117 #endif |
|
118 return 0; |
|
119 } |
|
120 |
|
121 /* Return a copy of the string between FROM and TO. |
|
122 FROM is inclusive, TO is not. */ |
|
123 char * |
|
124 rl_copy_text (from, to) |
|
125 int from, to; |
|
126 { |
|
127 register int length; |
|
128 char *copy; |
|
129 |
|
130 /* Fix it if the caller is confused. */ |
|
131 if (from > to) |
|
132 SWAP (from, to); |
|
133 |
|
134 length = to - from; |
|
135 copy = xmalloc (1 + length); |
|
136 strncpy (copy, rl_line_buffer + from, length); |
|
137 copy[length] = '\0'; |
|
138 return (copy); |
|
139 } |
|
140 |
|
141 /* Increase the size of RL_LINE_BUFFER until it has enough space to hold |
|
142 LEN characters. */ |
|
143 void |
|
144 rl_extend_line_buffer (len) |
|
145 int len; |
|
146 { |
|
147 while (len >= rl_line_buffer_len) |
|
148 { |
|
149 rl_line_buffer_len += DEFAULT_BUFFER_SIZE; |
|
150 rl_line_buffer = xrealloc (rl_line_buffer, rl_line_buffer_len); |
|
151 } |
|
152 |
|
153 _rl_set_the_line (); |
|
154 } |
|
155 |
3779
|
156 |
|
157 /* A function for simple tilde expansion. */ |
|
158 int |
|
159 rl_tilde_expand (ignore, key) |
|
160 int ignore, key; |
|
161 { |
|
162 register int start, end; |
|
163 char *homedir, *temp; |
|
164 int len; |
|
165 |
|
166 end = rl_point; |
|
167 start = end - 1; |
|
168 |
|
169 if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') |
|
170 { |
|
171 homedir = tilde_expand ("~"); |
|
172 _rl_replace_text (homedir, start, end); |
|
173 return (0); |
|
174 } |
|
175 else if (rl_line_buffer[start] != '~') |
|
176 { |
|
177 for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) |
|
178 ; |
|
179 start++; |
|
180 } |
|
181 |
|
182 end = start; |
|
183 do |
|
184 end++; |
|
185 while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); |
|
186 |
|
187 if (whitespace (rl_line_buffer[end]) || end >= rl_end) |
|
188 end--; |
|
189 |
|
190 /* If the first character of the current word is a tilde, perform |
|
191 tilde expansion and insert the result. If not a tilde, do |
|
192 nothing. */ |
|
193 if (rl_line_buffer[start] == '~') |
|
194 { |
|
195 len = end - start + 1; |
|
196 temp = xmalloc (len + 1); |
|
197 strncpy (temp, rl_line_buffer + start, len); |
|
198 temp[len] = '\0'; |
|
199 homedir = tilde_expand (temp); |
|
200 free (temp); |
|
201 |
|
202 _rl_replace_text (homedir, start, end); |
|
203 } |
|
204 |
|
205 return (0); |
|
206 } |
|
207 |
2996
|
208 /* **************************************************************** */ |
|
209 /* */ |
|
210 /* String Utility Functions */ |
|
211 /* */ |
|
212 /* **************************************************************** */ |
|
213 |
|
214 /* Determine if s2 occurs in s1. If so, return a pointer to the |
|
215 match in s1. The compare is case insensitive. */ |
|
216 char * |
|
217 _rl_strindex (s1, s2) |
3779
|
218 register const char *s1, *s2; |
2996
|
219 { |
|
220 register int i, l, len; |
|
221 |
|
222 for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) |
|
223 if (_rl_strnicmp (s1 + i, s2, l) == 0) |
3779
|
224 return ((char *) (s1 + i)); |
2996
|
225 return ((char *)NULL); |
|
226 } |
|
227 |
|
228 #if !defined (HAVE_STRCASECMP) |
|
229 /* Compare at most COUNT characters from string1 to string2. Case |
|
230 doesn't matter. */ |
|
231 int |
|
232 _rl_strnicmp (string1, string2, count) |
|
233 char *string1, *string2; |
|
234 int count; |
|
235 { |
|
236 register char ch1, ch2; |
|
237 |
|
238 while (count) |
|
239 { |
|
240 ch1 = *string1++; |
|
241 ch2 = *string2++; |
|
242 if (_rl_to_upper(ch1) == _rl_to_upper(ch2)) |
|
243 count--; |
|
244 else |
|
245 break; |
|
246 } |
|
247 return (count); |
|
248 } |
|
249 |
|
250 /* strcmp (), but caseless. */ |
|
251 int |
|
252 _rl_stricmp (string1, string2) |
|
253 char *string1, *string2; |
|
254 { |
|
255 register char ch1, ch2; |
|
256 |
|
257 while (*string1 && *string2) |
|
258 { |
|
259 ch1 = *string1++; |
|
260 ch2 = *string2++; |
|
261 if (_rl_to_upper(ch1) != _rl_to_upper(ch2)) |
|
262 return (1); |
|
263 } |
|
264 return (*string1 - *string2); |
|
265 } |
|
266 #endif /* !HAVE_STRCASECMP */ |
|
267 |
|
268 /* Stupid comparison routine for qsort () ing strings. */ |
|
269 int |
|
270 _rl_qsort_string_compare (s1, s2) |
|
271 char **s1, **s2; |
|
272 { |
|
273 #if defined (HAVE_STRCOLL) |
|
274 return (strcoll (*s1, *s2)); |
|
275 #else |
|
276 int result; |
|
277 |
|
278 result = **s1 - **s2; |
|
279 if (result == 0) |
|
280 result = strcmp (*s1, *s2); |
|
281 |
|
282 return result; |
|
283 #endif |
|
284 } |
|
285 |
|
286 /* Function equivalents for the macros defined in chartypes.h. */ |
|
287 #undef _rl_uppercase_p |
|
288 int |
|
289 _rl_uppercase_p (c) |
|
290 int c; |
|
291 { |
|
292 return (isupper (c)); |
|
293 } |
|
294 |
|
295 #undef _rl_lowercase_p |
|
296 int |
|
297 _rl_lowercase_p (c) |
|
298 int c; |
|
299 { |
|
300 return (islower (c)); |
|
301 } |
|
302 |
|
303 #undef _rl_pure_alphabetic |
|
304 int |
|
305 _rl_pure_alphabetic (c) |
|
306 int c; |
|
307 { |
|
308 return (isupper (c) || islower (c)); |
|
309 } |
|
310 |
|
311 #undef _rl_digit_p |
|
312 int |
|
313 _rl_digit_p (c) |
|
314 int c; |
|
315 { |
|
316 return (isdigit (c)); |
|
317 } |
|
318 |
|
319 #undef _rl_to_lower |
|
320 int |
|
321 _rl_to_lower (c) |
|
322 int c; |
|
323 { |
|
324 return (isupper (c) ? tolower (c) : c); |
|
325 } |
|
326 |
|
327 #undef _rl_to_upper |
|
328 int |
|
329 _rl_to_upper (c) |
|
330 int c; |
|
331 { |
|
332 return (islower (c) ? toupper (c) : c); |
|
333 } |
|
334 |
|
335 #undef _rl_digit_value |
|
336 int |
|
337 _rl_digit_value (c) |
|
338 int c; |
|
339 { |
|
340 return (isdigit (c) ? c - '0' : c); |
|
341 } |
3779
|
342 |
|
343 /* Backwards compatibility, now that savestring has been removed from |
|
344 all `public' readline header files. */ |
|
345 #undef _rl_savestring |
|
346 char * |
|
347 _rl_savestring (s) |
|
348 const char *s; |
|
349 { |
|
350 return (strcpy (xmalloc (1 + (int)strlen (s)), (s))); |
|
351 } |