123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527 |
- /* util.c -- readline utility functions */
- /* Copyright (C) 1987-2010 Free Software Foundation, Inc.
- This file is part of the GNU Readline Library (Readline), a library
- for reading lines of text with interactive input and history editing.
- Readline is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
- Readline is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with Readline. If not, see <http://www.gnu.org/licenses/>.
- */
- #define READLINE_LIBRARY
- #if defined (HAVE_CONFIG_H)
- # include <config.h>
- #endif
- #include <sys/types.h>
- #include <fcntl.h>
- #include "posixjmp.h"
- #if defined (HAVE_UNISTD_H)
- # include <unistd.h> /* for _POSIX_VERSION */
- #endif /* HAVE_UNISTD_H */
- #if defined (HAVE_STDLIB_H)
- # include <stdlib.h>
- #else
- # include "ansi_stdlib.h"
- #endif /* HAVE_STDLIB_H */
- #include <stdio.h>
- #include <ctype.h>
- /* System-specific feature definitions and include files. */
- #include "rldefs.h"
- #include "rlmbutil.h"
- #if defined (TIOCSTAT_IN_SYS_IOCTL)
- # include <sys/ioctl.h>
- #endif /* TIOCSTAT_IN_SYS_IOCTL */
- /* Some standard library routines. */
- #include "readline.h"
- #include "rlprivate.h"
- #include "xmalloc.h"
- /* **************************************************************** */
- /* */
- /* Utility Functions */
- /* */
- /* **************************************************************** */
- /* Return 0 if C is not a member of the class of characters that belong
- in words, or 1 if it is. */
- int _rl_allow_pathname_alphabetic_chars = 0;
- static const char * const pathname_alphabetic_chars = "/-_=~.#$";
- int
- rl_alphabetic (c)
- int c;
- {
- if (ALPHABETIC (c))
- return (1);
- return (_rl_allow_pathname_alphabetic_chars &&
- strchr (pathname_alphabetic_chars, c) != NULL);
- }
- #if defined (HANDLE_MULTIBYTE)
- int
- _rl_walphabetic (wchar_t wc)
- {
- int c;
- if (iswalnum (wc))
- return (1);
- c = wc & 0177;
- return (_rl_allow_pathname_alphabetic_chars &&
- strchr (pathname_alphabetic_chars, c) != NULL);
- }
- #endif
- /* How to abort things. */
- int
- _rl_abort_internal ()
- {
- rl_ding ();
- rl_clear_message ();
- _rl_reset_argument ();
- rl_clear_pending_input ();
- RL_UNSETSTATE (RL_STATE_MACRODEF);
- while (rl_executing_macro)
- _rl_pop_executing_macro ();
- rl_last_func = (rl_command_func_t *)NULL;
- longjmp (_rl_top_level, 1);
- return (0);
- }
- int
- rl_abort (count, key)
- int count, key;
- {
- return (_rl_abort_internal ());
- }
- int
- _rl_null_function (count, key)
- int count, key;
- {
- return 0;
- }
- int
- rl_tty_status (count, key)
- int count, key;
- {
- #if defined (TIOCSTAT)
- ioctl (1, TIOCSTAT, (char *)0);
- rl_refresh_line (count, key);
- #else
- rl_ding ();
- #endif
- return 0;
- }
- /* Return a copy of the string between FROM and TO.
- FROM is inclusive, TO is not. */
- char *
- rl_copy_text (from, to)
- int from, to;
- {
- register int length;
- char *copy;
- /* Fix it if the caller is confused. */
- if (from > to)
- SWAP (from, to);
- length = to - from;
- copy = (char *)xmalloc (1 + length);
- strncpy (copy, rl_line_buffer + from, length);
- copy[length] = '\0';
- return (copy);
- }
- /* Increase the size of RL_LINE_BUFFER until it has enough space to hold
- LEN characters. */
- void
- rl_extend_line_buffer (len)
- int len;
- {
- while (len >= rl_line_buffer_len)
- {
- rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
- rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
- }
- _rl_set_the_line ();
- }
- /* A function for simple tilde expansion. */
- int
- rl_tilde_expand (ignore, key)
- int ignore, key;
- {
- register int start, end;
- char *homedir, *temp;
- int len;
- end = rl_point;
- start = end - 1;
- if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
- {
- homedir = tilde_expand ("~");
- _rl_replace_text (homedir, start, end);
- xfree (homedir);
- return (0);
- }
- else if (rl_line_buffer[start] != '~')
- {
- for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
- ;
- start++;
- }
- end = start;
- do
- end++;
- while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
- if (whitespace (rl_line_buffer[end]) || end >= rl_end)
- end--;
- /* If the first character of the current word is a tilde, perform
- tilde expansion and insert the result. If not a tilde, do
- nothing. */
- if (rl_line_buffer[start] == '~')
- {
- len = end - start + 1;
- temp = (char *)xmalloc (len + 1);
- strncpy (temp, rl_line_buffer + start, len);
- temp[len] = '\0';
- homedir = tilde_expand (temp);
- xfree (temp);
- _rl_replace_text (homedir, start, end);
- xfree (homedir);
- }
- return (0);
- }
- #if defined (USE_VARARGS)
- void
- #if defined (PREFER_STDARG)
- _rl_ttymsg (const char *format, ...)
- #else
- _rl_ttymsg (va_alist)
- va_dcl
- #endif
- {
- va_list args;
- #if defined (PREFER_VARARGS)
- char *format;
- #endif
- #if defined (PREFER_STDARG)
- va_start (args, format);
- #else
- va_start (args);
- format = va_arg (args, char *);
- #endif
- fprintf (stderr, "readline: ");
- vfprintf (stderr, format, args);
- fprintf (stderr, "\n");
- fflush (stderr);
- va_end (args);
- rl_forced_update_display ();
- }
- void
- #if defined (PREFER_STDARG)
- _rl_errmsg (const char *format, ...)
- #else
- _rl_errmsg (va_alist)
- va_dcl
- #endif
- {
- va_list args;
- #if defined (PREFER_VARARGS)
- char *format;
- #endif
- #if defined (PREFER_STDARG)
- va_start (args, format);
- #else
- va_start (args);
- format = va_arg (args, char *);
- #endif
- fprintf (stderr, "readline: ");
- vfprintf (stderr, format, args);
- fprintf (stderr, "\n");
- fflush (stderr);
- va_end (args);
- }
- #else /* !USE_VARARGS */
- void
- _rl_ttymsg (format, arg1, arg2)
- char *format;
- {
- fprintf (stderr, "readline: ");
- fprintf (stderr, format, arg1, arg2);
- fprintf (stderr, "\n");
- rl_forced_update_display ();
- }
- void
- _rl_errmsg (format, arg1, arg2)
- char *format;
- {
- fprintf (stderr, "readline: ");
- fprintf (stderr, format, arg1, arg2);
- fprintf (stderr, "\n");
- }
- #endif /* !USE_VARARGS */
- /* **************************************************************** */
- /* */
- /* String Utility Functions */
- /* */
- /* **************************************************************** */
- /* Determine if s2 occurs in s1. If so, return a pointer to the
- match in s1. The compare is case insensitive. */
- char *
- _rl_strindex (s1, s2)
- register const char *s1, *s2;
- {
- register int i, l, len;
- for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
- if (_rl_strnicmp (s1 + i, s2, l) == 0)
- return ((char *) (s1 + i));
- return ((char *)NULL);
- }
- #ifndef HAVE_STRPBRK
- /* Find the first occurrence in STRING1 of any character from STRING2.
- Return a pointer to the character in STRING1. */
- char *
- _rl_strpbrk (string1, string2)
- const char *string1, *string2;
- {
- register const char *scan;
- #if defined (HANDLE_MULTIBYTE)
- mbstate_t ps;
- register int i, v;
- memset (&ps, 0, sizeof (mbstate_t));
- #endif
- for (; *string1; string1++)
- {
- for (scan = string2; *scan; scan++)
- {
- if (*string1 == *scan)
- return ((char *)string1);
- }
- #if defined (HANDLE_MULTIBYTE)
- if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
- {
- v = _rl_get_char_len (string1, &ps);
- if (v > 1)
- string1 += v - 1; /* -1 to account for auto-increment in loop */
- }
- #endif
- }
- return ((char *)NULL);
- }
- #endif
- #if !defined (HAVE_STRCASECMP)
- /* Compare at most COUNT characters from string1 to string2. Case
- doesn't matter (strncasecmp). */
- int
- _rl_strnicmp (string1, string2, count)
- char *string1, *string2;
- int count;
- {
- register char *s1, *s2;
- int d;
- if (count <= 0 || (string1 == string2))
- return 0;
- s1 = string1;
- s2 = string2;
- do
- {
- d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
- if (d != 0)
- return d;
- if (*s1++ == '\0')
- break;
- s2++;
- }
- while (--count != 0);
- return (0);
- }
- /* strcmp (), but caseless (strcasecmp). */
- int
- _rl_stricmp (string1, string2)
- char *string1, *string2;
- {
- register char *s1, *s2;
- int d;
- s1 = string1;
- s2 = string2;
- if (s1 == s2)
- return 0;
- while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
- {
- if (*s1++ == '\0')
- return 0;
- s2++;
- }
- return (d);
- }
- #endif /* !HAVE_STRCASECMP */
- /* Stupid comparison routine for qsort () ing strings. */
- int
- _rl_qsort_string_compare (s1, s2)
- char **s1, **s2;
- {
- #if defined (HAVE_STRCOLL)
- return (strcoll (*s1, *s2));
- #else
- int result;
- result = **s1 - **s2;
- if (result == 0)
- result = strcmp (*s1, *s2);
- return result;
- #endif
- }
- /* Function equivalents for the macros defined in chardefs.h. */
- #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
- FUNCTION_FOR_MACRO (_rl_digit_p)
- FUNCTION_FOR_MACRO (_rl_digit_value)
- FUNCTION_FOR_MACRO (_rl_lowercase_p)
- FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
- FUNCTION_FOR_MACRO (_rl_to_lower)
- FUNCTION_FOR_MACRO (_rl_to_upper)
- FUNCTION_FOR_MACRO (_rl_uppercase_p)
- /* A convenience function, to force memory deallocation to be performed
- by readline. DLLs on Windows apparently require this. */
- void
- rl_free (mem)
- void *mem;
- {
- if (mem)
- free (mem);
- }
- /* Backwards compatibility, now that savestring has been removed from
- all `public' readline header files. */
- #undef _rl_savestring
- char *
- _rl_savestring (s)
- const char *s;
- {
- return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
- }
- #if defined (USE_VARARGS)
- static FILE *_rl_tracefp;
- void
- #if defined (PREFER_STDARG)
- _rl_trace (const char *format, ...)
- #else
- _rl_trace (va_alist)
- va_dcl
- #endif
- {
- va_list args;
- #if defined (PREFER_VARARGS)
- char *format;
- #endif
- #if defined (PREFER_STDARG)
- va_start (args, format);
- #else
- va_start (args);
- format = va_arg (args, char *);
- #endif
- if (_rl_tracefp == 0)
- _rl_tropen ();
- vfprintf (_rl_tracefp, format, args);
- fprintf (_rl_tracefp, "\n");
- fflush (_rl_tracefp);
- va_end (args);
- }
- int
- _rl_tropen ()
- {
- char fnbuf[128];
- if (_rl_tracefp)
- fclose (_rl_tracefp);
- sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid());
- unlink(fnbuf);
- _rl_tracefp = fopen (fnbuf, "w+");
- return _rl_tracefp != 0;
- }
- int
- _rl_trclose ()
- {
- int r;
- r = fclose (_rl_tracefp);
- _rl_tracefp = 0;
- return r;
- }
- #endif
|