home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
488.lha
/
csh_v5.0
/
src
/
csh500src.lzh
/
rawcon.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-24
|
18KB
|
795 lines
/*
* rawcon.c
*
* Shell 2.07M 17-Jun-87
* console handling, command line editing support for Shell
* using new console packets from 1.2.
* Written by Steve Drew. (c) 14-Oct-86.
* 16-Dec-86 Slight mods to rawgets() for Disktrashing.
*
* Version 4.01A by Carlo Borreo & Cesare Dieni 17-Feb-90
* Version 5.00L by Urban Mueller 17-Feb-91
*
*/
#include "shell.h"
static int myget( void );
static void myunget(int c);
static void setrawcon( long flag, int ievent );
static int get_seq( long *param );
static int bkspcword( int i, int max, int cnt );
#if RAW_CONSOLE
static char *tyahdptr, *lasttya;
static int tabctr, qcdctr, unget;
#define SETRAW setrawcon(-1L,1);
#define SETCON setrawcon( 0L,1);
int w_width;
extern char *MenuCommand[MAXMENUS][MAXITEMS];
#define CTRL -64
#define SHIFT 512
#define ESC 1024
#define CUP 256
#define CDN 257
#define CRT 258
#define CLT 259
#define TAB 9
static int Curmap;
static USHORT *Keymap[8];
static USHORT DefKeymap0[]={
CLT, 0, /* CursLt = Move.Left */
CRT, 1, /* CursRt = Move.Right */
SHIFT+CLT, 2, /* SCursLt= Move.WordL */
SHIFT+CRT, 3, /* SCursRt= Move.WordR */
ESC+CLT, 4, /* ESC-CLt= Move.SOL */
ESC+CRT, 5, /* ESC-CRt= Move.EOL */
CTRL+'A', 4, /* ^A = Move.SOL */
CTRL+'E', 5, /* ^E = Move.EOL */
CTRL+'Z', 4, /* ^Z = Move.SOL */
8, 10, /* BackSp = Del.BackSp */
127, 11, /* Delete = Del.Delete */
ESC+ 8, 12, /* ESC-BkS= Del.WordL */
ESC+127, 13, /* ESC-Del= Del.WordR */
CTRL+'W', 12, /* ^W = Del.WordL */
CTRL+'B', 14, /* ^B = Del.SOL */
CTRL+'K', 15, /* ^K = Del.EOL */
ESC+'x',513, /* ESC-x = Setmap 1 */
ESC+'d', 16, /* ESC-d = Del.Line */
CTRL+'X', 16, /* ^X = Del.Line */
CUP, 20, /* CursUp = Hist.Back */
CDN, 21, /* CursDn = Hist.Forw */
SHIFT+CUP, 22, /* SCursUp= Hist.Beg */
SHIFT+CDN, 23, /* SCursDn= Hist.End */
ESC+'!', 24, /* ESC-! = Hist.Compl */
ESC+ 13, 25, /* ESC-Ret= Hist.Exec */
CTRL+'T', 26, /* ^T = Hist.Tail */
TAB, 30, /* Tab = Comp.Norm */
SHIFT+TAB, 31, /* STab = Comp.Part */
ESC+TAB, 32, /* ESC-TAB= Comp.All */
ESC+'c', 33, /* ESC-c = Comp.CD */
ESC+'~', 34, /* ESC-~ = Comp.LastCD*/
ESC+'i', 40, /* ESC-i = Spec.Insert*/
CTRL+'L', 43, /* ^L = Spec.Refr */
10, 44, /* Enter = Spec.Accept*/
13, 44, /* ^Enter = Spec.Accept*/
CTRL+'N', 45, /* ^N = Spec.Next */
CTRL+'O', 48, /* ^O = Spec.EchoO */
CTRL+'\\', 46, /* ^\ = Spec.EOF */
260, 42, /* Help = Misc.Help */
271, 51, /* Menu = Menu */
CTRL+'U', 52, /* Undo = Spec.Undo */
CTRL+'R', 53, /* Repeat = Spec.Repeat*/
0, 0
};
static USHORT DefKeymap1[]={
8, 14,
127, 15
};
static char *Line, *Prompt;
static int Pl;
static char LastDir[128];
void
initmap(void)
{
if( !Keymap[0] )
Keymap[0]=DefKeymap0, Keymap[1]=DefKeymap1;
}
char *
rawgets( char line[], char prompt[] )
{
static int inslen, lastrecall=-1;
static int lastfn, lastkey;
int n, pl, max, i, c, key, fn, cnt;
USHORT *p;
char *s, *ps, typeahd[256], undo[256];
int savn, insert=1, recall, undo_i, undo_max;
struct HIST *hist;
char **eav=NULL, *ret, fake;
int eac, eactr;
long param[10], *par;
typeahd[0]=0;
tyahdptr=lasttya=typeahd;
newwidth();
if ( o_noraw || !IsInteractive(Input()) ) {
if( IsInteractive(Input())) {
printf("%s",prompt);
fflush(stdout);
}
return(gets(line));
}
if (WaitForChar((long)Input(), 100L) || /* don't switch to 1L ...*/
CHARSWAIT(stdin)) { /* else causes read err's*/
gets(line);
return(line);
}
SETRAW;
begin:
printf("\015%s\033[6n",prompt);
fake= savn = pl = n = 0;
tyahdptr = typeahd;
while( (typeahd[n]=getchar()) != 'R') {
if (typeahd[n] == 155) savn = n;
if (typeahd[n] == 27 && getchar()=='[')
typeahd[n] =155, savn=n;
n++;
}
/* typeahd now contains possible type a head chars
followed by <CSI> cursor position report. */
typeahd[savn] = '\0';
if (typeahd[n-2] != ';') pl = (typeahd[n-2] -'0') * 10;
pl += typeahd[n-1] - 49;
ps = line + pl;
line[max = i = pl] = '\0';
Line=line; Prompt=prompt; Pl=pl;
if (s = get_var (LEVEL_SET, "_insert")) insert = atoi(s) ? 1 : 0;
if( (recall=lastrecall)>=0 ) {
lastrecall=-1;
goto recallh;
}
while( (c=myget()) != -1) {
int esc=0;
key=-1;
if( c==27 ) esc=ESC, c=myget();
switch(c) {
case 155:
switch(c=myget()) {
case 'A': key=256; break; /* CursUp */
case 'B': key=257; break; /* CursDn */
case 'C': key=258; break; /* CursRt */
case 'D': key=259; break; /* CursLt */
case 'T': key=256+SHIFT; break; /* SCursUp */
case 'S': key=257+SHIFT; break; /* SCursDn */
case ' ':
switch( myget() ) {
case '@': key=258+SHIFT; break; /* SCursRt */
case 'A': key=259+SHIFT; break; /* SCursLt */
} break;
case 'Z': key=9+SHIFT; break; /* STab */
case '?': key=260; myget(); break; /* Help */
default :
myunget(c);
par=param;
do {
for( *par=0; (c=myget())>='0' && c<='9'; )
*par=10* *par + c-'0';
par++;
} while( c==';' );
if( c=='~' ) {
key=param[0]+261;
if( key>270 ) key+=SHIFT-10;
}
if( c=='|' ) key=271;
} break;
default: key=c; break;
}
key+=esc;
for( fn=-1, p=Keymap[Curmap]; *p; p+=2 )
if( *p==key )
{ fn=p[1]; break; }
if( fn==-1 && key>=261 && key<=270 || key>=261+SHIFT && key<=270+SHIFT )
fn=50;
if( fn!=52 && !*lasttya) {
memcpy( undo+pl, line+pl, max-pl );
undo_i=i; undo_max=max;
}
switch( fn/512 ) {
case 1:
fn&=511;
if( fn<8 && Keymap[fn] ) Curmap=fn;
fn=-2;
break;
case 2:
key=fn&511, fn=-1;
break;
}
if( fn!=-2 )
Curmap=0;
if( fn!=53 && !*lasttya )
lastfn=fn, lastkey=key;
dofn:
switch( fn ) {
case -2:
break;
case 0: /* cursor left */
if (i > pl)
i--, printf("\033[D");
break;
case 1: /* cursor right */
if (i < max)
i++, printf("\033[C");
break;
case 2: /* word left */
for (cnt=0; i>pl && line[i-1] == ' '; cnt++,i--);
for ( ; i>pl && line[i-1] != ' '; cnt++,i--);
if( cnt ) printf("\033[%dD",cnt);
break;
case 3: /* word right */
for( cnt=0; i<max && line[i] != ' '; i++,cnt++) ;
for( ; i<max && line[i] == ' '; i++,cnt++) ;
if( cnt ) printf("\033[%dC",cnt);
break;
case 4: /* beg of line */
if (i>pl) printf("\033[%dD",i-pl);
i = pl;
break;
case 5: /* end of line */
if (i!=max) printf("\033[%dC",max - i);
i = max;
break;
case 10: /* backspace */
if (i > pl) {
i--;
printf("\010");
} else break;
case 11: /* delete */
if (i < max) {
int j,t,l = 0;
memmove(&line[i],&line[i+1],max-i);
--max;
printf("\033[P");
j = w_width - i % w_width - 1; /* amount to end */
t = max/w_width - i/w_width; /* no of lines */
for(n = 0; n < t; n++) {
l += j; /* # of char moved*/
if (j) printf("\033[%dC",j);/* goto eol */
printf("%c\033[P",line[w_width*(i/w_width+n+1)-1]);
j = w_width-1;
}
if (t)
printf("\033[%dD",l+t); /* get back */
}
break;
case 12: /* bkspc word */
cnt= bkspcword(i,max,-1);
max-=cnt; i-=cnt;
break;
case 13:
for( cnt=0; i<max && line[i]!=' '; i++,cnt++ ) ;
for( ; i<max && line[i]==' '; i++,cnt++ ) ;
if ( cnt ) printf("\033[%dC",cnt);
cnt=bkspcword(i,max,cnt);
i-=cnt; max-=cnt;
break;
case 14:
cnt=bkspcword(i,max,i-pl);
i-=cnt; max-=cnt;
break;
case 16: /* delete line */
if (i>pl) printf("\033[%dD",i-pl);
i = pl;
case 15: /* delete to EOL */
printf("\033[J");
max = i;
line[i] = '\0';
break;
case 20: /* history up */
++recall;
case 21: /* history down */
line[pl] = '\0';
if (recall >= 0 || fn==20) {
if ( fn==21 ) --recall;
recallh:
n=recall;
if (recall >= 0) {
for(hist = H_head; hist && n--;
hist = hist->next);
if (hist) strcpy(&line[pl],hist->line);
else recall = H_len;
}
}
if (i != pl)
printf("\033[%dD",i-pl);
printf("\033[J%s",ps);
i = max = strlen(ps) + pl;
break;
case 22: /* beg of hist */
recall = H_len-1;
case 23: /* end of hist */
line[pl] = '\0';
if (fn == 23) {
recall = 0;
if (H_head) strcpy(&line[pl], H_head->line);
} else if (H_tail)
strcpy(&line[pl], H_tail->line);
printf("\015\033[J%s%s", prompt, ps);
i = max = strlen(ps) + pl;
break;
case 24: /* complete hist */
line[max]=0;
if( s=get_history(&line[pl-1],0 )) {
if (i>pl) printf("\033[%dD\033[J",i-pl);
line[i=max=pl]=0;
strncpy(typeahd,s,256);
tyahdptr=typeahd;
}
break;
case 25: /* exec hist */
lastrecall= recall;
goto done;
case 26: /* tail of prev */
if( H_head && (s=H_head->line) && (s=index(s,' ')) )
tyahdptr=s;
break;
case 30: /* complete */
case 31:
case 32:
case 33: {
static int lastcompl;
int j, k, n, e, cnt, len, radlen;
char *name, *q, abbrev;
abbrev= fn==31;
complete:
tyahdptr="";
if( tabctr!=0 ) {
char *dest=typeahd, *lcd;
lastcompl=fn;
for( cnt=0; i<max && line[i]!=' '; ++i, ++cnt ) ;
if(cnt) printf("\033[%dC",cnt);
for( e=i, j=i-1, cnt=0; j>=pl && line[j]!=' ' && line[j]!='<' &&
line[j]!='>' && line[j]!=';' ; --j ) cnt++;
++j;
if( line[j]=='~' && (lcd=get_var(LEVEL_SET,v_lcd))) {
strcpy(dest,lcd);
dest+=strlen(dest);
j++;
}
memcpy(dest,&line[j],e-j);
dest+=e-j;
if( fn!=33 )
*dest++='*';
*dest=0;
if( eav ) free_expand( eav ), eav=NULL;
breakreset();
tabctr=1;
if( fn==33 ) {
strncpy(LastDir,typeahd,128);
if( !quick_cd( name=typeahd+128, LastDir, 0))
{ putchar(7); break; }
} else {
eav =expand(typeahd,&eac);
if( eac==0 ) { putchar(7); break; }
QuickSort(eav, eac);
if( fn==30 )
name=eav[ eactr=0 ];
else
name=compile_av(eav,0,eac,' ',1), tabctr=0;
}
inslen=cnt;
} else {
abbrev=0, tabctr=1;
if( lastcompl==33 ) {
quick_cd( name=typeahd+128, LastDir, 1);
} else {
if( !eac ) break;
name=eav[eactr=++eactr % eac];
}
}
len=bkspcword(i,max,inslen);
i-=len; max-=len;
if( abbrev && eac>1) {
strcpy( typeahd, eav[0] );
radlen= 9999;
for( k=0; k<eac; k++ ) {
if ( (n=strlen(eav[k])) < radlen ) radlen=n;
for( n=0; n<radlen && eav[0][n]==eav[k][n]; n++ ) ;
if ( n<radlen ) radlen=n;
}
typeahd[radlen]=0;
eactr--;
} else {
if( lastcompl==32 ) {
strncpy( typeahd,name,250 );
name[250]=0;
} else {
strcpy(typeahd,(q=index( name, ' ' )) ? "\"" : "" );
strcat(typeahd,name);
if( q ) strcat(typeahd,"\"");
if( lastcompl==33 || isdir(name) )
appendslash( typeahd );
else
strcat( typeahd, " " );
}
}
tyahdptr=typeahd;
inslen=strlen(typeahd);
}
break;
case 34:
strncpy(typeahd,get_var( LEVEL_SET, v_lcd ),230);
appendslash(tyahdptr=typeahd);
break;
case 40: /* ins/ovr */
insert ^= 1;
break;
case 41: /* quit */
strcpy(ps,"quit");
goto done;
case 42: /* help */
strcpy(ps,"help");
goto done;
case 43: /* refresh */
if ((n = i/w_width)) printf("\033[%dF",n);
printf("\015\033[J%s%s",prompt,ps);
i = max;
break;
case 44:
line[max] = '\0';
done: printf("\033[%dC\n",max - i);
strcpy(line, ps);
ret=line;
if( fake ) goto begin;
goto exit;
case 45: /* leave */
line[max] = '\0';
add_history( ps );
fake=1;
goto done;
case 46: /* EOF */
ret=NULL;
goto exit;
case 47:
break;
case 48:
printf("\017");
break;
case 49:
printf("\07");
break;
case 50: {
char fkeys[8];
sprintf(fkeys,"%c%d",param[0]>=10?'F':'f',param[0]%10+1);
if (s = get_var(LEVEL_SET, fkeys)) {
tyahdptr = strcpy(typeahd,s);
a0tospace( tyahdptr );
}
break;
}
case 51: {
int class=param[0], code=param[2];
if( class==10 ) {
int num=MENUNUM( code ), item=ITEMNUM( code );
tyahdptr="";
if( num>=0 && num<MAXMENUS && item>=0 && item<=MAXITEMS )
tyahdptr=MenuCommand[num][item];
}
if( class==11 ) {
strcpy(ps,"quit");
goto done;
}
}
case 52: {
int t;
if ((n = i/w_width)) printf("\033[%dF",n);
swapmem( undo+pl, line+pl, MAX( max, undo_max)-pl );
t=max; max=undo_max; undo_max=t;
t=i; i =undo_i; undo_i =t;
line[max]=0;
printf("\015\033[J%s%s",prompt,ps);
if( i<max ) printf("\033[%dD",max-i);
}
break;
case 53:
fn=lastfn; key=lastkey;
goto dofn;
default:
key&=255;
if (key == 9) key = 32;
if (key > 31 && (insert?max:i) < 256) {
if (i < max && insert) {
int j,t,l = 0;
memmove(&line[i+1], &line[i], max - i);
printf("\033[@%c",key);
t = max/w_width - i/w_width;
j = w_width - i % w_width - 1;
for(n = 0; n < t; n++) {
l += j;
if (j) printf("\033[%dC",j);
printf("\033[@%c",line[w_width*(i/w_width+n+1)]);
j = w_width-1;
}
if (t) printf("\033[%dD",l + t);
++max;
}
else {
if(i == pl && max == i) printf("\015%s%s",prompt,ps);
putchar(key);
}
line[i++] = key;
if (max < i) max = i;
line[max] = '\0';
}
}
}
ret=NULL;
exit:
newwidth();
if( eav ) free_expand(eav);
SETCON;
return ret;
}
int
bkspcword( int i, int max, int cnt )
{
int o=i;
if( !cnt ) return 0;
if( cnt==-1 ) {
cnt=0;
while( i>Pl && Line[i-1]==' ' ) i--, cnt++;
while( i>Pl && Line[i-1]!=' ' ) i--, cnt++;
} else
i-=cnt;
if( cnt ) printf("\033[%dD",cnt);
memmove( Line+i, Line+o, max-o );
memset ( Line+max-cnt, ' ', cnt );
printf("%s",Line+i);
if( max-i ) printf("\033[%dD", max-i );
fflush(stdout);
Line[max-=cnt]=0;
return cnt;
}
void
setrawcon( long flag, int ievent ) /* -1L=RAW:, 0L=CON: */
{
static char menuon, button;
long packargs[8];
if( !o_nowindow && ievent && flag==0 && menuon)
printf("\033[10}"), menuon=0;
packargs[0]=flag;
SendPacket(994L, packargs, (void *)Myprocess->pr_ConsoleTask);
if( !o_nowindow && ievent && flag==-1 ) {
if( !menuon )
printf("\033[10{"), menuon=1;
if( !button )
printf("\033[11{"), button=1;
}
}
static int row, height, cnt, noquick=1;
static char scrollstr[10];
extern char *Cin_name, *Cout_name;
extern BPTR OldCin;
static int FromTee;
void
prepscroll( int fromtee )
{
BPTR truecin=0;
long param[8];
row=height=0;
FromTee=fromtee;
if(( noquick=!o_scroll ||o_noraw || o_nofastscr ))
return;
if(( noquick=Cout_name && !fromtee ))
return;
if( Cin_name ) {
truecin=Myprocess->pr_CIS;
if( noquick=!IsInteractive(OldCin) )
return;
Myprocess->pr_CIS = DEVTAB(stdin) = OldCin;
}
if( !CHARSWAIT(stdin) ) {
SETRAW;
fprintf(fromtee?stderr:stdout,"\033[ q");
get_seq( param );
height=param[2];
while( getchar()!='r') ;
fprintf(fromtee?stderr:stdout,"\033[6n");
get_seq( param );
row=param[0];
SETCON;
cnt= height-row+1;
noquick= height<o_minrows;
}
sprintf(scrollstr,"\033[%cS\033[%cA", o_scroll+'0', o_scroll+'0');
if( truecin )
Myprocess->pr_CIS = DEVTAB(stdin) = truecin;
}
static int
get_seq( long *param )
{
int c;
while( (c=getchar())!=155 ) ;
do {
*param=0;
while( (c=getchar())>='0' && c<='9' )
*param=10* *param + c-'0';
param++;
} while( c==';' );
return c;
}
void
quickscroll( void )
{
if( noquick ) return;
if( --cnt<=0 ) {
cnt=o_scroll;
fprintf( FromTee ? stderr : stdout, "%s",scrollstr);
}
}
int
do_keymap( void )
{
int i, n, len;
USHORT *tmp, *put, *get, *map;
char *ind;
n=myatoi(av[1],0,7);
if( atoierr ) return 20;
map=Keymap[n]; len=0;
if( map )
for( len=0; map[2*len]; len++ ) ;
put=tmp=malloc((len+ac)*2*sizeof(USHORT));
for( i=2; i<ac; i++ ) {
if( !(ind=index(av[i],'='))) {
ierror( av[i],500);
free( tmp );
return 20;
}
*put++=atoi(av[i]);
*put++=atoi(ind+1);
}
for( i=0; i<len; i++ ) {
for( get=tmp; get<put; get+=2 )
if( *get==map[2*i] )
break;
if( get==put ) {
*put++=map[2*i];
*put++=map[2*i+1];
}
}
if( map && map!=DefKeymap0 && map!=DefKeymap1 )
free( map );
Keymap[n]=tmp;
Curmap=0;
return 0;
}
static int
myget( void )
{
int c;
lasttya=tyahdptr;
if( unget )
c=unget, unget=0;
else if( tyahdptr && *tyahdptr)
c=*tyahdptr++;
else {
#ifndef AZTEC_C
fflush(stdout);
#endif
if( (c=getchar())!=155 )
tabctr--, qcdctr--;
}
return c;
}
static void
myunget(int c)
{
unget=c;
}
int
newwidth( void )
{
extern struct Window *Win;
if( !o_nowindow && Win )
w_width=(Win->Width-(Win->BorderLeft+Win->BorderRight))/
Win->RPort->TxWidth;
else
w_width=80;
return w_width;
}
#else
prepscroll(){}
quickscroll(){}
#endif