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