1 /* $FreeBSD$ */
2 /* util.c -- readline utility functions */
3
4 /* Copyright (C) 1987-2005 Free Software Foundation, Inc.
5
6 This file is part of the GNU Readline Library, a library for
7 reading lines of text with interactive input and history editing.
8
9 The GNU Readline Library is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2, or
12 (at your option) any later version.
13
14 The GNU Readline Library is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 The GNU General Public License is often shipped with GNU software, and
20 is generally kept in a file called COPYING or LICENSE. If you do not
21 have a copy of the license, write to the Free Software Foundation,
22 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
23 #define READLINE_LIBRARY
24
25 #if defined (HAVE_CONFIG_H)
26 # include <config.h>
27 #endif
28
29 #include <sys/types.h>
30 #include <fcntl.h>
31 #include "posixjmp.h"
32
33 #if defined (HAVE_UNISTD_H)
34 # include <unistd.h> /* for _POSIX_VERSION */
35 #endif /* HAVE_UNISTD_H */
36
37 #if defined (HAVE_STDLIB_H)
38 # include <stdlib.h>
39 #else
40 # include "ansi_stdlib.h"
41 #endif /* HAVE_STDLIB_H */
42
43 #include <stdio.h>
44 #include <ctype.h>
45
46 /* System-specific feature definitions and include files. */
47 #include "rldefs.h"
48 #include "rlmbutil.h"
49
50 #if defined (TIOCSTAT_IN_SYS_IOCTL)
51 # include <sys/ioctl.h>
52 #endif /* TIOCSTAT_IN_SYS_IOCTL */
53
54 /* Some standard library routines. */
55 #include "readline.h"
56
57 #include "rlprivate.h"
58 #include "xmalloc.h"
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;
70 static const char *pathname_alphabetic_chars = "/-_=~.#$";
71
72 int
rl_alphabetic(c)73 rl_alphabetic (c)
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 #if defined (HANDLE_MULTIBYTE)
84 int
_rl_walphabetic(wc)85 _rl_walphabetic (wc)
86 wchar_t wc;
87 {
88 int c;
89
90 if (iswalnum (wc))
91 return (1);
92
93 c = wc & 0177;
94 return (_rl_allow_pathname_alphabetic_chars &&
95 strchr (pathname_alphabetic_chars, c) != NULL);
96 }
97 #endif
98
99 /* How to abort things. */
100 int
_rl_abort_internal()101 _rl_abort_internal ()
102 {
103 rl_ding ();
104 rl_clear_message ();
105 _rl_reset_argument ();
106 rl_clear_pending_input ();
107
108 RL_UNSETSTATE (RL_STATE_MACRODEF);
109 while (rl_executing_macro)
110 _rl_pop_executing_macro ();
111
112 rl_last_func = (rl_command_func_t *)NULL;
113 longjmp (readline_top_level, 1);
114 return (0);
115 }
116
117 int
rl_abort(count,key)118 rl_abort (count, key)
119 int count, key;
120 {
121 return (_rl_abort_internal ());
122 }
123
124 int
rl_tty_status(count,key)125 rl_tty_status (count, key)
126 int count, key;
127 {
128 #if defined (TIOCSTAT)
129 ioctl (1, TIOCSTAT, (char *)0);
130 rl_refresh_line (count, key);
131 #else
132 rl_ding ();
133 #endif
134 return 0;
135 }
136
137 /* Return a copy of the string between FROM and TO.
138 FROM is inclusive, TO is not. */
139 char *
rl_copy_text(from,to)140 rl_copy_text (from, to)
141 int from, to;
142 {
143 register int length;
144 char *copy;
145
146 /* Fix it if the caller is confused. */
147 if (from > to)
148 SWAP (from, to);
149
150 length = to - from;
151 copy = (char *)xmalloc (1 + length);
152 strncpy (copy, rl_line_buffer + from, length);
153 copy[length] = '\0';
154 return (copy);
155 }
156
157 /* Increase the size of RL_LINE_BUFFER until it has enough space to hold
158 LEN characters. */
159 void
rl_extend_line_buffer(len)160 rl_extend_line_buffer (len)
161 int len;
162 {
163 while (len >= rl_line_buffer_len)
164 {
165 rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
166 rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
167 }
168
169 _rl_set_the_line ();
170 }
171
172
173 /* A function for simple tilde expansion. */
174 int
rl_tilde_expand(ignore,key)175 rl_tilde_expand (ignore, key)
176 int ignore, key;
177 {
178 register int start, end;
179 char *homedir, *temp;
180 int len;
181
182 end = rl_point;
183 start = end - 1;
184
185 if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
186 {
187 homedir = tilde_expand ("~");
188 _rl_replace_text (homedir, start, end);
189 return (0);
190 }
191 else if (rl_line_buffer[start] != '~')
192 {
193 for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
194 ;
195 start++;
196 }
197
198 end = start;
199 do
200 end++;
201 while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
202
203 if (whitespace (rl_line_buffer[end]) || end >= rl_end)
204 end--;
205
206 /* If the first character of the current word is a tilde, perform
207 tilde expansion and insert the result. If not a tilde, do
208 nothing. */
209 if (rl_line_buffer[start] == '~')
210 {
211 len = end - start + 1;
212 temp = (char *)xmalloc (len + 1);
213 strncpy (temp, rl_line_buffer + start, len);
214 temp[len] = '\0';
215 homedir = tilde_expand (temp);
216 free (temp);
217
218 _rl_replace_text (homedir, start, end);
219 }
220
221 return (0);
222 }
223
224 /* **************************************************************** */
225 /* */
226 /* String Utility Functions */
227 /* */
228 /* **************************************************************** */
229
230 /* Determine if s2 occurs in s1. If so, return a pointer to the
231 match in s1. The compare is case insensitive. */
232 char *
_rl_strindex(s1,s2)233 _rl_strindex (s1, s2)
234 register const char *s1, *s2;
235 {
236 register int i, l, len;
237
238 for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
239 if (_rl_strnicmp (s1 + i, s2, l) == 0)
240 return ((char *) (s1 + i));
241 return ((char *)NULL);
242 }
243
244 #ifndef HAVE_STRPBRK
245 /* Find the first occurrence in STRING1 of any character from STRING2.
246 Return a pointer to the character in STRING1. */
247 char *
_rl_strpbrk(string1,string2)248 _rl_strpbrk (string1, string2)
249 const char *string1, *string2;
250 {
251 register const char *scan;
252 #if defined (HANDLE_MULTIBYTE)
253 mbstate_t ps;
254 register int i, v;
255
256 memset (&ps, 0, sizeof (mbstate_t));
257 #endif
258
259 for (; *string1; string1++)
260 {
261 for (scan = string2; *scan; scan++)
262 {
263 if (*string1 == *scan)
264 return ((char *)string1);
265 }
266 #if defined (HANDLE_MULTIBYTE)
267 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
268 {
269 v = _rl_get_char_len (string1, &ps);
270 if (v > 1)
271 string1 += v - 1; /* -1 to account for auto-increment in loop */
272 }
273 #endif
274 }
275 return ((char *)NULL);
276 }
277 #endif
278
279 #if !defined (HAVE_STRCASECMP)
280 /* Compare at most COUNT characters from string1 to string2. Case
281 doesn't matter. */
282 int
_rl_strnicmp(string1,string2,count)283 _rl_strnicmp (string1, string2, count)
284 char *string1, *string2;
285 int count;
286 {
287 register char ch1, ch2;
288
289 while (count)
290 {
291 ch1 = *string1++;
292 ch2 = *string2++;
293 if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
294 count--;
295 else
296 break;
297 }
298 return (count);
299 }
300
301 /* strcmp (), but caseless. */
302 int
_rl_stricmp(string1,string2)303 _rl_stricmp (string1, string2)
304 char *string1, *string2;
305 {
306 register char ch1, ch2;
307
308 while (*string1 && *string2)
309 {
310 ch1 = *string1++;
311 ch2 = *string2++;
312 if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
313 return (1);
314 }
315 return (*string1 - *string2);
316 }
317 #endif /* !HAVE_STRCASECMP */
318
319 /* Stupid comparison routine for qsort () ing strings. */
320 int
_rl_qsort_string_compare(s1,s2)321 _rl_qsort_string_compare (s1, s2)
322 char **s1, **s2;
323 {
324 #if defined (HAVE_STRCOLL)
325 return (strcoll (*s1, *s2));
326 #else
327 int result;
328
329 result = **s1 - **s2;
330 if (result == 0)
331 result = strcmp (*s1, *s2);
332
333 return result;
334 #endif
335 }
336
337 /* Function equivalents for the macros defined in chardefs.h. */
338 #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
339
340 FUNCTION_FOR_MACRO (_rl_digit_p)
341 FUNCTION_FOR_MACRO (_rl_digit_value)
342 FUNCTION_FOR_MACRO (_rl_lowercase_p)
343 FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
344 FUNCTION_FOR_MACRO (_rl_to_lower)
345 FUNCTION_FOR_MACRO (_rl_to_upper)
346 FUNCTION_FOR_MACRO (_rl_uppercase_p)
347
348 /* Backwards compatibility, now that savestring has been removed from
349 all `public' readline header files. */
350 #undef _rl_savestring
351 char *
352 _rl_savestring (s)
353 const char *s;
354 {
355 return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
356 }
357