home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / z / zsh220.zip / zsh2.2 / src / zle_main.c < prev    next >
C/C++ Source or Header  |  1992-05-11  |  15KB  |  725 lines

  1. /*
  2.  *
  3.  * zle_main.c - main routines for line editor
  4.  *
  5.  * This file is part of zsh, the Z shell.
  6.  *
  7.  * This software is Copyright 1992 by Paul Falstad
  8.  *
  9.  * Permission is hereby granted to copy, reproduce, redistribute or otherwise
  10.  * use this software as long as: there is no monetary profit gained
  11.  * specifically from the use or reproduction of this software, it is not
  12.  * sold, rented, traded or otherwise marketed, and this copyright notice is
  13.  * included prominently in any copy made. 
  14.  *
  15.  * The author make no claims as to the fitness or correctness of this software
  16.  * for any use whatsoever, and it is provided as is. Any use of this software
  17.  * is at the user's own risk. 
  18.  *
  19.  */
  20.  
  21. #define ZLEGLOBALS
  22. #define ZLE
  23. #include "zsh.h"
  24. #include <sys/types.h>
  25. #include <sys/errno.h>
  26. #ifdef HAS_SYS_SELECT
  27. #include <sys/select.h>
  28. #endif
  29.  
  30. static Key cky;
  31.  
  32. /* set up terminal */
  33.  
  34. void setterm() /**/
  35. {
  36. struct ttyinfo ti;
  37. #ifdef FIONREAD
  38. long val;
  39. #endif
  40.  
  41. #ifdef CLOBBERS_TYPEAHEAD
  42. #ifdef FIONREAD
  43.     ioctl(SHTTY, FIONREAD, &val);
  44.     if (val) return;
  45. #endif
  46. #endif
  47.     inittty();
  48.     ti = shttyinfo;
  49. #ifdef TIO
  50.     ti.tio.c_lflag &= ~(ICANON|ECHO
  51. #ifdef FLUSHO
  52.         |FLUSHO
  53. #endif
  54.         );
  55.     ti.tio.c_cc[VQUIT] =
  56. #ifdef VDISCARD
  57.         ti.tio.c_cc[VDISCARD] = 
  58. #endif
  59. #ifdef VSUSP
  60.         ti.tio.c_cc[VSUSP] =
  61. #endif
  62. #ifdef VDSUSP
  63.         ti.tio.c_cc[VDSUSP] =
  64. #endif
  65. #ifdef VSWTCH
  66.         ti.tio.c_cc[VSWTCH] =
  67. #endif
  68.         VDISABLEVAL;
  69.     ti.tio.c_cc[VMIN] = 1;
  70.     ti.tio.c_cc[VTIME] = 0;
  71.     ti.tio.c_iflag &= ~(INLCR|ICRNL);
  72. #else
  73.     ti.sgttyb.sg_flags = (ti.sgttyb.sg_flags | CBREAK) & ~ECHO;
  74.     ti.lmodes &= ~LFLUSHO;
  75.     ti.tchars.t_quitc =
  76.         ti.ltchars.t_suspc =
  77.         ti.ltchars.t_flushc =
  78.         ti.ltchars.t_dsuspc = ti.ltchars.t_lnextc = -1;
  79. #endif
  80. #ifdef TTY_NEEDS_DRAINING
  81.     drainoutput();
  82. #endif
  83.     settyinfo(&ti);
  84. }
  85.  
  86. void unsetterm() /**/
  87. {
  88.     settyinfo(&shttyinfo);
  89. }
  90.  
  91. static char *kungetbuf;
  92. static int kungetct,kungetsz;
  93.  
  94. void ungetkey(ch) /**/
  95. int ch;
  96. {
  97.     if (kungetct == kungetsz)
  98.         kungetbuf = realloc(kungetbuf,kungetsz *= 2);
  99.     kungetbuf[kungetct++] = ch;
  100. }
  101.  
  102. void ungetkeys(s,len) /**/
  103. char *s;int len;
  104. {
  105.     s += len;
  106.     while (len--)
  107.         ungetkey(*--s);
  108. }
  109.  
  110. unsigned int getkey(tmok) /**/
  111. int tmok;
  112. {
  113. char cc;
  114. unsigned int ret = 0;
  115. int die = 0;
  116. #ifdef HAS_SELECT
  117. fd_set foofd;
  118. #endif
  119.  
  120.     if (kungetct)
  121.         ret = (unsigned int) (unsigned char) kungetbuf[--kungetct];
  122.     else {
  123.         while (
  124. #ifdef HAS_SELECT
  125.         FD_SET(0,&foofd), select(1,&foofd,NULL,NULL,NULL) != 1 ||
  126. #endif
  127.         read(0,&cc,1) != 1)
  128.             if (errno == EINTR) {
  129.                 if (!errflag)
  130.                     continue;
  131.                 errflag = 0;
  132.                 if (tmok)
  133.                     return -1;
  134.                 return 3;
  135.             } else if (errno == EWOULDBLOCK) {
  136.                 fcntl(0,F_SETFL,0);
  137.             } else if (errno == EIO && !die) {
  138.                 ret = jobbing;
  139.                 jobbing = 1;
  140.                 attachtty(mypgrp);
  141.                 refresh(); /* kludge! */
  142.                 jobbing = ret;
  143.                 die = 1;
  144.             } else {
  145.                 zerr("error on TTY read: %e",NULL,errno);
  146.                 exit(1);
  147.             }
  148.         ret = (unsigned int) (unsigned char) cc;
  149.     }
  150.     if (vichgflag) {
  151.         if (vichgbufptr == vichgbufsz)
  152.             vichgbuf = realloc(vichgbuf,vichgbufsz *= 2);
  153.         vichgbuf[vichgbufptr++] = ret;
  154.     }
  155.     return ret;
  156. }
  157.  
  158. /* read a line */
  159.  
  160. unsigned char *zleread(ppt,ppt2,plen) /**/
  161. unsigned char *ppt;unsigned char *ppt2;int plen;
  162. {
  163. int z;
  164. long costmult;
  165. unsigned char *s;
  166. #ifdef HAS_SELECT
  167. struct timeval tv;
  168. fd_set foofd;
  169.  
  170.     tv.tv_sec = 0;
  171. #endif
  172.     fflush(stdout);
  173.     fflush(stderr);
  174.     intr();
  175.     costmult = 3840000L/((baud) ? baud : 2400);
  176.     insmode = unset(OVERSTRIKE); eofsent = 0; resetneeded =0 ;
  177.     pmpt = (char *)ppt;
  178.     pmpt2 = (char *)ppt2;
  179.     permalloc();
  180.     histline = curhist;
  181.     pptlen = plen;
  182.     resetneeded = 1;
  183. #ifdef HAS_SELECT
  184.     FD_ZERO(&foofd);
  185. #endif
  186.     undoing = 1;
  187.     line = zalloc(linesz = 256);
  188.     *line = '\0';
  189.     virangeflag = lastcmd = done = cs = ll = mark = 0;
  190.     curhistline = NULL;
  191.     mult = 1;
  192.     vibufspec = 0;
  193.     bindtab = mainbindtab;
  194.     addedslash = vichgflag = 0;
  195.     viinsbegin = 0;
  196.     statusline = NULL;
  197.     if (s = getnode(bufstack))
  198.         {
  199.         setline((char *) s);
  200.         free(s);
  201.         if (stackcs != -1)
  202.             {
  203.             cs = stackcs;
  204.             stackcs = -1;
  205.             if (cs > ll)
  206.                 cs = ll;
  207.             }
  208.         if (stackhist != -1)
  209.             {
  210.             histline = stackhist;
  211.             stackhist = -1;
  212.             }
  213.         }
  214.     initundo();
  215.     if (unset(NOPROMPTCR))
  216.         putchar('\r');
  217.     if (tmout)
  218.         alarm(tmout);
  219.     refresh();
  220.     errflag = 0;
  221.     while (!done && !errflag)
  222.         {
  223.         struct zlecmd *zc;
  224.         
  225.         statusline = NULL;
  226.         bindk = getkeycmd();
  227.         if (c == 4 && !ll)
  228.             {
  229.             eofsent = 1;
  230.             break;
  231.             }
  232.         if (bindk != -1)
  233.             {
  234.             zc = zlecmds+bindk;
  235.             if (!(lastcmd & ZLE_ARG))
  236.                 mult = 1;
  237.             if ((lastcmd & ZLE_UNDO) != (zc->flags & ZLE_UNDO) && undoing)
  238.                 addundo();
  239.             if (!(zc->flags & ZLE_MENUCMP)) {
  240.                 if (menucmp) freemenu();
  241.                 if (addedslash &&
  242.                         !((zc->flags & ZLE_INSERT) && c != ' ')) {
  243.                     backdel(1);
  244.                 }
  245.                 addedslash = 0;
  246.             }
  247.             if (zc->func)
  248.                 (*zc->func)();
  249.             lastcmd = zc->flags;
  250.             if (!(lastcmd & ZLE_UNDO) && undoing) addundo();
  251.             }
  252.         else
  253.             {
  254.             errflag = 1;
  255.             break;
  256.             }
  257. #ifdef HAS_SELECT
  258.         FD_SET(0,&foofd);
  259.         if ((tv.tv_usec = cost*costmult) > 500000)
  260.             tv.tv_usec = 500000;
  261. #endif
  262.         if (!kungetct
  263. #ifdef HAS_SELECT
  264.             && select(1,&foofd,NULL,NULL,&tv) <= 0
  265. #endif
  266.             )
  267.             refresh();
  268.         }
  269.     if (menucmp)
  270.         freemenu();
  271.     statusline = NULL;
  272.     trashzle();
  273.     alarm(0);
  274.     z = strlen((char *)line);
  275.     line[z] = '\n';
  276.     line[z+1] = 0;
  277.     heapalloc();
  278.     if (curhistline)
  279.         free(curhistline);
  280.     if (eofsent)
  281.         {
  282.         free(line);
  283.         line = NULL;
  284.         }
  285.     zleactive = 0;
  286.     freeundo();
  287.     return line;
  288. }
  289.  
  290. int getkeycmd() /**/
  291. {
  292. char buf[10];
  293. int t0,ret;
  294. Key ky;
  295.  
  296.     t0 = 1;
  297.     cky = NULL;
  298.     if ((c = getkey(1)) == -1)
  299.         return -1;
  300.     if ((ret = bindtab[c]) == z_sequenceleadin)
  301.         {
  302.         buf[0] = (c) ? c : 0x80;
  303.         for (;;)
  304.             {
  305.             c = getkey(0);
  306.             buf[t0++] = (c) ? c : 0x80;
  307.             buf[t0] = '\0';
  308.             if (!(ky = (Key) gethnode(buf,xbindtab)))
  309.                 return z_undefinedkey;
  310.             if (ky->func != z_sequenceleadin)
  311.                 {
  312.                 cky = ky;
  313.                 ret = ky->func;
  314.                 break;
  315.                 }
  316.             }
  317.         }
  318.     if (ret == z_vidigitorbeginningofline)
  319.         ret = (lastcmd & ZLE_ARG) ? z_digitargument : z_beginningofline;
  320.     else if (ret == z_executenamedcmd)
  321.         ret = executenamedcommand();
  322.     else if (ret == z_executelastnamedcmd)
  323.         ret = lastnamed;
  324.     return ret;
  325. }
  326.  
  327. void sendstring() /**/
  328. {
  329. char buf[2];
  330.  
  331.     buf[0] = c;
  332.     buf[1] = '\0';
  333.     if (!cky)
  334.         cky = (Key) gethnode(buf,xbindtab);
  335.     ungetkeys(cky->str,cky->len);
  336. }
  337.  
  338. Key makefunckey(fun) /**/
  339. int fun;
  340. {
  341. Key ky = zcalloc(sizeof *ky);
  342.  
  343.     ky->func = fun;
  344.     return ky;
  345. }
  346.  
  347. /* initialize the bindings */
  348.  
  349. void initxbindtab() /**/
  350. {
  351. int t0,vi = 0;
  352. char buf[3],*s;
  353.  
  354.     lastnamed = z_undefinedkey;
  355.     if (s = zgetenv("VISUAL")) {
  356.         if (ztrstr(s,"vi"))
  357.             vi = 1;
  358.     }
  359.     else if ((s = zgetenv("EDITOR")) && ztrstr(s,"vi"))
  360.         vi = 1;
  361.     if (vi) {
  362.         for (t0 = 0; t0 != 32; t0++)
  363.             mainbindtab[t0] = viinsbind[t0];
  364.         for (t0 = 32; t0 != 256; t0++)
  365.             mainbindtab[t0] = z_selfinsert;
  366.         mainbindtab[127] = z_backwarddeletechar;
  367.     } else {
  368.         for (t0 = 0; t0 != 128; t0++)
  369.             mainbindtab[t0] = emacsbind[t0];
  370.         for (t0 = 128; t0 != 256; t0++)
  371.             mainbindtab[t0] = z_selfinsert;
  372.     }
  373.     for (t0 = 0200; t0 != 0240; t0++)
  374.         mainbindtab[t0] = z_undefinedkey;
  375.     for (t0 = 0; t0 != 128; t0++)
  376.         altbindtab[t0] = vicmdbind[t0];
  377.     for (t0 = 128; t0 != 256; t0++)
  378.         altbindtab[t0] = emacsbind[t0];
  379.     bindtab = mainbindtab;
  380.     kungetbuf = zalloc(kungetsz = 32);
  381.     kungetct = 0;
  382.     xbindtab = newhtable(67);
  383.     addhperm("\33\133C",makefunckey(z_forwardchar),xbindtab,NULL);
  384.     addhperm("\33\133D",makefunckey(z_backwardchar),xbindtab,NULL);
  385.     addhperm("\33\133A",makefunckey(z_uplineorhistory),xbindtab,NULL);
  386.     addhperm("\33\133B",makefunckey(z_downlineorhistory),xbindtab,NULL);
  387.     addhperm("\30*",makefunckey(z_expandword),xbindtab,NULL);
  388.     addhperm("\30g",makefunckey(z_listexpand),xbindtab,NULL);
  389.     addhperm("\30G",makefunckey(z_listexpand),xbindtab,NULL);
  390.     addhperm("\30\16",makefunckey(z_infernexthistory),xbindtab,NULL);
  391.     addhperm("\30\13",makefunckey(z_killbuffer),xbindtab,NULL);
  392.     addhperm("\30\6",makefunckey(z_vifindnextchar),xbindtab,NULL);
  393.     addhperm("\30\17",makefunckey(z_overwritemode),xbindtab,NULL);
  394.     addhperm("\30\25",makefunckey(z_undo),xbindtab,NULL);
  395.     addhperm("\30\26",makefunckey(z_vicmdmode),xbindtab,NULL);
  396.     addhperm("\30\12",makefunckey(z_vijoin),xbindtab,NULL);
  397.     addhperm("\30\2",makefunckey(z_vimatchbracket),xbindtab,NULL);
  398.     addhperm("\30s",makefunckey(z_historyincrementalsearchforward),
  399.         xbindtab,NULL);
  400.     addhperm("\30r",makefunckey(z_historyincrementalsearchbackward),
  401.         xbindtab,NULL);
  402.     addhperm("\30u",makefunckey(z_undo),xbindtab,NULL);
  403.     addhperm("\30\30",makefunckey(z_exchangepointandmark),
  404.         xbindtab,NULL);
  405.     addhperm("run-help",mkanode(ztrdup("man"),1),aliastab,NULL);
  406.     addhperm("which-command",mkanode(ztrdup("whence"),1),aliastab,NULL);
  407.     strcpy(buf,"\33q");
  408.     for (t0 = 128; t0 != 256; t0++)
  409.         if (emacsbind[t0] != z_undefinedkey) {
  410.             buf[1] = t0 & 0x7f;
  411.             addhnode(ztrdup(buf),makefunckey(emacsbind[t0]),xbindtab,NULL);
  412.         }
  413.     for (t0 = 0; t0 != 36; t0++) vibuf[t0] = NULL;
  414.     for (t0 = 0; t0 != 26; t0++) vimarkline[t0] = 0;
  415.     stackhist = stackcs = -1;
  416.     vichgbufsz = 0;
  417.     vichgbuf = NULL;
  418. }
  419.  
  420. char *getkeystring(s,len) /**/
  421. char *s;int *len;
  422. {
  423. static char buf[512];
  424. char *t = buf;
  425. int x,first = 1,metanext = 0;
  426.  
  427.     for (;*s;s++)
  428.         {
  429.         if (*s == '\\' && s[1])
  430.             switch(*++s)
  431.                 {
  432.                 case 'a': *t++ = '\07'; break;
  433.                 case 'n': *t++ = '\n'; break;
  434.                 case 'b': *t++ = '\010'; break;
  435.                 case 't': *t++ = '\t'; break;
  436.                 case 'v': *t++ = '\v'; break;
  437.                 case 'f': *t++ = '\f'; break;
  438.                 case 'r': *t++ = '\r'; break;
  439.                 case 'e': *t++ = '\033'; break;
  440.                 case 'M':
  441.                     if (s[1] == '-')
  442.                         s++;
  443.                     metanext = 2;
  444.                     break;
  445.                 default:
  446.                     if (idigit(*s))
  447.                         {
  448.                         for (x = 0; idigit(*s); s++)
  449.                             x = x*8+(*s-'0');
  450.                         s--;
  451.                         *t++ = x;
  452.                         }
  453.                     else
  454.                         *t++ = *s;
  455.                     break;
  456.                 }
  457.         else if (*s == '^')
  458.             if (*++s == '?')
  459.                 *t++ = 0x7f;
  460.             else
  461.                 *t++ = *s & 0x9f;
  462.         else
  463.             *t++ = *s;
  464.         if (metanext && !(--metanext))
  465.             {
  466.             t[-1] |= 0x80;
  467.             metanext = 0;
  468.             }
  469.         if (t > buf+500)
  470.             break;
  471.         first = 0;
  472.         }
  473.     *t = '\0';
  474.     *len = t-buf;
  475.     return buf;
  476. }
  477.  
  478. void printbind(s,len) /**/
  479. char *s;int len;
  480. {
  481. int ch;
  482.  
  483.     while (len--)
  484.         {
  485.         ch = (unsigned char) *s++;
  486.         if (ch & 0x80)
  487.             {
  488.             printf("\\M-");
  489.             ch &= 0x7f;
  490.             }
  491.         if (icntrl(ch))
  492.             switch(ch)
  493.                 {
  494.                 case 0x7f: printf("^?"); break;
  495.                 default: printf("^%c",(ch|0x40)); break;
  496.                 }
  497.         else
  498.             putchar(ch);
  499.         }
  500. }
  501.  
  502. void printbinding(str,k) /**/
  503. char *str;Key k;
  504. {
  505.     if (k->func == z_sequenceleadin)
  506.         return;
  507.     putchar('\"');
  508.     printbind(str,strlen(str));
  509.     printf("\"\t");
  510.     if (k->func == z_sendstring)
  511.         {
  512.         putchar('\"');
  513.         printbind(k->str,k->len);
  514.         printf("\"\n");
  515.         }
  516.     else
  517.         printf("%s\n",zlecmds[k->func].name);
  518. }
  519.  
  520. int bin_bindkey(name,argv,ops,junc) /**/
  521. char *name;char **argv;char *ops;int junc;
  522. {
  523. int t0,len;
  524. char *s;
  525. int func,*tab;
  526.  
  527.     tab = (ops['a']) ? altbindtab : mainbindtab;
  528.     if (ops['v'] || ops['e'] || ops['d'])
  529.         {
  530.         if (*argv)
  531.             {
  532.             zerrnam(name,"too many arguments",NULL,0);
  533.             return 1;
  534.             }
  535.         if (ops['d'] || ops['e'])
  536.             if (ops['m'])
  537.                 for (t0 = 0; t0 != 256; t0++)
  538.                     tab[t0] = emacsbind[t0];
  539.             else
  540.                 {
  541.                 for (t0 = 0; t0 != 128; t0++)
  542.                     tab[t0] = emacsbind[t0];
  543.                 for (t0 = 128; t0 != 256; t0++)
  544.                     tab[t0] = z_selfinsert;
  545.                 }
  546.         else
  547.             {
  548.             for (t0 = 0; t0 != 32; t0++)
  549.                 mainbindtab[t0] = viinsbind[t0];
  550.             for (t0 = 32; t0 != 256; t0++)
  551.                 mainbindtab[t0] = z_selfinsert;
  552.             mainbindtab[127] = z_backwarddeletechar;
  553.             }
  554.         for (t0 = 0; t0 != 128; t0++)
  555.             altbindtab[t0] = vicmdbind[t0];
  556.         for (t0 = 128; t0 != 256; t0++)
  557.             altbindtab[t0] = emacsbind[t0];
  558.         for (t0 = 0200; t0 != 0240; t0++)
  559.             tab[t0] = z_undefinedkey;
  560.         return 0;
  561.         }
  562.     if (!*argv)
  563.         {
  564.         char buf[2];
  565.         
  566.         buf[0] = 'x'; buf[1] = '\0';
  567.         for (t0 = 0; t0 != 256; t0++)
  568.             {
  569.             buf[0] = t0;
  570.             putchar('\"');
  571.             printbind(buf,1);
  572.             if (t0 < 254 && tab[t0] == tab[t0+1] && tab[t0] == tab[t0+2])
  573.                 {
  574.                 printf("\" to \"");
  575.                 while (tab[t0] == tab[t0+1]) t0++;
  576.                 buf[0] = t0;
  577.                 printbind(buf,1);
  578.                 }
  579.             printf("\"\t%s\n",zlecmds[tab[t0]].name);
  580.             }
  581.         listhtable(xbindtab,(HFunc) printbinding);
  582.         return 0;
  583.         }
  584.     while (*argv)
  585.         {
  586.         s = getkeystring(*argv++,&len);
  587.         if (len > 8)
  588.             {
  589.             zerrnam(name,"in-string too long",NULL,0);
  590.             return 1;
  591.             }
  592.         if (!*argv || ops['r'])
  593.             {
  594.             Key ky;
  595.  
  596.             ky = gethnode(s,xbindtab);
  597.             if (len == 1)
  598.                 func = tab[(unsigned char) *s];
  599.             else
  600.                 func = (ky) ? ky->func : z_undefinedkey;
  601.             if (func == z_undefinedkey)
  602.                 {
  603.                 zerrnam(name,"in-string is not bound",NULL,0);
  604.                 return 1;
  605.                 }
  606.             if (ops['r'])
  607.                 {
  608.                 if (len == 1)
  609.                     tab[(unsigned char) *s] = z_undefinedkey;
  610.                 else
  611.                     {
  612.                     while (strlen(s) > 1)
  613.                         {
  614.                         free(remhnode(s,xbindtab));
  615.                         s[strlen(s)-1] = '\0';
  616.                         }
  617.                     }
  618.                 continue;
  619.                 }
  620.             if (func == z_sendstring)
  621.                 {
  622.                 printbind(ky->str,ky->len);
  623.                 putchar('\n');
  624.                 return 0;
  625.                 }
  626.             printf("%s\n",zlecmds[func].name);
  627.             return 0;
  628.             }
  629.         if (!ops['s'])
  630.             {
  631.             for (t0 = 0; t0 != ZLECMDCOUNT; t0++)
  632.                 if (!strcmp(*argv,zlecmds[t0].name))
  633.                     break;
  634.             if (t0 == ZLECMDCOUNT)
  635.                 {
  636.                 zerr("undefined function: %s",*argv,0);
  637.                 return 1;
  638.                 }
  639.             func = t0;
  640.             }
  641.         else
  642.             func = z_sendstring;
  643.         if (len == 1)
  644.             {
  645.             Key ky;
  646.  
  647.             tab[(unsigned char) *s] = (ops['s']) ? z_sendstring : t0;
  648.             if (ops['s'])
  649.                 {
  650.                 addhnode(ztrdup(s),ky = makefunckey(z_sendstring),xbindtab,freekey);
  651.                 ky->str = ztrdup(getkeystring(*argv,&ky->len));
  652.                 }
  653.             }
  654.         else
  655.             {
  656.             int t1;
  657.             Key ky;
  658.  
  659.             if (tab[(unsigned char) *s] != z_undefinedkey &&
  660.                     tab[(unsigned char) *s] != z_sequenceleadin)
  661.                 {
  662.                 zerrnam(name,"in-string has already bound prefix",NULL,0);
  663.                 return 1;
  664.                 }
  665.             tab[(unsigned char) *s] = z_sequenceleadin;
  666.             if (!s[1])
  667.                 s[1] = 0x80;
  668.             for (t1 = 1; t1 != len-1; t1++)
  669.                 {
  670.                 char sav;
  671.  
  672.                 sav = s[t1+1];
  673.                 s[t1+1] = '\0';
  674.                 ky = gethnode(s,xbindtab);
  675.                 if (ky && ky->func != z_sequenceleadin)
  676.                     {
  677.                     zerrnam(name,"in-string has already bound prefix",NULL,0);
  678.                     return 1;
  679.                     }
  680.                 if (!ky)
  681.                     addhnode(ztrdup(s),makefunckey(z_sequenceleadin),xbindtab,
  682.                         freekey);
  683.                 if (!sav)
  684.                     sav = 0x80;
  685.                 s[t1+1] = sav;
  686.                 }
  687.             addhnode(ztrdup(s),ky = makefunckey(func),xbindtab,freekey);
  688.             if (ops['s'])
  689.                 ky->str = ztrdup(getkeystring(*argv,&ky->len));
  690.             }
  691.         argv++;
  692.         }
  693.     return 0;
  694. }
  695.  
  696. void freekey(x) /**/
  697. vptr x;
  698. {
  699. Key k = x;
  700.  
  701.     if (k->str)
  702.         free(k->str);
  703.     free(k);
  704. }
  705.  
  706. /* this is mostly stolen from bash's draino() */
  707.  
  708. void drainoutput() /**/
  709. {
  710. int n = 0;
  711.  
  712.     if (!baud) return;
  713. #ifdef TIOCOUTQ
  714. #ifdef HAS_SELECT
  715.     while ((ioctl(SHTTY,TIOCOUTQ,&n) >= 0) && n) {
  716.         struct timeval tv;
  717.         tv.tv_sec = n/baud;
  718.         tv.tv_usec = ((n%baud)*1000000)/baud;
  719.         select (0,(fd_set *)0,(fd_set *)0,(fd_set *)0,&tv);
  720.     }
  721. #endif
  722. #endif
  723. }
  724.  
  725.