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);