home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
115_01
/
ed3.c
< prev
next >
Wrap
Text File
|
1979-12-31
|
13KB
|
701 lines
/*
* Screen editor: command mode commands
*
* Source: ed3.c
* Version: September 5, 1981.
*
*/
/* data global to these routines */
char filename[SYSFNMAX];
/* append command.
* load a file into main buffer at current location.
* this command does NOT change the current file name.
*/
append(args) char *args;
{
char buffer[MAXLEN]; /* disk line buffer */
int file;
int n;
int topline;
char locfn[SYSFNMAX]; /* local file name */
/* get file name which follows command */
if (name1(args,locfn)==ERR) {
return;
}
if (locfn[0]==EOS) {
message("no file argument");
return;
}
/* open the new file */
if ((file=sysopen(locfn,"r"))==ERR) {
message("file not found");
return;
}
/* read the file into the buffer */
while ((n=readline(file,buffer,MAXLEN))>=0) {
if (n>MAXLEN) {
message("line truncated");
n=MAXLEN;
}
if (bufins(buffer,n)==ERR) {
break;
}
if (bufdn()==ERR) {
break;
}
}
/* close the file */
sysclose(file);
/* redraw the screen so topline will be at top
* of the screen after command() does a CR/LF.
*/
topline=max(1,bufln()-SCRNL2);
bufout(topline,2,SCRNL2);
bufgo(topline);
}
/* global change command */
change(args) char *args;
{
char oldline[MAXLEN1]; /* reserve space for EOS */
char newline[MAXLEN1];
char oldpat[MAXLEN1];
char newpat[MAXLEN1];
int from, to, col, n, k;
if (get2args(args,&from,&to)==ERR) {
return;
}
/* get search and change masks into oldpat, newpat */
fmtsout("search mask ? ",0);
getcmnd(oldpat,15);
fmtcrlf();
if (oldpat[0]==EOS) {
return;
}
pmtline();
fmtsout("change mask ? ",0);
getcmnd(newpat,15);
fmtcrlf();
/* make substitution for lines between from, to */
while (from<=to) {
if (chkkey()==YES) {
break;
}
if (bufgo(from++)==ERR) {
break;
}
if (bufatbot()==YES) {
break;
}
n=bufgetln(oldline,MAXLEN);
n=min(n,MAXLEN);
oldline[n]=EOS;
/* '^' anchors search */
if (oldpat[0]=='^') {
if (amatch(oldline,oldpat+1,0)==YES) {
k=replace(oldline,newline,
oldpat+1,newpat,0);
if (k==ERR) {
return;
}
fmtcrlf();
putdec(bufln(),5);
fmtsout(newline,5);
outdeol();
bufrepl(newline,k);
}
continue;
}
/* search oldline for oldpat */
col=0;
while (col<n) {
if (amatch(oldline,oldpat,col++)==YES){
k=replace(oldline,newline,
oldpat,newpat,col-1);
if (k==ERR) {
return;
}
fmtcrlf();
putdec(bufln(),5);
fmtsout(newline,5);
outdeol();
bufrepl(newline,k);
break;
}
}
}
fmtcrlf();
}
/* clear main buffer and file name */
clear()
{
/* make sure it is ok to clear buffer */
if (chkbuf()==YES) {
filename[0]=0;
pmtfile("");
outclr();
outxy(0,SCRNL1);
bufnew();
message("buffer cleared");
}
}
/* multiple line delete command */
delete(args) char *args;
{
int from, to;
if (get2args(args,&from,&to)==ERR) {
return;
}
if (from>to) {
return;
}
/* go to first line to be deleted */
if (bufgo(from)==ERR) {
return;
}
/* delete all line between from and to */
if (bufdeln(to-from+1)==ERR) {
return;
}
/* redraw the screen */
bufout(bufln(),1,SCRNL1);
}
/* search all lines below the current line for a pattern
* return -1 if pattern not found.
* otherwise, return column number of start of pattern.
*/
find()
{
return(search1(bufln()+1,HUGE,YES));
}
/* list lines to list device */
list(args) char *args;
{
char linebuf[MAXLEN1];
int n;
int from, to, line, oldline;
/* save the buffer's current line */
oldline=bufln();
/* get starting, ending lines to print */
if (get2args(args,&from,&to)==ERR) {
return;
}
/* print lines one at a time to list device */
line=from;
while (line<=to) {
/* make sure prompt goes to console */
fmtassn(NO);
/* check for interrupt */
if (chkkey()==YES) {
break;
}
/* print line to list device */
fmtassn(YES);
if (bufgo(line++)!=OK) {
break;
}
if (bufatbot()) {
break;
}
n=bufgetln(linebuf,MAXLEN1);
n=min(n,MAXLEN);
linebuf[n]=CR;
fmtsout(linebuf,0);
fmtcrlf();
}
/* redirect output to console */
fmtassn(NO);
/* restore cursor */
bufgo(oldline);
}
/* load file into buffer */
load (args) char *args;
{
char buffer[MAXLEN]; /* disk line buffer */
char locfn [SYSFNMAX]; /* file name until we check it */
int n;
int file;
int topline;
/* get filename following command */
if (name1(args,locfn)==ERR) {
return;
}
if (locfn[0]==EOS) {
message("no file argument");
return;
}
/* give user a chance to save the buffer */
if (chkbuf()==NO) {
return;
}
/* open the new file */
if ((file=sysopen(locfn,"r"))==ERR) {
message("file not found");
return;
}
/* update file name */
syscopfn(locfn, filename);
pmtfile(filename);
/* clear the buffer */
bufnew();
/* read the file into the buffer */
while ((n=readline(file,buffer,MAXLEN))>=0) {
if (n>MAXLEN) {
message("line truncated");
n=MAXLEN;
}
if (bufins(buffer,n)==ERR) {
break;
}
if (bufdn()==ERR) {
break;
}
}
/* close the file */
sysclose(file);
/* indicate that the buffer is fresh */
bufsaved();
/* set current line to line 1 */
bufgo(1);
/* redraw the screen so that topline will be
* on line 1 after command() does a CR/LF.
*/
topline=max(1,bufln()-SCRNL2);
bufout(topline,2,SCRNL2);
bufgo(topline);
}
/* change current file name */
name(args) char *args;
{
name1(args,filename);
pmtfile(filename);
}
/* check syntax of args.
* copy to filename.
* return OK if the name is valid.
*/
name1(args,filename) char *args, *filename;
{
/* skip command */
args=skiparg(args);
args=skipbl(args);
/* check file name syntax */
if (syschkfn(args)==ERR) {
return(ERR);
}
/* copy filename */
syscopfn(args,filename);
return(OK);
}
/* save the buffer in an already existing file */
resave()
{
char linebuf[MAXLEN];
int file, n, oldline;
/* make sure file has a name */
if (filename[0]==EOS) {
message("file not named");
return;
}
/* the file must exist for resave */
if ((file=sysopen(filename,"r"))==ERR) {
message("file not found");
return;
}
if (sysclose(file)==ERR) {
return;
}
/* open the file for writing */
if ((file=sysopen(filename,"w"))==ERR) {
return;
}
/* save the current position of file */
oldline=bufln();
/* write out the whole file */
if (bufgo(1)==ERR) {
sysclose(file);
return;
}
while (bufatbot()==NO) {
n=bufgetln(linebuf,MAXLEN);
n=min(n,MAXLEN);
if (pushline(file,linebuf,n)==ERR) {
break;
}
if (bufdn()==ERR) {
break;
}
}
/* indicate if all buffer was saved */
if (bufatbot()){
bufsaved();
}
/* close file and restore line number */
sysclose(file);
bufgo(oldline);
}
/* save the buffer in a new file */
save()
{
char linebuf[MAXLEN];
int file, n, oldline;
/* make sure the file is named */
if (filename[0]==EOS) {
message("file not named");
return;
}
/* file must NOT exist for save */
if ((file=sysopen(filename,"r"))!=ERR) {
sysclose(file);
message("file exists");
return;
}
/* open file for writing */
if ((file=sysopen(filename,"w"))==ERR) {
return;
}
/* remember current line */
oldline=bufln();
/* write entire buffer to file */
if (bufgo(1)==ERR) {
sysclose(file);
return;
}
while (bufatbot()==NO) {
n=bufgetln(linebuf,MAXLEN);
n=min(n,MAXLEN);
if (pushline(file,linebuf,n)==ERR) {
break;
}
if (bufdn()==ERR) {
break;
}
}
/* indicate buffer saved if good write */
if (bufatbot()) {
bufsaved();
}
/* restore line and close file */
bufgo(oldline);
sysclose(file);
}
/* global search command */
search(args) char *args;
{
int from, to;
if (get2args(args,&from,&to)==ERR) {
return;
}
search1(from, to, NO);
}
/* search lines for a pattern.
* if flag == YES: stop at the first match.
* return -1 if no match.
* otherwise return column number of match.
* if flag == NO: print all matches found.
*/
search1(from, to, flag) int from, to, flag;
{
char pat [MAXLEN1]; /* reserve space for EOS */
char line [MAXLEN1];
int col, n;
/* get search mask into pat */
fmtsout("search mask ? ",0);
getcmnd(pat,15);
fmtcrlf();
if (pat[0]==EOS) {
return;
}
/* search all lines between from and to for pat */
while (from<=to) {
if (chkkey()==YES) {
break;
}
if (bufgo(from++)==ERR) {
break;
}
if (bufatbot()==YES) {
break;
}
n=bufgetln(line,MAXLEN);
n=min(n,MAXLEN);
line[n]=EOS;
/* ^ anchors search */
if (pat[0]=='^') {
if (amatch(line,pat+1,0)==YES) {
if (flag==NO) {
fmtcrlf();
putdec(bufln(),5);
fmtsout(line,5);
outdeol();
}
else {
return(0);
}
}
continue;
}
/* search whole line for match */
col=0;
while (col<n) {
if (amatch(line,pat,col++)==YES) {
if (flag==NO) {
fmtcrlf();
putdec(bufln(),5);
fmtsout(line,5);
outdeol();
break;
}
else {
return(col-1);
}
}
}
}
/* all searching is finished */
if (flag==YES) {
return(-1);
}
else {
fmtcrlf();
}
}
/* set tab stops for fmt routines */
tabs(args) char *args;
{
int n, junk;
if (get2args(args,&n,&junk)==ERR) {
return;
}
fmtset(n);
}
/* return YES if buffer may be drastically changed */
chkbuf()
{
if (bufchng()==NO) {
/* buffer not changed. no problem */
return(YES);
}
fmtsout("buffer not saved. proceed ? ",0);
pmtline();
if (tolower(syscout(syscin()))!='y') {
fmtcrlf();
message("cancelled");
return(NO);
}
else {
fmtcrlf();
return(YES);
}
}
/* print message from a command */
message(s) char *s;
{
fmtsout(s,0);
fmtcrlf();
}
/* get two arguments the argument line args.
* no arguments imply 1 HUGE.
* one argument implies both args the same.
*/
get2args(args,val1,val2) char *args; int *val1, *val2;
{
/* skip over the command */
args=skiparg(args);
args=skipbl(args);
if (*args==EOS) {
*val1=1;
*val2=HUGE;
return(OK);
}
/* check first argument */
if (number(args,val1)==NO) {
message("bad argument");
return(ERR);
}
/* skip over first argument */
args=skiparg(args);
args=skipbl(args);
/* 1 arg: arg 2 is HUGE */
if (*args==EOS) {
*val2=HUGE;
return(OK);
}
/* check second argument */
if (number(args,val2)==NO) {
message("bad argument");
return(ERR);
}
else {
return(OK);
}
}
/* skip over all except EOS, and blanks */
skiparg(args) char *args;
{
while ((*args!=EOS)&(*args!=' ')) {
args++;
}
return(args);
}
/* skip over all blanks */
skipbl(args) char *args;
{
while (*args==' ') {
args++;
}
return(args);
}
/* return YES if the user has pressed any key.
* blanks cause a transparent pause.
*/
chkkey()
{
int c;
c=syscstat();
if (c==0) {
/* no character at keyboard */
return(NO);
}
else if (c==' ') {
/* pause. another blank ends pause */
pmtline();
if (syscin()==' ') {
return(NO);
}
}
/* we got a nonblank character */
return(YES);
}
/* anchored search for pattern in text line at column col.
* return YES if the pattern starts at col.
*/
amatch(line,pat,col) char *line, *pat; int col;
{
int k;
k=0;
while (pat[k]!=EOS) {
if (pat[k]==line[col]) {
k++;
col++;
}
else if ((pat[k]=='?')&(line[col]!=EOS)) {
/* question mark matches any char */
k++;
col++;
}
else {
return(NO);
}
}
/* the entire pattern matches */
return(YES);
}
/* replace oldpat in oldline by newpat starting at col.
* put result in newline.
* return number of characters in newline.
*/
replace(oldline,newline,oldpat,newpat,col)
char *oldline, *newline, *oldpat, *newpat; int col;
{
int k;
char *tail, *pat;
/* copy oldline preceding col to newline */
k=0;
while (k<col) {
newline[k++]=*oldline++;
}
/* remember where end of oldpat in oldline is */
tail=oldline;
pat=oldpat;
while (*pat++!=EOS) {
tail++;
}
/* copy newpat to newline.
* use oldline and oldpat to resolve question marks
* in newpat.
*/
while (*newpat!=EOS) {
if (k>MAXLEN-1) {
message("new line too long");
return(ERR);
}
if (*newpat!='?') {
/* copy newpat to newline */
newline[k++]=*newpat++;
continue;
}
/* scan for '?' in oldpat */
while (*oldpat!='?') {
if (*oldpat==EOS) {
message(
"too many ?'s in change mask"
);
return(ERR);
}
oldpat++;
oldline++;
}
/* copy char from oldline to newline */
newline[k++]=*oldline++;
oldpat++;
newpat++;
}
/* copy oldline after oldpat to newline */
while (*tail!=EOS) {
if (k>=MAXLEN-1) {
message("new line too long");
return(ERR);
}
newline[k++]=*tail++;
}
newline[k]=EOS;
return(k);
}