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