158314Sache/* $FreeBSD$ */ 221308Sache/* util.c -- readline utility functions */ 321308Sache 4157188Sache/* Copyright (C) 1987-2005 Free Software Foundation, Inc. 521308Sache 621308Sache This file is part of the GNU Readline Library, a library for 721308Sache reading lines of text with interactive input and history editing. 821308Sache 921308Sache The GNU Readline Library is free software; you can redistribute it 1021308Sache and/or modify it under the terms of the GNU General Public License 1158314Sache as published by the Free Software Foundation; either version 2, or 1221308Sache (at your option) any later version. 1321308Sache 1421308Sache The GNU Readline Library is distributed in the hope that it will be 1521308Sache useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1621308Sache of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1721308Sache GNU General Public License for more details. 1821308Sache 1921308Sache The GNU General Public License is often shipped with GNU software, and 2021308Sache is generally kept in a file called COPYING or LICENSE. If you do not 2121308Sache have a copy of the license, write to the Free Software Foundation, 2258314Sache 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 2321308Sache#define READLINE_LIBRARY 2421308Sache 2521308Sache#if defined (HAVE_CONFIG_H) 2621308Sache# include <config.h> 2721308Sache#endif 2821308Sache 2921308Sache#include <sys/types.h> 3021308Sache#include <fcntl.h> 3126500Sache#include "posixjmp.h" 3221308Sache 3321308Sache#if defined (HAVE_UNISTD_H) 3421308Sache# include <unistd.h> /* for _POSIX_VERSION */ 3521308Sache#endif /* HAVE_UNISTD_H */ 3621308Sache 3721308Sache#if defined (HAVE_STDLIB_H) 3821308Sache# include <stdlib.h> 3921308Sache#else 4021308Sache# include "ansi_stdlib.h" 4121308Sache#endif /* HAVE_STDLIB_H */ 4221308Sache 4326500Sache#include <stdio.h> 4426500Sache#include <ctype.h> 4526500Sache 4621308Sache/* System-specific feature definitions and include files. */ 4721308Sache#include "rldefs.h" 48157188Sache#include "rlmbutil.h" 4921308Sache 5021308Sache#if defined (TIOCSTAT_IN_SYS_IOCTL) 5121308Sache# include <sys/ioctl.h> 5221308Sache#endif /* TIOCSTAT_IN_SYS_IOCTL */ 5321308Sache 5421308Sache/* Some standard library routines. */ 5521308Sache#include "readline.h" 5621308Sache 5758314Sache#include "rlprivate.h" 5858314Sache#include "xmalloc.h" 5958314Sache 6021308Sache/* **************************************************************** */ 6121308Sache/* */ 6221308Sache/* Utility Functions */ 6321308Sache/* */ 6421308Sache/* **************************************************************** */ 6521308Sache 6621308Sache/* Return 0 if C is not a member of the class of characters that belong 6721308Sache in words, or 1 if it is. */ 6821308Sache 6921308Sacheint _rl_allow_pathname_alphabetic_chars = 0; 7075409Sachestatic const char *pathname_alphabetic_chars = "/-_=~.#$"; 7121308Sache 7221308Sacheint 7375409Sacherl_alphabetic (c) 7421308Sache int c; 7521308Sache{ 7621308Sache if (ALPHABETIC (c)) 7721308Sache return (1); 7821308Sache 7921308Sache return (_rl_allow_pathname_alphabetic_chars && 8021308Sache strchr (pathname_alphabetic_chars, c) != NULL); 8121308Sache} 8221308Sache 83157188Sache#if defined (HANDLE_MULTIBYTE) 84157188Sacheint 85157188Sache_rl_walphabetic (wc) 86157188Sache wchar_t wc; 87157188Sache{ 88157188Sache int c; 89157188Sache 90157188Sache if (iswalnum (wc)) 91157188Sache return (1); 92157188Sache 93157188Sache c = wc & 0177; 94157188Sache return (_rl_allow_pathname_alphabetic_chars && 95157188Sache strchr (pathname_alphabetic_chars, c) != NULL); 96157188Sache} 97157188Sache#endif 98157188Sache 9921308Sache/* How to abort things. */ 10021308Sacheint 10121308Sache_rl_abort_internal () 10221308Sache{ 10375409Sache rl_ding (); 10421308Sache rl_clear_message (); 105157188Sache _rl_reset_argument (); 10675409Sache rl_clear_pending_input (); 10721308Sache 108119614Sache RL_UNSETSTATE (RL_STATE_MACRODEF); 10975409Sache while (rl_executing_macro) 11021308Sache _rl_pop_executing_macro (); 11121308Sache 11275409Sache rl_last_func = (rl_command_func_t *)NULL; 11321308Sache longjmp (readline_top_level, 1); 11421308Sache return (0); 11521308Sache} 11621308Sache 11721308Sacheint 11821308Sacherl_abort (count, key) 11921308Sache int count, key; 12021308Sache{ 12121308Sache return (_rl_abort_internal ()); 12221308Sache} 12321308Sache 12421308Sacheint 12521308Sacherl_tty_status (count, key) 12621308Sache int count, key; 12721308Sache{ 12821308Sache#if defined (TIOCSTAT) 12921308Sache ioctl (1, TIOCSTAT, (char *)0); 13047563Sache rl_refresh_line (count, key); 13121308Sache#else 13275409Sache rl_ding (); 13321308Sache#endif 13421308Sache return 0; 13521308Sache} 13621308Sache 13721308Sache/* Return a copy of the string between FROM and TO. 13821308Sache FROM is inclusive, TO is not. */ 13921308Sachechar * 14021308Sacherl_copy_text (from, to) 14121308Sache int from, to; 14221308Sache{ 14321308Sache register int length; 14421308Sache char *copy; 14521308Sache 14621308Sache /* Fix it if the caller is confused. */ 14721308Sache if (from > to) 14821308Sache SWAP (from, to); 14921308Sache 15021308Sache length = to - from; 151119614Sache copy = (char *)xmalloc (1 + length); 15221308Sache strncpy (copy, rl_line_buffer + from, length); 15321308Sache copy[length] = '\0'; 15421308Sache return (copy); 15521308Sache} 15621308Sache 15721308Sache/* Increase the size of RL_LINE_BUFFER until it has enough space to hold 15821308Sache LEN characters. */ 15921308Sachevoid 16021308Sacherl_extend_line_buffer (len) 16121308Sache int len; 16221308Sache{ 16321308Sache while (len >= rl_line_buffer_len) 16421308Sache { 16521308Sache rl_line_buffer_len += DEFAULT_BUFFER_SIZE; 166119614Sache rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len); 16721308Sache } 16821308Sache 16921308Sache _rl_set_the_line (); 17021308Sache} 17121308Sache 17235489Sache 17335489Sache/* A function for simple tilde expansion. */ 17435489Sacheint 17535489Sacherl_tilde_expand (ignore, key) 17635489Sache int ignore, key; 17735489Sache{ 17835489Sache register int start, end; 17935489Sache char *homedir, *temp; 18035489Sache int len; 18135489Sache 18235489Sache end = rl_point; 18335489Sache start = end - 1; 18435489Sache 18535489Sache if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') 18635489Sache { 18735489Sache homedir = tilde_expand ("~"); 18835489Sache _rl_replace_text (homedir, start, end); 18935489Sache return (0); 19035489Sache } 19135489Sache else if (rl_line_buffer[start] != '~') 19235489Sache { 19335489Sache for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) 19435489Sache ; 19535489Sache start++; 19635489Sache } 19735489Sache 19835489Sache end = start; 19935489Sache do 20035489Sache end++; 20135489Sache while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); 20235489Sache 20335489Sache if (whitespace (rl_line_buffer[end]) || end >= rl_end) 20435489Sache end--; 20535489Sache 20635489Sache /* If the first character of the current word is a tilde, perform 20735489Sache tilde expansion and insert the result. If not a tilde, do 20835489Sache nothing. */ 20935489Sache if (rl_line_buffer[start] == '~') 21035489Sache { 21135489Sache len = end - start + 1; 212119614Sache temp = (char *)xmalloc (len + 1); 21335489Sache strncpy (temp, rl_line_buffer + start, len); 21435489Sache temp[len] = '\0'; 21535489Sache homedir = tilde_expand (temp); 21635489Sache free (temp); 21735489Sache 21835489Sache _rl_replace_text (homedir, start, end); 21935489Sache } 22035489Sache 22135489Sache return (0); 22235489Sache} 22335489Sache 22421308Sache/* **************************************************************** */ 22521308Sache/* */ 22621308Sache/* String Utility Functions */ 22721308Sache/* */ 22821308Sache/* **************************************************************** */ 22921308Sache 23021308Sache/* Determine if s2 occurs in s1. If so, return a pointer to the 23121308Sache match in s1. The compare is case insensitive. */ 23221308Sachechar * 23321308Sache_rl_strindex (s1, s2) 23475409Sache register const char *s1, *s2; 23521308Sache{ 23621308Sache register int i, l, len; 23721308Sache 23821308Sache for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) 23921308Sache if (_rl_strnicmp (s1 + i, s2, l) == 0) 24075409Sache return ((char *) (s1 + i)); 24121308Sache return ((char *)NULL); 24221308Sache} 24321308Sache 244119614Sache#ifndef HAVE_STRPBRK 24575409Sache/* Find the first occurrence in STRING1 of any character from STRING2. 24675409Sache Return a pointer to the character in STRING1. */ 24775409Sachechar * 24875409Sache_rl_strpbrk (string1, string2) 24975409Sache const char *string1, *string2; 25075409Sache{ 25175409Sache register const char *scan; 252119614Sache#if defined (HANDLE_MULTIBYTE) 253119614Sache mbstate_t ps; 254119614Sache register int i, v; 25575409Sache 256119614Sache memset (&ps, 0, sizeof (mbstate_t)); 257119614Sache#endif 258119614Sache 25975409Sache for (; *string1; string1++) 26075409Sache { 26175409Sache for (scan = string2; *scan; scan++) 26275409Sache { 26375409Sache if (*string1 == *scan) 26475409Sache return ((char *)string1); 26575409Sache } 266119614Sache#if defined (HANDLE_MULTIBYTE) 267119614Sache if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 268119614Sache { 269119614Sache v = _rl_get_char_len (string1, &ps); 270119614Sache if (v > 1) 271136759Speter string1 += v - 1; /* -1 to account for auto-increment in loop */ 272119614Sache } 273119614Sache#endif 27475409Sache } 27575409Sache return ((char *)NULL); 27675409Sache} 277119614Sache#endif 27875409Sache 27921308Sache#if !defined (HAVE_STRCASECMP) 28021308Sache/* Compare at most COUNT characters from string1 to string2. Case 28121308Sache doesn't matter. */ 28221308Sacheint 28321308Sache_rl_strnicmp (string1, string2, count) 28421308Sache char *string1, *string2; 28521308Sache int count; 28621308Sache{ 28721308Sache register char ch1, ch2; 28821308Sache 28921308Sache while (count) 29021308Sache { 29121308Sache ch1 = *string1++; 29221308Sache ch2 = *string2++; 29321308Sache if (_rl_to_upper(ch1) == _rl_to_upper(ch2)) 29421308Sache count--; 29521308Sache else 29621308Sache break; 29721308Sache } 29821308Sache return (count); 29921308Sache} 30021308Sache 30121308Sache/* strcmp (), but caseless. */ 30221308Sacheint 30321308Sache_rl_stricmp (string1, string2) 30421308Sache char *string1, *string2; 30521308Sache{ 30621308Sache register char ch1, ch2; 30721308Sache 30821308Sache while (*string1 && *string2) 30921308Sache { 31021308Sache ch1 = *string1++; 31121308Sache ch2 = *string2++; 31221308Sache if (_rl_to_upper(ch1) != _rl_to_upper(ch2)) 31321308Sache return (1); 31421308Sache } 31521308Sache return (*string1 - *string2); 31621308Sache} 31721308Sache#endif /* !HAVE_STRCASECMP */ 31821308Sache 31921308Sache/* Stupid comparison routine for qsort () ing strings. */ 32021308Sacheint 32121308Sache_rl_qsort_string_compare (s1, s2) 32221308Sache char **s1, **s2; 32321308Sache{ 32421308Sache#if defined (HAVE_STRCOLL) 32521308Sache return (strcoll (*s1, *s2)); 32621308Sache#else 32721308Sache int result; 32821308Sache 32921308Sache result = **s1 - **s2; 33021308Sache if (result == 0) 33121308Sache result = strcmp (*s1, *s2); 33221308Sache 33321308Sache return result; 33421308Sache#endif 33521308Sache} 33621308Sache 337119614Sache/* Function equivalents for the macros defined in chardefs.h. */ 338119614Sache#define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } 33921308Sache 340119614SacheFUNCTION_FOR_MACRO (_rl_digit_p) 341119614SacheFUNCTION_FOR_MACRO (_rl_digit_value) 342119614SacheFUNCTION_FOR_MACRO (_rl_lowercase_p) 343119614SacheFUNCTION_FOR_MACRO (_rl_pure_alphabetic) 344119614SacheFUNCTION_FOR_MACRO (_rl_to_lower) 345119614SacheFUNCTION_FOR_MACRO (_rl_to_upper) 346119614SacheFUNCTION_FOR_MACRO (_rl_uppercase_p) 34721308Sache 34835489Sache/* Backwards compatibility, now that savestring has been removed from 34935489Sache all `public' readline header files. */ 35035489Sache#undef _rl_savestring 35135489Sachechar * 35235489Sache_rl_savestring (s) 35375409Sache const char *s; 35435489Sache{ 355119614Sache return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); 35635489Sache} 357