6d0a6e38d9232957429d5d2fc99e302cd01239de
[platform/upstream/bash.git] / lib / readline / util.c
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
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    59 Temple Place, Suite 330, Boston, MA 02111 USA. */
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
55 #include "rlprivate.h"
56 #include "xmalloc.h"
57
58 #define SWAP(s, e)  do { int t; t = s; s = e; e = t; } while (0)
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
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 /* How to abort things. */
84 int
85 _rl_abort_internal ()
86 {
87   rl_ding ();
88   rl_clear_message ();
89   _rl_init_argument ();
90   rl_clear_pending_input ();
91
92   _rl_defining_kbd_macro = 0;
93   while (rl_executing_macro)
94     _rl_pop_executing_macro ();
95
96   rl_last_func = (rl_command_func_t *)NULL;
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);
114   rl_refresh_line (count, key);
115 #else
116   rl_ding ();
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
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
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)
218      register const char *s1, *s2;
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)
224       return ((char *) (s1 + i));
225   return ((char *)NULL);
226 }
227
228 /* Find the first occurrence in STRING1 of any character from STRING2.
229    Return a pointer to the character in STRING1. */
230 char *
231 _rl_strpbrk (string1, string2)
232      const char *string1, *string2;
233 {
234   register const char *scan;
235
236   for (; *string1; string1++)
237     {
238       for (scan = string2; *scan; scan++)
239         {
240           if (*string1 == *scan)
241             return ((char *)string1);
242         }
243     }
244   return ((char *)NULL);
245 }
246
247 #if !defined (HAVE_STRCASECMP)
248 /* Compare at most COUNT characters from string1 to string2.  Case
249    doesn't matter. */
250 int
251 _rl_strnicmp (string1, string2, count)
252      char *string1, *string2;
253      int count;
254 {
255   register char ch1, ch2;
256
257   while (count)
258     {
259       ch1 = *string1++;
260       ch2 = *string2++;
261       if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
262         count--;
263       else
264         break;
265     }
266   return (count);
267 }
268
269 /* strcmp (), but caseless. */
270 int
271 _rl_stricmp (string1, string2)
272      char *string1, *string2;
273 {
274   register char ch1, ch2;
275
276   while (*string1 && *string2)
277     {
278       ch1 = *string1++;
279       ch2 = *string2++;
280       if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
281         return (1);
282     }
283   return (*string1 - *string2);
284 }
285 #endif /* !HAVE_STRCASECMP */
286
287 /* Stupid comparison routine for qsort () ing strings. */
288 int
289 _rl_qsort_string_compare (s1, s2)
290   char **s1, **s2;
291 {
292 #if defined (HAVE_STRCOLL)
293   return (strcoll (*s1, *s2));
294 #else
295   int result;
296
297   result = **s1 - **s2;
298   if (result == 0)
299     result = strcmp (*s1, *s2);
300
301   return result;
302 #endif
303 }
304
305 /* Function equivalents for the macros defined in chartypes.h. */
306 #undef _rl_uppercase_p
307 int
308 _rl_uppercase_p (c)
309      int c;
310 {
311   return (isupper (c));
312 }
313
314 #undef _rl_lowercase_p
315 int
316 _rl_lowercase_p (c)
317      int c;
318 {
319   return (islower (c));
320 }
321
322 #undef _rl_pure_alphabetic
323 int
324 _rl_pure_alphabetic (c)
325      int c;
326 {
327   return (isupper (c) || islower (c));
328 }
329
330 #undef _rl_digit_p
331 int
332 _rl_digit_p (c)
333      int c;
334 {
335   return (isdigit (c));
336 }
337
338 #undef _rl_to_lower
339 int
340 _rl_to_lower (c)
341      int c;
342 {
343   return (isupper (c) ? tolower (c) : c);
344 }
345
346 #undef _rl_to_upper
347 int
348 _rl_to_upper (c)
349      int c;
350 {
351   return (islower (c) ? toupper (c) : c);
352 }
353
354 #undef _rl_digit_value
355 int
356 _rl_digit_value (c)
357      int c;
358 {
359   return (isdigit (c) ? c - '0' : c);
360 }
361
362 /* Backwards compatibility, now that savestring has been removed from
363    all `public' readline header files. */
364 #undef _rl_savestring
365 char *
366 _rl_savestring (s)
367      const char *s;
368 {
369   return (strcpy (xmalloc (1 + (int)strlen (s)), (s)));
370 }