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>