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-1335  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
rl_alphabetic(c)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 */
_rl_walphabetic(wchar_t wc)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
_rl_abort_internal()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
rl_abort(count,key)122 rl_abort (count, key)
123      int count __attribute__((unused)), key __attribute__((unused));
124 {
125   return (_rl_abort_internal ());
126 }
127 
128 int
rl_tty_status(count,key)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 *
rl_copy_text(from,to)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
rl_extend_line_buffer(len)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
rl_tilde_expand(ignore,key)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 *
_rl_strindex(s1,s2)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 *
_rl_strpbrk(string1,string2)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
_rl_strnicmp(string1,string2,count)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
_rl_stricmp(string1,string2)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
_rl_qsort_string_compare(s1,s2)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