home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
CPM
/
EDITOR
/
EDITOR.ARK
/
ED3.C
< prev
next >
Wrap
C/C++ Source or Header
|
1983-09-09
|
14KB
|
712 lines
/*
* Screen editor: command mode commands -- enhanced
*
* Source: ed3.bds
* Version: December 20, 1981.
* Transliteration of small-C version of September 5, 1981
*
*/
/* define globals */
#include ed.h
#include bdscio.h
#include ed1.ccc
#include edext.cc
/* data global to these routines */
/* comment out -----
char filename [SYSFNMAX];
----- end comment out */
/* 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);
}