Annotation of embedaddon/readline/util.c, revision 1.1
1.1 ! misho 1: /* util.c -- readline utility functions */
! 2:
! 3: /* Copyright (C) 1987-2012 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: #if defined (HAVE_POSIX_SIGSETJMP)
! 112: siglongjmp (_rl_top_level, 1);
! 113: #else
! 114: longjmp (_rl_top_level, 1);
! 115: #endif
! 116: return (0);
! 117: }
! 118:
! 119: int
! 120: rl_abort (count, key)
! 121: int count, key;
! 122: {
! 123: return (_rl_abort_internal ());
! 124: }
! 125:
! 126: int
! 127: _rl_null_function (count, key)
! 128: int count, key;
! 129: {
! 130: return 0;
! 131: }
! 132:
! 133: int
! 134: rl_tty_status (count, key)
! 135: int count, key;
! 136: {
! 137: #if defined (TIOCSTAT)
! 138: ioctl (1, TIOCSTAT, (char *)0);
! 139: rl_refresh_line (count, key);
! 140: #else
! 141: rl_ding ();
! 142: #endif
! 143: return 0;
! 144: }
! 145:
! 146: /* Return a copy of the string between FROM and TO.
! 147: FROM is inclusive, TO is not. */
! 148: char *
! 149: rl_copy_text (from, to)
! 150: int from, to;
! 151: {
! 152: register int length;
! 153: char *copy;
! 154:
! 155: /* Fix it if the caller is confused. */
! 156: if (from > to)
! 157: SWAP (from, to);
! 158:
! 159: length = to - from;
! 160: copy = (char *)xmalloc (1 + length);
! 161: strncpy (copy, rl_line_buffer + from, length);
! 162: copy[length] = '\0';
! 163: return (copy);
! 164: }
! 165:
! 166: /* Increase the size of RL_LINE_BUFFER until it has enough space to hold
! 167: LEN characters. */
! 168: void
! 169: rl_extend_line_buffer (len)
! 170: int len;
! 171: {
! 172: while (len >= rl_line_buffer_len)
! 173: {
! 174: rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
! 175: rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
! 176: }
! 177:
! 178: _rl_set_the_line ();
! 179: }
! 180:
! 181:
! 182: /* A function for simple tilde expansion. */
! 183: int
! 184: rl_tilde_expand (ignore, key)
! 185: int ignore, key;
! 186: {
! 187: register int start, end;
! 188: char *homedir, *temp;
! 189: int len;
! 190:
! 191: end = rl_point;
! 192: start = end - 1;
! 193:
! 194: if (rl_point == rl_end && rl_line_buffer[rl_point] == '~')
! 195: {
! 196: homedir = tilde_expand ("~");
! 197: _rl_replace_text (homedir, start, end);
! 198: xfree (homedir);
! 199: return (0);
! 200: }
! 201: else if (rl_line_buffer[start] != '~')
! 202: {
! 203: for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--)
! 204: ;
! 205: start++;
! 206: }
! 207:
! 208: end = start;
! 209: do
! 210: end++;
! 211: while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end);
! 212:
! 213: if (whitespace (rl_line_buffer[end]) || end >= rl_end)
! 214: end--;
! 215:
! 216: /* If the first character of the current word is a tilde, perform
! 217: tilde expansion and insert the result. If not a tilde, do
! 218: nothing. */
! 219: if (rl_line_buffer[start] == '~')
! 220: {
! 221: len = end - start + 1;
! 222: temp = (char *)xmalloc (len + 1);
! 223: strncpy (temp, rl_line_buffer + start, len);
! 224: temp[len] = '\0';
! 225: homedir = tilde_expand (temp);
! 226: xfree (temp);
! 227:
! 228: _rl_replace_text (homedir, start, end);
! 229: xfree (homedir);
! 230: }
! 231:
! 232: return (0);
! 233: }
! 234:
! 235: #if defined (USE_VARARGS)
! 236: void
! 237: #if defined (PREFER_STDARG)
! 238: _rl_ttymsg (const char *format, ...)
! 239: #else
! 240: _rl_ttymsg (va_alist)
! 241: va_dcl
! 242: #endif
! 243: {
! 244: va_list args;
! 245: #if defined (PREFER_VARARGS)
! 246: char *format;
! 247: #endif
! 248:
! 249: #if defined (PREFER_STDARG)
! 250: va_start (args, format);
! 251: #else
! 252: va_start (args);
! 253: format = va_arg (args, char *);
! 254: #endif
! 255:
! 256: fprintf (stderr, "readline: ");
! 257: vfprintf (stderr, format, args);
! 258: fprintf (stderr, "\n");
! 259: fflush (stderr);
! 260:
! 261: va_end (args);
! 262:
! 263: rl_forced_update_display ();
! 264: }
! 265:
! 266: void
! 267: #if defined (PREFER_STDARG)
! 268: _rl_errmsg (const char *format, ...)
! 269: #else
! 270: _rl_errmsg (va_alist)
! 271: va_dcl
! 272: #endif
! 273: {
! 274: va_list args;
! 275: #if defined (PREFER_VARARGS)
! 276: char *format;
! 277: #endif
! 278:
! 279: #if defined (PREFER_STDARG)
! 280: va_start (args, format);
! 281: #else
! 282: va_start (args);
! 283: format = va_arg (args, char *);
! 284: #endif
! 285:
! 286: fprintf (stderr, "readline: ");
! 287: vfprintf (stderr, format, args);
! 288: fprintf (stderr, "\n");
! 289: fflush (stderr);
! 290:
! 291: va_end (args);
! 292: }
! 293:
! 294: #else /* !USE_VARARGS */
! 295: void
! 296: _rl_ttymsg (format, arg1, arg2)
! 297: char *format;
! 298: {
! 299: fprintf (stderr, "readline: ");
! 300: fprintf (stderr, format, arg1, arg2);
! 301: fprintf (stderr, "\n");
! 302:
! 303: rl_forced_update_display ();
! 304: }
! 305:
! 306: void
! 307: _rl_errmsg (format, arg1, arg2)
! 308: char *format;
! 309: {
! 310: fprintf (stderr, "readline: ");
! 311: fprintf (stderr, format, arg1, arg2);
! 312: fprintf (stderr, "\n");
! 313: }
! 314: #endif /* !USE_VARARGS */
! 315:
! 316: /* **************************************************************** */
! 317: /* */
! 318: /* String Utility Functions */
! 319: /* */
! 320: /* **************************************************************** */
! 321:
! 322: /* Determine if s2 occurs in s1. If so, return a pointer to the
! 323: match in s1. The compare is case insensitive. */
! 324: char *
! 325: _rl_strindex (s1, s2)
! 326: register const char *s1, *s2;
! 327: {
! 328: register int i, l, len;
! 329:
! 330: for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
! 331: if (_rl_strnicmp (s1 + i, s2, l) == 0)
! 332: return ((char *) (s1 + i));
! 333: return ((char *)NULL);
! 334: }
! 335:
! 336: #ifndef HAVE_STRPBRK
! 337: /* Find the first occurrence in STRING1 of any character from STRING2.
! 338: Return a pointer to the character in STRING1. */
! 339: char *
! 340: _rl_strpbrk (string1, string2)
! 341: const char *string1, *string2;
! 342: {
! 343: register const char *scan;
! 344: #if defined (HANDLE_MULTIBYTE)
! 345: mbstate_t ps;
! 346: register int i, v;
! 347:
! 348: memset (&ps, 0, sizeof (mbstate_t));
! 349: #endif
! 350:
! 351: for (; *string1; string1++)
! 352: {
! 353: for (scan = string2; *scan; scan++)
! 354: {
! 355: if (*string1 == *scan)
! 356: return ((char *)string1);
! 357: }
! 358: #if defined (HANDLE_MULTIBYTE)
! 359: if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
! 360: {
! 361: v = _rl_get_char_len (string1, &ps);
! 362: if (v > 1)
! 363: string1 += v - 1; /* -1 to account for auto-increment in loop */
! 364: }
! 365: #endif
! 366: }
! 367: return ((char *)NULL);
! 368: }
! 369: #endif
! 370:
! 371: #if !defined (HAVE_STRCASECMP)
! 372: /* Compare at most COUNT characters from string1 to string2. Case
! 373: doesn't matter (strncasecmp). */
! 374: int
! 375: _rl_strnicmp (string1, string2, count)
! 376: const char *string1;
! 377: const char *string2;
! 378: int count;
! 379: {
! 380: register const char *s1;
! 381: register const char *s2;
! 382: register int d;
! 383:
! 384: if (count <= 0 || (string1 == string2))
! 385: return 0;
! 386:
! 387: s1 = string1;
! 388: s2 = string2;
! 389: do
! 390: {
! 391: d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
! 392: if (d != 0)
! 393: return d;
! 394: if (*s1++ == '\0')
! 395: break;
! 396: s2++;
! 397: }
! 398: while (--count != 0);
! 399:
! 400: return (0);
! 401: }
! 402:
! 403: /* strcmp (), but caseless (strcasecmp). */
! 404: int
! 405: _rl_stricmp (string1, string2)
! 406: const char *string1;
! 407: const char *string2;
! 408: {
! 409: register const char *s1;
! 410: register const char *s2;
! 411: register int d;
! 412:
! 413: s1 = string1;
! 414: s2 = string2;
! 415:
! 416: if (s1 == s2)
! 417: return 0;
! 418:
! 419: while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
! 420: {
! 421: if (*s1++ == '\0')
! 422: return 0;
! 423: s2++;
! 424: }
! 425:
! 426: return (d);
! 427: }
! 428: #endif /* !HAVE_STRCASECMP */
! 429:
! 430: /* Stupid comparison routine for qsort () ing strings. */
! 431: int
! 432: _rl_qsort_string_compare (s1, s2)
! 433: char **s1, **s2;
! 434: {
! 435: #if defined (HAVE_STRCOLL)
! 436: return (strcoll (*s1, *s2));
! 437: #else
! 438: int result;
! 439:
! 440: result = **s1 - **s2;
! 441: if (result == 0)
! 442: result = strcmp (*s1, *s2);
! 443:
! 444: return result;
! 445: #endif
! 446: }
! 447:
! 448: /* Function equivalents for the macros defined in chardefs.h. */
! 449: #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
! 450:
! 451: FUNCTION_FOR_MACRO (_rl_digit_p)
! 452: FUNCTION_FOR_MACRO (_rl_digit_value)
! 453: FUNCTION_FOR_MACRO (_rl_lowercase_p)
! 454: FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
! 455: FUNCTION_FOR_MACRO (_rl_to_lower)
! 456: FUNCTION_FOR_MACRO (_rl_to_upper)
! 457: FUNCTION_FOR_MACRO (_rl_uppercase_p)
! 458:
! 459: /* A convenience function, to force memory deallocation to be performed
! 460: by readline. DLLs on Windows apparently require this. */
! 461: void
! 462: rl_free (mem)
! 463: void *mem;
! 464: {
! 465: if (mem)
! 466: free (mem);
! 467: }
! 468:
! 469: /* Backwards compatibility, now that savestring has been removed from
! 470: all `public' readline header files. */
! 471: #undef _rl_savestring
! 472: char *
! 473: _rl_savestring (s)
! 474: const char *s;
! 475: {
! 476: return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
! 477: }
! 478:
! 479: #if defined (USE_VARARGS)
! 480: static FILE *_rl_tracefp;
! 481:
! 482: void
! 483: #if defined (PREFER_STDARG)
! 484: _rl_trace (const char *format, ...)
! 485: #else
! 486: _rl_trace (va_alist)
! 487: va_dcl
! 488: #endif
! 489: {
! 490: va_list args;
! 491: #if defined (PREFER_VARARGS)
! 492: char *format;
! 493: #endif
! 494:
! 495: #if defined (PREFER_STDARG)
! 496: va_start (args, format);
! 497: #else
! 498: va_start (args);
! 499: format = va_arg (args, char *);
! 500: #endif
! 501:
! 502: if (_rl_tracefp == 0)
! 503: _rl_tropen ();
! 504: vfprintf (_rl_tracefp, format, args);
! 505: fprintf (_rl_tracefp, "\n");
! 506: fflush (_rl_tracefp);
! 507:
! 508: va_end (args);
! 509: }
! 510:
! 511: int
! 512: _rl_tropen ()
! 513: {
! 514: char fnbuf[128];
! 515:
! 516: if (_rl_tracefp)
! 517: fclose (_rl_tracefp);
! 518: sprintf (fnbuf, "/var/tmp/rltrace.%ld", (long)getpid());
! 519: unlink(fnbuf);
! 520: _rl_tracefp = fopen (fnbuf, "w+");
! 521: return _rl_tracefp != 0;
! 522: }
! 523:
! 524: int
! 525: _rl_trclose ()
! 526: {
! 527: int r;
! 528:
! 529: r = fclose (_rl_tracefp);
! 530: _rl_tracefp = 0;
! 531: return r;
! 532: }
! 533:
! 534: void
! 535: _rl_settracefp (fp)
! 536: FILE *fp;
! 537: {
! 538: _rl_tracefp = fp;
! 539: }
! 540: #endif
! 541:
! 542:
! 543: #if HAVE_DECL_AUDIT_USER_TTY && defined (ENABLE_TTY_AUDIT_SUPPORT)
! 544: #include <sys/socket.h>
! 545: #include <linux/audit.h>
! 546: #include <linux/netlink.h>
! 547:
! 548: /* Report STRING to the audit system. */
! 549: void
! 550: _rl_audit_tty (string)
! 551: char *string;
! 552: {
! 553: struct sockaddr_nl addr;
! 554: struct msghdr msg;
! 555: struct nlmsghdr nlm;
! 556: struct iovec iov[2];
! 557: size_t size;
! 558: int fd;
! 559:
! 560: fd = socket (AF_NETLINK, SOCK_RAW, NETLINK_AUDIT);
! 561: if (fd < 0)
! 562: return;
! 563: size = strlen (string) + 1;
! 564:
! 565: nlm.nlmsg_len = NLMSG_LENGTH (size);
! 566: nlm.nlmsg_type = AUDIT_USER_TTY;
! 567: nlm.nlmsg_flags = NLM_F_REQUEST;
! 568: nlm.nlmsg_seq = 0;
! 569: nlm.nlmsg_pid = 0;
! 570:
! 571: iov[0].iov_base = &nlm;
! 572: iov[0].iov_len = sizeof (nlm);
! 573: iov[1].iov_base = string;
! 574: iov[1].iov_len = size;
! 575:
! 576: addr.nl_family = AF_NETLINK;
! 577: addr.nl_pid = 0;
! 578: addr.nl_groups = 0;
! 579:
! 580: msg.msg_name = &addr;
! 581: msg.msg_namelen = sizeof (addr);
! 582: msg.msg_iov = iov;
! 583: msg.msg_iovlen = 2;
! 584: msg.msg_control = NULL;
! 585: msg.msg_controllen = 0;
! 586: msg.msg_flags = 0;
! 587:
! 588: (void)sendmsg (fd, &msg, 0);
! 589: close (fd);
! 590: }
! 591: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>