11acd27e7Smillert /* util.c -- readline utility functions */
21acd27e7Smillert
31acd27e7Smillert /* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
41acd27e7Smillert
51acd27e7Smillert This file is part of the GNU Readline Library, a library for
61acd27e7Smillert reading lines of text with interactive input and history editing.
71acd27e7Smillert
81acd27e7Smillert The GNU Readline Library is free software; you can redistribute it
91acd27e7Smillert and/or modify it under the terms of the GNU General Public License
101acd27e7Smillert as published by the Free Software Foundation; either version 2, or
111acd27e7Smillert (at your option) any later version.
121acd27e7Smillert
131acd27e7Smillert The GNU Readline Library is distributed in the hope that it will be
141acd27e7Smillert useful, but WITHOUT ANY WARRANTY; without even the implied warranty
151acd27e7Smillert of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
161acd27e7Smillert GNU General Public License for more details.
171acd27e7Smillert
181acd27e7Smillert The GNU General Public License is often shipped with GNU software, and
191acd27e7Smillert is generally kept in a file called COPYING or LICENSE. If you do not
201acd27e7Smillert have a copy of the license, write to the Free Software Foundation,
211acd27e7Smillert 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
221acd27e7Smillert #define READLINE_LIBRARY
231acd27e7Smillert
241acd27e7Smillert #if defined (HAVE_CONFIG_H)
251acd27e7Smillert # include <config.h>
261acd27e7Smillert #endif
271acd27e7Smillert
281acd27e7Smillert #include <sys/types.h>
291acd27e7Smillert #include <fcntl.h>
301acd27e7Smillert #include "posixjmp.h"
311acd27e7Smillert
321acd27e7Smillert #if defined (HAVE_UNISTD_H)
331acd27e7Smillert # include <unistd.h> /* for _POSIX_VERSION */
341acd27e7Smillert #endif /* HAVE_UNISTD_H */
351acd27e7Smillert
361acd27e7Smillert #if defined (HAVE_STDLIB_H)
371acd27e7Smillert # include <stdlib.h>
381acd27e7Smillert #else
391acd27e7Smillert # include "ansi_stdlib.h"
401acd27e7Smillert #endif /* HAVE_STDLIB_H */
411acd27e7Smillert
421acd27e7Smillert #include <stdio.h>
431acd27e7Smillert #include <ctype.h>
441acd27e7Smillert
451acd27e7Smillert /* System-specific feature definitions and include files. */
461acd27e7Smillert #include "rldefs.h"
471acd27e7Smillert
481acd27e7Smillert #if defined (TIOCSTAT_IN_SYS_IOCTL)
491acd27e7Smillert # include <sys/ioctl.h>
501acd27e7Smillert #endif /* TIOCSTAT_IN_SYS_IOCTL */
511acd27e7Smillert
521acd27e7Smillert /* Some standard library routines. */
531acd27e7Smillert #include "readline.h"
541acd27e7Smillert
551acd27e7Smillert #include "rlprivate.h"
561acd27e7Smillert #include "xmalloc.h"
571acd27e7Smillert
581acd27e7Smillert /* **************************************************************** */
591acd27e7Smillert /* */
601acd27e7Smillert /* Utility Functions */
611acd27e7Smillert /* */
621acd27e7Smillert /* **************************************************************** */
631acd27e7Smillert
641acd27e7Smillert /* Return 0 if C is not a member of the class of characters that belong
651acd27e7Smillert in words, or 1 if it is. */
661acd27e7Smillert
671acd27e7Smillert int _rl_allow_pathname_alphabetic_chars = 0;
68*af70c2dfSkettenis static const char *pathname_alphabetic_chars = "/-_=~.#$";
691acd27e7Smillert
701acd27e7Smillert int
rl_alphabetic(c)71*af70c2dfSkettenis rl_alphabetic (c)
721acd27e7Smillert int c;
731acd27e7Smillert {
741acd27e7Smillert if (ALPHABETIC (c))
751acd27e7Smillert return (1);
761acd27e7Smillert
771acd27e7Smillert return (_rl_allow_pathname_alphabetic_chars &&
781acd27e7Smillert strchr (pathname_alphabetic_chars, c) != NULL);
791acd27e7Smillert }
801acd27e7Smillert
811acd27e7Smillert /* How to abort things. */
821acd27e7Smillert int
_rl_abort_internal()831acd27e7Smillert _rl_abort_internal ()
841acd27e7Smillert {
85*af70c2dfSkettenis rl_ding ();
861acd27e7Smillert rl_clear_message ();
871acd27e7Smillert _rl_init_argument ();
88*af70c2dfSkettenis rl_clear_pending_input ();
891acd27e7Smillert
90*af70c2dfSkettenis RL_UNSETSTATE (RL_STATE_MACRODEF);
91*af70c2dfSkettenis while (rl_executing_macro)
921acd27e7Smillert _rl_pop_executing_macro ();
931acd27e7Smillert
94*af70c2dfSkettenis rl_last_func = (rl_command_func_t *)NULL;
951acd27e7Smillert longjmp (readline_top_level, 1);
961acd27e7Smillert return (0);
971acd27e7Smillert }
981acd27e7Smillert
991acd27e7Smillert int
rl_abort(count,key)1001acd27e7Smillert rl_abort (count, key)
1011acd27e7Smillert int count, key;
1021acd27e7Smillert {
1031acd27e7Smillert return (_rl_abort_internal ());
1041acd27e7Smillert }
1051acd27e7Smillert
1061acd27e7Smillert int
rl_tty_status(count,key)1071acd27e7Smillert rl_tty_status (count, key)
1081acd27e7Smillert int count, key;
1091acd27e7Smillert {
1101acd27e7Smillert #if defined (TIOCSTAT)
1111acd27e7Smillert ioctl (1, TIOCSTAT, (char *)0);
1121acd27e7Smillert rl_refresh_line (count, key);
1131acd27e7Smillert #else
114*af70c2dfSkettenis rl_ding ();
1151acd27e7Smillert #endif
1161acd27e7Smillert return 0;
1171acd27e7Smillert }
1181acd27e7Smillert
1191acd27e7Smillert /* Return a copy of the string between FROM and TO.
1201acd27e7Smillert FROM is inclusive, TO is not. */
1211acd27e7Smillert char *
rl_copy_text(from,to)1221acd27e7Smillert rl_copy_text (from, to)
1231acd27e7Smillert int from, to;
1241acd27e7Smillert {
1251acd27e7Smillert register int length;
1261acd27e7Smillert char *copy;
1271acd27e7Smillert
1281acd27e7Smillert /* Fix it if the caller is confused. */
1291acd27e7Smillert if (from > to)
1301acd27e7Smillert SWAP (from, to);
1311acd27e7Smillert
1321acd27e7Smillert length = to - from;
133*af70c2dfSkettenis copy = (char *)xmalloc (1 + length);
1341acd27e7Smillert strncpy (copy, rl_line_buffer + from, length);
1351acd27e7Smillert copy[length] = '\0';
1361acd27e7Smillert return (copy);
1371acd27e7Smillert }
1381acd27e7Smillert
1391acd27e7Smillert /* Increase the size of RL_LINE_BUFFER until it has enough space to hold
1401acd27e7Smillert LEN characters. */
1411acd27e7Smillert void
rl_extend_line_buffer(len)1421acd27e7Smillert rl_extend_line_buffer (len)
1431acd27e7Smillert int len;
1441acd27e7Smillert {
1451acd27e7Smillert while (len >= rl_line_buffer_len)
1461acd27e7Smillert {
1471acd27e7Smillert rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
148*af70c2dfSkettenis rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
1491acd27e7Smillert }
1501acd27e7Smillert
1511acd27e7Smillert _rl_set_the_line ();
1521acd27e7Smillert }
1531acd27e7Smillert
1541acd27e7Smillert
1551acd27e7Smillert /* A function for simple tilde expansion. */
1561acd27e7Smillert int
rl_tilde_expand(ignore,key)1571acd27e7Smillert rl_tilde_expand (ignore, key)
1581acd27e7Smillert int ignore, key;
1591acd27e7Smillert {
1601acd27e7Smillert register int start, end;
1611acd27e7Smillert char *homedir, *temp;
1621acd27e7Smillert int len;
1631acd27e7Smillert
1641acd27e7Smillert end = rl_point;
1651acd27e7Smillert start = end - 1;
1661acd27e7Smillert
1671acd27e7Smillert if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
1681acd27e7Smillert {
1691acd27e7Smillert homedir = tilde_expand ("~");
1701acd27e7Smillert _rl_replace_text (homedir, start, end);
1711acd27e7Smillert return (0);
1721acd27e7Smillert }
1731acd27e7Smillert else if (rl_line_buffer[start] != '~')
1741acd27e7Smillert {
1751acd27e7Smillert for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
1761acd27e7Smillert ;
1771acd27e7Smillert start++;
1781acd27e7Smillert }
1791acd27e7Smillert
1801acd27e7Smillert end = start;
1811acd27e7Smillert do
1821acd27e7Smillert end++;
1831acd27e7Smillert while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
1841acd27e7Smillert
1851acd27e7Smillert if (whitespace (rl_line_buffer[end]) || end >= rl_end)
1861acd27e7Smillert end--;
1871acd27e7Smillert
1881acd27e7Smillert /* If the first character of the current word is a tilde, perform
1891acd27e7Smillert tilde expansion and insert the result. If not a tilde, do
1901acd27e7Smillert nothing. */
1911acd27e7Smillert if (rl_line_buffer[start] == '~')
1921acd27e7Smillert {
1931acd27e7Smillert len = end - start + 1;
194*af70c2dfSkettenis temp = (char *)xmalloc (len + 1);
1951acd27e7Smillert strncpy (temp, rl_line_buffer + start, len);
1961acd27e7Smillert temp[len] = '\0';
1971acd27e7Smillert homedir = tilde_expand (temp);
1981acd27e7Smillert free (temp);
1991acd27e7Smillert
2001acd27e7Smillert _rl_replace_text (homedir, start, end);
2011acd27e7Smillert }
2021acd27e7Smillert
2031acd27e7Smillert return (0);
2041acd27e7Smillert }
2051acd27e7Smillert
2061acd27e7Smillert /* **************************************************************** */
2071acd27e7Smillert /* */
2081acd27e7Smillert /* String Utility Functions */
2091acd27e7Smillert /* */
2101acd27e7Smillert /* **************************************************************** */
2111acd27e7Smillert
2121acd27e7Smillert /* Determine if s2 occurs in s1. If so, return a pointer to the
2131acd27e7Smillert match in s1. The compare is case insensitive. */
2141acd27e7Smillert char *
_rl_strindex(s1,s2)2151acd27e7Smillert _rl_strindex (s1, s2)
216*af70c2dfSkettenis register const char *s1, *s2;
2171acd27e7Smillert {
2181acd27e7Smillert register int i, l, len;
2191acd27e7Smillert
2201acd27e7Smillert for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
2211acd27e7Smillert if (_rl_strnicmp (s1 + i, s2, l) == 0)
222*af70c2dfSkettenis return ((char *) (s1 + i));
2231acd27e7Smillert return ((char *)NULL);
2241acd27e7Smillert }
2251acd27e7Smillert
226*af70c2dfSkettenis #ifndef HAVE_STRPBRK
227*af70c2dfSkettenis /* Find the first occurrence in STRING1 of any character from STRING2.
228*af70c2dfSkettenis Return a pointer to the character in STRING1. */
229*af70c2dfSkettenis char *
_rl_strpbrk(string1,string2)230*af70c2dfSkettenis _rl_strpbrk (string1, string2)
231*af70c2dfSkettenis const char *string1, *string2;
232*af70c2dfSkettenis {
233*af70c2dfSkettenis register const char *scan;
234*af70c2dfSkettenis #if defined (HANDLE_MULTIBYTE)
235*af70c2dfSkettenis mbstate_t ps;
236*af70c2dfSkettenis register int i, v;
237*af70c2dfSkettenis
238*af70c2dfSkettenis memset (&ps, 0, sizeof (mbstate_t));
239*af70c2dfSkettenis #endif
240*af70c2dfSkettenis
241*af70c2dfSkettenis for (; *string1; string1++)
242*af70c2dfSkettenis {
243*af70c2dfSkettenis for (scan = string2; *scan; scan++)
244*af70c2dfSkettenis {
245*af70c2dfSkettenis if (*string1 == *scan)
246*af70c2dfSkettenis return ((char *)string1);
247*af70c2dfSkettenis }
248*af70c2dfSkettenis #if defined (HANDLE_MULTIBYTE)
249*af70c2dfSkettenis if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
250*af70c2dfSkettenis {
251*af70c2dfSkettenis v = _rl_get_char_len (string1, &ps);
252*af70c2dfSkettenis if (v > 1)
253*af70c2dfSkettenis string += v - 1; /* -1 to account for auto-increment in loop */
254*af70c2dfSkettenis }
255*af70c2dfSkettenis #endif
256*af70c2dfSkettenis }
257*af70c2dfSkettenis return ((char *)NULL);
258*af70c2dfSkettenis }
259*af70c2dfSkettenis #endif
260*af70c2dfSkettenis
2611acd27e7Smillert #if !defined (HAVE_STRCASECMP)
2621acd27e7Smillert /* Compare at most COUNT characters from string1 to string2. Case
2631acd27e7Smillert doesn't matter. */
2641acd27e7Smillert int
_rl_strnicmp(string1,string2,count)2651acd27e7Smillert _rl_strnicmp (string1, string2, count)
2661acd27e7Smillert char *string1, *string2;
2671acd27e7Smillert int count;
2681acd27e7Smillert {
2691acd27e7Smillert register char ch1, ch2;
2701acd27e7Smillert
2711acd27e7Smillert while (count)
2721acd27e7Smillert {
2731acd27e7Smillert ch1 = *string1++;
2741acd27e7Smillert ch2 = *string2++;
2751acd27e7Smillert if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
2761acd27e7Smillert count--;
2771acd27e7Smillert else
2781acd27e7Smillert break;
2791acd27e7Smillert }
2801acd27e7Smillert return (count);
2811acd27e7Smillert }
2821acd27e7Smillert
2831acd27e7Smillert /* strcmp (), but caseless. */
2841acd27e7Smillert int
_rl_stricmp(string1,string2)2851acd27e7Smillert _rl_stricmp (string1, string2)
2861acd27e7Smillert char *string1, *string2;
2871acd27e7Smillert {
2881acd27e7Smillert register char ch1, ch2;
2891acd27e7Smillert
2901acd27e7Smillert while (*string1 && *string2)
2911acd27e7Smillert {
2921acd27e7Smillert ch1 = *string1++;
2931acd27e7Smillert ch2 = *string2++;
2941acd27e7Smillert if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
2951acd27e7Smillert return (1);
2961acd27e7Smillert }
2971acd27e7Smillert return (*string1 - *string2);
2981acd27e7Smillert }
2991acd27e7Smillert #endif /* !HAVE_STRCASECMP */
3001acd27e7Smillert
3011acd27e7Smillert /* Stupid comparison routine for qsort () ing strings. */
3021acd27e7Smillert int
_rl_qsort_string_compare(s1,s2)3031acd27e7Smillert _rl_qsort_string_compare (s1, s2)
3041acd27e7Smillert char **s1, **s2;
3051acd27e7Smillert {
3061acd27e7Smillert #if defined (HAVE_STRCOLL)
3071acd27e7Smillert return (strcoll (*s1, *s2));
3081acd27e7Smillert #else
3091acd27e7Smillert int result;
3101acd27e7Smillert
3111acd27e7Smillert result = **s1 - **s2;
3121acd27e7Smillert if (result == 0)
3131acd27e7Smillert result = strcmp (*s1, *s2);
3141acd27e7Smillert
3151acd27e7Smillert return result;
3161acd27e7Smillert #endif
3171acd27e7Smillert }
3181acd27e7Smillert
319*af70c2dfSkettenis /* Function equivalents for the macros defined in chardefs.h. */
320*af70c2dfSkettenis #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
3211acd27e7Smillert
322*af70c2dfSkettenis FUNCTION_FOR_MACRO (_rl_digit_p)
323*af70c2dfSkettenis FUNCTION_FOR_MACRO (_rl_digit_value)
324*af70c2dfSkettenis FUNCTION_FOR_MACRO (_rl_lowercase_p)
325*af70c2dfSkettenis FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
326*af70c2dfSkettenis FUNCTION_FOR_MACRO (_rl_to_lower)
327*af70c2dfSkettenis FUNCTION_FOR_MACRO (_rl_to_upper)
328*af70c2dfSkettenis FUNCTION_FOR_MACRO (_rl_uppercase_p)
3291acd27e7Smillert
3301acd27e7Smillert /* Backwards compatibility, now that savestring has been removed from
3311acd27e7Smillert all `public' readline header files. */
3321acd27e7Smillert #undef _rl_savestring
3331acd27e7Smillert char *
3341acd27e7Smillert _rl_savestring (s)
335*af70c2dfSkettenis const char *s;
3361acd27e7Smillert {
33763bef317Sbeck char *cp;
33863bef317Sbeck cp = strdup(s);
33963bef317Sbeck if (cp == NULL)
34063bef317Sbeck memory_error_and_abort ("savestring");
34163bef317Sbeck return(cp);
3421acd27e7Smillert }
343