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-1301, 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
68int _rl_allow_pathname_alphabetic_chars = 0;
69static const char *pathname_alphabetic_chars = "/-_=~.#$";
70
71int
72rl_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)
83int
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*/
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. */
104int
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
121int
122rl_abort (count, key)
123 int count __attribute__((unused)), key __attribute__((unused));
124{
125 return (_rl_abort_internal ());
126}
127
128int
129rl_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. */
143char *
144rl_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. */
163void
164rl_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. */
178int
179rl_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. */
236char *
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. */
251char *
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. */
286int
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. */
306int
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. */
324int
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
344FUNCTION_FOR_MACRO (_rl_digit_p)
345FUNCTION_FOR_MACRO (_rl_digit_value)
346FUNCTION_FOR_MACRO (_rl_lowercase_p)
347FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
348FUNCTION_FOR_MACRO (_rl_to_lower)
349FUNCTION_FOR_MACRO (_rl_to_upper)
350FUNCTION_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
355char *
356_rl_savestring (s)
357 const char *s;
358{
359 return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
360}
361