blob: dcacb5b4abdbd7eacc7ac4c13ef937a2edbab116 [file] [log] [blame]
Dan Pasanenc6e37862014-10-02 14:08:59 -05001/* bind.c, created from bind.def. */
2#line 22 "./bind.def"
3
4#include <config.h>
5
6#line 63 "./bind.def"
7
8#if defined (READLINE)
9
10#if defined (HAVE_UNISTD_H)
11# ifdef _MINIX
12# include <sys/types.h>
13# endif
14# include <unistd.h>
15#endif
16
17#include <stdio.h>
18#include <errno.h>
19#if !defined (errno)
Ricardo Cerqueiraa02fbff2013-07-25 22:35:34 +010020#include <errno.h>
Dan Pasanenc6e37862014-10-02 14:08:59 -050021#endif /* !errno */
22
23#include <readline/readline.h>
24#include <readline/history.h>
25
26#include "../bashintl.h"
27
28#include "../shell.h"
29#include "../bashline.h"
30#include "bashgetopt.h"
31#include "common.h"
32
33static int query_bindings __P((char *));
34static int unbind_command __P((char *));
35
36extern int no_line_editing;
37
38#define BIND_RETURN(x) do { return_code = x; goto bind_exit; } while (0)
39
40#define LFLAG 0x0001
41#define PFLAG 0x0002
42#define FFLAG 0x0004
43#define VFLAG 0x0008
44#define QFLAG 0x0010
45#define MFLAG 0x0020
46#define RFLAG 0x0040
47#define PPFLAG 0x0080
48#define VVFLAG 0x0100
49#define SFLAG 0x0200
50#define SSFLAG 0x0400
51#define UFLAG 0x0800
52#define XFLAG 0x1000
53#define XXFLAG 0x2000
54
55int
56bind_builtin (list)
57 WORD_LIST *list;
58{
59 int return_code;
60 Keymap kmap, saved_keymap;
61 int flags, opt;
62 char *initfile, *map_name, *fun_name, *unbind_name, *remove_seq, *cmd_seq;
63
64 if (no_line_editing)
65 {
66#if 0
67 builtin_error (_("line editing not enabled"));
68 return (EXECUTION_FAILURE);
69#else
70 builtin_warning (_("line editing not enabled"));
71#endif
72 }
73
74 kmap = saved_keymap = (Keymap) NULL;
75 flags = 0;
76 initfile = map_name = fun_name = unbind_name = remove_seq = (char *)NULL;
77 return_code = EXECUTION_SUCCESS;
78
79 if (bash_readline_initialized == 0)
80 initialize_readline ();
81
82 begin_unwind_frame ("bind_builtin");
83 unwind_protect_var (rl_outstream);
84
85 rl_outstream = stdout;
86
87 reset_internal_getopt ();
88 while ((opt = internal_getopt (list, "lvpVPsSXf:q:u:m:r:x:")) != EOF)
89 {
90 switch (opt)
91 {
92 case 'l':
93 flags |= LFLAG;
94 break;
95 case 'v':
96 flags |= VFLAG;
97 break;
98 case 'p':
99 flags |= PFLAG;
100 break;
101 case 'f':
102 flags |= FFLAG;
103 initfile = list_optarg;
104 break;
105 case 'm':
106 flags |= MFLAG;
107 map_name = list_optarg;
108 break;
109 case 'q':
110 flags |= QFLAG;
111 fun_name = list_optarg;
112 break;
113 case 'u':
114 flags |= UFLAG;
115 unbind_name = list_optarg;
116 break;
117 case 'r':
118 flags |= RFLAG;
119 remove_seq = list_optarg;
120 break;
121 case 'V':
122 flags |= VVFLAG;
123 break;
124 case 'P':
125 flags |= PPFLAG;
126 break;
127 case 's':
128 flags |= SFLAG;
129 break;
130 case 'S':
131 flags |= SSFLAG;
132 break;
133 case 'x':
134 flags |= XFLAG;
135 cmd_seq = list_optarg;
136 break;
137 case 'X':
138 flags |= XXFLAG;
139 break;
140 default:
141 builtin_usage ();
142 BIND_RETURN (EX_USAGE);
143 }
144 }
145
146 list = loptend;
147
148 /* First, see if we need to install a special keymap for this
149 command. Then start on the arguments. */
150
151 if ((flags & MFLAG) && map_name)
152 {
153 kmap = rl_get_keymap_by_name (map_name);
154 if (kmap == 0)
155 {
156 builtin_error (_("`%s': invalid keymap name"), map_name);
157 BIND_RETURN (EXECUTION_FAILURE);
158 }
159 }
160
161 if (kmap)
162 {
163 saved_keymap = rl_get_keymap ();
164 rl_set_keymap (kmap);
165 }
166
167 /* XXX - we need to add exclusive use tests here. It doesn't make sense
168 to use some of these options together. */
169 /* Now hack the option arguments */
170 if (flags & LFLAG)
171 rl_list_funmap_names ();
172
173 if (flags & PFLAG)
174 rl_function_dumper (1);
175
176 if (flags & PPFLAG)
177 rl_function_dumper (0);
178
179 if (flags & SFLAG)
180 rl_macro_dumper (1);
181
182 if (flags & SSFLAG)
183 rl_macro_dumper (0);
184
185 if (flags & VFLAG)
186 rl_variable_dumper (1);
187
188 if (flags & VVFLAG)
189 rl_variable_dumper (0);
190
191 if ((flags & FFLAG) && initfile)
192 {
193 if (rl_read_init_file (initfile) != 0)
194 {
195 builtin_error (_("%s: cannot read: %s"), initfile, strerror (errno));
196 BIND_RETURN (EXECUTION_FAILURE);
197 }
198 }
199
200 if ((flags & QFLAG) && fun_name)
201 return_code = query_bindings (fun_name);
202
203 if ((flags & UFLAG) && unbind_name)
204 return_code = unbind_command (unbind_name);
205
206 if ((flags & RFLAG) && remove_seq)
207 {
208 if (rl_bind_keyseq (remove_seq, (rl_command_func_t *)NULL) != 0)
209 {
210 builtin_error (_("`%s': cannot unbind"), remove_seq);
211 BIND_RETURN (EXECUTION_FAILURE);
212 }
213 }
214
215 if (flags & XFLAG)
216 return_code = bind_keyseq_to_unix_command (cmd_seq);
217
218 if (flags & XXFLAG)
219 return_code = print_unix_command_map ();
220
221 /* Process the rest of the arguments as binding specifications. */
222 while (list)
223 {
224 rl_parse_and_bind (list->word->word);
225 list = list->next;
226 }
227
228 bind_exit:
229 if (saved_keymap)
230 rl_set_keymap (saved_keymap);
231
232 run_unwind_frame ("bind_builtin");
233
234 return (sh_chkwrite (return_code));
235}
236
237static int
238query_bindings (name)
239 char *name;
240{
241 rl_command_func_t *function;
242 char **keyseqs;
243 int j;
244
245 function = rl_named_function (name);
246 if (function == 0)
247 {
248 builtin_error (_("`%s': unknown function name"), name);
249 return EXECUTION_FAILURE;
250 }
251
252 keyseqs = rl_invoking_keyseqs (function);
253
254 if (!keyseqs)
255 {
256 printf (_("%s is not bound to any keys.\n"), name);
257 return EXECUTION_FAILURE;
258 }
259
260 printf (_("%s can be invoked via "), name);
261 for (j = 0; j < 5 && keyseqs[j]; j++)
262 printf ("\"%s\"%s", keyseqs[j], keyseqs[j + 1] ? ", " : ".\n");
263 if (keyseqs[j])
264 printf ("...\n");
265 strvec_dispose (keyseqs);
266 return EXECUTION_SUCCESS;
267}
268
269static int
270unbind_command (name)
271 char *name;
272{
273 rl_command_func_t *function;
274
275 function = rl_named_function (name);
276 if (function == 0)
277 {
278 builtin_error (_("`%s': unknown function name"), name);
279 return EXECUTION_FAILURE;
280 }
281
282 rl_unbind_function_in_map (function, rl_get_keymap ());
283 return EXECUTION_SUCCESS;
284}
285#endif /* READLINE */