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