Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!cs.utexas.edu!uunet!munnari!gwydir!gara!wtoomey From: wtoomey@gara.une.oz (Warren Toomey) Newsgroups: comp.os.minix Subject: Official Clam Patch #2 (Part 2 of 4) Message-ID: <780@gara.une.oz> Date: 1 Jun 89 10:34:54 GMT Organization: University of New England, Armidale, Australia Lines: 822 # This is a shell archive. Remove anything before this line, then # unpack it by saving it in a file and typing "sh file". (Files # unpacked will be owned by you and have default permissions.) # # This archive contains: # comlined.c echo x - comlined.c cat > "comlined.c" << '//E*O*F comlined.c//' /****************************************************************************** ** ** ** comlined.c ** ** This file contains the COMmand LINe EDitor. ** ** ** ******************************************************************************/ #include "header.h" /* Minix seems to have a strange stdio.h FILE struct */ #ifdef MINIX #define _file _fd #endif extern char termcapbuf[]; extern FILE *zin,*zout,*fopen(); #ifndef ATARI_ST void mputc(c,f,curs) char c; FILE *f; int curs[]; { extern int wid; write(f->_file,&c,1); curs[0]++; if (curs[0]>=wid) { write(f->_file,"\n",1); /* goto start of next line */ curs[0]=curs[0]%wid; /* hopefully gives zero */ curs[1]++; } } #else void mputc(c,f,curs) int c; FILE *f; int curs[]; { extern int wid; char cc = c; write(f->_file,&cc,1); curs[0]++; if (curs[0]>=wid) { write(f->_file,"\n",1); /* goto start of next line */ curs[0]=curs[0]%wid; /* hopefully gives zero */ curs[1]++; } } #endif #ifndef ATARI_ST void oputc(c) char c; { write(zout->_file,&c,1); } #else int oputc(c) int c; { char cc = c; return write(zout->_file,&cc,1); } #endif void go(curs,hor,vert) int curs[],hor,vert; { extern char bs[],nd[],up[]; int hdiff,vdiff; vdiff=vert-curs[1]; /* vertical difference between */ /* current and future positions */ if (vdiff<=0) /* if negative go up */ for(;vdiff;vdiff++) tputs(up,1,oputc); else /* else go down */ { for(;vdiff;vdiff--) write(1,"\n",1); curs[0]=0; } hdiff=hor-curs[0]; /* horizontal difference between */ /* current and future positions */ curs[0]=hor; curs[1]=vert; /* a new current pos, hopefully */ /* assigned here because hor changed below and curs needed above */ if (hdiff<0) /* if negative go back */ if (-hdiff<=hor) /* if shorter distance just use ^H */ for(;hdiff;hdiff++) write(zout->_file,bs,strlen(bs)); else /* else cr and go forward */ { write(zout->_file,"\r",1); for (;hor;hor--) tputs(nd,1,oputc); } else /* have to go forward */ for (;hdiff;hdiff--) tputs(nd,1,oputc); } void backward(curs) int curs[]; { extern int wid; extern char bs[]; if (curs[0]==0) go(curs,wid-1,curs[1]-1); else { write(zout->_file,bs,strlen(bs)); curs[0]--; } } void forward(curs) int curs[]; { extern int wid; extern char nd[]; curs[0]++; if (curs[0]>=wid) { write(zout->_file,"\n",1); /* goto start of next line */ curs[0]=curs[0]%wid; /* hopefully gives zero */ curs[1]++; } else tputs(nd,1,oputc); } void clrscrn() { extern char cl[]; tputs(cl,1,oputc); /* clear the screen */ } void insert(line,pos,letter,curs) char *line,letter; int pos,curs[]; { extern int wid; int i,horig,vorig; char c; for (i=pos;line[i];i++); /* goto end of line */ for (;i!=pos;i--) line[i]=line[i-1]; /* copy characters forward */ line[pos]=letter; /* insert new char */ if (letter<32) horig=curs[0]+2; else horig=curs[0]+1; vorig=curs[1]; if (horig>wid-1) { horig=horig%wid; vorig++; } for (c=line[pos];c;c=line[++pos]) /* write out rest of line */ { if (c<32) /* if it's a control char */ { mputc('^',zout,curs); /* print out the ^ and */ mputc(c+64,zout,curs); /* the equivalent char for it*/ } else mputc(c,zout,curs); } go(curs,horig,vorig); } #ifdef __STDC__ void show(char *line, int *curs, bool clearing) #else void show(line,curs,clearing) char *line; int curs[]; bool clearing; #endif { extern int lenprompt; int pos=0,horig,vorig; char c; horig=curs[0];vorig=curs[1]; /* save original values */ if (clearing==TRUE) { curs[0]=lenprompt;curs[1]=0; } else { go(curs,lenprompt,0); /* goto start of line */ } for (c=line[pos];c!=EOS;c=line[++pos]) /* write out rest of line */ if (c<32) /* if it's a control char */ { mputc('^',zout,curs); /* print out the ^ and */ mputc(c+64,zout,curs); /* the equivalent char for it*/ } else mputc(c,zout,curs); go(curs,horig,vorig); /* go back from whence you came */ } void goend(line,pos,curs) char *line; int *pos,curs[]; { char c; for (c=line[*pos];c;c=line[++(*pos)]) { if (c<32) { mputc('^',zout,curs); mputc(c+64,zout,curs); } else mputc(c,zout,curs); } } void copyback(line,pos,curs,count) char *line; int pos,curs[],count; { char c; int i,horig,vorig,wipe; #ifdef DEBUG fprintf(stderr,"pos %d count %d\n",pos,count); #endif if ((i=pos+count)horig && i':case '<':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) l=0; else charcount++; break; default: inword=1; charcount++; } #ifdef DEBUG fprintf(stderr,"Deleting %d chars\n",charcount); #endif copyback(line,pos,curs,charcount); } void delprevword(line,pos,curs) char *line; int *pos,curs[]; { int inword=0,l=1,charcount=0; char c; while(l) if ((*pos)>0) switch (c=line[(*pos)-1]) { case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) l=0; else { charcount++; (*pos)--; } break; default: inword=1; charcount++; (*pos)--; } else l=0; #ifdef DEBUG fprintf(stderr,"Deleting %d chars\n",charcount); #endif /* l should be zero already, aren't I naughty! */ for (;l0) switch (c=line[(*pos)-1]) { case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) l=0; else { backward(curs); (*pos)--; } break; default: inword=1; if (c<32) backward(curs); backward(curs); (*pos)--; } else l=0; } void forword(line,pos,curs) char *line; int *pos,curs[]; { int inspace=0,l=1; char c; while(l) switch (c=line[*pos]) { case EOS: l=0; break; case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': inspace=1; forward(curs); (*pos)++; break; default: if (inspace) l=0; else { if (c<32) forward(curs); forward(curs); (*pos)++; } } } void yanknext(line,pos,yankbuf) char *line,*yankbuf; int pos; { int l=1,inword=0,i=0; while(l) switch(line[pos]) { case EOS: l=0; yankbuf[i]=EOS; break; case ' ':case '\t':case '<':case '>':case '|': case ';':case '=':case '+':case '&':case '`': if (inword) { l=0; yankbuf[i]=EOS; } else yankbuf[i++]=line[pos++]; break; default: inword=1; yankbuf[i++]=line[pos++]; } } void yankprev(line,pos,yankbuf) char *line,*yankbuf; int pos; { int stpos=pos,inword=0,l=1; while(l && stpos>0) /* this loop finds the start of the */ switch(line[stpos-1]) /* previous word (at stpos) */ { case ' ':case '\t':case '>':case '<':case '|':case '"': case ';':case '=':case '+':case '&':case '`':case '\'': if (inword) l=0; else stpos--; break; default: inword=1; stpos--; } for (l=0;stpos0;times--) switch(c) { case EOF : fprintf(stderr,"Help me, I'm being hit by a looney with a stick.\n"); if (!try) { fprintf(stderr,"Trying to reassign stdin..."); zin=stdin; try=1; continue; } else { fprintf(stderr,"Trying to reopen stdin..."); if ((zin=fopen("/dev/tty","w+"))==NULL) { fprintf(stderr,"failed!\n"); exit(1); } fprintf(stderr,"Successful!\n"); try=0; } continue; case EOS : hsave=curs[0]; /* save position (make mark) */ vsave=curs[1]; possave=pos; break; case 1 : go(curs,lenprompt,0); /* goto start of the line */ pos=0; break; case 2 : if (pos>0) /* if not at home, go back */ { if (line[pos-1]<32) backward(curs); backward(curs); pos--; } else write(1,beep,beeplength); /* else ring bell */ break; case 3 : goend(line,&pos,curs); write(zout->_file,"\n",1); return(FALSE); case 4 : if (line[0]==EOS && !feature_off) leave_shell(); /*eof*/ else if (line[pos]!=EOS) copyback(line,pos,curs,1); /* delete char */ else if (!feature_off) nameopt(line,pos,curs); break; case 5 : goend(line,&pos,curs); /* goto end of the line */ break; case 6 : if (line[pos]!=EOS) /* if not at end, go forward */ { if (line[pos]<32) forward(curs); forward(curs); pos++; } else write(1,beep,beeplength); /* else ring bell */ break; case 7 : pos=0; /* kill the whole line */ go(curs,lenprompt,0); /* goto start */ clrline(line,0,curs); /* and kill from pos=0 */ hist=curr_hist; /* reset hist */ break; case 127: case 8 : if (pos>0) /* if not at home, delete */ { if (line[pos-1]<32) backward(curs); backward(curs); copyback(line,--pos,curs,1); /*move line back on to prev char*/ } else write(1,beep,beeplength); /* else ring bell */ break; case '\t': if (line[0]!=EOS) complete(line,&pos,curs); /* try to complete word */ else write(1,beep,beeplength); break; case '\r': /* end of the line, go and */ case '\n': goend(line,&pos,curs); write(zout->_file,"\n",1); if (feature_off) return(TRUE); *nosave=strip(line); /* process it now */ if (line[0]!=EOS) { if (O_echoline) { write(2,line,strlen(line)); write(2,"\n",1); } return(TRUE); } else return(FALSE); case 11 : clrline(line,pos,curs); /* kill line from cursor on */ break; case 12 : if (feature_off) break; clrscrn(); /* Clear the screen */ prprompt(1); /* Reprint the prompt and */ show(line,curs,TRUE); /* the line typed so far. */ break; case 14 : if (feature_off) break; if (histcurr_hist-maxhist && hist>1) /* put prev hist in line buf */ { if (hist==curr_hist) savehist(line,curr_hist,maxhist); loadhist(line,&pos,--hist,curs); } else write(1,beep,beeplength); break; case 17 : continue; case 18 : show(line,curs,FALSE); /* reprint the line */ break; case 19 : continue; case 20 : if (pos>0 && line[pos]!=EOS) /* if not home or at end */ transpose(line,pos,curs); /* swap current and prev char */ else write(1,beep,beeplength); /* else ring bell */ break; case 21 : times=0; c=getc(zin); while(isdigit(c)) { times=times*10+c-48; c=getc(zin); } times++; /* need to add 1 because it's dec'ed */ break; /* immediately at end of for loop */ case 22 : if (pos>=MAXLL) { write(1,beep,beeplength); continue; } mputc('"',zout,curs); backward(curs); /* literal char */ c=getc(zin); if (c) /* don't allow EOS (null) */ insert(line,pos++,c,curs); break; case 23 : if (pos) delprevword(line,&pos,curs); else write(1,beep,beeplength); break; case 24 : pos=possave; go(curs,hsave,vsave); break; case 25 : if (pos!=0) /* if not at home */ yankprev(line,pos,yankbuf); /* yank previous word */ else write(1,beep,beeplength); /* else ring bell */ break; case 26 : continue; case 27 : switch(c=getc(zin)) { case 4 : if (!feature_off) nameopt(line,pos,curs); break; case 0177: case 8 : if (pos>0) { backward(curs); copyback(line,--pos,curs,1); } else write(1,beep,beeplength); break; case 12 : if (feature_off) break; clrscrn(); prprompt(1); show(line,curs,TRUE); break; case 27 : case '\t': if (!feature_off) if (line[0]!=EOS) complete(line,&pos,curs); else write(1,beep,beeplength); break; case 'b' : case 2: case 'B' : if (pos>0) backword(line,&pos,curs); else write(1,beep,beeplength); break; case 'd' : case 'D' : if (line[pos]!=EOS) delnextword(line,pos,curs); else write(1,beep,beeplength); break; case 'f' : case 6: case 'F' : if (line[pos]!=EOS) forword(line,&pos,curs); else write(1,beep,beeplength); break; case 'h' : case 'H' : if (!feature_off) help(line,pos,curs); break; case 'p' : case 'P' : if (pos>MAXLL-strlen(yankbuf)) { write(1,beep,beeplength); break; } for (i=0;yankbuf[i];i++) /* insert yank buffer */ insert(line,pos++,yankbuf[i],curs); break; case 25 : if (pos!=0) /* as above */ yankprev(line,pos,yankbuf); else write(1,beep,beeplength); break; case 'y' : case 'Y' : if (line[pos]!=EOS) /* if not at end */ yanknext(line,pos,yankbuf);/* yank next word */ else write(1,beep,beeplength);/* else ring bell */ break; case 'w' : case 23: case 'W' : if (pos) /* if not at end */ delprevword(line,&pos,curs); else write(1,beep,beeplength); break; case '0':case '1':case '2':case '3':case '4': case '5':case '6':case '7':case '8':case '9': times=0; while(isdigit(c)) { times=times*10+c-48; c=getc(zin); } times++; /* need to add 1 because it's dec'ed */ break; /* immediately at end of for loop */ case '/' : if (line[pos]) /* search forward */ { c=getc(zin); /* char to search for */ for (i=pos+1;line[i] && c!=line[i];i++); if (line[i]) while (pos0) /* search backwards */ { c=getc(zin); /* char to search for */ for (i=pos-1;i>=0 && c!=line[i];i--); if (i>=0) while (pos>i) { pos--; if (line[pos]<32) backward(curs); backward(curs); } else write(1,beep,beeplength); /* not found */ } else write(1,beep,beeplength); /* at end of line */ break; default : write(1,beep,beeplength); } break; case 29 : continue; default : if (pos>=MAXLL) { write(1,beep,beeplength); break; } insert(line,pos++,c,curs); break; } times=1; } } //E*O*F comlined.c// exit 0