1 | /* util.c -- readline utility 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 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ |
22 | #define READLINE_LIBRARY |
23 | |
24 | #if defined (HAVE_CONFIG_H) |
25 | # include "config_readline.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 | #include "rlmbutil.h" |
48 | |
49 | #if defined (TIOCSTAT_IN_SYS_IOCTL) |
50 | # include <sys/ioctl.h> |
51 | #endif /* TIOCSTAT_IN_SYS_IOCTL */ |
52 | |
53 | /* Some standard library routines. */ |
54 | #include "readline.h" |
55 | |
56 | #include "rlprivate.h" |
57 | #include "xmalloc.h" |
58 | |
59 | /* **************************************************************** */ |
60 | /* */ |
61 | /* Utility Functions */ |
62 | /* */ |
63 | /* **************************************************************** */ |
64 | |
65 | /* Return 0 if C is not a member of the class of characters that belong |
66 | in words, or 1 if it is. */ |
67 | |
68 | int _rl_allow_pathname_alphabetic_chars = 0; |
69 | static const char *pathname_alphabetic_chars = "/-_=~.#$" ; |
70 | |
71 | int |
72 | rl_alphabetic (c) |
73 | int c; |
74 | { |
75 | if (ALPHABETIC (c)) |
76 | return (1); |
77 | |
78 | return (_rl_allow_pathname_alphabetic_chars && |
79 | strchr (pathname_alphabetic_chars, c) != NULL); |
80 | } |
81 | |
82 | #if defined (HANDLE_MULTIBYTE) |
83 | int |
84 | /* |
85 | Portability issue with VisualAge C++ Professional / C for AIX Compiler, Version 6: |
86 | "util.c", line 84.1: 1506-343 (S) Redeclaration of _rl_walphabetic differs |
87 | from previous declaration on line 110 of "rlmbutil.h". |
88 | So, put type in the function signature here. |
89 | */ |
90 | _rl_walphabetic (wchar_t wc) |
91 | { |
92 | int c; |
93 | |
94 | if (iswalnum (wc)) |
95 | return (1); |
96 | |
97 | c = wc & 0177; |
98 | return (_rl_allow_pathname_alphabetic_chars && |
99 | strchr (pathname_alphabetic_chars, c) != NULL); |
100 | } |
101 | #endif |
102 | |
103 | /* How to abort things. */ |
104 | int |
105 | _rl_abort_internal () |
106 | { |
107 | rl_ding (); |
108 | rl_clear_message (); |
109 | _rl_reset_argument (); |
110 | rl_clear_pending_input (); |
111 | |
112 | RL_UNSETSTATE (RL_STATE_MACRODEF); |
113 | while (rl_executing_macro) |
114 | _rl_pop_executing_macro (); |
115 | |
116 | rl_last_func = (rl_command_func_t *)NULL; |
117 | longjmp (readline_top_level, 1); |
118 | return (0); |
119 | } |
120 | |
121 | int |
122 | rl_abort (count, key) |
123 | int count __attribute__((unused)), key __attribute__((unused)); |
124 | { |
125 | return (_rl_abort_internal ()); |
126 | } |
127 | |
128 | int |
129 | rl_tty_status (count, key) |
130 | int count __attribute__((unused)), key __attribute__((unused)); |
131 | { |
132 | #if defined (TIOCSTAT) |
133 | ioctl (1, TIOCSTAT, (char *)0); |
134 | rl_refresh_line (count, key); |
135 | #else |
136 | rl_ding (); |
137 | #endif |
138 | return 0; |
139 | } |
140 | |
141 | /* Return a copy of the string between FROM and TO. |
142 | FROM is inclusive, TO is not. */ |
143 | char * |
144 | rl_copy_text (from, to) |
145 | int from, to; |
146 | { |
147 | register int length; |
148 | char *copy; |
149 | |
150 | /* Fix it if the caller is confused. */ |
151 | if (from > to) |
152 | SWAP (from, to); |
153 | |
154 | length = to - from; |
155 | copy = (char *)xmalloc (1 + length); |
156 | strncpy (copy, rl_line_buffer + from, length); |
157 | copy[length] = '\0'; |
158 | return (copy); |
159 | } |
160 | |
161 | /* Increase the size of RL_LINE_BUFFER until it has enough space to hold |
162 | LEN characters. */ |
163 | void |
164 | rl_extend_line_buffer (len) |
165 | int len; |
166 | { |
167 | while (len >= rl_line_buffer_len) |
168 | { |
169 | rl_line_buffer_len += DEFAULT_BUFFER_SIZE; |
170 | rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len); |
171 | } |
172 | |
173 | _rl_set_the_line (); |
174 | } |
175 | |
176 | |
177 | /* A function for simple tilde expansion. */ |
178 | int |
179 | rl_tilde_expand (ignore, key) |
180 | int ignore __attribute__((unused)), key __attribute__((unused)); |
181 | { |
182 | register int start, end; |
183 | char *homedir, *temp; |
184 | int len; |
185 | |
186 | end = rl_point; |
187 | start = end - 1; |
188 | |
189 | if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') |
190 | { |
191 | homedir = tilde_expand ("~" ); |
192 | _rl_replace_text (homedir, start, end); |
193 | return (0); |
194 | } |
195 | else if (rl_line_buffer[start] != '~') |
196 | { |
197 | for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) |
198 | ; |
199 | start++; |
200 | } |
201 | |
202 | end = start; |
203 | do |
204 | end++; |
205 | while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); |
206 | |
207 | if (whitespace (rl_line_buffer[end]) || end >= rl_end) |
208 | end--; |
209 | |
210 | /* If the first character of the current word is a tilde, perform |
211 | tilde expansion and insert the result. If not a tilde, do |
212 | nothing. */ |
213 | if (rl_line_buffer[start] == '~') |
214 | { |
215 | len = end - start + 1; |
216 | temp = (char *)xmalloc (len + 1); |
217 | strncpy (temp, rl_line_buffer + start, len); |
218 | temp[len] = '\0'; |
219 | homedir = tilde_expand (temp); |
220 | free (temp); |
221 | |
222 | _rl_replace_text (homedir, start, end); |
223 | } |
224 | |
225 | return (0); |
226 | } |
227 | |
228 | /* **************************************************************** */ |
229 | /* */ |
230 | /* String Utility Functions */ |
231 | /* */ |
232 | /* **************************************************************** */ |
233 | |
234 | /* Determine if s2 occurs in s1. If so, return a pointer to the |
235 | match in s1. The compare is case insensitive. */ |
236 | char * |
237 | _rl_strindex (s1, s2) |
238 | register const char *s1, *s2; |
239 | { |
240 | register int i, l, len; |
241 | |
242 | for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) |
243 | if (_rl_strnicmp (s1 + i, s2, l) == 0) |
244 | return ((char *) (s1 + i)); |
245 | return ((char *)NULL); |
246 | } |
247 | |
248 | #ifndef HAVE_STRPBRK |
249 | /* Find the first occurrence in STRING1 of any character from STRING2. |
250 | Return a pointer to the character in STRING1. */ |
251 | char * |
252 | _rl_strpbrk (string1, string2) |
253 | const char *string1, *string2; |
254 | { |
255 | register const char *scan; |
256 | #if defined (HANDLE_MULTIBYTE) |
257 | mbstate_t ps; |
258 | register int i, v; |
259 | |
260 | memset (&ps, 0, sizeof (mbstate_t)); |
261 | #endif |
262 | |
263 | for (; *string1; string1++) |
264 | { |
265 | for (scan = string2; *scan; scan++) |
266 | { |
267 | if (*string1 == *scan) |
268 | return ((char *)string1); |
269 | } |
270 | #if defined (HANDLE_MULTIBYTE) |
271 | if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) |
272 | { |
273 | v = _rl_get_char_len (string1, &ps); |
274 | if (v > 1) |
275 | string1 += v - 1; /* -1 to account for auto-increment in loop */ |
276 | } |
277 | #endif |
278 | } |
279 | return ((char *)NULL); |
280 | } |
281 | #endif |
282 | |
283 | #if !defined (HAVE_STRCASECMP) |
284 | /* Compare at most COUNT characters from string1 to string2. Case |
285 | doesn't matter. */ |
286 | int |
287 | _rl_strnicmp (string1, string2, count) |
288 | char *string1, *string2; |
289 | int count; |
290 | { |
291 | register char ch1, ch2; |
292 | |
293 | while (count) |
294 | { |
295 | ch1 = *string1++; |
296 | ch2 = *string2++; |
297 | if (_rl_to_upper(ch1) == _rl_to_upper(ch2)) |
298 | count--; |
299 | else |
300 | break; |
301 | } |
302 | return (count); |
303 | } |
304 | |
305 | /* strcmp (), but caseless. */ |
306 | int |
307 | _rl_stricmp (string1, string2) |
308 | char *string1, *string2; |
309 | { |
310 | register char ch1, ch2; |
311 | |
312 | while (*string1 && *string2) |
313 | { |
314 | ch1 = *string1++; |
315 | ch2 = *string2++; |
316 | if (_rl_to_upper(ch1) != _rl_to_upper(ch2)) |
317 | return (1); |
318 | } |
319 | return (*string1 - *string2); |
320 | } |
321 | #endif /* !HAVE_STRCASECMP */ |
322 | |
323 | /* Stupid comparison routine for qsort () ing strings. */ |
324 | int |
325 | _rl_qsort_string_compare (s1, s2) |
326 | char **s1, **s2; |
327 | { |
328 | #if defined (HAVE_STRCOLL) |
329 | return (strcoll (*s1, *s2)); |
330 | #else |
331 | int result; |
332 | |
333 | result = **s1 - **s2; |
334 | if (result == 0) |
335 | result = strcmp (*s1, *s2); |
336 | |
337 | return result; |
338 | #endif |
339 | } |
340 | |
341 | /* Function equivalents for the macros defined in chardefs.h. */ |
342 | #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } |
343 | |
344 | FUNCTION_FOR_MACRO (_rl_digit_p) |
345 | FUNCTION_FOR_MACRO (_rl_digit_value) |
346 | FUNCTION_FOR_MACRO (_rl_lowercase_p) |
347 | FUNCTION_FOR_MACRO (_rl_pure_alphabetic) |
348 | FUNCTION_FOR_MACRO (_rl_to_lower) |
349 | FUNCTION_FOR_MACRO (_rl_to_upper) |
350 | FUNCTION_FOR_MACRO (_rl_uppercase_p) |
351 | |
352 | /* Backwards compatibility, now that savestring has been removed from |
353 | all `public' readline header files. */ |
354 | #undef _rl_savestring |
355 | char * |
356 | _rl_savestring (s) |
357 | const char *s; |
358 | { |
359 | return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); |
360 | } |
361 | |