1 /* util.c -- readline utility functions */ 2 3 /* Copyright (C) 1987-2010 Free Software Foundation, Inc. 4 5 This file is part of the GNU Readline Library (Readline), a library 6 for reading lines of text with interactive input and history editing. 7 8 Readline is free software: you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation, either version 3 of the License, or 11 (at your option) any later version. 12 13 Readline is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with Readline. If not, see <http://www.gnu.org/licenses/>. 20 */ 21 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 #include "rlmbutil.h" 48 49 #if defined (TIOCSTAT_IN_SYS_IOCTL) 50 # include <sys/ioctl.h> 51 #endif /* TIOCSTAT_IN_SYS_IOCTL */ 52 53 /* Some standard library routines. */ 54 #include "readline.h" 55 56 #include "rlprivate.h" 57 #include "xmalloc.h" 58 59 /* **************************************************************** */ 60 /* */ 61 /* Utility Functions */ 62 /* */ 63 /* **************************************************************** */ 64 65 /* Return 0 if C is not a member of the class of characters that belong 66 in words, or 1 if it is. */ 67 68 int _rl_allow_pathname_alphabetic_chars = 0; 69 static const char * const pathname_alphabetic_chars = "/-_=~.#$"; 70 71 int 72 rl_alphabetic (c) 73 int c; 74 { 75 if (ALPHABETIC (c)) 76 return (1); 77 78 return (_rl_allow_pathname_alphabetic_chars && 79 strchr (pathname_alphabetic_chars, c) != NULL); 80 } 81 82 #if defined (HANDLE_MULTIBYTE) 83 int 84 _rl_walphabetic (wchar_t wc) 85 { 86 int c; 87 88 if (iswalnum (wc)) 89 return (1); 90 91 c = wc & 0177; 92 return (_rl_allow_pathname_alphabetic_chars && 93 strchr (pathname_alphabetic_chars, c) != NULL); 94 } 95 #endif 96 97 /* How to abort things. */ 98 int 99 _rl_abort_internal () 100 { 101 rl_ding (); 102 rl_clear_message (); 103 _rl_reset_argument (); 104 rl_clear_pending_input (); 105 106 RL_UNSETSTATE (RL_STATE_MACRODEF); 107 while (rl_executing_macro) 108 _rl_pop_executing_macro (); 109 110 rl_last_func = (rl_command_func_t *)NULL; 111 longjmp (_rl_top_level, 1); 112 return (0); 113 } 114 115 int 116 rl_abort (count, key) 117 int count, key; 118 { 119 return (_rl_abort_internal ()); 120 } 121 122 int 123 _rl_null_function (count, key) 124 int count, key; 125 { 126 return 0; 127 } 128 129 int 130 rl_tty_status (count, key) 131 int count, key; 132 { 133 #if defined (TIOCSTAT) 134 ioctl (1, TIOCSTAT, (char *)0); 135 rl_refresh_line (count, key); 136 #else 137 rl_ding (); 138 #endif 139 return 0; 140 } 141 142 /* Return a copy of the string between FROM and TO. 143 FROM is inclusive, TO is not. */ 144 char * 145 rl_copy_text (from, to) 146 int from, to; 147 { 148 register int length; 149 char *copy; 150 151 /* Fix it if the caller is confused. */ 152 if (from > to) 153 SWAP (from, to); 154 155 length = to - from; 156 copy = (char *)xmalloc (1 + length); 157 strncpy (copy, rl_line_buffer + from, length); 158 copy[length] = '\0'; 159 return (copy); 160 } 161 162 /* Increase the size of RL_LINE_BUFFER until it has enough space to hold 163 LEN characters. */ 164 void 165 rl_extend_line_buffer (len) 166 int len; 167 { 168 while (len >= rl_line_buffer_len) 169 { 170 rl_line_buffer_len += DEFAULT_BUFFER_SIZE; 171 rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len); 172 } 173 174 _rl_set_the_line (); 175 } 176 177 178 /* A function for simple tilde expansion. */ 179 int 180 rl_tilde_expand (ignore, key) 181 int ignore, key; 182 { 183 register int start, end; 184 char *homedir, *temp; 185 int len; 186 187 end = rl_point; 188 start = end - 1; 189 190 if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') 191 { 192 homedir = tilde_expand ("~"); 193 _rl_replace_text (homedir, start, end); 194 xfree (homedir); 195 return (0); 196 } 197 else if (rl_line_buffer[start] != '~') 198 { 199 for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) 200 ; 201 start++; 202 } 203 204 end = start; 205 do 206 end++; 207 while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); 208 209 if (whitespace (rl_line_buffer[end]) || end >= rl_end) 210 end--; 211 212 /* If the first character of the current word is a tilde, perform 213 tilde expansion and insert the result. If not a tilde, do 214 nothing. */ 215 if (rl_line_buffer[start] == '~') 216 { 217 len = end - start + 1; 218 temp = (char *)xmalloc (len + 1); 219 strncpy (temp, rl_line_buffer + start, len); 220 temp[len] = '\0'; 221 homedir = tilde_expand (temp); 222 xfree (temp); 223 224 _rl_replace_text (homedir, start, end); 225 xfree (homedir); 226 } 227 228 return (0); 229 } 230 231 #if defined (USE_VARARGS) 232 void 233 #if defined (PREFER_STDARG) 234 _rl_ttymsg (const char *format, ...) 235 #else 236 _rl_ttymsg (va_alist) 237 va_dcl 238 #endif 239 { 240 va_list args; 241 #if defined (PREFER_VARARGS) 242 char *format; 243 #endif 244 245 #if defined (PREFER_STDARG) 246 va_start (args, format); 247 #else 248 va_start (args); 249 format = va_arg (args, char *); 250 #endif 251 252 fprintf (stderr, "readline: "); 253 vfprintf (stderr, format, args); 254 fprintf (stderr, "\n"); 255 fflush (stderr); 256 257 va_end (args); 258 259 rl_forced_update_display (); 260 } 261 262 void 263 #if defined (PREFER_STDARG) 264 _rl_errmsg (const char *format, ...) 265 #else 266 _rl_errmsg (va_alist) 267 va_dcl 268 #endif 269 { 270 va_list args; 271 #if defined (PREFER_VARARGS) 272 char *format; 273 #endif 274 275 #if defined (PREFER_STDARG) 276 va_start (args, format); 277 #else 278 va_start (args); 279 format = va_arg (args, char *); 280 #endif 281 282 fprintf (stderr, "readline: "); 283 vfprintf (stderr, format, args); 284 fprintf (stderr, "\n"); 285 fflush (stderr); 286 287 va_end (args); 288 } 289 290 #else /* !USE_VARARGS */ 291 void 292 _rl_ttymsg (format, arg1, arg2) 293 char *format; 294 { 295 fprintf (stderr, "readline: "); 296 fprintf (stderr, format, arg1, arg2); 297 fprintf (stderr, "\n"); 298 299 rl_forced_update_display (); 300 } 301 302 void 303 _rl_errmsg (format, arg1, arg2) 304 char *format; 305 { 306 fprintf (stderr, "readline: "); 307 fprintf (stderr, format, arg1, arg2); 308 fprintf (stderr, "\n"); 309 } 310 #endif /* !USE_VARARGS */ 311 312 /* **************************************************************** */ 313 /* */ 314 /* String Utility Functions */ 315 /* */ 316 /* **************************************************************** */ 317 318 /* Determine if s2 occurs in s1. If so, return a pointer to the 319 match in s1. The compare is case insensitive. */ 320 char * 321 _rl_strindex (s1, s2) 322 register const char *s1, *s2; 323 { 324 register int i, l, len; 325 326 for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) 327 if (_rl_strnicmp (s1 + i, s2, l) == 0) 328 return ((char *) (s1 + i)); 329 return ((char *)NULL); 330 } 331 332 #ifndef HAVE_STRPBRK 333 /* Find the first occurrence in STRING1 of any character from STRING2. 334 Return a pointer to the character in STRING1. */ 335 char * 336 _rl_strpbrk (string1, string2) 337 const char *string1, *string2; 338 { 339 register const char *scan; 340 #if defined (HANDLE_MULTIBYTE) 341 mbstate_t ps; 342 register int i, v; 343 344 memset (&ps, 0, sizeof (mbstate_t)); 345 #endif 346 347 for (; *string1; string1++) 348 { 349 for (scan = string2; *scan; scan++) 350 { 351 if (*string1 == *scan) 352 return ((char *)string1); 353 } 354 #if defined (HANDLE_MULTIBYTE) 355 if (MB_CUR_MAX > 1 && rl_byte_oriented == 0) 356 { 357 v = _rl_get_char_len (string1, &ps); 358 if (v > 1) 359 string1 += v - 1; /* -1 to account for auto-increment in loop */ 360 } 361 #endif 362 } 363 return ((char *)NULL); 364 } 365 #endif 366 367 #if !defined (HAVE_STRCASECMP) 368 /* Compare at most COUNT characters from string1 to string2. Case 369 doesn't matter (strncasecmp). */ 370 int 371 _rl_strnicmp (string1, string2, count) 372 char *string1, *string2; 373 int count; 374 { 375 register char *s1, *s2; 376 int d; 377 378 if (count <= 0 || (string1 == string2)) 379 return 0; 380 381 s1 = string1; 382 s2 = string2; 383 do 384 { 385 d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */ 386 if (d != 0) 387 return d; 388 if (*s1++ == '\0') 389 break; 390 s2++; 391 } 392 while (--count != 0) 393 394 return (0); 395 } 396 397 /* strcmp (), but caseless (strcasecmp). */ 398 int 399 _rl_stricmp (string1, string2) 400 char *string1, *string2; 401 { 402 register char *s1, *s2; 403 int d; 404 405 s1 = string1; 406 s2 = string2; 407 408 if (s1 == s2) 409 return 0; 410 411 while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0) 412 { 413 if (*s1++ == '\0') 414 return 0; 415 s2++; 416 } 417 418 return (d); 419 } 420 #endif /* !HAVE_STRCASECMP */ 421 422 /* Stupid comparison routine for qsort () ing strings. */ 423 int 424 _rl_qsort_string_compare (s1, s2) 425 char **s1, **s2; 426 { 427 #if defined (HAVE_STRCOLL) 428 return (strcoll (*s1, *s2)); 429 #else 430 int result; 431 432 result = **s1 - **s2; 433 if (result == 0) 434 result = strcmp (*s1, *s2); 435 436 return result; 437 #endif 438 } 439 440 /* Function equivalents for the macros defined in chardefs.h. */ 441 #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); } 442 443 FUNCTION_FOR_MACRO (_rl_digit_p) 444 FUNCTION_FOR_MACRO (_rl_digit_value) 445 FUNCTION_FOR_MACRO (_rl_lowercase_p) 446 FUNCTION_FOR_MACRO (_rl_pure_alphabetic) 447 FUNCTION_FOR_MACRO (_rl_to_lower) 448 FUNCTION_FOR_MACRO (_rl_to_upper) 449 FUNCTION_FOR_MACRO (_rl_uppercase_p) 450 451 /* A convenience function, to force memory deallocation to be performed 452 by readline. DLLs on Windows apparently require this. */ 453 void 454 rl_free (mem) 455 void *mem; 456 { 457 if (mem) 458 free (mem); 459 } 460 461 /* Backwards compatibility, now that savestring has been removed from 462 all `public' readline header files. */ 463 #undef _rl_savestring 464 char * 465 _rl_savestring (s) 466 const char *s; 467 { 468 return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s))); 469 } 470 471 #if defined (USE_VARARGS) 472 static FILE *_rl_tracefp; 473 474 void 475 #if defined (PREFER_STDARG) 476 _rl_trace (const char *format, ...) 477 #else 478 _rl_trace (va_alist) 479 va_dcl 480 #endif 481 { 482 va_list args; 483 #if defined (PREFER_VARARGS) 484 char *format; 485 #endif 486 487 #if defined (PREFER_STDARG) 488 va_start (args, format); 489 #else 490 va_start (args); 491 format = va_arg (args, char *); 492 #endif 493 494 if (_rl_tracefp == 0) 495 _rl_tropen (); 496 vfprintf (_rl_tracefp, format, args); 497 fprintf (_rl_tracefp, "\n"); 498 fflush (_rl_tracefp); 499 500 va_end (args); 501 } 502 503 int 504 _rl_tropen () 505 { 506 char fnbuf[128]; 507 508 if (_rl_tracefp) 509 fclose (_rl_tracefp); 510 sprintf (fnbuf, "/var/tmp/rltrace.%ld", getpid()); 511 unlink(fnbuf); 512 _rl_tracefp = fopen (fnbuf, "w+"); 513 return _rl_tracefp != 0; 514 } 515 516 int 517 _rl_trclose () 518 { 519 int r; 520 521 r = fclose (_rl_tracefp); 522 _rl_tracefp = 0; 523 return r; 524 } 525 526 #endif 527