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