1 /* util.c -- readline utility functions */ 2 3 /* Copyright (C) 1987, 1989, 1992 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 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ 22 #define READLINE_LIBRARY 23 24 #if defined (HAVE_CONFIG_H) 25 # include <config.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 48 #if defined (TIOCSTAT_IN_SYS_IOCTL) 49 # include <sys/ioctl.h> 50 #endif /* TIOCSTAT_IN_SYS_IOCTL */ 51 52 /* Some standard library routines. */ 53 #include "readline.h" 54 55 #include "rlprivate.h" 56 #include "xmalloc.h" 57 58 /* **************************************************************** */ 59 /* */ 60 /* Utility Functions */ 61 /* */ 62 /* **************************************************************** */ 63 64 /* Return 0 if C is not a member of the class of characters that belong 65 in words, or 1 if it is. */ 66 67 int _rl_allow_pathname_alphabetic_chars = 0; 68 static const char *pathname_alphabetic_chars = "/-_=~.#$"; 69 70 int 71 rl_alphabetic (c) 72 int c; 73 { 74 if (ALPHABETIC (c)) 75 return (1); 76 77 return (_rl_allow_pathname_alphabetic_chars && 78 strchr (pathname_alphabetic_chars, c) != NULL); 79 } 80 81 /* How to abort things. */ 82 int 83 _rl_abort_internal () 84 { 85 rl_ding (); 86 rl_clear_message (); 87 _rl_init_argument (); 88 rl_clear_pending_input (); 89 90 RL_UNSETSTATE (RL_STATE_MACRODEF); 91 while (rl_executing_macro) 92 _rl_pop_executing_macro (); 93 94 rl_last_func = (rl_command_func_t *)NULL; 95 longjmp (readline_top_level, 1); 96 return (0); 97 } 98 99 int 100 rl_abort (count, key) 101 int count, key; 102 { 103 return (_rl_abort_internal ()); 104 } 105 106 int 107 rl_tty_status (count, key) 108 int count, key; 109 { 110 #if defined (TIOCSTAT) 111 ioctl (1, TIOCSTAT, (char *)0); 112 rl_refresh_line (count, key); 113 #else 114 rl_ding (); 115 #endif 116 return 0; 117 } 118 119 /* Return a copy of the string between FROM and TO. 120 FROM is inclusive, TO is not. */ 121 char * 122 rl_copy_text (from, to) 123 int from, to; 124 { 125 register int length; 126 char *copy; 127 128 /* Fix it if the caller is confused. */ 129 if (from > to) 130 SWAP (from, to); 131 132 length = to - from; 133 copy = (char *)xmalloc (1 + length); 134 strncpy (copy, rl_line_buffer + from, length); 135 copy[length] = '\0'; 136 return (copy); 137 } 138 139 /* Increase the size of RL_LINE_BUFFER until it has enough space to hold 140 LEN characters. */ 141 void 142 rl_extend_line_buffer (len) 143 int len; 144 { 145 while (len >= rl_line_buffer_len) 146 { 147 rl_line_buffer_len += DEFAULT_BUFFER_SIZE; 148 rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len); 149 } 150 151 _rl_set_the_line (); 152 } 153 154 155 /* A function for simple tilde expansion. */ 156 int 157 rl_tilde_expand (ignore, key) 158 int ignore, key; 159 { 160 register int start, end; 161 char *homedir, *temp; 162 int len; 163 164 end = rl_point; 165 start = end - 1; 166 167 if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') 168 { 169 homedir = tilde_expand ("~"); 170 _rl_replace_text (homedir, start, end); 171 return (0); 172 } 173 else if (rl_line_buffer[start] != '~') 174 { 175 for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) 176 ; 177 start++; 178 } 179 180 end = start; 181 do 182 end++; 183 while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); 184 185 if (whitespace (rl_line_buffer[end]) || end >= rl_end) 186 end--; 187 188 /* If the first character of the current word is a tilde, perform 189 tilde expansion and insert the result. If not a tilde, do 190 nothing. */ 191 if (rl_line_buffer[start] == '~') 192 { 193 len = end - start + 1; 194 temp = (char *)xmalloc (len + 1); 195 strncpy (temp, rl_line_buffer + start, len); 196 temp[len] = '\0'; 197 homedir = tilde_expand (temp); 198 free (temp); 199 200 _rl_replace_text (homedir, start, end); 201 } 202 203 return (0); 204 } 205 206 /* **************************************************************** */ 207 /* */ 208 /* String Utility Functions */ 209 /* */ 210 /* **************************************************************** */ 211 212 /* Determine if s2 occurs in s1. If so, return a pointer to the 213 match in s1. The compare is case insensitive. */ 214 char * 215 _rl_strindex (s1, s2) 216 register const char *s1, *s2; 217 { 218 register int i, l, len; 219 220 for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) 221 if (_rl_strnicmp (s1 + i, s2, l) == 0) 222 return ((char *) (s1 + i)); 223 return ((char *)NULL); 224 } 225 226 #ifndef HAVE_STRPBRK 227 /* Find the first occurrence in STRING1 of any character from STRING2. 228 Return a pointer to the character in STRING1. */ 229 char * 230 _rl_strpbrk (string1, string2) 231 const char *string1, *string2; 232 { 233 register const char *scan; 234 #if defined (HANDLE_MULTIBYTE) 235 mbstate_t ps; 236 register int i, v; 237 238 memset (&ps, 0, sizeof (mbstate_t)); 239 #endif 240 241 for (; *string1; string1++) 242 { 243 for (scan = string2; *scan; scan++) 244 { 245 if (*string1 == *scan) 246 return ((char *)string1); 247 } 248 #if defined (HANDLE_MULTIBYTE) 249 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 250 { 251 v = _rl_get_char_len (string1, &ps); 252 if (v > 1) 253 string += v - 1; /* -1 to account for auto-increment in loop */ 254 } 255 #endif 256 } 257 return ((char *)NULL); 258 } 259 #endif 260 261 #if !defined (HAVE_STRCASECMP) 262 /* Compare at most COUNT characters from string1 to string2. Case 263 doesn't matter. */ 264 int 265 _rl_strnicmp (string1, string2, count) 266 char *string1, *string2; 267 int count; 268 { 269 register char ch1, ch2; 270 271 while (count) 272 { 273 ch1 = *string1++; 274 ch2 = *string2++; 275 if (_rl_to_upper(ch1) == _rl_to_upper(ch2)) 276 count--; 277 else 278 break; 279 } 280 return (count); 281 } 282 283 /* strcmp (), but caseless. */ 284 int 285 _rl_stricmp (string1, string2) 286 char *string1, *string2; 287 { 288 register char ch1, ch2; 289 290 while (*string1 && *string2) 291 { 292 ch1 = *string1++; 293 ch2 = *string2++; 294 if (_rl_to_upper(ch1) != _rl_to_upper(ch2)) 295 return (1); 296 } 297 return (*string1 - *string2); 298 } 299 #endif /* !HAVE_STRCASECMP */ 300 301 /* Stupid comparison routine for qsort () ing strings. */ 302 int 303 _rl_qsort_string_compare (s1, s2) 304 char **s1, **s2; 305 { 306 #if defined (HAVE_STRCOLL) 307 return (strcoll (*s1, *s2)); 308 #else 309 int result; 310 311 result = **s1 - **s2; 312 if (result == 0) 313 result = strcmp (*s1, *s2); 314 315 return result; 316 #endif 317 } 318 319 /* Function equivalents for the macros defined in chardefs.h. */ 320 #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } 321 322 FUNCTION_FOR_MACRO (_rl_digit_p) 323 FUNCTION_FOR_MACRO (_rl_digit_value) 324 FUNCTION_FOR_MACRO (_rl_lowercase_p) 325 FUNCTION_FOR_MACRO (_rl_pure_alphabetic) 326 FUNCTION_FOR_MACRO (_rl_to_lower) 327 FUNCTION_FOR_MACRO (_rl_to_upper) 328 FUNCTION_FOR_MACRO (_rl_uppercase_p) 329 330 /* Backwards compatibility, now that savestring has been removed from 331 all `public' readline header files. */ 332 #undef _rl_savestring 333 char * 334 _rl_savestring (s) 335 const char *s; 336 { 337 char *cp; 338 cp = strdup(s); 339 if (cp == NULL) 340 memory_error_and_abort ("savestring"); 341 return(cp); 342 } 343