36 #if !defined(lint) && !defined(SCCSID)
38 static char sccsid[] =
"@(#)key.c 8.1 (Berkeley) 6/4/93";
92 private int node_lookup(
EditLine *,
const Char *,
96 #define KEY_BUFSIZ EL_BUFSIZ
106 el->el_keymacro.buf = el_malloc(KEY_BUFSIZ *
107 sizeof(*el->el_keymacro.buf));
108 if (el->el_keymacro.buf == NULL)
110 el->el_keymacro.map = NULL;
122 el_free(el->el_keymacro.buf);
123 el->el_keymacro.buf = NULL;
124 node__free(el->el_keymacro.map);
132 keymacro_map_cmd(
EditLine *el,
int cmd)
135 el->el_keymacro.val.cmd = (el_action_t) cmd;
136 return &el->el_keymacro.val;
144 keymacro_map_str(
EditLine *el, Char *str)
147 el->el_keymacro.val.str = str;
148 return &el->el_keymacro.val;
161 node__put(el, el->el_keymacro.map);
162 el->el_keymacro.map = NULL;
179 return node_trav(el, el->el_keymacro.map, ch, val);
193 if (key[0] ==
'\0') {
194 (void) fprintf(el->el_errfile,
195 "keymacro_add: Null extended-key not allowed.\n");
198 if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
199 (void) fprintf(el->el_errfile,
200 "keymacro_add: sequence-lead-in command not allowed\n");
203 if (el->el_keymacro.map == NULL)
205 el->el_keymacro.map = node__get(key[0]);
209 (void) node__try(el, el->el_keymacro.map, key, val, ntype);
218 keymacro_clear(
EditLine *el, el_action_t *map,
const Char *in)
224 if ((map[(
unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
225 ((map == el->el_map.key &&
226 el->el_map.alt[(
unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
227 (map == el->el_map.alt &&
228 el->el_map.key[(
unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
229 (void) keymacro_delete(el, in);
238 keymacro_delete(
EditLine *el,
const Char *key)
241 if (key[0] ==
'\0') {
242 (void) fprintf(el->el_errfile,
243 "keymacro_delete: Null extended-key not allowed.\n");
246 if (el->el_keymacro.map == NULL)
249 (void) node__delete(el, &el->el_keymacro.map, key);
259 keymacro_print(
EditLine *el,
const Char *key)
263 if (el->el_keymacro.map == NULL && *key == 0)
266 el->el_keymacro.buf[0] =
'"';
267 if (node_lookup(el, key, el->el_keymacro.map, (
size_t)1) <= -1)
269 (void) fprintf(el->el_errfile,
"Unbound extended key \"" FSTR
283 if (ptr->ch == *ch) {
287 if (FUN(el,getc)(el, ch) != 1) {
288 val->cmd = ED_END_OF_FILE;
292 return node_trav(el, ptr->next, ch, val);
295 if (ptr->type != XK_CMD)
303 return node_trav(el, ptr->sibling, ch, val);
321 if (ptr->ch != *str) {
324 for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
325 if (xm->sibling->ch == *str)
327 if (xm->sibling == NULL)
328 xm->sibling = node__get(*str);
331 if (*++str ==
'\0') {
333 if (ptr->next != NULL) {
334 node__put(el, ptr->next);
345 el_free(ptr->val.str);
348 EL_ABORT((el->el_errfile,
"Bad XK_ type %d\n",
353 switch (ptr->type = ntype) {
359 if ((ptr->val.str = Strdup(val->str)) == NULL)
363 EL_ABORT((el->el_errfile,
"Bad XK_ type %d\n", ntype));
368 if (ptr->next == NULL)
369 ptr->next = node__get(*str);
370 (void) node__try(el, ptr->next, str, val, ntype);
387 if (ptr->ch != *str) {
390 for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
391 if (xm->sibling->ch == *str)
393 if (xm->sibling == NULL)
398 if (*++str ==
'\0') {
400 if (prev_ptr == NULL)
401 *inptr = ptr->sibling;
403 prev_ptr->sibling = ptr->sibling;
407 }
else if (ptr->next != NULL &&
408 node__delete(el, &ptr->next, str) == 1) {
409 if (ptr->next != NULL)
411 if (prev_ptr == NULL)
412 *inptr = ptr->sibling;
414 prev_ptr->sibling = ptr->sibling;
433 if (ptr->next != NULL) {
434 node__put(el, ptr->next);
437 node__put(el, ptr->sibling);
445 if (ptr->val.str != NULL)
446 el_free(ptr->val.str);
449 EL_ABORT((el->el_errfile,
"Bad XK_ type %d\n", ptr->type));
464 ptr = el_malloc(
sizeof(*ptr));
480 node__free(k->sibling);
497 if (!str || *str == 0) {
499 (void) node_enum(el, ptr, cnt);
503 if (ptr->ch == *str) {
505 used = ct_visual_char(el->el_keymacro.buf + cnt,
506 KEY_BUFSIZ - cnt, ptr->ch);
509 if (ptr->next != NULL)
511 return (node_lookup(el, str + 1, ptr->next,
512 (
size_t)used + cnt));
516 size_t px = cnt + (size_t)used;
517 el->el_keymacro.buf[px] =
'"';
518 el->el_keymacro.buf[px + 1] =
'\0';
519 keymacro_kprint(el, el->el_keymacro.buf,
520 &ptr->val, ptr->type);
529 return (node_lookup(el, str, ptr->sibling,
546 if (cnt >= KEY_BUFSIZ - 5) {
547 el->el_keymacro.buf[++cnt] =
'"';
548 el->el_keymacro.buf[++cnt] =
'\0';
549 (void) fprintf(el->el_errfile,
550 "Some extended keys too long for internal print buffer");
551 (void) fprintf(el->el_errfile,
" \"" FSTR
"...\"\n",
552 el->el_keymacro.buf);
557 (void) fprintf(el->el_errfile,
558 "node_enum: BUG!! Null ptr passed\n!");
563 used = ct_visual_char(el->el_keymacro.buf + cnt, KEY_BUFSIZ - cnt,
565 if (ptr->next == NULL) {
567 el->el_keymacro.buf[cnt + (size_t)used ] =
'"';
568 el->el_keymacro.buf[cnt + (size_t)used + 1] =
'\0';
569 keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type);
571 (
void) node_enum(el, ptr->next, cnt + (
size_t)used);
575 (void) node_enum(el, ptr->sibling, cnt);
588 char unparsbuf[EL_BUFSIZ];
589 static const char fmt[] =
"%-15s-> %s\n";
592 memset(&state, 0,
sizeof(mbstate_t));
597 (void) keymacro__decode_str(val->str, unparsbuf,
599 ntype == XK_STR ?
"\"\"" :
"[]");
600 (void) fprintf(el->el_outfile, fmt,
601 ct_encode_string(key, &el->el_scratch), unparsbuf);
604 for (fp = el->el_map.help; fp->name; fp++)
605 if (val->cmd == fp->func) {
606 memset(&state, 0,
sizeof(mbstate_t));
607 wcsrtombs(unparsbuf, (
const wchar_t **) &fp->name,
608 sizeof(unparsbuf), &state);
609 unparsbuf[
sizeof(unparsbuf) -1] =
'\0';
610 (void) fprintf(el->el_outfile, fmt,
611 ct_encode_string(key, &el->el_scratch), unparsbuf);
615 if (fp->name == NULL)
616 (void) fprintf(el->el_outfile,
617 "BUG! Command not found.\n");
622 EL_ABORT((el->el_errfile,
"Bad XK_ type %d\n", ntype));
626 (
void) fprintf(el->el_outfile, fmt, ct_encode_string(key,
627 &el->el_scratch),
"no input");
640 keymacro__decode_str(
const Char *str,
char *
buf,
size_t len,
const char *sep)
642 char *b =
buf, *eb = b + len;
646 memset(&state, 0,
sizeof(mbstate_t));
648 if (sep[0] !=
'\0') {
656 for (p = str; *p != 0; p++) {
657 Char dbuf[VISUAL_WIDTH_MAX];
659 ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p);
661 ssize_t
n = ct_encode_char(b, (
size_t)(eb - b), *p2++,
670 if (sep[0] !=
'\0' && sep[1] !=
'\0') {
674 if ((
size_t)(b - buf) >= len)
676 return (
size_t)(b -
buf);