LCOV - code coverage report
Current view: top level - builtins - bind.def (source / functions) Hit Total Coverage
Test: cov-bash.info Lines: 41 148 27.7 %
Date: 2020-10-29 14:49:28 Functions: 1 3 33.3 %

          Line data    Source code
       1             : This file is bind.def, from which is created bind.c.
       2             : It implements the builtin "bind" in Bash.
       3             : 
       4             : Copyright (C) 1987-2015 Free Software Foundation, Inc.
       5             : 
       6             : This file is part of GNU Bash, the Bourne Again SHell.
       7             : 
       8             : Bash 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             : Bash 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 Bash.  If not, see <http://www.gnu.org/licenses/>.
      20             : 
      21             : $PRODUCES bind.c
      22             : 
      23             : #include <config.h>
      24             : 
      25             : $BUILTIN bind
      26             : $DEPENDS_ON READLINE
      27             : $FUNCTION bind_builtin
      28             : $SHORT_DOC bind [-lpsvPSVX] [-m keymap] [-f filename] [-q name] [-u name] [-r keyseq] [-x keyseq:shell-command] [keyseq:readline-function or readline-command]
      29             : Set Readline key bindings and variables.
      30             : 
      31             : Bind a key sequence to a Readline function or a macro, or set a
      32             : Readline variable.  The non-option argument syntax is equivalent to
      33             : that found in ~/.inputrc, but must be passed as a single argument:
      34             : e.g., bind '"\C-x\C-r": re-read-init-file'.
      35             : 
      36             : Options:
      37             :   -m  keymap         Use KEYMAP as the keymap for the duration of this
      38             :                      command.  Acceptable keymap names are emacs,
      39             :                      emacs-standard, emacs-meta, emacs-ctlx, vi, vi-move,
      40             :                      vi-command, and vi-insert.
      41             :   -l                 List names of functions.
      42             :   -P                 List function names and bindings.
      43             :   -p                 List functions and bindings in a form that can be
      44             :                      reused as input.
      45             :   -S                 List key sequences that invoke macros and their values
      46             :   -s                 List key sequences that invoke macros and their values
      47             :                      in a form that can be reused as input.
      48             :   -V                 List variable names and values
      49             :   -v                 List variable names and values in a form that can
      50             :                      be reused as input.
      51             :   -q  function-name  Query about which keys invoke the named function.
      52             :   -u  function-name  Unbind all keys which are bound to the named function.
      53             :   -r  keyseq         Remove the binding for KEYSEQ.
      54             :   -f  filename       Read key bindings from FILENAME.
      55             :   -x  keyseq:shell-command      Cause SHELL-COMMAND to be executed when
      56             :                                 KEYSEQ is entered.
      57             :   -X                 List key sequences bound with -x and associated commands
      58             :                      in a form that can be reused as input.
      59             : 
      60             : Exit Status:
      61             : bind returns 0 unless an unrecognized option is given or an error occurs.
      62             : $END
      63             : 
      64             : #if defined (READLINE)
      65             : 
      66             : #if defined (HAVE_UNISTD_H)
      67             : #  ifdef _MINIX
      68             : #    include <sys/types.h>
      69             : #  endif
      70             : #  include <unistd.h>
      71             : #endif
      72             : 
      73             : #include <stdio.h>
      74             : #include <errno.h>
      75             : #if !defined (errno)
      76             : extern int errno;
      77             : #endif /* !errno */
      78             : 
      79             : #include <readline/readline.h>
      80             : #include <readline/history.h>
      81             : 
      82             : #include "../bashintl.h"
      83             : 
      84             : #include "../shell.h"
      85             : #include "../bashline.h"
      86             : #include "bashgetopt.h"
      87             : #include "common.h"
      88             : 
      89             : static int query_bindings __P((char *));
      90             : static int unbind_command __P((char *));
      91             : 
      92             : extern int no_line_editing;
      93             : 
      94             : #define BIND_RETURN(x)  do { return_code = x; goto bind_exit; } while (0)
      95             : 
      96             : #define LFLAG   0x0001
      97             : #define PFLAG   0x0002
      98             : #define FFLAG   0x0004
      99             : #define VFLAG   0x0008
     100             : #define QFLAG   0x0010
     101             : #define MFLAG   0x0020
     102             : #define RFLAG   0x0040
     103             : #define PPFLAG  0x0080
     104             : #define VVFLAG  0x0100
     105             : #define SFLAG   0x0200
     106             : #define SSFLAG  0x0400
     107             : #define UFLAG   0x0800
     108             : #define XFLAG   0x1000
     109             : #define XXFLAG  0x2000
     110             : 
     111             : int
     112          75 : bind_builtin (list)
     113             :      WORD_LIST *list;
     114             : {
     115          75 :   int return_code;
     116          75 :   Keymap kmap, saved_keymap;
     117          75 :   int flags, opt;
     118          75 :   char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq, *t;
     119             : 
     120          75 :   if (no_line_editing)
     121             :     {
     122             : #if 0
     123             :       builtin_error (_("line editing not enabled"));
     124             :       return (EXECUTION_FAILURE);
     125             : #else
     126          75 :       builtin_warning (_("line editing not enabled"));
     127             : #endif
     128             :     }
     129             : 
     130          75 :   kmap = saved_keymap = (Keymap) NULL;
     131          75 :   flags = 0;
     132          75 :   initfile = map_name = fun_name = unbind_name = remove_seq = cmd_seq = (char *)NULL;
     133          75 :   return_code = EXECUTION_SUCCESS;
     134             : 
     135          75 :   if (bash_readline_initialized == 0)
     136          75 :     initialize_readline ();
     137             : 
     138          75 :   begin_unwind_frame ("bind_builtin");
     139          75 :   unwind_protect_var (rl_outstream);
     140             : 
     141          75 :   rl_outstream = stdout;
     142             : 
     143          75 :   reset_internal_getopt ();  
     144         150 :   while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != -1)
     145             :     {
     146           0 :       switch (opt)
     147             :         {
     148           0 :         case 'l':
     149           0 :           flags |= LFLAG;
     150           0 :           break;
     151           0 :         case 'v':
     152           0 :           flags |= VFLAG;
     153           0 :           break;
     154           0 :         case 'p':
     155           0 :           flags |= PFLAG;
     156           0 :           break;
     157           0 :         case 'f':
     158           0 :           flags |= FFLAG;
     159           0 :           initfile = list_optarg;
     160           0 :           break;
     161           0 :         case 'm':
     162           0 :           flags |= MFLAG;
     163           0 :           map_name = list_optarg;
     164           0 :           break;
     165           0 :         case 'q':
     166           0 :           flags |= QFLAG;
     167           0 :           fun_name = list_optarg;
     168           0 :           break;
     169           0 :         case 'u':
     170           0 :           flags |= UFLAG;
     171           0 :           unbind_name = list_optarg;
     172           0 :           break;
     173           0 :         case 'r':
     174           0 :           flags |= RFLAG;
     175           0 :           remove_seq = list_optarg;
     176           0 :           break;
     177           0 :         case 'V':
     178           0 :           flags |= VVFLAG;
     179           0 :           break;
     180           0 :         case 'P':
     181           0 :           flags |= PPFLAG;
     182           0 :           break;
     183           0 :         case 's':
     184           0 :           flags |= SFLAG;
     185           0 :           break;
     186           0 :         case 'S':
     187           0 :           flags |= SSFLAG;
     188           0 :           break;
     189           0 :         case 'x':
     190           0 :           flags |= XFLAG;
     191           0 :           cmd_seq = list_optarg;
     192           0 :           break;
     193           0 :         case 'X':
     194           0 :           flags |= XXFLAG;
     195           0 :           break;
     196           0 :         CASE_HELPOPT;
     197           0 :         default:
     198           0 :           builtin_usage ();
     199          75 :           BIND_RETURN (EX_USAGE);
     200             :         }
     201             :     }
     202             : 
     203          75 :   list = loptend;
     204             : 
     205             :   /* First, see if we need to install a special keymap for this
     206             :      command.  Then start on the arguments. */
     207             : 
     208          75 :   if ((flags & MFLAG) && map_name)
     209             :     {
     210           0 :       kmap = rl_get_keymap_by_name (map_name);
     211           0 :       if (kmap == 0)
     212             :         {
     213           0 :           builtin_error (_("`%s': invalid keymap name"), map_name);
     214           0 :           BIND_RETURN (EXECUTION_FAILURE);
     215             :         }
     216             :     }
     217             : 
     218           0 :   if (kmap)
     219             :     {
     220           0 :       saved_keymap = rl_get_keymap ();
     221           0 :       rl_set_keymap (kmap);
     222             :     }
     223             : 
     224             :   /* XXX - we need to add exclusive use tests here.  It doesn't make sense
     225             :      to use some of these options together. */
     226             :   /* Now hack the option arguments */
     227          75 :   if (flags & LFLAG)
     228           0 :     rl_list_funmap_names ();
     229             : 
     230          75 :   if (flags & PFLAG)
     231           0 :     rl_function_dumper (1);
     232             : 
     233          75 :   if (flags & PPFLAG)
     234           0 :     rl_function_dumper (0);
     235             : 
     236          75 :   if (flags & SFLAG)
     237           0 :     rl_macro_dumper (1);
     238             : 
     239          75 :   if (flags & SSFLAG)
     240           0 :     rl_macro_dumper (0);
     241             : 
     242          75 :   if (flags & VFLAG)
     243           0 :     rl_variable_dumper (1);
     244             : 
     245          75 :   if (flags & VVFLAG)
     246           0 :     rl_variable_dumper (0);
     247             : 
     248          75 :   if ((flags & FFLAG) && initfile)
     249             :     {
     250           0 :       if (rl_read_init_file (initfile) != 0)
     251             :         {
     252           0 :           t = printable_filename (initfile, 0);
     253           0 :           builtin_error (_("%s: cannot read: %s"), t, strerror (errno));
     254           0 :           if (t != initfile)
     255           0 :             free (t);
     256           0 :           BIND_RETURN (EXECUTION_FAILURE);
     257             :         }
     258             :     }
     259             : 
     260          75 :   if ((flags & QFLAG) && fun_name)
     261           0 :     return_code = query_bindings (fun_name);
     262             : 
     263          75 :   if ((flags & UFLAG) && unbind_name)
     264           0 :     return_code = unbind_command (unbind_name);
     265             : 
     266          75 :   if ((flags & RFLAG) && remove_seq)
     267             :     {
     268           0 :       if (rl_bind_keyseq (remove_seq, (rl_command_func_t *)NULL) != 0)
     269             :         {
     270           0 :           builtin_error (_("`%s': cannot unbind"), remove_seq);
     271           0 :           BIND_RETURN (EXECUTION_FAILURE);
     272             :         }
     273             :     }
     274             : 
     275          75 :   if (flags & XFLAG)
     276           0 :     return_code = bind_keyseq_to_unix_command (cmd_seq);
     277             : 
     278          75 :   if (flags & XXFLAG)
     279           0 :     return_code = print_unix_command_map ();
     280             : 
     281             :   /* Process the rest of the arguments as binding specifications. */
     282         107 :   while (list)
     283             :     {
     284          32 :       rl_parse_and_bind (list->word->word);
     285          32 :       list = list->next;
     286             :     }
     287             : 
     288          75 :  bind_exit:
     289          75 :   if (saved_keymap)
     290           0 :     rl_set_keymap (saved_keymap);
     291             : 
     292          75 :   run_unwind_frame ("bind_builtin");
     293             : 
     294          75 :   return (sh_chkwrite (return_code));
     295             : }
     296             : 
     297             : static int
     298           0 : query_bindings (name)
     299             :      char *name;
     300             : {
     301           0 :   rl_command_func_t *function;
     302           0 :   char **keyseqs;
     303           0 :   int j;
     304             : 
     305           0 :   function = rl_named_function (name);
     306           0 :   if (function == 0)
     307             :     {
     308           0 :       builtin_error (_("`%s': unknown function name"), name);
     309           0 :       return EXECUTION_FAILURE;
     310             :     }
     311             : 
     312           0 :   keyseqs = rl_invoking_keyseqs (function);
     313             : 
     314           0 :   if (!keyseqs)
     315             :     {
     316           0 :       printf (_("%s is not bound to any keys.\n"), name);
     317           0 :       return EXECUTION_FAILURE;
     318             :     }
     319             : 
     320           0 :   printf (_("%s can be invoked via "), name);
     321           0 :   for (j = 0; j < 5 && keyseqs[j]; j++)
     322           0 :     printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n");
     323           0 :   if (keyseqs[j])
     324           0 :     printf ("...\n");
     325           0 :   strvec_dispose (keyseqs);
     326           0 :   return EXECUTION_SUCCESS;
     327             : }
     328             : 
     329             : static int
     330           0 : unbind_command (name)
     331             :      char *name;
     332             : {
     333           0 :   rl_command_func_t *function;
     334             : 
     335           0 :   function = rl_named_function (name);
     336           0 :   if (function == 0)
     337             :     {
     338           0 :       builtin_error (_("`%s': unknown function name"), name);
     339           0 :       return EXECUTION_FAILURE;
     340             :     }
     341             : 
     342           0 :   rl_unbind_function_in_map (function, rl_get_keymap ());
     343           0 :   return EXECUTION_SUCCESS;
     344             : }
     345             : #endif /* READLINE */

Generated by: LCOV version 1.14.0.6.4058