"Fossies" - the Fresh Open Source Software Archive

Member "readline-8.0/util.c" (15 Jun 2017, 12070 Bytes) of package /linux/misc/readline-8.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "util.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 7.0_vs_8.0.

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