home *** CD-ROM | disk | FTP | other *** search
/ back2roots/padua / padua.7z / padua / shell / csh537src.lha / rawcon.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-13  |  21.7 KB  |  1,027 lines

  1. /* rawcon.c
  2.  *
  3.  * Shell 2.07M  17-Jun-87
  4.  * console handling, command line editing support for Shell
  5.  * using new console packets from 1.2.
  6.  * Written by Steve Drew. (c) 14-Oct-86.
  7.  * 16-Dec-86 Slight mods to rawgets() for Disktrashing.
  8.  *
  9.  * Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
  10.  * Version 5.00L by Urban Mueller 17-Feb-91
  11.  * Version 5.20L by Andreas M. Kirchwitz (Fri, 13 Mar 1992)
  12.  *
  13.  */
  14.  
  15. #include "shell.h"
  16.  
  17. void setrawcon( long flag, int ievent );
  18.  
  19. #define LINELEN 255
  20.  
  21. int w_width=80, w_height=24;
  22.  
  23. #if RAW_CONSOLE
  24.  
  25. static int myget( void );
  26. static void myunget(int c);
  27. static int get_seq( long *param );
  28.  
  29. static void back( int n );
  30. static void left( int n );
  31. static void right( int n );
  32. static int  leftwordlen( void );
  33. static int  rightwordlen( void );
  34. static void delete( int i );
  35. static void history( int hnum );
  36. static void display( char *str );
  37. static void redraw( void );
  38. static void abbrev( char *buf, char **eav, int eac );
  39. static void quote( char *buf, char *sep );
  40. static void getword( char *buf );
  41. static void delword( void );
  42. static int  getkey(void);
  43.  
  44. static char *tyahdptr;
  45. static int unget;
  46.  
  47. #define SETRAW setrawcon(-1,1);
  48. #define SETCON setrawcon( 0,1);
  49.  
  50. extern char *MenuCommand[MAXMENUS][MAXMENUITEMS];
  51.  
  52. #define CTRL  -64
  53. #define SHIFT 512
  54. #define ESC   1024
  55.  
  56. #define CUP   256
  57. #define CDN   257
  58. #define CRT   258
  59. #define CLT   259
  60. #define TAB   9
  61.  
  62. static int Curmap;
  63. static USHORT *Keymap[8];
  64. static USHORT DefKeymap0[]={
  65.        CLT,  0, /* CursLt = Move.Left  */
  66.        CRT,  1, /* CursRt = Move.Right */
  67.  SHIFT+CLT,  2, /* SCursLt= Move.WordL */
  68.  SHIFT+CRT,  3, /* SCursRt= Move.WordR */
  69.    ESC+CLT,  4, /* ESC-CLt= Move.SOL   */
  70.    ESC+CRT,  5, /* ESC-CRt= Move.EOL   */
  71.   CTRL+'A',  4, /* ^A     = Move.SOL   */
  72.   CTRL+'E',  5, /* ^E     = Move.EOL   */
  73.   CTRL+'Z',  4, /* ^Z     = Move.SOL   */
  74.          8, 10, /* BackSp = Del.BackSp */
  75.        127, 11, /* Delete = Del.Delete */
  76.    ESC+  8, 12, /* ESC-BkS= Del.WordL  */
  77.    ESC+127, 13, /* ESC-Del= Del.WordR  */
  78.   CTRL+'W', 12, /* ^W     = Del.WordL  */
  79.   CTRL+'B', 14, /* ^B     = Del.SOL    */
  80.   CTRL+'K', 15, /* ^K     = Del.EOL    */
  81.    ESC+'x',513, /* ESC-x  = Setmap 1   */
  82.    ESC+'d', 16, /* ESC-d  = Del.Line   */
  83.   CTRL+'X', 16, /* ^X     = Del.Line   */
  84.        CUP, 20, /* CursUp = Hist.Back  */
  85.        CDN, 21, /* CursDn = Hist.Forw  */
  86.    ESC+CUP, 22, /* ECursUp= Hist.Beg   */
  87.    ESC+CDN, 23, /* ECursDn= Hist.End   */
  88.  SHIFT+CUP, 24, /* SCursUp= Hist.Compl */
  89.    ESC+'!', 24, /* ESC-!  = Hist.Compl */
  90.    ESC+ 13, 25, /* ESC-Ret= Hist.Exec  */
  91.   CTRL+'T', 26, /* ^T     = Hist.Tail  */
  92.  SHIFT+CDN, 27, /* SCursDn= Hist.Clr   */
  93.   CTRL+'P', 28, /* ^P     = Hist.DupWrd*/
  94.        TAB, 30, /* Tab    = Comp.Norm  */
  95.  SHIFT+TAB, 31, /* STab   = Comp.Part  */
  96.    ESC+TAB, 32, /* ESC-TAB= Comp.All   */
  97.    ESC+'*', 32, /* ESC-*  = Comp.All   */
  98.    ESC+'c', 33, /* ESC-c  = Comp.CD    */
  99.    ESC+'~', 34, /* ESC-~  = Comp.LastCD*/
  100.   CTRL+'D', 35, /* CTRL-D = Comp.Dir   */
  101.    ESC+'=', 35, /* ESC-=  = Comp.Dir   */
  102.    ESC+'p', 36, /* ESC-p  = Comp.Prg1  */
  103.    ESC+'P', 37, /* ESC-P  = Comp.PrgAll*/
  104.    ESC+'i', 40, /* ESC-i  = Spec.Insert*/
  105.   CTRL+'L', 43, /* ^L     = Spec.Refr  */
  106.         10, 44, /* Enter  = Spec.Accept*/
  107.         13, 44, /* ^Enter = Spec.Accept*/
  108.   CTRL+'N', 45, /* ^N     = Spec.Next  */
  109.   CTRL+'O', 48, /* ^O     = Spec.EchoO */
  110.  CTRL+'\\', 46, /* ^\     = Spec.EOF   */
  111.        260, 42, /* Help   = Spec.Help  */
  112.        271, 51, /* Menu   = Misc.Menu  */
  113.   CTRL+'U', 52, /* ^U     = Misc.Undo  */
  114.   CTRL+'R', 53, /* ^R     = Misc.Repeat*/
  115.    ESC+'s', 54, /* ESC-s  = Misc.Swap  */
  116.          0,  0
  117. };
  118.  
  119. static USHORT DefKeymap1[]={
  120.          8, 14,
  121.        127, 15,
  122.          0, 0
  123. };
  124.  
  125. static int  Pos, Len;
  126. static char *Line, *Prompt;
  127. static char LastDir[128];
  128. static char Undo[256];
  129. static int  LastFn=-99, LastKey=-99;
  130. long   Param[10];
  131.  
  132. void
  133. initmap(void)
  134. {
  135.     if( !Keymap[0] )
  136.         Keymap[0]=DefKeymap0, Keymap[1]=DefKeymap1;
  137. }
  138.  
  139. char *
  140. rawgets( char line[], char prompt[] )
  141. {
  142.     static int HNum=-1;
  143.  
  144.     int  key, fn, old, hnum=-1, olen=0, inslen=0;
  145.     int  insert, undo_pos=0, undo_len=0;
  146.     int  eac, eactr=0;
  147.     char typeahd[LINELEN], **eav=NULL, *ret=line;
  148.     char *prghash_hit;
  149.     char prghash_pat[LINELEN];
  150.  
  151.     char *prio_set;
  152.     long oldprio,prio;
  153.  
  154.     if ( o_noraw || !isconsole(Input()) ) {
  155.         if( isconsole(Input())) {
  156.             printf("%s",prompt);
  157.             fflush(stdout);
  158.         }
  159.         return gets(line);
  160.     }
  161.  
  162.     if (WaitForChar(Input(), 100L) || CHARSWAIT(stdin)) /* don't switch to 1 */
  163.         return gets(line);
  164.  
  165. /*
  166.    KingCON dislikes o_noraw == 0, meaning console device in raw-input mode:
  167.    DoPkt( (void *)Myprocess->pr_ConsoleTask, ACTION_SCREEN_MODE, -1,  NULL,NULL,NULL,NULL );
  168. */
  169.  
  170.     SETRAW;
  171.  
  172.     if (prio_set = get_var(LEVEL_SET,v_clipri)) {
  173.         prio=atol(prio_set);
  174.         if (!isnum(prio_set)) {
  175.             printf("error: variable _clipri (%s) is not a number\n",prio_set);
  176.             prio_set = NULL;
  177.         }
  178.         else if (prio<-128 || prio>127) {
  179.             printf("error: variable _clipri (%s) is out of range (-128,127)\n",prio_set);
  180.             prio_set = NULL;
  181.         }
  182.         else {
  183.             oldprio = SetTaskPri((struct Task *)Myprocess,prio);
  184.         }
  185.     }
  186.  
  187.     tyahdptr=typeahd;
  188.     typeahd[0]=0;
  189.     Flush(Output());
  190.     printf("\015\017\033[ p%s",prompt);
  191.  
  192.     Line= line; Prompt= prompt;
  193.     line[ Len=Pos=0 ]=0;
  194.     insert= o_insert;
  195.  
  196.     if( LastFn!=25 )
  197.         LastFn=-1;
  198.  
  199.     if( HNum>=0 ) {
  200.         history( hnum=HNum );
  201.         HNum=-1;
  202.     }
  203.  
  204.     while( (key=getkey()) != -1) {
  205.         USHORT *p;
  206.         int    t;
  207.         char   c, *s, *src, *sep;
  208.  
  209.         for( fn=-1, p=Keymap[Curmap]; *p; p+=2 )
  210.             if( *p==key )
  211.                 { fn=p[1]; break; }
  212.         if( fn==-1 && (key>=261 && key<=270 || key>=261+SHIFT && key<=270+SHIFT))
  213.             fn=50;
  214.         if( fn==-1 && tyahdptr )
  215.             fn=-2;
  216.         if( fn!=52 && fn!=-2 ) {
  217.             memcpy( Undo, line, Len+1 );
  218.             undo_pos=Pos; undo_len=Len;
  219.         }
  220.  
  221.         switch( fn/512 ) {
  222.         case 1:
  223.             fn&=511;
  224.             if( fn<8 && Keymap[fn] ) Curmap=fn;
  225.             fn=-3;
  226.             break;
  227.         case 2:
  228.             key=fn&511, fn=-1;
  229.             break;
  230.         }
  231.  
  232.         if( fn!=-3 )
  233.             Curmap=0;
  234.  
  235.         if( fn==53 )
  236.             fn=LastFn, key=LastKey;
  237.  
  238.         switch( fn ) {
  239.         case -3:                                /* change keymap */
  240.             break;
  241.         case -2:                                /* auto insert   */
  242.         case -1:                                /* insert key    */
  243.             key&=255;
  244.             if (key < 31 || (insert?Len:Pos) >= LINELEN-1 )
  245.                 break;
  246.             putchar(key);
  247.             if (Pos < Len && insert) {
  248.                 memmove( line+Pos+1, line+Pos, Len-Pos+1);
  249.                 printf("%s",line+Pos+1);
  250.                 back(Len-Pos);
  251.                 Len++;
  252.             }
  253.             line[Pos++] = key;
  254.             if (Len < Pos) Len = Pos;
  255.             line[Len] = 0;
  256.             break;
  257.  
  258.         case 0:                                 /* cursor left  */
  259.             left(1);
  260.             break;
  261.         case 1:                                 /* cursor right */
  262.             right(1);
  263.             break;
  264.         case 2:                                 /* word left    */
  265.             left( leftwordlen() );
  266.             break;
  267.         case 3:                                 /* word right   */
  268.             right( rightwordlen() );
  269.             break;
  270.         case 4:                                 /* beg of line  */
  271.             left(Pos);
  272.             break;
  273.         case 5:                                 /* end of line  */
  274.             right(Len-Pos);
  275.             break;
  276.  
  277.         case 10:                                /* backspace    */
  278.             if (Pos==0)
  279.                 break;
  280.             left(1);
  281.         case 11:                                /* delete       */
  282.             if (Pos==Len)
  283.                 break;
  284.             delete(1);
  285.             break;
  286.         case 12:                                /* bkspc word     */
  287.             if( !leftwordlen() )
  288.                 break;
  289.             left( leftwordlen() );
  290.         case 13:                                /* del word       */
  291.             delete( rightwordlen() );
  292.             break;
  293.         case 14:                                /* del to SOL     */
  294.             left( old=Pos );
  295.             delete( old );
  296.             break;
  297.         case 16:                                /* delete line    */
  298.             left( Pos );
  299.         case 15:                                /* delete to EOL  */
  300.             delete( Len-Pos );
  301.             break;
  302.  
  303.         case 17: /* AMK */                      /* clear screen + refresh */
  304.             fprintf(stdout,"\033c\017");
  305.             fflush(stdout);
  306.             redraw();
  307.             break;
  308.  
  309.         case 20:                                /* history up   */
  310.             if( hnum>=H_len-1 )
  311.                 hnum=H_len-1;
  312.             history( ++hnum );
  313.             break;
  314.         case 21:                                /* history down */
  315.             if( hnum<=0 )
  316.                 hnum=0;
  317.             history( --hnum );
  318.             break;
  319.         case 22:                                /* beg of hist */
  320.             history( hnum=H_len-1 );
  321.             break;
  322.         case 23:                                /* end of hist */
  323.             history( hnum=0 );
  324.             break;
  325.         case 24:                                /* complete hist */
  326.             if( LastFn!=fn )
  327.                 hnum=-1, olen=Len;
  328.             line[Len=olen]=0;
  329.             if((hnum=find_history( line, ++hnum ))==-1)
  330.                 display(line);
  331.             else
  332.                 history(hnum);
  333.             break;
  334.         case 25:                                /* exec hist  */
  335.             HNum= hnum;
  336.             LastFn= fn;
  337.             goto done;
  338.         case 26:                                /* tail of prev */
  339.             if( H_head && (s=H_head->line) && (s=index(s,' ')))
  340.                 tyahdptr=s;
  341.             break;
  342.         case 27:                                /* bottom   */
  343.             history( hnum=-1 );
  344.             break;
  345.         case 28:                                /* duplicate word */
  346.             for( s=line+Pos,t=0; s>line && s[-1]==' '; s--,t++ ) ;
  347.             left(t);
  348.             *(tyahdptr=typeahd)=' ';
  349.             getword( typeahd+(t?0:1) );
  350.             right(t);
  351.             break;
  352.         case 29: /* AMK */                      /* last word of prev */
  353.             if( H_head && (s=H_head->line)) {
  354.                 int l = strlen(s) - 1;
  355.                 while (l>=0 && s[l]==' ')    /* skip spaces */
  356.                     --l;
  357.                 while (l>=0 && s[l]!=' ')    /* find next space */
  358.                     --l;
  359.                 if (l>=0)
  360.                     tyahdptr=&s[l];
  361.             }
  362.             break;
  363.  
  364.         case 32:                                /* complete all  */
  365.         case 35: LastFn=-1;                     /* show files    */
  366.         case 30:                                /* complete      */
  367.         case 31:                                /* complete part */
  368.         case 33:                                /* qcd           */
  369.             sep=" ";
  370.             if( fn!=LastFn ) {
  371.                 getword( typeahd );
  372.                 filemap( typeahd, 1 );
  373.                 if( eav    ) free_expand( eav ), eav=NULL;
  374.                 eac=0;
  375.                 breakreset();
  376.                 if( fn==35 ) {
  377.                     int tmp=o_scroll;
  378.                     int old_Pos=Pos;
  379.                     right(Len-Pos);
  380.                     putchar('\n');
  381.                     memmove( typeahd+8, typeahd, strlen(typeahd)+1);
  382.                     /*
  383.                        we need to escape "dir" here in
  384.                        such a way that it works even if
  385.                        a user aliased "dir" to something
  386.                        completely else
  387.                     */
  388.                     memcpy ( typeahd, "\\dir -s ", 8);
  389.                     o_scroll=0;
  390.                     execute( typeahd );
  391.                     o_scroll=tmp;
  392.                     printf("\033[J%s%s",Prompt,Line);
  393.                     back(Len-old_Pos);
  394.                     Pos = old_Pos;
  395.                     break;
  396.                 }
  397.                 if( fn!=33 ) {
  398.                     strcat(  typeahd, "*");
  399.                     if( !index(typeahd,'&' ))
  400.                         eav =expand(typeahd,&eac);
  401.                     if( eac==0 ) {
  402.                         putchar(7);
  403.                         break;
  404.                     }
  405.                 }
  406.                 if( fn==30 )
  407.                     s=eav[ eactr=0 ];
  408.                 else if( fn==31 )
  409.                     abbrev(s=typeahd,eav,eac), eactr=-1, sep= eac==1?" ":"";
  410.                 else if( fn==32 ) {
  411.                     strncpy(s=typeahd, src=compile_av(eav,0,eac,' ',1),LINELEN);
  412.                     typeahd[LINELEN-1]=0;
  413.                     free(src);
  414.                 } else if( fn==33 ) {     /* 33 */
  415.                     strncpy(LastDir,typeahd,128);
  416.                     if( !quick_cd( s=typeahd+128, LastDir, 0)) {
  417.                         putchar(7);
  418.                         break;
  419.                     }
  420.                 }
  421.                 delword();
  422.             } else {
  423.                 if( fn==33 )
  424.                     quick_cd( s=typeahd+128, LastDir, 1);
  425.                 else { /* 30,31 */
  426.                     if( eac==0 ) {
  427.                         putchar(7);
  428.                         break;
  429.                     }
  430.                     s=eav[eactr=++eactr % eac];
  431.                 }
  432.                 left(inslen);
  433.                 delete(inslen);
  434.             }
  435.             strcpy( tyahdptr=typeahd, s );
  436.             if( fn!=32 )
  437.                 quote( typeahd, sep );
  438.             inslen=strlen(typeahd);
  439.             break;
  440.         case 34:                      /* last CD */
  441.             strncpy(typeahd,get_var( LEVEL_SET, v_lcd ),230);
  442.             appendslash(tyahdptr=typeahd);
  443.             break;
  444.         case 36:
  445.             if( fn!=LastFn ) {
  446.                 getword( typeahd );
  447.                 filemap( typeahd, 1 );
  448.                 strcpy(prghash_pat,typeahd);
  449.                 if (prghash_hit=get_rehash_prog(NULL,prghash_pat)) {
  450.                     delword();
  451.                     strcpy(tyahdptr=typeahd,prghash_hit);
  452.                     /*quote(typeahd," ");*/
  453.                     inslen=strlen(typeahd);
  454.                 }
  455.                 else
  456.                     putchar(7);
  457.             }
  458.             else {
  459.                 if (prghash_hit) {
  460.                     if (prghash_hit=get_rehash_prog(prghash_hit,prghash_pat)) {
  461.                         left(inslen);
  462.                         delete(inslen);
  463.                         strcpy(tyahdptr=typeahd,prghash_hit);
  464.                         /*quote(typeahd," ");*/
  465.                         inslen=strlen(typeahd);
  466.                     }
  467.                     else
  468.                         putchar(7);
  469.                 }
  470.                 else
  471.                     putchar(7);
  472.             }
  473.             break;
  474.         case 37:
  475.             {
  476.             char *firsthit;
  477.             int tmp=o_scroll;
  478.             int old_Pos=Pos;
  479.             int cnt = 0;
  480.  
  481.             getword( typeahd );
  482.             filemap( typeahd, 1 );
  483.  
  484.             prghash_hit = NULL;
  485.             if (firsthit=get_rehash_prog(NULL,typeahd)) {
  486.                 right(Len-Pos);
  487.                 putchar('\n');
  488.                 o_scroll=0;
  489.                 printf(" %d. %s\n",++cnt,firsthit);
  490.                 prghash_hit = firsthit;
  491.                 breakreset();
  492.                 while ( !dobreak() && (prghash_hit=get_rehash_prog(prghash_hit,typeahd)) && prghash_hit!=firsthit ) {
  493.                     printf(" %d. %s\n",++cnt,prghash_hit);
  494.                 }
  495.                 breakreset();
  496.                 o_scroll=tmp;
  497.                 printf("\033[J%s%s",Prompt,Line);
  498.                 back(Len-old_Pos);
  499.                 Pos = old_Pos;
  500.             }
  501.             else
  502.                 putchar(7);
  503.  
  504.             break;
  505.             }
  506.  
  507.         case 40:                      /* ins/ovr */
  508.             insert ^= 1;
  509.             break;
  510.         case 41:                      /* quit    */
  511.             strcpy(line,"quit");
  512.             goto done;
  513.         case 42:                      /* help    */
  514.             strcpy(line,"help");
  515.             goto done;
  516.         case 43:                      /* refresh */
  517.             redraw();
  518.             break;
  519.         case 44:                      /* exec    */
  520.             goto done;
  521.         case 45:                      /* leave   */
  522.             add_history( line );
  523.             right(Len-Pos);
  524.             putchar('\n');
  525.             line[Len=Pos=0]=0;
  526.             update_sys_var(v_prompt);
  527.             update_sys_var(v_titlebar);
  528.             redraw();
  529.             hnum=-1;
  530.             break;
  531.         case 46:                      /* EOF */
  532.             ret=NULL;
  533.             goto done;
  534.         case 47:                      /* NOP */
  535.             break;
  536.         case 48:                      /* ^O  */
  537.             /*putchar( CTRL+'O' );*/
  538.             putchar( '\017' );
  539.             redraw();
  540.             break;
  541.         case 49:                      /* ^G  */
  542.             /*putchar( CTRL+'G' );*/
  543.             putchar( '\007' );
  544.             break;
  545.  
  546.         case 50:                      /* FKey */
  547.             sprintf(typeahd,"%c%d",Param[0]>=10?'F':'f',Param[0]%10+1);
  548.             if (s = get_var(LEVEL_SET, typeahd)) {
  549.                 tyahdptr = strcpy(typeahd,s);
  550.                 a0tospace( tyahdptr );
  551.             }
  552.             break;
  553.         case 51:                      /* RawRaw */
  554.             if( Param[0]==10 ) {   /* P0=class P2=code */
  555.                 int num=MENUNUM( Param[2] ), item=ITEMNUM( Param[2] );
  556.                 tyahdptr="";
  557.                 if( num>=0 && num<MAXMENUS && item>=0 && item<MAXMENUITEMS )
  558.                     tyahdptr=MenuCommand[num][item];                                 
  559.             }
  560.             if( Param[0]==11 ) {
  561.                 strcpy(line,"quit");
  562.                 goto done;
  563.             }
  564.             break;
  565.         case 52:                      /* Undo   */
  566.             back(Pos);
  567.             t=Len; Len=undo_len; undo_len=t;
  568.             t=Pos; Pos=undo_pos; undo_pos=t;
  569.             swapmem( Undo, line, MAX( Len, undo_len)+1 );
  570.             printf("\033[J%s",line);
  571.             back(Len-Pos);
  572.             break;
  573.         case 53:                      /* repeat */
  574.             break;
  575.         case 54:                      /* swap   */
  576.             if( (t=Pos==Len?Pos-1:Pos)>0 )
  577.                 c=line[t-1], line[t-1]=line[t], line[t]=c;
  578.             redraw();
  579.             break;
  580.         }
  581.         if( fn!=-2 )
  582.             LastFn=fn, LastKey=key;
  583.     }
  584.     ret=NULL;
  585. done:
  586.     if( ret )
  587.         printf("\033[%dC\n", Len-Pos );
  588.     newwidth();
  589.     if( eav ) free_expand(eav);
  590.     SETCON;
  591.  
  592.     if (prio_set)
  593.         SetTaskPri((struct Task *)Myprocess,oldprio);
  594.  
  595.     return ret;
  596. }
  597.  
  598. static int
  599. getkey(void)
  600. {
  601.     int   esc=0, key, c;
  602.     long *par;
  603.  
  604.     key=-1;
  605.     if( (c=myget())==27 ) {
  606.         esc=ESC;
  607.         if((c=myget())=='[')
  608.             c=155, esc=0;
  609.     }
  610.  
  611.     if(c!=155)
  612.         key=c;
  613.     else {
  614.         switch(c=myget()) {
  615.         case 'A': key=256;       break; /* CursUp */
  616.         case 'B': key=257;       break; /* CursDn */
  617.         case 'C': key=258;       break; /* CursRt */
  618.         case 'D': key=259;       break; /* CursLt */
  619.         case 'T': key=256+SHIFT; break; /* SCursUp */
  620.         case 'S': key=257+SHIFT; break; /* SCursDn */
  621.         case ' ':
  622.             switch( myget() ) {
  623.             case '@': key=258+SHIFT; break; /* SCursRt */
  624.             case 'A': key=259+SHIFT; break; /* SCursLt */
  625.             }
  626.             break;
  627.         case 'Z': key= 9+SHIFT;       break; /* STab    */
  628.         case '?': key= 260; myget();  break; /* Help    */
  629.         case -1 : return -99;
  630.         default :
  631.             if( c>='0' && c<='9' ) {
  632.                 myunget(c);
  633.                 par=Param;
  634.                 do {
  635.                     for( *par=0; (c=myget())>='0' && c<='9';  )
  636.                         *par=10* *par + c-'0';
  637.                     par++;
  638.                 } while( c==';' );
  639.                 if( c=='~' ) {
  640.                     key=Param[0]+261;
  641.                     if( key>270 ) key+=SHIFT-10;
  642.                 }
  643.                 if( c=='|' ) key=271;
  644.             } else
  645.                 key=c;
  646.         }
  647.     }
  648.  
  649.     return key+esc;
  650. }
  651.  
  652. static void
  653. back(int n)
  654. {
  655.     if( n>0 ) printf("\033[%dD",n);
  656. }
  657.  
  658. static void
  659. left(int n)
  660. {
  661.     if( n>Pos ) n=Pos;
  662.     if( n<=0  ) return;
  663.     back(n);
  664.     Pos-=n;
  665. }
  666.  
  667. static void
  668. right(int n)
  669. {
  670.     if( n+Pos>Len ) n=Len-Pos;
  671.     if( n<=0      ) return;
  672.     printf("\033[%dC",n);
  673.     Pos+=n;
  674. }
  675.  
  676. static int
  677. leftwordlen( void )
  678. {
  679.     char  *ptr= Line+Pos;
  680.     while( ptr>Line && *(ptr-1) == ' ' ) ptr--;
  681.     while( ptr>Line && *(ptr-1) != ' ' ) ptr--;
  682.     return (Line+Pos)-ptr;
  683. }
  684.  
  685. static int
  686. rightwordlen( void )
  687. {
  688.     char  *ptr= Line+Pos;
  689.     while( ptr<Line+Len && *ptr != ' ' ) ptr++;
  690.     while( ptr<Line+Len && *ptr == ' ' ) ptr++;
  691.     return ptr-(Line+Pos);
  692. }
  693.  
  694. static void
  695. delete( int cnt )
  696. {
  697.     if( !cnt ) return;
  698.     memmove( Line+Pos, Line+Pos+cnt, Len-Pos-cnt );
  699.     memset ( Line+Len-cnt, ' ', cnt );
  700.     printf("%s",Line+Pos);
  701.     back(Len-Pos);
  702.     Line[ Len-=cnt ]=0;
  703. }
  704.  
  705. static void
  706. history( int hnum )
  707. {
  708.     HIST *hist;
  709.  
  710.     for( hist=H_head; hist && hnum--; hist=hist->next) ;
  711.     display( hist ? hist->line : "");
  712. }
  713.  
  714. static void 
  715. display( char *str )
  716. {
  717.     left(Pos);
  718.     strcpy(Line,str);
  719.     printf("\033[J%s",str);
  720.     Pos= Len= strlen(str);
  721. }
  722.  
  723. static void
  724. redraw( void )
  725. {
  726.     back(Pos);
  727.     printf("\015\033[J%s%s",Prompt,Line);
  728.     back(Len-Pos);
  729. }
  730.  
  731. static int wleft, wdel;
  732.  
  733. static void
  734. getword( char *buf )
  735. {
  736.     char *beg, *end, *l=Line;
  737.  
  738.     for( end=l+Pos; *end  && *end!=' '; ++end ) ;
  739.     for( beg=l+Pos; beg>l && !index(" <>;",*(beg-1)) ; beg-- ) ;
  740.     memcpy( buf, beg, end-beg );
  741.     buf[end-beg]=0;
  742.     wleft= (l+Pos)-beg;
  743.     wdel = end-beg;
  744. }
  745.  
  746. static void
  747. delword()
  748. {
  749.     left( wleft);
  750.     delete( wdel );
  751. }
  752.  
  753.  
  754.  
  755. static void
  756. abbrev( char *buf, char **eav, int eac )
  757. {
  758.     int i, j, radlen=9999;
  759.  
  760.     /*if( eac>1 ) putchar( CTRL+'G' );*/
  761.     if( eac>1 ) putchar( '\007' );    /* ^G */
  762.  
  763.     strcpy( buf, eav[0] );
  764.     for( i=0; i<eac; i++ ) {
  765.         if ( (j=strlen(eav[i])) < radlen ) radlen=j;
  766.         for( j=0; j<radlen && tolower(eav[0][j])==tolower(eav[i][j]); j++ ) ;
  767.         if ( j<radlen ) radlen=j;
  768.     }
  769.     buf[radlen]=0;
  770. }
  771.  
  772.  
  773.  
  774. static int must_be_quoted(char *s)
  775. {
  776.     if (!*s)
  777.         return 1;
  778.     for ( ; *s; s++)
  779.         if (ISSPACE(*s) || *s==';' || *s=='|' || *s=='#' || *s=='^'
  780.              || *s=='?' || *s=='*' || *s=='&' || *s=='$' || *s=='!'
  781.              || *s=='~' || *s=='`' || *s=='\'')
  782.            return 1;
  783.     return 0;
  784. }
  785.  
  786. static void quote( char *buf, char *sep )
  787. {
  788.     int len=strlen(buf), dir=isdir(buf);
  789.  
  790.     if (must_be_quoted(buf)) {
  791.         memmove(buf+1,buf,len);
  792.         buf[0]=buf[++len]='\"';
  793.         buf[++len]=0;
  794.     }
  795.     strcat(buf,dir?"/":sep);
  796. }
  797.  
  798.  
  799.  
  800. void
  801. setrawcon( long flag, int ievent ) /* -1L=RAW:, 0L=CON: */
  802. {
  803.     static char menuon, button;
  804.  
  805.     if( !o_nowindow && ievent && flag==0 && menuon)
  806.         printf("\033[10}"), menuon=0;
  807.  
  808.     DoPkt( (void *)Myprocess->pr_ConsoleTask, ACTION_SCREEN_MODE, flag,  NULL,NULL,NULL,NULL );
  809.  
  810.     if( !o_nowindow && ievent && flag==-1 ) {
  811.         if( !menuon )
  812.             printf("\033[10{"), menuon=1;
  813.         if( !button )
  814.             printf("\033[11{"), button=1;
  815.     }
  816.     fflush(stdout);
  817. }
  818.  
  819.  
  820. static int row, height, cnt;
  821. static char scrollstr[10];
  822. static int noquick=1;
  823.  
  824.  
  825. extern BPTR OldCin;
  826.  
  827. static int FromTee;
  828.  
  829. static UBYTE
  830. mygetchar(void)
  831. {
  832.     UBYTE c;
  833.     Read( Input(), &c, 1 );
  834.     return c;
  835. }
  836.  
  837. void
  838. prepscroll( int fromtee )
  839. {
  840.     BPTR truecin=0;
  841.     long param[8];
  842.  
  843.     row=height=0;
  844.     FromTee=fromtee;
  845.  
  846.     if(( noquick=!o_scroll || o_noraw || o_nofastscr))
  847.         return;
  848.     if(( noquick=!isconsole(Myprocess->pr_COS) && !fromtee ))
  849.         return;
  850.     if( !isconsole(Myprocess->pr_CIS)) {
  851.         truecin=Myprocess->pr_CIS;
  852.  
  853.         if( noquick=!isconsole(OldCin) )
  854.             return;
  855.  
  856.         Myprocess->pr_CIS = DEVTAB(stdin) = OldCin;
  857.     }
  858.  
  859.     if( !CHARSWAIT(stdin) ) {
  860.         SETRAW;
  861.         Write(OldCin,"\033[ q",4);
  862.         get_seq( param );
  863.         height=param[2];
  864.         while( mygetchar()!='r') ;
  865.  
  866.         Write(OldCin,"\033[6n",4);
  867.         get_seq( param );
  868.         row=param[0];
  869.  
  870.         SETCON;
  871.  
  872.         cnt= height-row+1;
  873.         noquick= height<o_minrows;
  874.     }
  875.  
  876.     sprintf(scrollstr,"\033[%cS\033[%cA", o_scroll+'0', o_scroll+'0');
  877.  
  878.     if( truecin )
  879.         Myprocess->pr_CIS = DEVTAB(stdin) = truecin;
  880. }
  881.  
  882. static int
  883. get_seq( long *param )
  884. {
  885.     int c;
  886.  
  887.     while( (c=mygetchar())!=155 ) ;
  888.     do {
  889.         *param=0;
  890.         while( (c=mygetchar())>='0' && c<='9' )
  891.             *param=10* *param + c-'0';
  892.         param++;
  893.     } while( c==';' );
  894.  
  895.     return c;
  896. }
  897.  
  898.  
  899. void
  900. quickscroll( void )
  901. {
  902.     if( noquick ) return;
  903.  
  904.     if( --cnt<=0 ) {
  905.         cnt=o_scroll;
  906.         fprintf( FromTee ? stderr : stdout, "%s",scrollstr);
  907.     }
  908. }
  909.  
  910. int
  911. do_keymap( void )
  912. {
  913.     int i, n, len;
  914.     USHORT *tmp, *put, *get, *map;
  915.     char   *ind;
  916.  
  917. #if 0
  918.     if( ac==1 ) {
  919.         for( get=Keymap[0]; *get; get+=2 )
  920.             printf("%4d %4d\n",get[0],get[1]);
  921.         return 0;
  922.     }
  923. #endif
  924.  
  925.     n=myatoi(av[1],0,7);
  926.     if( atoierr ) return 20;
  927.  
  928.     map=Keymap[n]; len=0;
  929.     if( map )
  930.         for( len=0; map[2*len]; len++ ) ;
  931.  
  932.     put=tmp=salloc((len+ac)*2*sizeof(USHORT));
  933.     for( i=2; i<ac; i++ ) {
  934.         if( !(ind=index(av[i],'='))) {
  935.             ierror( av[i],500);
  936.             free( tmp );
  937.             return 20;
  938.         }
  939.         *put++=atoi(av[i]);
  940.         *put++=atoi(ind+1);
  941.     }
  942.  
  943.     for( i=0; i<len; i++ ) {
  944.         for( get=tmp; get<put; get+=2 )
  945.             if( *get==map[2*i] )
  946.                 break;
  947.         if( get==put ) {
  948.             *put++=map[2*i];
  949.             *put++=map[2*i+1];
  950.         }
  951.     }
  952.     *put++=0;
  953.     *put  =0;
  954.  
  955.     if( map && map!=DefKeymap0 && map!=DefKeymap1 )
  956.         free( map );
  957.     Keymap[n]=tmp;
  958.     Curmap=0;
  959.  
  960.     return 0;
  961. }
  962.  
  963. static int
  964. myget( void )
  965. {
  966.     int c;
  967.  
  968.     if( unget )
  969.         c=unget, unget=0;
  970.     else if( tyahdptr && *tyahdptr ) {
  971.         c=*tyahdptr++;
  972.     } else {
  973.         tyahdptr=NULL;
  974.         fflush(stdout);
  975.         c=getchar();
  976.     }
  977.  
  978.     return c;
  979. }
  980.  
  981. static void
  982. myunget(int c)
  983. {
  984.     unget=c;
  985. }
  986.  
  987. int
  988. newwidth( void )
  989. {
  990. #if 0
  991.     extern struct Window *Win;
  992. #endif
  993.  
  994.     w_width = 80;
  995.     w_height= 24;
  996.     if( !o_nowindow && Mywindow ) {
  997.         w_width =(Mywindow->Width - Mywindow->BorderLeft - Mywindow->BorderRight)/
  998.                   Mywindow->RPort->TxWidth;
  999.         w_height=(Mywindow->Height- Mywindow->BorderTop  - Mywindow->BorderBottom)/
  1000.                   Mywindow->RPort->TxHeight;
  1001.     }
  1002.     if( w_width<1 ) w_width=1;          /* crash after resizing was reported */
  1003.     return w_width;
  1004. }
  1005.  
  1006.  
  1007.  
  1008. #else
  1009.  
  1010. void prepscroll(int fromtee) {}
  1011. void quickscroll(void) {}
  1012. int  do_keymap( void ) {}
  1013. void setrawcon( long flag, int ievent ) {}
  1014. int  newwidth( void ) {}
  1015. void initmap(void) {}
  1016.  
  1017. #endif
  1018.  
  1019. extern struct MsgPort *Console;
  1020.  
  1021. int
  1022. isconsole( BPTR fh )
  1023. {
  1024.     return ((struct FileHandle *)(4*fh))->fh_Type==Console &&
  1025.         IsInteractive(fh);
  1026. }
  1027.