home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The C Users' Group Library 1994 August
/
wc-cdrom-cusersgrouplibrary-1994-08.iso
/
vol_100
/
133_01
/
e
< prev
next >
Wrap
Text File
|
1985-03-10
|
11KB
|
503 lines
/*
CUG-HEADER:
TITLE: "e screen editor"
VER: 4.8
AUTHOR: G.N. GILBERT
O.S.: CP/M 2.2 CP/M 3.0
DESC: a complete screen editor for programmers, with lots
of useful features, an easy to use interface,
virtual memory management, 'undo' facility etc.
KEYWORDS: editor, programming environment, tool
DATE: 1/30/1985
*/
/*
e screen editor
(C) G. Nigel Gilbert, MICROLOGY, 1981
licensed for private non-profitmaking use 1983
August-December 1981
FILE: e
FUNCTIONS: main, initialise, edit, finish, seldisk, askforfile,
xit, startstop
PURPOSE: initialise; process commands, finish
*/
#include "e.h"
main(argc,argv)
int argc;
char **argv;
{
int argn, i, startline;
char *dig, cpmversion;
/**************************Default option settings***************************/
autoin=YES; /*auto indent [YES/NO]*/
backup=NO; /*make ".BAK" file [YES/NO]*/
trail=NO; /*don't strip trailing blanks [YES/NO]*/
helpon=NO; /*start with help menu on [YES/NO]*/
tabwidth=8; /*tab stops every n cols [number]*/
displaypos=YES; /*display line:column at top of screen*/
blockscroll=NO; /*don't scroll whole page, just current line*/
pagingdisk=0; /*create buffer file on this disk -
set to either 0 (for currently logged-in disk)
or to desired disk letter (eg 'B') */
wboot=NO; /*do a warm boot at end of edit [YES/NO]
(ignored for non CP/M 2.x systems)
SET THIS OPTION TO YES if you do not have an
entirely standard CP/M 2.x system */
hilight=YES; /*highlight current line*/
/***********************End of default option settings***********************/
switch(bdos(VERNO,0) & 0xf0) {
case 0x20 : /* CP/M 2.x */
cpm2x=YES;
break;
case 0x31 : /* CP/M 3.1 [CP/M Plus] */
bdos(CPM3ERRORMODE, 0xfe); /*set error mode to
return and display
error */
cpm2x=NO; /*disable fast
re-boot option*/
break;
default: /*weird CP/M*/
cpm2x=NO;
break;
}
/*initialisations only done once at start of all editing: */
inbufp=0;
startline=1;
filename[0]=name[0]=ans[0]=patt[0]=changeto[0]=opts[0]='\0';
argn=0;
while (++argn < argc)
if (*argv[argn] == '-') {
dig=argv[argn]+1;
switch(*dig) {
case 'A' :
autoin=!autoin;
break;
case 'B' :
backup=!backup;
break;
case 'L' :
displaypos=!displaypos;
break;
case 'H' :
blockscroll=!blockscroll;
break;
case 'I' :
hilight=!hilight;
break;
case 'T' :
tabwidth=0;
while (*++dig) tabwidth=tabwidth*10+*dig-'0';
break;
case 'S' :
trail=!trail;
break;
case 'V' :
helpon=!helpon;
break;
case 'X' :
wboot=!wboot;
break;
case 'D' :
pagingdisk=*(dig+1);
if (pagingdisk >= 'A' && pagingdisk <= 'P') break;
default :
if (isdigit(*dig)) {
for (startline=0; *dig; dig++)
startline=startline*10 + *dig - '0';
break;
}
puts("Illegal option: ");
puts(argv[argn]);
exit();
}
}
else strcpy(filename[0] ? name : filename,argv[argn]);
terminit();
keytranslate();
startstop(YES);
do {
initialise(startline);
edit();
startline=1;
}
while (YES);
}
initialise(startline)
int startline;
{
/*initialisations that are done before editing each new file: */
cursorx=charn=offset=lastoff=from=to=histptr=histcnt=ncommand=0;
cursory=topline=lastread=lastl=findir=1;
isdim=replace=repeat=blocking=blankedmess=storehist=NO;
pfirst=-100;
goteof=YES;
errmess=NULL;
curdsk=bdos(CURDSK);
initvm();
text[0]='\0';
cline=1;
altered=YES;
puttext();
if (filename[0]) {
putclr();
gotoxy(8,11);
puts("e screen editor version ");
puts(VERSION);
puts(" MICROLOGY 1983");
gotoxy(20,12);
terminal();
while (opentext(filename) == FAIL) {
askforfile();
if (!filename[0]) goto newfile;
}
lastl=UNKNOWN;
lastread=0;
goteof=NO;
if (name[0]) {
strcpy(filename,name);
name[0]='\0';
}
format(filename);
}
newfile: errmess=NULL;
gettext(startline);
cline=loc(startline,0);
putclr();
if (helpon) dohelp();
putpage();
}
edit() /*command processor*/
{
char c;
int to;
setjmp(mainmenu);
while (YES) {
goodline=cline;
unmess();
putlineno(cline);
resetcursor();
c=getkey();
if (errmess != NULL) {
errmess=NULL;
putstatusline(cline);
}
ncommand++;
storehist=YES;
switch(c) {
case DOWNKEY :
moveline(1);
break;
case UPKEY :
moveline(-1);
break;
case LEFTKEY :
movechar(-1);
break;
case RIGHTKEY :
movechar(1);
break;
case LEFTWKEY :
moveword(-1);
break;
case RIGHTWKEY :
moveword(1);
break;
case BOLKEY :
sync(0);
break;
case EOLKEY :
sync(strlen(text));
break;
case UPPAGE :
movepage(-1);
break;
case DOWNPAGE :
movepage(0);
break;
case HOMEKEY :
if (jumpline(lastl-cline)) sync(strlen(text));
break;
case BOFKEY :
if (jumpline(1-cline)) sync(0);
break;
case DELLEFT :
deletechar(-1);
break;
case DELRIGHT :
deletechar(0);
break;
case DELLNKEY :
text[0]='\0';
crdelete((cline == lastl ? -1 : 0));
break;
case DELWDKEY :
deleteword();
break;
case JUMPKEY :
putmess("Jump to? ");
scans(ans,6);
if ((to=atoi(ans))) jumpline(to-cline);
break;
case FINDKEY :
replace=NO;
findorrep();
break;
case ALTERKEY :
replace=YES;
findorrep();
break;
case REPKEY :
repeat=YES;
dofindrep(1);
repeat=NO;
break;
case BLOCKKEY :
blockops();
break;
case RDFILEKEY :
putmess("File to read? ");
scans(name,FILELEN);
if (strlen(name) > 0) {
readfile(name);
putpage();
}
break;
case HELPKEY :
if (helpon) {
helpon=NO;
unmess();
}
else {
helpon=YES;
dohelp();
}
break;
case CR :
crinsert(0);
break;
case CRSTILL :
crinsert(-1);
break;
case ENVIRKEY :
envir();
break;
case QUITKEY :
if (finish()) return;
break;
case UNDOKEY :
undo();
break;
case TAB:
insertchar('\t');
break;
case ESCKEY :
resetcursor();
c=inchar();
default :
insertchar(c);
break;
}
}
}
finish() /*return YES to edit another file; NO to return to current file
or don't return, but exit if finished altogther */
{
int abandon;
char c, tempname[FILELEN], namebak[FILELEN], *strcpy(), getlow();
putmess("W|rite edited text to file, |A|bandon all edits, or |R|eturn? ");
while ( (c=getlow()) != 'w' && c != 'a' && c != 'r');
putch(c);
if (c == 'r') return NO;
abandon= c == 'a';
if (c == 'w') {
if (!filename[0]) {
putmess("File to write to? ");
scans(filename,FILELEN);
format(filename);
if (filename[0] <= ' ' || (!backup && !exists(filename)))
{
filename[0]='\0';
return NO;
}
}
if (backup) { /*delete old bak file*/
retag(strcpy(namebak,filename),"BAK");
if (checkexists(namebak) && funlink(namebak) == FAIL) {
error("Can't delete backup file");
return NO;
}
}
strcpy(tempname,filename); /*keep old name in 'filename'*/
retag(tempname,"$$$"); /*new file called'.$$$'*/
if (writefile(1,lastl,tempname,filename,YES) == FAIL) return NO;
/*check original file still exists - may have been deleted or
renamed by user */
if (checkexists(filename)) {
if (backup) {
/*orig. file becomes '.bak' */
if (frename(filename,namebak) == FAIL) {
error("Can't rename old file to .BAK");
goto failed;
}
}
else {
/*delete orig file*/
if (funlink(filename) == FAIL) {
error("Can't delete old file");
failed: /*if can't delete/rename old file, change
new name to '.$$$'*/
strcpy(filename,tempname);
goto nowrite;
}
}
}
frename(tempname,filename); /*new file goes from '$$$' to orig name*/
}
nowrite:
putmess("E|xit to CP/M, |R|eturn to this file, or edit |A|nother file? ");
while ( (c=getlow()) != 'e' && c!='a' && c!='r');
putch(c);
switch(c) {
case 'e' :
if (pagefd != NOFILE) {
close(pagefd);
funlink(pagingfile);
}
xit();
case 'a' :
fclose(textbuf);
if (pagefd != NOFILE) {
close(pagefd);
funlink(pagingfile);
}
askforfile();
return YES;
case 'r' :
if (!abandon) {
gotoxy(WAITPOS,0);
opentext(filename);
lastl=UNKNOWN;
lastread=0;
goteof=NO;
initvm();
gettext(cline);
errmess=NULL;
putstatusline(cline);
}
return NO;
}
}
xit() /*leave the editor, either by returning to CCP or by
warm booting, according to X option*/
{
unsigned *cpm;
deleteline(0,23);
gotoxy(0,22);
termfini(); /*close down terminal*/
startstop(NO);
if (!cpm2x || wboot) exit();
else {
cpm=6;
/*call the standard return address within CCP - this is
just after where CCP calls a user program to start it off -
to avaoid having to do a warm boot */
call(*cpm-6-CCP+0x75f);
}
}
askforfile() /*get another file to edit into 'filename' */
{
int drive, n;
while(YES) {
printdirectory(curdsk);
puts("Name of file to edit |or [return] to create a new file,\n");
puts(" |A:-P: to change drive, 0/-15/ to change user area,\n");
puts(" |[escape] to exit)| ? ");
if (scans(filename,FILELEN) == ESCKEY) xit();
for (n=0; isdigit(filename[n]); n++);
if (filename[n] == '/' && !filename[n+1]) {
bdos(USERCODE,atoi(filename));
continue;
}
if (filename[1] == ':' && !filename[2] &&
(drive=toupper(filename[0])-'A') >= 0 && drive < 16) {
if (seldisk(drive)) continue;
bdos(RESETDRV,1 << (curdsk=drive));
continue;
}
name[0]='\0';
return;
}
}
seldisk(drive) /*log in 'drive', returning 0 for success, else FAIL */
int drive;
{
if (dskcheck(setjmp(dskerr))) return FAIL;
bdos(SELDSK,drive);
return 0;
}
startstop(sw) /*set up system to catch BDOS errors - or close
it down*/
int sw;
{
char *bdosbase;
int i,*six,*errbase,err1(),err2(),err3(),err4();
if (!cpm2x) return; /*only works for CP/M 2.x */
six=6;
bdosbase=*six;
errbase=bdosbase+3;
if (sw) {
for (i=0; i < 4; i++) errold[i]=*(errbase+i);
*(errbase)=err1;
*(errbase+1)=err2;
*(errbase+2)=err3;
*(errbase+3)=err4;
}
else for (i=0; i < 4; i++) *(errbase+i)=errold[i];
}
,0);
opentext(filename);
lastl=UNKNOWN;
lastread=0;
goteo