|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T b ┃
Length: 7473 (0x1d31) Types: TextFile Names: »bas7.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/basic/bas7.c«
/* * BASIC by Phil Cockcroft */ #include "bas.h" #define COMPILE #include "cursor.c" #undef COMPILE /* * this file conatins the user interface e.g. the line editor */ #define PADC 0400 /* the character output for padding */ /* more than 0377 but can still be passed to putc */ /* read a single character */ readc() { char c=RETURN; #ifdef BSD42 if(!setjmp(ecall)){ ecalling = 1; if(!read(0,&c,1)){ ecalling = 0; quit(); } ecalling = 0; } #else if(!read(0,&c,1)) /* reading from a pipe exit on eof */ quit(); #endif return(c&0177); } /* sets up the terminal structures so that the editor is in rare * with no paging or line boundries and no echo * Also sets up the user modes so that they are sensible when * we exit. ( friendly ). */ setupterm() { set_cap(); setu_term(); } /* the actual editor pretty straight forward but.. */ edit(fl,fi,fc) { register int cursr; register char *q; register char *p; int c; int quitf=0; /* say we have finished the edit */ int special; int lastc; int inschar =1; set_term(); for(p= &line[fi]; p<= &line[MAXLIN] ;) *p++ = ' '; *p=0; write(1,line,fi); cursr=fi; if(noedit){ for(p= &line[cursr];p< &line[MAXLIN] ; ){ c=readc(); if(c=='\n' || trapped) break; else if(c >=' ' ) *p++ =c; else if(c == ESCAPE) break; } while(c != '\n' && c != ESCAPE && !trapped) c=readc(); } else do{ putch(0); /* flush the buffers */ lastc = lastch(fl); c=readc(); if(c >= ' ' && c < '\177'){ if( cursr < MAXLIN && ( inschar && lastc < MAXLIN || !inschar) ){ if(cursr < lastc && inschar){ p= &line[MAXLIN]; q= p-1; while(p> &line[cursr]) *--p= *--q; if(*o_INSCHAR) puts(o_INSCHAR); else inchar(cursr,lastc,c); } putch(c); line[cursr++]=c; continue; } } else switch( (c <' ') ? _in_char[c] : _in_char[32] ){ case i_LEFT: if(cursr==fl) break; cursr--; puts(o_LEFT); continue; case i_CLEAR: /* control l - redraw */ puts(o_RETURN); cursr=lastc; for(p= line; p< &line[cursr];) putch(*p++); deol(cursr); continue; case i_DELLINE: /* control b - zap line */ if(cursr==fl && lastc == fl) break; puts(o_RETURN); p=line; while(p<&line[fl]) putch(*p++); deol(cursr); p= &line[fl]; while(p<&line[MAXLIN]) *p++ = ' '; cursr=fl; continue; case i_DELCHAR: if(cursr >= lastc ) break; goto rubit; case i_RUBOUT: if(cursr==fl) break; puts(o_LEFT); cursr--; if(!inschar) continue; rubit: if(cursr <= lastc ){ if(*o_DELCHAR) puts(o_DELCHAR); p= &line[cursr]; q= p+1; while(q < &line[MAXLIN] ) *p++ = *q++; *p= ' '; } if(!*o_DELCHAR) delchar(cursr,lastc); continue; case i_UP: if(cursr-ter_width< fl) break; if(*o_UP) puts(o_UP); else for(special = 0; special < ter_width ; special++) puts(o_LEFT); cursr -= ter_width; continue; case i_DOWN1: if(cursr+ter_width > MAXLIN ) break; puts(o_DOWN2); cursr+=ter_width; continue; case i_CNTRLD: if( (c = readc()) >= ' ' || _in_char[c] != i_CNTRLD) break; putch(0); cursor= (cursor+cursr)%ter_width; quit(); case i_INSCHAR: inschar = !inschar; continue; case i_RIGHT: if(cursr>= MAXLIN) break; putch(line[cursr++]); continue; case i_LLEFT: if(cursr <= fl) break; do{ puts(o_LEFT); }while(((--cursr) &07) && cursr > fl); continue; case i_RRIGHT: if(cursr>= MAXLIN) break; do{ putch(line[cursr++]); }while((cursr&07) && cursr < MAXLIN); continue; case i_DELSOL: /* delete to start of line */ if(cursr==fl) break; special = cursr; cursr = fl; goto delit; /* same code as del word almost */ case i_DELWORD: /* control w - del word */ if(cursr==fl) break; special=cursr; do{ cursr--; }while(cursr>fl &&(line[cursr-1]!=' ' || line[cursr]==' ')); delit: q= &line[special]; p= &line[cursr]; while(q < &line[MAXLIN] ) *p++ = *q++; while(p < &line[MAXLIN]){ puts(o_LEFT); *p++ = ' '; if(*o_DELCHAR && --special <= lastc ) puts(o_DELCHAR); } if(!*o_DELCHAR) delchar(cursr,lastc); continue; case i_BACKWORD: /* back word */ if(cursr==fl) break; do{ puts(o_LEFT); cursr--; }while(cursr>fl && (line[cursr-1]!=' ' || line[cursr]==' ' )); continue; case i_NEXTWORD: /* next word */ if(cursr >= MAXLIN || cursr > lastc || lastc == fl) break; do{ putch(line[cursr++]); }while(cursr < MAXLIN && cursr <= lastc && (line[cursr]==' '|| line[cursr-1]!=' ' ) ); continue; case i_DEOL: if(cursr >= lastc ) break; for(p= &line[cursr];p < &line[MAXLIN];) *p++ = ' '; deol(cursr); continue; case i_ESCAPE: case i_RETURN: case i_DOWN2: while(cursr< lastc) putch(line[cursr++]); puts(o_RETURN); puts(o_DOWN2); quitf++; continue; default: break; } puts(o_PING); }while(!quitf && !trapped); putch(0); line[lastch(fl)]=0; /* special characters are dealt with here- null is never returned */ for(p=line,q=line,special=0;*p;p++){ if(special){ special=0; if(*p>='a' && *p<='~') *q++ = *p -('a'-1); else *q++ = *p; } else if(*p=='\\') special++; else *q++ = *p; } *q=0; cursor=0; rset_term(0); return(c); } /* * put a string out ( using putch ) */ puts(s) register char *s; { /* * now cope with padding */ if(*s >='0' && *s <= '9'){ register i = 0; do{ i = i * 10 + *s++ -'0'; }while(*s >= '0' && *s <= '9'); if(*s == '.') s++, i++; if(*s == '*') /* should only affect 1 line */ s++; while(i-- > 0) putch(PADC); } while(*s) putch(*s++); } /* put out a character uses buffere output of up to 256 characters * It used to use a static buffer but this is a waste of space so * it now uses gblock as this is never used during an edit. * A value of zero for the parameter will flush the buffer. */ putch(c) { static nleft=0; if(!c || nleft>=256){ if(nleft) write(1,gblock,nleft); nleft=0; } if(!c) return; gblock[nleft++]= c; } /* lastch() returns the last character on the line used in the * editor to see if any more characters can be placed on the line and * by the redraw key. */ lastch(f) { register char *p; register char *q; p= &line[f]; q= &line[MAXLIN]; while(*q==' ' && q>=p) q--; return(q-line+1); } /* delete from current cursor position to end of line. */ deol(cursr) { register cc,i; if(*o_DEOL){ puts(o_DEOL); return; } i = ter_width - (cursr % ter_width); for(cc = i ; cc ; cc--) putch(' '); for(; i ; i--) puts(o_LEFT); } /* delete nchar characters from cursr */ delchar(cursr,lc) { register char *p; register char *q; p = &line[cursr]; q = &line[lc]; while(p < q ) putch(*p++); q = &line[cursr]; while(p > q ){ if( *o_UP && p - q > ter_width ){ puts(o_UP); p -= ter_width; } else { p--; puts(o_LEFT); } } } /* display a new character */ inchar(cursr,lastc,c) { register char *p,*q; p = &line[cursr+1]; q = &line[lastc+1]; putch(c); while(p < q) putch(*p++); q = &line[cursr]; while(p > q ){ if( *o_UP && p - q > ter_width ){ puts(o_UP); p -= ter_width; } else { p--; puts(o_LEFT); } } }