/*
EDIT
Copyright (C) A.Gibbons University of Edinburgh MCMXC
*/
#define msdos 1
#define castle 2
#define metsun 4
#define hp9000 8
#define cssun 16
#define DRS 32
#define PTX 64
#define LINUX 128
#define TARGET LINUX
#if (TARGET == msdos)
#include <graph.h>
#include <stdlib.h>
#include <process.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <io.h>
#include <malloc.h>
#include <time.h>
#else
#if (TARGET == hp9000)
#include <fcntl.h>
#include <termio.h>
struct termio termio0, *tio0;
#else
#if (TARGET == DRS)
#include <fcntl.h>
#endif
#include <sgtty.h>
struct sgttyb sgttyb0;
#endif
#include <sys/ioctl.h>
#include <signal.h>
#include <pwd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#if (TARGET!=PTX)
#include <sys/file.h>
#include <sys/time.h>
#else
#include <fcntl.h>
#endif
#include <sys/param.h>
#endif
extern int errno;
extern int sys_nerr;
extern char *sys_errlist[];
/* --------------------edit variables-------------------- */
char indent[64];
int wordm1, emode, use_sif, caseind, topa, bota, seta, curp, begp, endp, txtp,
actions, cadnew, tmpnew, asl, wsp0, wsp, wse, level, comp, wseen,
haltered, altered, hcurp, hset, back, changed, nlc, linecomplete,
lcomp, slinest, sparast, slinel, eterminate, fileusedcount, newf_exists,
linel, sym, firstpos, /* this line for LAYOUT */
presif_altered;
#define MAXPDICT 16384
#define PRIVDICTNAME "~/.edit-dict"
#define MAXSDICT 131072
#ifndef SYSDICTNAME
/* May be given on CC command line, eg -DSYSDICTNAME=\"./edit-dict\" */
#define SYSDICTNAME "/usr/local/lib/edit-dict"
#endif
int privdict_changed;
int sysdicta, sysdictb, privdicta, privdictb, tempdicta, tempdictb;
#define MAXHASH 10
int hash[MAXHASH+1];
static char spellch[] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0, 0, 0, 0, 0,
0, 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 0, 0, 0, 0, 0};
char cline[160], nls[2], sps[132];
static char *tempfile = "temp";
char *byteinteger, *ccase;
int *integer;
#define MAXCOUNT 15
int count[MAXCOUNT+1];
#define MAXFILE 8
char fileused[MAXFILE][MAXPATHLEN+1];
int start_address[MAXFILE], end_address[MAXFILE];
char oldf[MAXPATHLEN+1], newf[MAXPATHLEN+1], word[33];
char in[MAXPATHLEN+1], out[MAXPATHLEN+1], prstring[8];
static char *eha = "~/eha";
static char *explanation = "well\nnow";
struct cell {int ll, lp, rp, rl;};
#define TOPIDENTIFIER 512
#define TOPSTRING 64
char identifier[TOPIDENTIFIER], ident[31];
struct cell string[TOPSTRING];
struct cell lastrec [16]; /* twice as many as there are commands to allow */
/* two strings to be saved */
struct cell *top, *bot, *set, *cur, *beg, *edit_end, *txt, *new,
*htop, *hbot, *hcur, *scur,
*ptop, *pbot; /* for LAYOUT */
struct cform {
char lett, flags, level, swno, errno, loop;
int count, par;};
struct cform clist [100];
struct cform *currcomp, *curcom, *lastcom;
static unsigned char onecase[]= {0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,112,
113,114,115,116,117,118,119,120,121,122, 91, 92, 93, 94, 95, 96,
97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,112,
113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,
145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,
161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,
193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,
209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,
241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
static unsigned char twocase[]= {0,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,112,
113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,
145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,
161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,
177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,
193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,
209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,
225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,
241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
#define BACKWARDS 1
#define NUMPAR 2
#define TEXTPAR 4
#define FILEPAR 8
#define ERROR 128
#define NOTINLOOK 128
#define SPECIAL 64
#define ALLPAR 14
#define NEEDSS 32
#define STOPSPELL 16
#define MAXI 20000000
#define SHRIEK 11
#define NONNULL 9
#define TEXTCHAR 2
#define LOOPSTART 7
#define LOOPEND 8
#define NUMCHAR 3
#define FILECHAR 4
#define FILEEND 5
#define MINUS 6
#define COMMAND 1
#define YES 1
#define NO 0
#define SYNTAXERROR 7
#define INVALIDLOOP 1
#define CHINLOOK 2
#define NL 10
#define SP 32
#define QUOTE 39
#define DOUBLEQUOTE 34
#define PSEUDX "/tmp/edit-XXXXXX"
char PSEUD[32];
struct sdf {long len, adr;}; /* so called 'string descriptor' */
static char chartype1 [] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NL, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, NL, 0, 0, 0, 0, 0, 0,
SP, SHRIEK, NONNULL, NONNULL, NONNULL, COMMAND, NONNULL, TEXTCHAR,
LOOPSTART, LOOPEND, NUMCHAR, NUMCHAR, NONNULL, MINUS, TEXTCHAR, TEXTCHAR,
NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR,
NUMCHAR, NUMCHAR, NONNULL, NONNULL, FILECHAR, NONNULL, FILEEND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, NONNULL, COMMAND,
COMMAND, COMMAND, COMMAND, NONNULL, NONNULL, NONNULL, NONNULL, NONNULL,
NONNULL, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, NONNULL, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, NONNULL, COMMAND,
COMMAND, COMMAND, COMMAND, NONNULL, NONNULL, NONNULL, NONNULL, 0};
static char chartype2 [] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, NL, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, NL, 0, 0, 0, 0, 0, 0,
SP, SHRIEK, TEXTCHAR, TEXTCHAR, NONNULL, TEXTCHAR, NONNULL, TEXTCHAR,
LOOPSTART, LOOPEND, NUMCHAR, NUMCHAR, NONNULL, MINUS, TEXTCHAR, TEXTCHAR,
NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR, NUMCHAR,
NUMCHAR, NUMCHAR, NONNULL, NONNULL, FILECHAR, NONNULL, FILEEND, TEXTCHAR,
NONNULL, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, NONNULL, COMMAND,
COMMAND, COMMAND, COMMAND, NONNULL, NONNULL, NONNULL, NONNULL, NONNULL,
NONNULL, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, NONNULL, COMMAND, COMMAND, COMMAND,
COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, COMMAND, NONNULL, COMMAND,
COMMAND, COMMAND, COMMAND, NONNULL, NONNULL, NONNULL, NONNULL, 0};
#define FIRSTCOM 62
#define LASTCOM 90
/* ie from > (which is pseudo) to Z */
static int comdef[] = {
/*%*/ (36<<16) | TEXTPAR | SPECIAL,
/*?*/ (35<<24) | NUMPAR,
/*@*/ (34<<24) | NUMPAR,
/*A*/ (8<<24) | (7<<16) | ALLPAR | BACKWARDS | STOPSPELL,
/*B*/ (2<<24) | STOPSPELL,
/*C*/ (33<<24) | (32<<16) | (7<<12) | ALLPAR | BACKWARDS | NOTINLOOK | NEEDSS | STOPSPELL,
/*D*/ (12<<24) | (11<<16) | (1<<12) | ALLPAR | BACKWARDS | NOTINLOOK | STOPSPELL,
/*E*/ (3<<24) | SPECIAL,
/*F*/ (24<<16) | FILEPAR,
/*G*/ (23<<24) | NUMPAR | NOTINLOOK | STOPSPELL,
/*H*/ (18<<24) | SPECIAL | STOPSPELL,
/*I*/ (4<<16) | (2<<12) | BACKWARDS | FILEPAR | TEXTPAR |NOTINLOOK | STOPSPELL,
/*J*/ (28<<24) | NUMPAR | NOTINLOOK | STOPSPELL,
/*K*/ (17<<24) | NEEDSS | STOPSPELL,
/*L*/ (27<<24) | NUMPAR | NOTINLOOK | STOPSPELL,
/*M*/ (6<<24) | (5<<16) | (3<<12) |ALLPAR | BACKWARDS | STOPSPELL,
/*N*/ (31<<24),
/*O*/ (21<<24) | NEEDSS | STOPSPELL,
/*P*/ (10<<24) | (9<<16) | (4<<12) | ALLPAR | BACKWARDS,
/*Q*/ (15<<24),
/*R*/ (14<<24) | (13<<16) | (5<<12) |ALLPAR | BACKWARDS | NOTINLOOK | STOPSPELL,
/*S*/ (16<<24),
/*T*/ (1<<24) | STOPSPELL,
/*U*/ (20<<24) | (19<<16) | (6<<12) | ALLPAR | BACKWARDS | NOTINLOOK | NEEDSS | STOPSPELL,
/*V*/ -1,
/*W*/ (25<<24) | NOTINLOOK | STOPSPELL,
/*X*/ (29<<24),
/*Y*/ (30<<24),
/*Z*/ (26<<24)};
/*----------------------------------------------------------------------*/
static int input_pointer;
static char inputline[256];
static char prompt_string[80];
static char default_prompt[64];
struct ff {
int start;
int end;
int descr;
int size;
int timestamp;
char file[MAXPATHLEN+1];
};
struct tracef {char w[256];};
struct tracef traceb[20];
int tracep;
/*----------------------------------------------------------------------*/
wrs(s) char *s; {
printf("%s\n", s);
} /* wrs */
/*----------------------------------------------------------------------*/
textof(flag, text) int flag; char *text; {
if (flag < sys_nerr) strcpy(text, sys_errlist[flag]);
else sprintf(text, "UNIX error %d", flag);
} /* textof */
/*----------------------------------------------------------------------*/
emasconnect(f) struct ff *f; {
struct stat buf;
char s[127];
/* open(2) #include <sys/file.h>
stat(2) #include <sys/types.h>
#include <sys/stat.h>
*/
if ((f->descr = open(f->file, O_RDONLY, 0)) >= 0) {
if (stat(f->file, &buf) >= 0) {
f->size = buf.st_size;
f->timestamp = buf.st_mtime;
f->start = calloc(1, f->size+32);
if (f->start >= 0) {
f->start = (f->start + 31) & (-32);
if(read(f->descr, f->start, f->size) >= 0) {
f->end = f->start + f->size;
close(f->descr); return(0);
}
}
}
}
textof(errno, s);
printf("%s\n", s);
return(errno);
} /* emasconnect */
/*----------------------------------------------------------------------*/
readline() {
int p, ch;
printf("%s", prompt_string);
for (p=0;;) {
if ((ch = getchar()) == NL) break;
inputline[p++] = ch;
}
inputline[p] = 0;
trace(inputline);
inputline[p++] = NL; inputline[p] = 0;
input_pointer = 0;
} /* readline */
/*----------------------------------------------------------------------*/
skipsymbol() {
if (inputline[input_pointer++] == 0) {
readline();
input_pointer = 1;
}
} /* skipsymbol */
/*----------------------------------------------------------------------*/
nextsymbol() {
if (inputline[input_pointer] == 0) readline();
return(inputline[input_pointer]);
} /* nextsymbol */
/*----------------------------------------------------------------------*/
readsymbol() {
if (inputline[input_pointer] == 0) readline();
return(inputline[input_pointer++]);
} /* readsymbol */
/*----------------------------------------------------------------------*/
substr(s1, s2, p, q) char *s1, *s2; int p, q; {
int j;
for (j=0;;) {
s1[j++] = s2[p++];
if (p > q) break;
}
s1[j] = 0;
} /* substr */
/*----------------------------------------------------------------------*/
kday(d, m, y, dayno, date, ttime) int *d, *m, *y, *dayno; char *date, *ttime; {
int id, im, iy,tvsecs;
char dd[3], mm[5], yy[3];
int secs_per_day, k, w;
char *udt;
/* gettimeofday(2) #include <sys/time.h>
ctime(3c)
*/
#if (TARGET != PTX)
struct timeval tv;
struct timezone tz;
gettimeofday(&tv, &tz);
udt = ctime(&tv.tv_sec);
tvsecs=tv.tv_sec;
#else
tvsecs=time(0);
udt=ctime(&tvsecs);
#endif
substr(ttime, udt, 11, 18);
secs_per_day = 60 * 60 * 24;
k = tvsecs / secs_per_day;
k = k + 25567;
*dayno = k;
k = k + 693902;
w = (4*k) - 1;
iy = w / 146097;
k = w - (146097*iy);
id = k / 4;
k = (4*id + 3) / 1461;
id = 4*id + 3 - 1461*k;
id = (id + 4) / 4;
im = (5*id - 3) / 153;
id = 5*id - 3 - 153*im;
id = (id + 5) / 5;
iy = k;
if (im < 10) im = im + 3; else {
im = im - 9;
if (iy == 99) iy = 0; else iy++;
}
sprintf(dd, "%02d", id);
sprintf(mm, "%02d", im);
sprintf(yy, "%d", iy);
strcpy(date, dd);
strcat(date, "/"); strcat(date, mm);
strcat(date, "/"); strcat(date, yy);
*d = id; *m = im; *y = iy;
} /* kday */
/*----------------------------------------------------------------------*/
datefields(monday, nth, july, y1988, date, time) char *monday, *nth, *july, *y1988, *date, *time; {
static char *day[] = {"Mon", "Tues", "Wednes", "Thurs", "Fri", "Sat", "Sun"};
static char *mon[] = {"", "January", "February", "March", "April", "May",
"June", "July", "August", "September", "October", "November", "December"};
static char *ord[] = {"", "st", "nd", "rd"};
int d, m, y, q, r, dayno;
char th[3], dd[3], yy[3];
kday(&d, &m, &y, &dayno, date, time);
dayno = dayno - 7*(dayno/7);
strcpy(monday, day[dayno]); strcat(monday, "day");
q = d/10; r = d - (10*q);
if ((q != 1) && (1 <= r) && (r <= 3)) strcpy(th, ord[r]); else strcpy(th, "th");
sprintf(nth, "%d%s", d, th);
strcpy(july, mon[m]);
sprintf(y1988, "19%d", y);
} /* datefields */
/*----------------------------------------------------------------------*/
vstring(n, s) int n; char *s; {
char monday[15], nth[7], july[15], y1988[7];
char date[16], time[16];
datefields(monday, nth, july, y1988, date, time);
switch(n) {
case 1:
sprintf(s, "%s %s %s %s", monday, nth, july, y1988);
return;
case 2:
strcpy(s, time); return;
default:
sprintf(s, "%d", n);
}
} /* vstring */
/*----------------------------------------------------------------------*/
trace(w) char *w; {
char ww[256];
strcpy(ww, w);
ww[80] = 0;
strcpy(traceb[tracep++].w, ww);
if (tracep == 19) tracep = 0;
} /* trace */
/*----------------------------------------------------------------------*/
help(screen) int screen; {
int q, p0;
char w[80];
if (screen <= 1) {
wrs(" HELP Information for edit");
drawline();
wrs("a After n igNore ");
wrs("b Bottom o Over ");
wrs("c Copy p Print ");
wrs("d Delete q Quit ");
wrs("e Exit r Remove ");
wrs("f File s Separate ");
wrs("g Goto t Top ");
wrs("h Hold u Uproot ");
wrs("i Insert v XXXX ");
wrs("j Justify w Write ");
wrs("k Kill x Spell ");
wrs("l Layout y Yes ");
wrs("m Move z Case ");
wrs("?2 for ALERT");
drawline();
}
if (screen == 2) {
wrs(" edit ALERT");
drawline();
wrs("? gives help information");
wrs("");
wrs("A value can be assigned to a variable and then used wherever a text");
wrs("string is appropriate. For example,");
wrs(" Edit: %me=/Tony Gibbons/");
wrs(" Edit: (r.xxx.i%me)*");
wrs("Assignments can also be made with f<%name>. %date and %time give the");
wrs("current date and time. %z gives the value of the string last entered.");
wrs("%name includes the value of the variable in the command string.");
wrs("");
wrs("#, or #1, gives the repetition number within a loop (0, 1, 2...)");
wrs("#2, #3 etc for inner loops");
wrs("");
wrs("i-/text/ inserts text and leaves cursor before it");
wrs("");
wrs("c is similar to u but copies the text rather than moving it");
wrs("");
wrs("i' refers to the last specific text, i\" to the one before");
wrs("similarly for a, d, m, p, r, u and v");
drawline();
}
if (screen == 3) {
wrs("edit trace");
drawline();
q = p0 = tracep;
for (;;) {
wrs(traceb[q++].w);
if (q == 19) q = 0;
if (q == p0) break;
}
}
} /* help */
/*----------------------------------------------------------------------*/
drawline() {
int n, width;
char w[255];
width = 80;
for (n=0; n<width; n++) w[n] = '-';
w[width] = 0;
wrs(w);
} /* drawline */
/*----------------------------------------------------------------------*/
move(length, from, to) int length; char *from, *to; {
int j;
for (j=0;j<length;j++) to[j] = from[j];
} /* move */
/*----------------------------------------------------------------------*/
strres(s1,s2,s3,s4) /* performs s1 -> s2 . (s3) . s4 */
/* return(0) for success */
char *s1;
char *s2;
char *s3;
char *s4;
{
int len1, len3, i, j, p;
len1 = strlen(s1);
len3 = strlen(s3);
if (len3 == 0) return(1);
if (len3 > len1) return(2);
for(i=0;;++i){
if (i > (len1-len3)) return(3);
for(j=0;;++j) {
if (s3[j] == 0) { /* success */
if (i>0) strncpy(s2,s1,i);
s2[i]=0;
p=0;
while ((s4[p]=s1[i+j+p]) != 0) ++p;
return(0);
}
if (s3[j] != s1[i+j]) break;
}
}
} /* strres */
/*----------------------------------------------------------------------*/
dump(adr, len) int adr, len; {
int *p, j, k, t, u, lines;
char *ch, y[36];
lines = (len+15) >> 4;
for (;;) {
if (lines-- <= 0) break;
p = (int *)adr;
ch = (char *)adr;
adr = adr + 16;
/* for (j=0; j<16; j++) {
if ((ch[j]<32)||(ch[j]>126)) y[j]=32; else y[j] = ch[j];
}
y[16] = 0;
*/
j = p[1]; k = p[2]; y[0] = 0;
if (k > (j+32)) k = j + 32;
if ((0 < j) && (j <= k)) {
for (t=0; j<=k; j++) {
u = byteinteger[j];
if (u == NL) u = '<';
y[t++] = u;
}
y[t] = 0;
}
printf("%c %x %x %x %x %x %s\n", fn1(adr-16), adr-16, p[0], p[1], p[2], p[3], y);
}
} /* dump */
/*----------------------------------------------------------------------*/
fn1(n) int n; {
if (n == 0) return(42);
return(((n-wsp0)>>4)+65);
} /* fn1 */
/*----------------------------*/
diagnostic(n) int n; {
int j, k, p, q, s;
char w[80];
struct cform *c;
printf("Diagnostic output:\n");
if ((n & 8) > 0) {
printf("Strings:\n");
p = 0;
for (s=0;;s++) {
for (q=0;;) {
if ((ident[q++] = identifier[p++]) == 0) break;
}
if (q == 1) break;
printf("%%%s is ", ident);
switch(string[s].ll) {
case 0:
if (string[s].lp == 0) {printf("unassigned"); break;}
case 1:
if (string[s].lp != 0) {
for (j=string[s].lp; j<=string[s].rp; j++) printf("%c", byteinteger[j]);
break;
}
case 2:
vstring(s, &w[0]);
printf("%s", w);
break;
}
printf("\n");
}
}
if ((n & 4) > 0) {
printf("Clist:\n");
printf("currcomp=%x, curcom=%x, lastcom=%x, comp=%d, lcomp=%d\n",
&currcomp->lett, &curcom->lett, &lastcom->lett, comp, lcomp);
/* dump(&clist[0].lett, 64); */
for (j=0; j<comp; j++) {
c = (struct cform *)(int)&clist[j].lett;
printf("lett=%c, flags=x%02x, level=%d, swno=%2d, errno=%d, loop=%d,\
count=%d, par=x%x\n", c->lett, c->flags, c->level, c->swno,
c->errno, c->loop, c->count, c->par);
}
}
if ((n & 1) > 0) {
printf("Cell area:\n");
printf("begp=%x, endp=%x, curp=%x, asl=%c\n", begp, endp, curp, fn1(asl));
printf("topa=%c, seta=%c, bota=%c\n", fn1(topa), fn1(seta), fn1(bota));
printf("top=%c, bot=%c, cur=%c, beg=%c\n",
fn1(&top->ll), fn1(&bot->ll), fn1(&cur->ll), fn1(&beg->ll));
printf("set=%c, end=%c, txt=%c, new=%c\n",
fn1(&set->ll), fn1(&edit_end->ll), fn1(&txt->ll), fn1(&new->ll));
printf("htop=%c, hbot=%c, hcur=%c, scur=%c\n",
fn1(&htop->ll), fn1(&hbot->ll), fn1(&hcur->ll), fn1(&scur->ll));
}
if ((n & 2) > 0) {
dump(wsp0, 256);
}
} /* diagnostic */
/*-------------------------------------------------------*/
expand_filename(s) char *s; {
int j, pwad;
char w[MAXPATHLEN];
struct passwd *passwd;
pwad = 0;
if (s[0] == '~') {
j = strres(s, w, "~", s);
j = strres(s, w, "/", s);
if (j == 0) {
if (w[0] == 0) pwad = (int)getpwuid(getuid()); else pwad = (int)getpwnam(w);
if (pwad != 0) {
passwd = (struct passwd*)pwad;
strcpy(w, passwd->pw_dir);
strcat(w, "/"); strcat(w, s);
strcpy(s, w);
}
}
}
} /* expand_filename
/*----------------------------------------------------------------------*/
exist(file) char *file; {
int descr;
char s[MAXPATHLEN+1];
struct stat buf;
strcpy(s, file);
expand_filename(s);
if (stat(s, &buf) == 0)
return(1); /* exists */
else return(0);
} /* exist */
/*----------------------------------------------------------------------*/
newcell() { /* 757 */
int i, j, k;
struct cell *w;
i = asl;
if (i == 0) {
i = (wsp+3) & (-4);
j = i + 4096;
if (j > wse) extendwork("newcell");
wsp = j; k = 0;
while (j > i) {
j = j - 16;
integer[j>>2] = k;
k = j;
}
}
asl = integer[i>>2];
w = (struct cell *) i;
w->ll = w->lp = w->rp = w->rl = 0;
/* printf("newcell: %c\n", fn1(i)); */
return(i);
} /* newcell */
/*----------------------------------------------------------------------*/
returnlist(one, two) int one, two; { /* 790 */
struct cell *work;
int i;
/* printf("returnlist: one=%c, two=%c\n", fn1(one), fn1(two)); */
work = (struct cell *)one;
while ((int)&work->ll != two) {
i = work->rl;
work = (struct cell *)returncell(&work->ll);
}
} /* returnlist */
/*----------------------------------------------------------------------*/
returncell(i) int i; { /* 804 */
struct cell *work;
/* printf("returncell: %c\n", fn1(i)); */
work = (struct cell *)i;
work->ll = asl;
asl = i;
return(work->rl);
} /* returncell */
/*----------------------------------------------------------------------*/
lookup(insert) int insert; {
int n, p, q;
/* printf("lookup %s, insert=%d\n", ident, insert); */
n = p = q = 0;
for (;;) {
if (identifier[p] == ident[q++]) {
if (identifier[p] == 0) {
/* printf("return %d\n", n); */
return(n);
}
p++;
} else {
n++;
if (n >= TOPSTRING) {printf("Too many variables!!!\n"); return(-1);}
while (identifier[p++] != 0) ;
if (identifier[p] == 0) {
if (insert == 0) {/* printf("not found\n"); */ return(-1);}
if ((p+strlen(ident))>= TOPIDENTIFIER) {printf("Too many variable names!!!\n"); return(-1);}
strcpy(&identifier[p], ident);
/* printf("newname, return %d\n", n); */
return(n);
}
q = 0;
}
}
} /* lookup */
/*----------------------*/
readtext() { /* 810 */
int marker, ch, skippedch, cch, n, p, q;
char w[128];
cch = 0x3600; /* tab nl cr ff */
while(nextsymbol() <= SP) skipsymbol();
if (nextsymbol() == '%') { /* use a string */
skipsymbol();
for (p=0;;) {
ch = onecase[nextsymbol()];
if ((('a' <= ch) && (ch <= 'z')) ||
((p > 0) && ('0' <= ch) && (ch <= '9'))) {
ident[p++] = ch; skipsymbol();
} else break;
}
if (p == 0) return(SYNTAXERROR);
ident[p] = 0;
q = lookup(0);
if (q < 0) return(8); /* not known */
switch(string[q].ll) {
case 0: /* ordinary */
if (string[q].lp == 0) return(8); /* string has name but */
/* no value, ie %z initially */
break;
case 1: /* fixed fn */
if (string[q].lp != 0) break;
case 2: /* variable fn */
vstring(q, &w[0]);
n = strlen(w);
if ((wsp+n) >= wse) extendwork("eval fn");
string[q].lp = wsp;
move(n, &w[0], wsp); wsp = wsp + n;
string[q].rp = wsp - 1;
break;
}
txt = (struct cell *)newcell();
move(8, &string[q].lp, &txt->lp);
return(0);
}
if (nextsymbol() == '#') { /* loop counter */
skipsymbol();
ch = nextsymbol();
if ((ch < '0') || (ch > '9')) n = 1;
else {if (readi(&n) == 0) return(SYNTAXERROR);}
if ((n < 1) || (n > level)) return(9);
if (wsp+2 >= wse) extendwork("counter");
txt = (struct cell *)newcell();
txt->lp = wsp;
byteinteger[wsp++] = 1;
txt->rp = wsp;
byteinteger[wsp++] = n;
return(0);
}
if (nextsymbol() == '<') {marker = '>'; ch = 0;}
else {
marker = readsymbol();
if ((marker != '.') && (marker != '/') && (marker != '?')) return(SYNTAXERROR);
ch = nextsymbol();
if (ch == marker) {
skippedch = readsymbol();
if (nextsymbol() != marker) return(SYNTAXERROR);
}
}
w[0] = marker; w[1] = ':'; w[2] = 0;
strcpy(prompt_string, w);
txt = (struct cell *)newcell();
txt->lp = wsp;
for(;;) {
skippedch = readsymbol();
for (;;) {
if (wsp == wse) extendwork("readtext");
if ((marker == '?') || ((marker == '>') && (ch == 0)) ||
(ch >= 32) || (((1<<ch) & cch) != 0)) byteinteger[wsp++] = ch;
for (;;) {
ch = readsymbol();
if ((marker != '>') || ((ch != NL) && (ch != ' '))) break;
}
if (ch == marker) break;
}
ch = nextsymbol();
if (ch != marker) break;
}
txt->rp = wsp - 1;
if (level == 0) strcpy(prompt_string, prstring);
else strcpy(prompt_string, "):");
if (marker != '>') move(8, &txt->lp, &string[0].lp);
return(0);
} /* readtext */
/*----------------------------------------------------------------------*/
readi(n) int *n; { /* 847 */
int i, j, k, pm;
for (;;) {
i = readsymbol();
if (i > SP) break;
}
pm = 1;
if (i == '-') pm = -1;
if ((i == '-') || (i == '+')) i = readsymbol();
if (i == '*') {j = 1; k = MAXI;
} else {
j = k = 0;
for (;;) {
if ((i < '0') || (i > '9')) break;
k = 10 * k + i - '0';
if (k > MAXI) return(0);
if (j != 0) skipsymbol();
else j = 1;
i = nextsymbol();
while (i == ' ') {
skipsymbol();
i = nextsymbol();
}
}
}
*n = k * pm;
return(j);
} /* readi */
/*----------------------------------------------------------------------*/
maptxt(adr) int adr; { /* 873 */
int d, q;
char s[MAXPATHLEN+1];
struct ff f;
if (adr < 0) adr = -adr;
txt = (struct cell *)adr;
d = txt->lp;
q = byteinteger[d];
if (q == 1) { /* # = loop counter */
sprintf(s, "%d", count[byteinteger[d+1]]);
q = strlen(s);
if ((wsp + q) >= wse) extendwork("eval counter");
txt = (struct cell *)newcell();
txt->lp = wsp;
txt->rp = wsp + q - 1;
strncpy(wsp, s, q);
wsp = wsp + q;
return(1);
}
if (q == 0) { /* a filename */
q = txt->rp - d; /* length of name */
strncpy(s, d+1, q);
s[q] = 0;
expand_filename(s);
if (strcmp(s, newf) == 0) {
printf("Inconsistent file use\n");
return(0);
}
for (q=0; q<=fileusedcount; q++) {
if (strcmp(s, fileused[q]) == 0) {
/* printf("file %s already known\n", s); */
txt->lp = start_address[q];
txt->rp = end_address[q];
return(1);
}
}
/* not already known */
strcpy(f.file, s);
q = emasconnect(&f);
if (q != 0) return(0);
txt->lp = f.start;
txt->rp = f.end - 1;
if ((fileusedcount+1) < MAXFILE) { /* put in table */
/* printf("file %s added to table\n", s); */
strcpy(fileused[++fileusedcount], s);
start_address[fileusedcount] = txt->lp;
end_address[fileusedcount] = txt->rp;
}
return(1);
}
if (txt->rp < d) return(0);
return(1);
} /* maptxt */
/*----------------------------------------------------------------------*/
separate() { /* 926 */
new = (struct cell *)newcell();
integer[(cur->ll + 12)>>2] = (int)&new->ll;
new->ll = cur->ll;
new->lp = cur->lp;
new->rp = curp - 1;
cur->lp = curp;
cur->ll = (int)&new->ll;
new->rl = (int)&cur->ll;
altered++;
} /* separate */
/*----------------------------------------------------------------------*/
hsave() { /* 944 */
int i;
struct cell *work, *last, *acopy;
if (haltered < altered) {
returnlist(htop->rl, &hbot->ll);
i = top->rl; last = (struct cell *)&htop->ll;
for(;;) {
acopy = (struct cell *)i;
if (&acopy->ll == &bot->ll) break;
work = (struct cell *)newcell();
last->rl = (int)&work->ll;
work->ll = (int)&last->ll;
work->lp = acopy->lp;
work->rp = acopy->rp;
i = acopy->rl;
if (&acopy->ll == &cur->ll) {
hcur = (struct cell *)&work->ll;
scur = (struct cell *)&cur->ll;
hcurp = curp;
}
last = (struct cell *)&work->ll;
}
if (&cur->ll == &bot->ll) {
hcur = (struct cell *)&hbot->ll;
scur = (struct cell *)&cur->ll;
hcurp = curp;
}
hbot->ll = (int)&last->ll;
last->rl = (int)&hbot->ll;
haltered = altered;
return;
}
if (&scur->ll != &cur->ll) {
acopy = (struct cell *)&top->ll;
work = (struct cell *)&htop->ll;
for (;;) {
if (&acopy->ll == &cur->ll) break;
acopy = (struct cell *)acopy->rl;
work = (struct cell *)work->rl;
}
hcur = (struct cell *)&work->ll;
scur = (struct cell *)&cur->ll;
}
hcurp = curp;
} /* hsave */
/*----------------------------------------------------------------------*/
hrestore() { /* 995 */
int i, j;
struct cell *work, *last, *copy;
seta = 0;
returnlist(top->rl, &bot->ll);
last = (struct cell *)&top->ll;
i = htop->rl;
for (;;) {
copy = (struct cell *)i;
if (i == (int)&hbot->ll) break;
j = newcell();
last->rl = j;
work = (struct cell *)j;
work->ll = (int)&last->ll;
work->lp = copy->lp;
work->rp = copy->rp;
i = copy->rl;
if ((work->lp == 0) && (work->rp == 0)) {
set = (struct cell *)&work->ll;
seta = j;
}
if ((int)©->ll == (int)&hcur->ll) {
cur = (struct cell *)&work->ll;
scur = (struct cell *)&work->ll;
curp = hcurp;
}
last = (struct cell *)&work->ll;
}
if ((int)&hcur->ll == (int)&hbot->ll) {
cur = (struct cell *)&bot->ll;
scur = (struct cell *)&bot->ll;
curp = hcurp;
}
last->rl = bota;
bot->ll = (int)&last->ll;
altered = haltered;
} /* hrestore */
/*----------------------------------------------------------------------*/
insert() { /* 1025 */
int new, prev, ac;
if ((txt->lp != 0) || (txt->rp != 0)) changed = 1;
altered++;
if (curp != cur->lp) separate();
ac = (int)&cur->ll;
prev = integer[ac>>2];
new = (int)&txt->ll;
integer[ac>>2] = new;
integer[(prev+12)>>2] = new;
integer[new>>2] = prev;
integer[(new+12)>>2] = ac;
} /* insert */
/*----------------------------------------------------------------------*/
find() { /* 1045 */
int i;
beg = (struct cell *) (int) &cur->ll;
begp = curp;
i = ccase[byteinteger[txt->lp]];
thestart: if (begp == 0) return(0);
again: if (ccase[byteinteger[begp]] == i) goto imp1;
begp++;
if (begp <= beg->rp) goto again;
beg = (struct cell *)beg->rl;
begp = beg->lp;
goto thestart;
imp1: edit_end = (struct cell *) (int) &beg->ll;
endp = begp;
txtp = txt->lp;
for(;;) {
if (caseind == 0) {
if (byteinteger[endp] != byteinteger[txtp]) break;
} else {
if (ccase[byteinteger[endp]] != ccase[byteinteger[txtp]]) break;
}
endp++;
if (endp > edit_end->rp) {
edit_end = (struct cell *) edit_end->rl;
endp = edit_end->lp;
}
if (txtp == txt->rp) return(1);
txtp++;
if (endp == 0) {
beg = (struct cell *) (int) &edit_end->ll;
begp = 0;
return(0);
}
}
begp++;
if (begp > beg->rp) {
beg = (struct cell *)beg->rl;
begp = beg->lp;
goto thestart;
}
goto again;
} /* find */
/*----------------------------------------------------------------------*/
findb() { /* 1104 */
int last;
edit_end = (struct cell *) (int) &cur->ll;
endp = curp;
last = ccase[byteinteger[txt->rp]];
for (;;) {
for (;;) {
if (endp == edit_end->lp) {
if (integer[(edit_end->ll+8)>>2] == 0) {
beg = (struct cell *) (int) &edit_end->ll;
begp = endp;
return(0);
}
edit_end = (struct cell *) edit_end->ll;
endp = edit_end->rp;
} else endp--;
if (ccase[byteinteger[endp]] == last) break;
}
beg = (struct cell *) (int) &edit_end->ll;
begp = endp;
txtp = txt->rp;
for (;;) {
if (txtp <= txt->lp) {
endp++;
if (endp > edit_end->rp) {
edit_end = (struct cell *) edit_end->rl;
endp = edit_end->lp;
}
return(1);
}
begp--;
if (begp <beg->lp) {
if (integer[(beg->ll+8)>>2] == 0) {
begp = beg->lp;
return(0);
}
beg = (struct cell *) beg->ll;
begp = beg->rp;
}
txtp--;
if (ccase[byteinteger[txtp]] != ccase[byteinteger[begp]]) break;
}
}
} /* findb */
/*----------------------------------------------------------------------*/
delete() { /* 1156 */
int i;
changed = 1;
altered++;
if ((int)&beg->ll == (int)&edit_end->ll) {
if (begp == endp) return;
if (begp == beg->lp) {
beg->lp = endp;
} else {
edit_end = (struct cell *)newcell();
edit_end->rl = beg->rl;
integer[(edit_end->rl)>>2] = (int)&edit_end->ll;
edit_end->rp = beg->rp;
edit_end->lp = endp;
edit_end->ll = (int)&beg->ll;
beg->rl = (int)&edit_end->ll;
beg->rp = begp - 1;
}
} else {
i = beg->rl;
while (i != (int)&edit_end->ll) i = returncell(i);
beg->rl = i;
edit_end->ll = (int)&beg->ll;
edit_end->lp = endp;
if (begp == beg->lp) {
edit_end->ll = beg->ll;
if (edit_end->ll != 0) integer[(edit_end->ll + 12)>>2] = i;
i = returncell(&beg->ll);
} else {
beg->rp = begp - 1;
}
}
cur = (struct cell *)&edit_end->ll;
curp = endp;
} /* delete */
/*----------------------------------------------------------------------*/
printtext() { /* 1201 */
int i, j, x;
char w[3];
j = 0; w[1] = 0;
if (begp == beg->lp) {
if (beg->ll == topa) printf("*T*\n");
if (beg->ll == seta) printf("*S*\n");
}
for(;;) {
if ((begp == curp) && (&beg->ll == &cur->ll)) printf("^");
if ((begp == endp) && (&beg->ll == &edit_end->ll)) {
if (begp == 0) {
x = (int)&beg->ll;
if (x == seta) printf("*S*\n");
if (x == bota) printf("*B*\n");
}
return;
}
w[0] = byteinteger[begp];
printf("%s", w);
if (w[0] == NL) nlc++;
begp++;
if (begp > beg->rp) {
beg = (struct cell *) beg->rl;
begp = beg->lp;
}
}
} /* printtext */
/*----------------------------------------------------------------------*/
charson(n) int n; { /* 1236 */
int len;
edit_end = (struct cell *) &cur->ll;
endp = curp;
while (endp != 0) {
len = edit_end->rp - endp;
if (n <= len) {endp = endp + n; return(1);} /* found OK */
n = n - (len+1);
edit_end = (struct cell *) edit_end->rl;
endp = edit_end->lp;
if (n == 0) return(1); /* hit *S* or *B* exactly (it says) */
}
return(0); /* hit *S* or *B* */
} /* charson */
/*----------------------------------------------------------------------*/
lineson(n) int n; { /* 1253 */
int i; /* moves end,endp forward from cur,curp */
if (n == MAXI) return(charson(n));
edit_end = (struct cell *) &cur->ll;
endp = curp;
i = 0;
for(;;) {
if (i == n) return(1);
if (endp == 0) return(0);
if (byteinteger[endp] == NL) i++;
endp++;
if (endp > edit_end->rp) {
edit_end = (struct cell *) edit_end->rl;
endp = edit_end->lp;
}
}
} /* lineson */
/*----------------------------------------------------------------------*/
charsback(n) int n; { /* 1274 */
int len;
beg = (struct cell *) &cur->ll;
begp = curp;
for(;;){
len = begp - beg->lp;
if (len >= n) {
begp = begp - n;
return(1);
}
begp = beg->lp;
n = n - (len+1);
if (integer[(beg->ll+8)>>2] == 0) return(0);
beg = (struct cell *) beg->ll;
begp = beg->rp;
}
} /* charsback */
/*----------------------------------------------------------------------*/
linesback(n) int n; { /* 1292 */
int i, j;
if (n == MAXI) return(charsback(n));
j = (int)&cur->ll;
beg = (struct cell *)j;
begp = curp;
i = -1;
for (;;) {
if (begp == beg->lp) {
if (integer[(beg->ll+8)>>2] == 0) {
if (i = (n-1)) return(1); else return(0);
}
beg = (struct cell *)beg->ll;
begp = beg->rp;
} else begp--;
if (byteinteger[begp] == NL) i++;
if (i == n) break;
}
begp++;
if (begp > beg->rp) {
beg = (struct cell *) beg->rl;
begp = beg->lp;
}
return(1);
} /* linesback */
/*----------------------------------------------------------------------*/
position(n) int n; { /* 1316 */
int i;
n--;
if (n < 0) n = 0;
if (n > 132) n = 132;
i = linesback(0);
i = 0;
for (;;) {
if (i == n) {
cur = (struct cell *)&beg->ll;
curp = begp;
return;
}
if ((begp == 0) || (byteinteger[begp] == NL)) {
if (begp != 0) {
edit_end = (struct cell *)&beg->ll;
endp = begp + 1;
if (endp > edit_end->rp) {
edit_end = (struct cell *)edit_end->rl;
endp = edit_end->lp;
}
}
cur = (struct cell *)&beg->ll;
curp = begp;
txt = (struct cell *)newcell();
txt->ll = 0;
txt->lp = (int)&sps[0];
txt->rp = txt->lp + n - i - 1;
txt->rl = 0;
insert();
return;
}
begp++;
i++;
if (begp > beg->rp) {
beg = (struct cell *)beg->rl;
begp = beg->lp;
}
}
} /* position */
/*----------------------------------------------------------------------*/
killpart() { /* 1356 */
int j;
/* printf("-> killpart "); diagnostic(3); */
altered++;
integer[(set->ll + 12)>>2] = set->rl;
integer[set->rl>>2] = set->ll;
if ((int)&cur->ll == seta) {
cur = (struct cell *)cur->rl;
curp = cur->lp;
}
j = returncell(seta);
seta = 0;
} /* killpart */
/*----------------------------------------------------------------------*/
extract(adr) int adr; { /* 1369 */
int n, j, k, mod, desc, flag, wp;
char file[MAXPATHLEN+1], com[256], dev[32], junk[2], tab[2], doubleq[2];
struct cell *w;
char errtxt[128];
if (curp == 0) return;
txt = (struct cell *)adr;
j = txt->rp - txt->lp;
if (j == 0) {
printf("No destination specified\n");
return;
}
strncpy(file, txt->lp+1, j); file[j] = 0;
if (file[0] == '%') {
k = 0;
for (j=1;;) {
if ((ident[k++] = onecase[file[j++]]) == 0) break;
}
j = lookup(YES);
if (j < 0) return;
string[j].ll = 0; /* ordinary string */
string[j].lp = wsp;
n = 0; w = (struct cell *)&cur->ll; wp = curp;
while (wp != 0) {
k = w->rp - wp + 1;
w = (struct cell *)w->rl;
if ((n == 0) && (w->lp == 0)) { /* only one cell */
string[j].lp = wp;
string[j].rp = wp + k - 1;
return;
}
if ((wsp+k) >= wse) extendwork("extract");
move(k, wp, wsp); wsp = wsp + k;
wp = w->lp;
n++;
}
string[j].rp = wsp - 1;
return;
}
mod = O_TRUNC; com[0] = 0;
if (file[0] == '.') {
strres(file, junk, ".", dev);
if (strcmp(dev, "lp") == 0) strcpy(com, "lpr ");
else {
strcpy(com, "lpr -P");
tab[0] = 9; tab[1] = 0; doubleq[0] = 34; doubleq[1] = 0;
sprintf(file, "printers | grep -s %s^%s%s\\\\*%s",
doubleq, dev, tab, doubleq);
if (system(file) == 0) strcpy(com, "edlpr -P");
}
strcpy(file, PSEUDX); mktemp(file);
sprintf(com, "%s%s %s", com, dev, file);
printf("com=%s\n", com);
} else {
if (j > 4) {
if ((onecase[file[j-1]] == 'D') &&
(onecase[file[j-2]] == 'O') &&
(onecase[file[j-3]] == 'M') &&
(file[j-4] == '-')) {file[j-4] = 0; mod = O_APPEND;}
}
expand_filename(file);
/* this bit not required
for (j=0; j<=fileusedcount; j++) {
if (strcmp(file, fileused[j]) == 0) {
printf("File currently in use\n");
return;
}
}
*/
}
desc = open(file, O_WRONLY | O_CREAT | mod, 0664);
if (desc < 0) {
textof(errno, errtxt);
printf("edit failed to open %s: %s\n", file, errtxt);
return;
}
w = (struct cell *)&cur->ll; wp = curp;
while (wp != 0) {
flag = write(desc, wp, w->rp - wp + 1);
if (flag < 0) {
textof(errno, txt);
printf("edit failed to write to %s: %s\n", file, txt);
return;
}
w = (struct cell *)w->rl; wp = w->lp;
}
close(desc);
if (com[0] != 0) system(com);
} /* extract */
/*----------------------------------------------------------------------*/
replace () { /* 1419 */
if (begp != beg->lp) {
cur = (struct cell *)&beg->ll;
curp = begp;
separate();
}
cur = (struct cell *)&edit_end->ll;
curp = endp;
if (endp == edit_end->lp) {
new = (struct cell *)cur->ll;
} else {
separate();
if ((int)&beg->ll == (int)&edit_end->ll) beg = (struct cell *)&new->ll;
}
if (((int)&beg->ll != (int)&bot->ll) && ((int)&new->ll != (int)&top->ll)) {
changed = 1;
altered++;
cur->ll = beg->ll;
integer[(beg->ll+12)>>2] = new->rl;
beg->ll = set->ll;
integer[(set->ll+12)>>2] = (int)&beg->ll;
new->rl = seta;
set->ll = (int)&new->ll;
}
} /* replace */
/*----------------------------------------------------------------------*/
insertats() {
/* inserts txt before separator */
txt->ll = set->ll;
txt->rl = seta;
integer[(set->ll+12)>>2] = (int)&txt->ll;
set->ll = (int)&txt->ll;
} /* insertats */
/*-------------------------*/
copychain() {
int lp, rl;
/* printf("-> copychain "); diagnostic(3); */
changed = 1; altered++;
if (((int)&beg->ll == (int)&edit_end->ll) /* only one cell in chain */
&& (begp == endp)) return; /* nothing to copy */
lp = begp;
for (;;) {
txt = (struct cell *)newcell();
txt->lp = lp;
if ((int)&beg->ll == (int)&edit_end->ll) {
txt->rp = endp - 1;
lp = -1;
} else txt->rp = beg->rp;
rl = beg->rl;
insertats();
if (lp < 0) break;
beg = (struct cell *)rl;
lp = beg->lp;
if (lp == 0) break; /* reached *S* or *B* */
}
} /* copychain */
/*-----------------------------------*/
copy(i) int i; { /* 1443 */
txt = (struct cell *)newcell();
move(16, i, &txt->ll);
} /* copy */
/*----------------------------------------------------------------------*/
insertsp(after, last) int after, *last; { /* 1677 */
int k;
k = *last;
k = k + 2;
for (; k >= after+1; k--) cline[k] = cline[k-1];
(*last)++;
} /* insertsp */
/*----------------------------------------------------------------------*/
just(line, first, last, desired, ss) int line, first, last, desired, ss; { /* 1627 */
int gaps, needed, i, flip, sgaps, sym;
needed = desired - last;
gaps = 0;
sgaps = 0;
if (needed <= 0) return(last+1);
for (i=first+1; i <= last; i++) {
if (cline[i] == SP) {
sym = cline[i-1];
if (sym != SP) gaps++;
if ((sym == '.') || (sym == ',') || (sym == ';') || (sym == '!')
|| (sym == '?')) sgaps++;
}
}
if (gaps == 0) return(last+1);
if ((ss == 0) && (sgaps > 0)) {
i = first + 1;
for (;;) {
if (cline[i] == SP) {
sym = cline[i-1];
if ((sym == '.') || (sym == ',') || (sym == ';')
|| (sym == '?') || (sym == '!')) {
insertsp(i, &last);
sgaps--;
needed--;
if ((needed > 0) && (needed > sgaps)) {
insertsp(i, &last);
needed--;
}
if (needed <= 0) return(last+1);
}
}
i++;
if ((i >= last) || (sgaps <= 0)) break;
}
}
if ((line & 1) != 0) {
flip = -1;
i = last;
} else {
flip = 1;
i = first + 1;
}
for (;;) {
if ((cline[i] == SP) && (cline[i-1] != SP)) {
insertsp(i, &last);
i = i + flip;
needed--;
if (needed <= 0) return(last+1);
}
i = i + flip;
if ((i <= first) || (i >= last)) break;
}
return(just(line, first, last, desired, 1));
} /* just */
/*----------------------------------------------------------------------*/
adjustline(last) int last; { /* 1567 */
int i, j, xcurp;
struct cell *xcur;
if ((int)&cur->ll == (int)&pbot->ll) return(last);
if ((sym == NL) && (linel <= last) && (last <= (linel+1))) return(last);
if (last >= linel) {
i = last + 1;
while (i > firstpos) {
if (cline[i] == ' ') break;
i--;
}
if (i == firstpos) {
cline[last+1] = NL;
return(last+1);
}
j = charsback(last-i+1);
cline[i] = NL;
cur = (struct cell *)&beg->ll;
curp = begp;
return(i);
}
xcur = (struct cell *)&cur->ll;
xcurp = curp;
j = byteinteger[curp];
while ((j == ' ') || (j == NL)) {
if (curp < cur->rp) {
curp++;
} else {
cur = (struct cell *)cur->rl;
curp = cur->lp;
if ((int)&cur->ll == (int)&pbot->ll) goto miss;
}
j = byteinteger[curp];
}
i = last + 1;
for (;;) {
j = byteinteger[curp];
if ((j == ' ') || (j == NL)) break;
cline[i] = j;
if (i > linel) goto miss;
i++;
if (curp < cur->rp) {
curp++;
} else {
cur = (struct cell *)cur->rl;
curp = cur->lp;
if ((int)&cur->ll == (int)&pbot->ll) {
cline[last] = SP;
return(i-1);
}
}
}
cline[last] = SP;
cline[i] = NL;
sym = NL;
return(adjustline(i));
miss:
cur = (struct cell *)&xcur->ll;
curp = xcurp;
return(last);
} /* adjustline */
/*----------------------------------------------------------------------*/
layout(param, justify) int param, justify; { /* 1448 */
/*
NB some variables made global:
linel, sym, firstpos, ptop, pbot, cline
*/
int linest, parast, i, j, ptopp, line, n, scurp;
struct cell *scur;
linest = param / 100000;
parast = (param - (100000*linest)) / 1000;
linel = param - (100000*linest) - (1000*parast);
if (linel == 0) linel = slinel;
if (linest == 0) linest = slinest;
if (parast == 0) parast = sparast;
slinel = linel; slinest = linest; sparast = parast;
/* printf("linel=%d, linest=%d, parast=%d\n", linel, linest, parast); */
txt = (struct cell *)newcell();
txt->lp = (int)&nls[0]; /* double NL */
txt->rp = (int)&nls[1];
i = find();
cur = (struct cell *)&beg->ll;
curp = begp;
edit_end = (struct cell *)&cur->ll;
endp = curp;
for (;;) {
if (charsback(1) == 0) break;
if (byteinteger[begp] != SP) break;
delete();
}
cur = (struct cell *)&edit_end->ll;
curp = endp;
txt->ll = txt->lp = txt->rp = txt->rl = 0; insert();
pbot = (struct cell *)&txt->ll;
cur = (struct cell *)&pbot->ll;
curp = cur->rp;
txt = (struct cell *)newcell();
txt->lp = (int)&nls[0];
txt->rp = (int)&nls[1];
i = findb();
ptop = (struct cell *)&edit_end->ll;
ptopp = endp;
cur = (struct cell *)&ptop->ll;
curp = ptopp;
i = returncell(&txt->ll);
line = 0;
for (;;) {
line++;
if (line == 1) i = parast; else i = linest;
j = i - 1;
while (j >= 1) {
cline[j] = SP;
j--;
}
firstpos = i;
if ((int)&cur->ll == (int)&pbot->ll) break;
scur = (struct cell *)&cur->ll;
scurp = curp;
for (;;) {
i = byteinteger[curp];
if ((i != SP) && (i != NL)) break;
if (curp < cur->rp) {
curp++;
} else {
cur = (struct cell *)cur->rl;
curp = cur->lp;
if ((int)&cur->ll == (int)&pbot->ll) goto wayout;
}
}
n = firstpos;
for (;;) {
sym = byteinteger[curp];
if ((justify == 0) || (n <= firstpos) || (cline[n-1] != SP)
|| (sym != SP)) cline[n++] = sym;
if (curp < cur->rp) {
curp++;
} else {
cur = (struct cell *)cur->rl;
curp = cur->lp;
}
while ((sym == NL) && (n > (firstpos+1)) && (cline[n-2] == SP)) {
n--;
cline[n-1] = NL;
}
if ((sym == NL) || (n > linel+1) || ((int)&cur->ll == (int)&pbot->ll)) break;
}
j = adjustline(n-1);
i = firstpos;
if (i < linest) i = linest;
if ((justify != 0) && ((int)&cur->ll != (int)&pbot->ll)) j = just(line, i, j-1, linel, 0);
beg = (struct cell *)&scur->ll;
begp = scurp;
edit_end = (struct cell *)&cur->ll;
endp = curp;
delete();
if (j < firstpos) break;
txt = (struct cell *)newcell();
txt->lp = wsp;
for (i=1; i <= j; i++) {
byteinteger[wsp++] = cline[i];
}
txt->rp = wsp - 1;
insert();
}
wayout:
scur = (struct cell *)pbot->ll;
scur->rl = pbot->rl;
cur = (struct cell *)pbot->rl;
cur->ll = pbot->ll;
curp = cur->lp;
i = returncell(&pbot->ll);
i = charson(2);
cur = (struct cell *)&edit_end->ll;
curp = endp;
return(i);
} /* layout */
/*----------------------------------------------------------------------*/
initdict() { /* 1687 */
int j;
struct ff f;
strcpy(f.file, SYSDICTNAME);
if (exist(f.file) == 0) {
printf("sysdict %s does not exist\n", f.file);
sysdicta = -1;
} else {
expand_filename(f.file);
j = emasconnect(&f);
if (j == 0) {
sysdicta = f.start;
sysdictb = f.size * 8;
/* printf("%s emasconnected, size=%d\n", f.file, f.size); */
} else printf("could not emasconnect sysdict %s\n", f.file);
}
if (exist(PRIVDICTNAME) == 0) {
privdicta = calloc(1, MAXPDICT);
privdictb = MAXPDICT * 8;
} else {
strcpy(f.file, PRIVDICTNAME);
expand_filename(f.file);
j = emasconnect(&f);
if (j == 0) {
privdicta = f.start;
privdictb = f.size * 8;
/* printf("%s emasconnected, size=%d\n", f.file, f.size); */
}
}
wsp = (wsp + 3) & (-4);
tempdicta = wsp;
tempdictb = 4096 * 8;
if (wsp + 4096 > wse) extendwork("init dict");
for (j=0; j<1024; j++) {integer[wsp>>2] = 0; wsp = wsp + 4;}
/* printf("dictionaries initialised\n"); */
return(0);
} /* initdict */
/*----------------------------------------------------------------------*/
nextword() { /* 1734 */
int ch, len;
if (curp == 0) return(0);
ch = byteinteger[curp] & 127;
while (spellch[ch] > 0) {
if (charsback(1) == 0) break;
cur = (struct cell *)&beg->ll;
curp = begp;
ch = byteinteger[curp] & 127;
}
for (;;) {
ch = byteinteger[curp] & 127;
if ((65 <= spellch[ch]) && (spellch[ch] <= 90)) break;
if (curp < cur->rp) {
curp++;
} else {
cur = (struct cell *)cur->rl;
curp = cur->lp;
if (curp == 0) return(0);
}
}
len = 0;
for (;;) {
ch = byteinteger[curp] & 127;
if (spellch[ch] == 0) break;
word[len++] = spellch[ch];
if (len > 31) break;
if (curp < cur->rp) {
curp++;
} else {
cur = (struct cell *)cur->rl;
curp = cur->lp;
if (curp == 0) break;
}
}
if (len == 1) return(nextword());
word[len] = 0;
wordm1 = len;
return(1);
} /* nextword */
/*----------------------------------------------------------------------*/
sethashes() { /* 1777 */
int i, j;
static int hconsts[] = {0, 1,
997, 47, 2897, 19, 937, 2203,
311, 1019, 23, 3041, 823, 227,
2239, 211, 3181, 197, 3889,
191, 2447, 179, 2153, 167, 163,
3121, 2213, 149, 139, 2551, 131,
3947, 113, 2707, 107, 103, 3109, 97,
2647, 83, 79, 3797, 71, 2333,
61, 3517, 53, 43, 3821, 37,
31, 29, 17, 13, 11,
7, 5};
for (i=1; i<=MAXHASH; i++) {
hash[i] = 0;
for (j=0; word[j]!=0; j++) {
hash[i] = hash[i] + word[j] * hconsts[(j+2*i)];
}
}
} /* sethashes */
/*----------------------------------------------------------------------*/
dictlookup() { /* 1799 */
int i, j, found;
if (sysdicta > 0) {
found = 1;
for (i=1; i<=MAXHASH; i++) {
j = hash[i];
j = j - (j / sysdictb) * sysdictb;
if ((byteinteger[sysdicta+(j>>3)] & (128>>(j&7))) == 0) {
found = 0;
break;
}
}
if (found != 0) return(found);
}
if (privdicta > 0) {
found = 2;
for (i=1; i<=MAXHASH; i++) {
j = hash[i];
j = j - (j / privdictb) * privdictb;
if ((byteinteger[privdicta+(j>>3)] & (128>>(j&7))) == 0) {
found = 0;
break;
}
}
if (found != 0) return(found);
}
found = 3;
for (i=1; i<=MAXHASH; i++) {
j = hash[i];
j = j - (j / tempdictb) * tempdictb;
if ((byteinteger[tempdicta+(j>>3)] & (128>>(j&7))) == 0) {
found = 0;
break;
}
}
return(found);
} /* dictlookup */
/*----------------------------------------------------------------------*/
enter() { /* 1828 */
int i, j;
if (privdicta > 0) {
for (i=1; i<=MAXHASH; i++) {
j = hash[i];
j = j - (j / privdictb) * privdictb;
byteinteger[privdicta+(j>>3)] = (byteinteger[privdicta+(j>>3)] | (128>>(j&7)));
}
privdict_changed = YES;
}
} /* enter */
/*----------------------------------------------------------------------*/
entertemp() { /* 1840 */
int i, j;
for (i=1; i<=MAXHASH; i++) {
j = hash[i];
j = j - (j / tempdictb) * tempdictb;
byteinteger[tempdicta+(j>>3)] = (byteinteger[tempdicta+(j>>3)] | (128>>(j&7)));
}
} /* entertemp */
/*----------------------------------------------------------------------*/
extendwork(s) char *s; { /* 1853 */
printf("\nWorkspace Full, called from %s\nEdit:e invoked\n", s);
diagnostic(3); help(3);
editexit(0);
exit(0);
} /* extendwork */
/*----------------------------------------------------------------------*/
readcstring() { /* 1868 */
int i, sym, j, k, err, n, def, cflags, parval, lrptr, ch, len, lp;
char loopback[41], line[80];
lcomp = comp;
comp = level = hset = nlc = linecomplete = 0;
goto normal;
re_enter:
strcpy(prompt_string, "):");
level++;
loopback[level] = comp;
normal:
while (linecomplete == 0) {
for (;;) {
sym = nextsymbol();
if (('a' <= sym) && (sym <= 'z')) sym = sym - 32;
j = chartype1[sym&127];
if ((j != 0) && (j != SP)) break;
skipsymbol();
}
err = SYNTAXERROR;
/* printf("stype(%d)\n", j); */
switch(j) { /* FIRSTSWITCH */
case TEXTCHAR:
case FILECHAR:
case FILEEND:
case MINUS:
case NONNULL:
skipsymbol();
break;
case NUMCHAR:
if ((comp == 0) && (lcomp > 1) && (readi(&i) > 0) && (nextsymbol() == NL)) {
currcomp = (struct cform *) &clist[lcomp-2].lett;
if (currcomp->lett == ']')
comp = lcomp -1;
else {
currcomp = (struct cform *) &clist[lcomp-1].lett;
comp = lcomp;
}
currcomp->flags = 0;
currcomp->level = 0;
currcomp->swno = 0;
currcomp->errno = 0;
currcomp->loop = 0;
currcomp->count = 0;
currcomp->lett = ']';
currcomp->par = i;
err = 0;
}
break;
case SHRIEK:
if (input_pointer > 0) {skipsymbol(); break;}
n = 0;
for (;;) {
skipsymbol();
j = nextsymbol();
if (j == NL) break;
line[n++] = j;
}
line[n] = 0;
skipsymbol();
system(line);
err = 0;
break;
case NL:
skipsymbol();
err = 0;
if ((level > 0) || (comp == 0)) break;
goodcommand('P', NUMPAR, 1);
linecomplete = 1;
break;
case LOOPEND:
skipsymbol();
if (level == 0) break;
if (loopback[level] >= comp) break;
if (readi(&i) > 0) {
goodcommand(sym, 0, i);
currcomp->loop = loopback[level--];
goto backup;
}
err = INVALIDLOOP;
break;
case LOOPSTART:
skipsymbol();
goto re_enter;
backup:
if (level == 0) strcpy(prompt_string, prstring);
if (i < 0) return(i);
err = 0;
break;
case COMMAND:
skipsymbol();
if (sym == '%') {
sym = FIRSTCOM;
for (j=0;;) {
ch = onecase[nextsymbol()];
if ((('a' <= ch) && (ch <= 'z')) ||
((j>0) && ('0' <= ch) && (ch <= '9'))) {
ident[j++] = ch;
skipsymbol();
} else break;
}
if (j == 0) break;
ident[j] = 0;
if ((ch = lookup(1)) < 0) break;
while (nextsymbol() == SP) skipsymbol();
if (nextsymbol() != '=') { /* %name */
if ((lp = string[ch].lp) == 0) {err=8; break;} /* unassigned */
len = string[ch].rp - lp + 1;
k = strlen(inputline);
n = k - input_pointer;
/* printf("was: %s", inputline); */
for (j=0; j<=n; j++) inputline[k+len-j] = inputline[k-j];
for (j=0; j<len; j++) inputline[input_pointer+j] = byteinteger[lp+j];
/* printf(" is: %s", inputline); */
err = 0; break;
} else skipsymbol();
}
def = comdef[sym - FIRSTCOM];
lrptr = (def >> 12) & 15;
cflags = def & (STOPSPELL | NEEDSS);
parval = 0;
if ((emode != 0) && ((def & NOTINLOOK) != 0)) {
err = CHINLOOK;
break;
}
if ((def & ALLPAR) == 0) goto noparam;
for(;;) { /* a parameter required */
k = nextsymbol();
if ((k == NL) || (k > SP)) break;
skipsymbol();
}
j = chartype2[k & 127];
if (j == MINUS) {
if ((def & BACKWARDS) == 0) break;
cflags = cflags | BACKWARDS;
for(;;) {
skipsymbol(); k = nextsymbol();
if ((k == NL) || (k > SP)) break;
}
j = chartype2[k & 127];
}
/* printf("sub(%d)\n", j); */
switch(j) { /* SECONDSWITCH */
case NL:
case LOOPSTART:
case LOOPEND:
case MINUS:
case SHRIEK:
case NONNULL:
case FILEEND:
case COMMAND:
if (sym != '?')
/* if ((def & NOTINLOOK) != 0) */ break; /* 'dangerous' commands */
case NUMCHAR:
if ((def & NUMPAR) == 0) break;
parval = 1; /* default */
if (j == NUMCHAR) readi(&parval);
if (((sym == 'L') || (sym == 'J')) && (parval != 0)) {
i = parval / 100000;
j = (parval - (100000*i)) / 1000;
k = parval - (100000*i) - (1000*j);
if (i == 0) i = slinest;
if (j == 0) j = sparast;
if (k == 0) k = slinel;
if (!((0<i)&&(i<k)&&(0<j)&&(j<k)&&(k<133)&&(j<51))) break;
}
cflags = cflags | NUMPAR;
goto noparam;
case TEXTCHAR:
if ((def & TEXTPAR) == 0) break;
if (sym == FIRSTCOM) {
if ((err = readtext()) != 0) break;
} else {
if (k == QUOTE) {
skipsymbol();
if (lastrec[lrptr].lp == 0) break;
copy(&lastrec[lrptr].ll);
} else {
if (k == DOUBLEQUOTE) {
skipsymbol();
if (lastrec[lrptr+8].lp == 0) break;
copy(&lastrec[lrptr+8].ll);
} else {
if ((err = readtext()) != 0) break;
move(16, &lastrec[lrptr].ll, &lastrec[lrptr+8].ll);
move(16, &txt->ll, &lastrec[lrptr].ll);
}
}
}
parval = (int)&txt->ll;
cflags = cflags | TEXTPAR;
goto noparam;
case FILECHAR:
if ((def & FILEPAR) == 0) break;
if ((err = readtext()) != 0) break;
cflags = cflags | FILEPAR;
parval = (int)&txt->ll;
noparam:
if ((def & SPECIAL) != 0) {
if (sym == 'H') hset = 1;
if ((sym == 'E') && (nextsymbol() != NL)) break;
if (sym == FIRSTCOM) { /* string assignment */
cflags = cflags | SPECIAL;
sym = ch;
}
}
goodcommand(sym, cflags, parval);
err = 0;
break;
} /* END OF SECONDSWITCH */
break;
} /* END OF FIRSTSWITCH */
if (err > 0) {
goodcommand(sym, ERROR, err);
goodcommand('P', NUMPAR, 1);
linecomplete = -1;
}
}
return(linecomplete);
} /* readcstring */
/*----------------------------------------------------------------------*/
goodcommand(sym, flags, param) int sym, flags, param; { /* 2049 */
int swno, i, lett;
if (comp > 99) {
printf("TOO MANY COMMANDS\n");
editexit(0);
exit(0);
}
if ((comp == 0) && (lcomp > 0)) {
i = 0;
for (;;) {
curcom = (struct cform *) &clist[i].lett;
/* printf("curcom->flags=%d\n", curcom->flags); */
if ((curcom->flags & (TEXTPAR | FILEPAR)) != 0) returncell(curcom->par);
i++;
if (i == lcomp) break;
}
lcomp = 0;
}
lett = sym;
if ((flags & SPECIAL) != 0) sym = FIRSTCOM;
if ((FIRSTCOM <= sym) && (sym <= LASTCOM)) swno = comdef[sym-FIRSTCOM] >> 16; else swno = 0;
if ((flags & (TEXTPAR|FILEPAR)) == 0) swno = swno >> 8;
currcomp = (struct cform *) &clist[comp++].lett;
currcomp->errno = currcomp->loop = currcomp->count = currcomp->par = 0;
currcomp->lett = lett;
currcomp->flags = flags;
if ((flags & ERROR) == 0) currcomp->par = param;
else currcomp->errno = param;
currcomp->level = level;
currcomp->swno = swno;
} /* goodcommand */
/*----------------------------------------------------------------------*/
ermess(n, lett) int n, lett; { /* 2093 */
char w[7], a[60], b[60], c[60];
static char *etext[] = {
"",
"Invalid loop repetition count",
"## not allowed when looking",
"Separator S not set for ##",
"Cannot create private lexicon",
"No word set up for Y command",
"No word set up for N command",
"Syntax error in command string",
"",
"Loop counter out of context"
};
if (n == 8) {
sprintf(a, "Variable %%%s not assigned", ident);
} else {
strcpy(a, etext[n]);
if (strres(a, b, "##", c) == 0) {
w[0] = lett; w[1] = 0;
sprintf(a, "%s%s%s", b, w, c);
}
}
printf("%s\n", a);
} /* ermess */
/*----------------------------------------------------------------------*/
initialise() { /* 2126 */
int flag;
struct ff f;
strcpy(prompt_string, prstring);
eterminate = 0;
while (fileusedcount >= 0) free(start_address[fileusedcount--]);
flag = checkff(&f);
if (flag == 0) {
bot = (struct cell *)newcell();
top = (struct cell *)newcell();
htop = (struct cell *)newcell();
hbot = (struct cell *)newcell();
htop->rl = (int)&hbot->ll;
hbot->ll = (int)&htop->ll;
bota = (int)&bot->ll;
top->rl = bota;
topa = (int)&top->ll;
bot->ll = topa;
cur = (struct cell *) &bot->ll;
curp = 0; altered = 0; presif_altered = 0; seta = 0;
if (f.end > f.start) {
txt = (struct cell *)newcell();
txt->lp = f.start;
txt->rp = f.end - 1;
insert();
cur = (struct cell *)top->rl;
curp = cur->lp;
}
changed = 0;
haltered = -1;
hsave();
/* dump(wsp0, 128);
dump(f.start, f.size); */
}
/* printf("Initialise, flag=%d\n", flag); */
return(flag);
} /* initialise */
/*----------------------------------------------------------------------*/
editexit(why) int why; { /* 2187 */
int filelength, adr, desc, flag, p, len, err;
char file[MAXPATHLEN+1], txt[MAXPATHLEN+1];
struct cell *loccur;
if (privdict_changed == YES) {
err = 1;
printf("privdict %s changed\n", PRIVDICTNAME);
strcpy(txt, PRIVDICTNAME); expand_filename(txt);
desc = creat(txt, 0664); /* read+write by owner */
if (desc > 0) {
flag = write(desc, privdicta, privdictb>>3);
if (flag >= 0) {
err = 0; close(desc);
privdict_changed = NO;
printf("privdict %s successfully written\n", PRIVDICTNAME);
} else printf("failed to write privdict %s\n", PRIVDICTNAME);
} else printf("failed to create privdict %s\n", PRIVDICTNAME);
if (err > 0) {textof(errno, txt); printf("%s\n", txt);}
}
if ((strcmp(newf, ".NULL") == 0) || ((changed == 0) &&
(strcmp(newf, oldf) == 0))) {
if (wseen > 0) eterminate = 1; /* completed */
else eterminate = 3; /* no changes */
return;
}
eterminate = 4; /* ***NOT*** completed */
if (seta != 0) killpart();
filelength = 0;
loccur = (struct cell *)top->rl;
while (loccur->lp != 0) {
filelength = filelength + loccur->rp - loccur->lp + 1;
loccur = (struct cell *)loccur->rl;
}
/* printf("filelength=%d\n", filelength); */
adr = calloc(1, filelength);
if (adr > 0) {
p = adr;
loccur = (struct cell *)top->rl;
while (loccur->lp != 0) {
len = loccur->rp - loccur->lp + 1;
move(len, loccur->lp, p);
p = p + len;
loccur = (struct cell *)returncell(&loccur->ll);
}
desc = creat(newf, 0664); /* read+write by owner */
if (desc > 0) {
flag = write(desc, adr, filelength);
if ((flag > 0) || (filelength == 0)) eterminate = 1;
else printf("edit failed to write to");
} else printf("edit failed to create");
if (eterminate == 4) {
textof(errno, txt);
printf(" %s: %s\n", newf, txt);
strcpy(file, PSEUDX); mktemp(file); /* so try and write temp file */
desc = creat(file, 0664);
if (desc > 0) {
flag = write(desc, adr, filelength);
if (flag > 0) {
eterminate = 1;
printf("HOWEVER, your editing has been saved in %s\n", file);
} else printf("edit failed to write to");
} else printf("edit failed to create");
if (eterminate == 4) {textof(errno, txt); printf(" %s: %s\n", file, txt);}
else {close(desc); free(adr);}
}
} else printf("edit failed to get VM");
} /* editexit */
/*----------------------------------------------------------------------*/
checkff(f) struct ff *f; { /* 2316 */
int j, k;
f->start = f->end = 0;
k = 1; /* oldf = newf */
if (strcmp(oldf, newf) != 0) {
if (strcmp(newf, ".NULL") == 0) k = 0; else k = 2;
}
newf_exists = exist(newf);
if ((k != 1) || (newf_exists != 0)) {
strcpy(f->file, oldf);
j = emasconnect(f);
if (j != 0) return(j);
strcpy(fileused[++fileusedcount], oldf);
start_address[fileusedcount] = f->start;
end_address[fileusedcount] = f->end - 1;
}
if (newf_exists == 0) {
if (k > 0) printf("%s is a new file\n", newf);
} else {
if (k == 2) printf("%s already exists\n", newf);
}
if (k == 2) strcpy(fileused[++fileusedcount], newf);
return(0);
} /* checkff */
/*----------------------------------------------------------------------*/
ed() { /* 315 */
static char *prt[] = {"Edit:", "Look:"};
int i, j, k;
strcpy(prstring, prt[emode]);
caseind = 1;
ccase = (char *)&onecase[0];
for (j=0; j<=MAXCOUNT; j++) count[j] = 0;
for (j=0; j<16;) lastrec[j++].lp = 0;
for (j=0; j<26;) string[j++].lp = 0;
strcpy(identifier, "z0date0time0");
identifier[1] = identifier[6] = identifier[11] = 0;
string[1].ll = 1; /* date is a const fn */
string[2].ll = 2; /* time is a variable fn */
if (emode == 0) { /* edit rather than look */
if (exist(eha) > 0) {
printf("%s\n", explanation);
return(2);
}
}
sysdicta = privdict_changed = privdicta = 0;
wordm1 = 0;
j = calloc(1, 512<<10);
if (j < 0) return(errno);
wsp0 = wsp = j; wse = j + (512<<10);
comp = 0;
slinest = 1; sparast = 6; slinel = 72;
wseen = 0; asl = 0;
strcpy(oldf, in);
strcpy(newf, out);
fileusedcount = -1;
j = initialise();
if (j != 0) goto err;
lastcom = (struct cform *) (int) &clist[0].lett;
for(;;) { /* ********* primary loop ********* */
linecomplete = readcstring();
if (linecomplete < 0) {
strcpy(prompt_string, prstring);
while (nextsymbol() != NL) skipsymbol();
}
if (hset == 0) hsave();
i = 0;
for(;;) {
/* printf("ed, i=%d, comp=%d\n", i, comp); */
if (i >= comp) break;
if ((i != 0) && (curcom->swno != 0)) lastcom = (struct cform *)&curcom->lett;
curcom = (struct cform *) &clist[i++].lett;
j = curcom->flags;
if (((j & NEEDSS) != 0) && (seta == 0)) {
ermess(3, curcom->lett);
i = comp -1;
continue;
}
back = j & BACKWARDS;
if ((j & STOPSPELL) != 0) wordm1 = 0;
if ((j & ERROR) != 0) {
ermess(curcom->errno, curcom->lett);
i = comp -1;
continue;
}
/* printf("ed(%d) ", curcom->swno); */
switch(curcom->swno) {
case 0: /* loop test */
if (++curcom->count >= curcom->par) curcom->count = 0;
else i = curcom->loop;
count[curcom->level] = curcom->count;
break;
case 1: /* T */
cur = (struct cell *) top->rl;
curp = cur->lp;
break;
case 2: /* B */
cur = (struct cell *) &bot->ll;
curp = 0;
break;
case 3: /* E */
editexit(0);
return(eterminate);
case 4: /* I */
if (maptxt(curcom->par) == 0) {i = comp; break;}
copy(&txt->ll);
insert();
if (back != 0) {
cur = (struct cell *)&txt->ll;
curp = txt->lp;
}
break;
case 5: /* M TEXT */
if (maptxt(curcom->par) == 0) {i = comp; break;}
if (back == 0) k = find(); else k = findb();
cur = (struct cell *) (int) &beg->ll;
curp = begp;
if (k == 0) i = comp - 1;
break;
case 6: /* M NO */
if ((back == 0) && (curcom->par > 0)) {
k = lineson(curcom->par);
cur = (struct cell *)(int)&edit_end->ll;
curp = endp;
} else {
k = linesback(curcom->par);
cur = (struct cell *)(int)&beg->ll;
curp = begp;
}
if (k == 0) i = comp - 1;
break;
case 7: /* A TEXT */
if (maptxt(curcom->par) == 0) {i=comp; break;}
if (back == 0) k = find(); else k = findb();
if (k == 0) {
cur = (struct cell *)&beg->ll;
curp = begp;
i = comp - 1;
break;
}
cur = (struct cell *)&edit_end->ll;
curp = endp;
break;
case 8: /* A NO */
if (back == 0) {
k = charson(curcom->par);
cur = (struct cell *)&edit_end->ll;
curp = endp;
} else {
k = charsback(curcom->par);
cur = (struct cell *)&beg->ll;
curp = begp;
}
if (k == 0) i = comp - 1;
break;
case 9: /* P TEXT */
if (maptxt(curcom->par) == 0) {i = comp; break;}
if (back == 0) {
if (find() == 0) {
edit_end = (struct cell *)&beg->ll;
endp = begp;
} else {
beg = (struct cell *)&cur->ll;
begp = curp;
cur = (struct cell *)&edit_end->ll;
curp = endp;
k = lineson(1);
cur = (struct cell *)&beg->ll;
curp = begp;
}
j = linesback(0);
} else {
k = findb();
edit_end = (struct cell *)&cur->ll;
endp = curp;
cur = (struct cell *)&beg->ll;
curp = begp;
k = linesback(0);
cur = (struct cell *)&edit_end->ll;
curp = endp;
k = lineson(1);
}
printtext();
break;
case 10: /* Pn */
if ((i == comp) && (lastcom->lett == 'P')) break;
if ((back == 0) && (curcom->par > 0)) {
j = linesback(0);
k = lineson(curcom->par);
} else {
k = linesback(curcom->par);
j = lineson(1);
}
printtext();
if ((j == 0) || (k == 0)) i = comp-1;
break;
case 11: /* D TEXT */
case 19: /* U TEXT */
case 32: /* C TEXT */
if (maptxt(curcom->par) == 0) {i = comp; break;}
if (back == 0) {
if (find() == 0) {
cur = (struct cell *)&beg->ll;
curp = begp;
i = comp - 1;
break;
}
beg = (struct cell *)&cur->ll;
begp = curp;
} else {
if (findb() == 0) {
cur = (struct cell *)&beg->ll;
curp = begp;
i = comp - 1;
break;
}
edit_end = (struct cell *)&cur->ll;
endp = curp;
}
switch(curcom->swno) {
case 11: delete(); break;
case 19: replace(); break;
case 32: copychain(); break;
}
break;
case 12: /* D NO */
case 20: /* U NO */
case 33: /* C NO */
j = linesback(0);
if (curcom->par == 0) { /* n = 0 is a noop */
cur = (struct cell *)&beg->ll;
curp = begp;
break;
}
if (back == 0) {
k = lineson(curcom->par);
} else {
edit_end = (struct cell *)&beg->ll;
endp = begp;
k = linesback(curcom->par);
}
switch(curcom->swno) {
case 12: delete(); break;
case 20: replace(); break;
case 33: copychain(); break;
}
if (k == 0) i = comp - 1;
break;
case 13: /* R TEXT */
if (maptxt(curcom->par) == 0) {i = comp; break;}
if (back == 0) k = find(); else k = findb();
if (k == 0) {
cur = (struct cell *)&beg->ll;
curp = begp;
i = comp -1;
break;
}
delete();
break;
case 14: /* R NO */
if (back == 0) {
beg = (struct cell *)&cur->ll;
begp = curp;
k = charson(curcom->par);
} else {
k = charsback(curcom->par);
edit_end = (struct cell *)&cur->ll;
endp = curp;
}
delete();
if (k == 0) i = comp - 1;
break;
case 15: /* Q */
return(2);
case 16: /* S */
if (seta != 0) killpart();
seta = newcell();
txt = (struct cell *)seta;
insert();
set = (struct cell *)seta;
break;
case 17: /* K */
cur = (struct cell *)&set->ll;
killpart();
break;
case 18: /* H */
hrestore();
break;
case 21: /* O */
cur = (struct cell *)seta;
curp = 0;
break;
case 23: /* G NO */
position(curcom->par);
break;
case 24: /* F */
extract(curcom->par);
break;
case 25: /* W */
if (strcmp(newf, ".NULL") == 0) break;
wseen++;
j = seta;
if (seta != 0) killpart();
k = curp - cur->rp - 1;
while((int)&cur->ll != (int)&top->ll) {
k = k + cur->rp - cur->lp + 1;
cur = (struct cell *)cur->ll;
}
editexit(-1);
if (eterminate == 99) break;
/* if (contains(newf, tempfile) == 0) {
strcpy(newf, oldf);
}
*/
printf("All changes incorporated in %s\n", newf);
if (j != 0) printf("NB Separator *S* has been killed\n");
strcpy(oldf, newf);
returnlist(htop, hbot);
j = returncell(&hbot->ll);
j = initialise();
if (j != 0) goto err;
j = charson(k);
cur = (struct cell *)&edit_end->ll;
curp = endp;
break;
case 26: /* Z */
if (caseind == 0) {
ccase = (char *)&onecase[0];
} else {
ccase = (char *)&twocase[0];
}
caseind = 1 - caseind;
break;
case 27: /* L */
if (layout(curcom->par, 0) == 0) i = comp - 1;
break;
case 28: /* J */
if (layout(curcom->par, 1) == 0) i = comp - 1;
break;
case 29: /* X */
if (sysdicta == 0) {
j = initdict();
if (j != 0) {
ermess(4, 0);
i = comp - 1;
break;
}
}
for (;;) {
j = nextword();
if (j == 0) break;
sethashes();
j = dictlookup();
/* printf("lookup %s, j=%d\n", word, j); */
if (j == 0) {j = -1; break;}
}
if (j == 0) {i = comp - 1; break;}
j = charsback(wordm1);
cur = (struct cell *)&beg->ll;
curp = begp;
break;
case 30: /* Y */
if (wordm1 == 0) {
ermess(5, 0);
i = comp - 1;
break;
}
enter();
j = charson(wordm1);
cur = (struct cell *)&edit_end->ll;
curp = endp;
break;
case 31: /* N */
if (wordm1 == 0) {
ermess(6, 0);
i = comp - 1;
break;
}
entertemp();
j = charson(wordm1);
cur = (struct cell *)&edit_end->ll;
curp = endp;
break;
case 34: /* @ */
diagnostic(curcom->par);
break;
case 35: /* ? */
help(curcom->par);
break;
case 36: /* % */
if (maptxt(curcom->par) == 0) {i = comp; break;}
move(16, &txt->ll, &string[curcom->lett].ll);
break;
} /* end of switch */
}
}
err:
return(0);
} /* ed */
/*----------------------------------------------------------------------*/
main(argc, argv) int argc; char *argv[]; {
int j;
char hold[128];
static char *com[] = {"edit", "look"};
static char *msg[] = {"finished", "completed", "abandoned", "no changes", "***NOT*** completed"};
extern int optind;
extern char *optarg;
indent[0] = 0;
nls[0] = NL; nls[1] = NL;
for (j=0; j<132;) sps[j++] = SP;
byteinteger = (char *)0;
integer = (int *)0;
input_pointer = 0; inputline[0] = 0;
emode = 0; use_sif = 0;
while ((j = getopt(argc, argv, "ls")) != EOF) switch(j) {
case 'l': emode = 1; break;
case 's': use_sif = 1; break;
case '?': return;
}
j = 0;
for (; optind < argc; optind++) {
if (j == 0) strcpy(in, argv[optind]);
if (j == 1) strcpy(out, argv[optind]);
if (j > (1-emode)) {printf("Too many parameters\n"); return;}
j++;
}
if (j == 0) {printf("No file name given\n"); return;}
if (j == 1) {strcpy(out, in); strcpy(hold, in);
} else sprintf(hold, "%s %s", in, out);
expand_filename(in); expand_filename(out);
if (emode == 1) strcpy(out, ".NULL");
j = ed();
if (emode == 1) j = 0;
if ((0 <= j) && (j <= 4)) printf("%s %s %s\n", com[emode], hold, msg[j]);
}