Back
//main.ctp Copyright (C) 1989-2010 I.Pedley (CTPP) Tue 25-Apr-2000 at 20:05:01
//ChaOS source file editor
#pragma breakpoints on
#include {stdlib.htm} //stdlib.html
#include {string.htm} //string.html
#include {drive.htm} //drive.html
#include {accdis.htm} //accdis.html
#include {bios.htm} //bios.html
#include {ctype.htm} //ctype.html
#include {chaoskey.htm} //chaoskey.html
#include {os.htm} //os.html
#include {e3.htm} //e3.html
#include {box.htm} //box.html
CH* dsavebox(BOX* b);
VD drestorebox(BOX* b,CH* ptr);
VD dbox1(BOX* b,UL no,CH* str,UI col);
VD dobsbox1 (UL dispoff,BOX* b,UL no,CH* str,UI col);
VD dobclearbox(UL dispoff,BOX* b,UL col);
VD dclear(BOX* b,UL col);
SL dcat(UL row,UL col,CH* format,...);
VD dvblit(VD);
SL catprint(CH* buf,CH* format,...);
SL catdisp(UL row,UL col,CH* format,...);
SL getkey(VD);
EX UL* kbinptr;
EX UL* kboutptr;
EX UL kbdstate;
VD ipx_poll(VD);
SL clidisplay(CH* format,...);
SL clitype(CH* str);
VD clidownline(VD);
EX SL clistartline;
EX SL cliendline;
EX SL clicur;
E3 ectl;
E3 E[MAXEFILES];
UL efiles;
UL ecur;
VD handleeditchar(E3* e,UL key);
SL saveE3 (E3* e,UL preserve);
VD efcleanup(VD);
VD cleanup(VD);
SL savecontrolfile (E3* ec);
SL createcontrolfile(E3* e);
SL insertblankline (E3* e);
SL deleteline (E3* e);
SL repeatline (E3* e);
SL retypeline (E3* e);
SL insertblock (E3* e);
SL clearundeletebuffer (VD);
SL makeundeletebuffer (VD);
SL destroyundeletebuffer (VD);
SL alreadyedited (E3* e,CH* name);
SL createnewE3 (E3* e,CH* name);
EX LDRIVE* LDcur;
LSEQ* dosloadSEQ(CH* name);
CH banner[]="|c2ED - ChaOS Source File Editor ";
CH blankline[256];
UL insert=1;
CH ctfname[]="e.control";
UC* loadfile(CH* fname,CHAOSFILE* cf,PATH* sp);
SL loadfile(UL idx);
VD buildpathstring(PATH* sp,CH* str);
VD buildchaospathstring(LDRIVE* l,CHAOSFILE* cf,CH* str);
//UC* cfupload(CHAOSFILE* cf,PATH* sp,UL* fsiz);
//SL splitpath(CH* str,PATH* sp);
SL patch(E3* e,UL size);
SL patch(LSEQ* L,UL size);
SL createeditbuffer(E3* e);
UL erroronscreen;
SL errordisplay(CH* str)
{
UL n=strlen(str);
if(n>79){n=79;}
displayat(49,0,"%79sc1500",str);
erroronscreen=1;
return 0;
}
VD displayE3name(E3* e);
SL clearerrorline(E3* e)
{
CH* str="\x0";
erroronscreen++;
if(erroronscreen>=2)
{
displayat(49,0,"%79s",str);
erroronscreen=0;
displayE3name(e);
}
erroronscreen=0;
return 0;
}
SL splitpath(CH* str,PATH* sp);
UC* uploadfile(CH* fname,PATH* sp);
SL wildcardchar(CH* str);
SL loadE3(CH* str,E3* e,UL flag)
{
PATH sp;
CH* ptr;
CH* buf=NULL;
UL fsiz;
CH fname[256];memset(fname,0,256);
if(flag)
{//str should be of the form wx wy curx cury
//#pragma breakpoint
while(isspace(*str)){str++;}
ptr=strchr(str,' ');
if(!ptr)
{
displayat(49,0,"|c1500Control file appears to be corrupt");
//clidisplay("Corrupt control file");
return 1;
}
strncpy(fname,str,ptr-str);
fname[ptr-str]=0;
e->wy=strtol(ptr,&ptr,10);
e->wx=strtol(ptr,&ptr,10);
e->cury=strtol(ptr,&ptr,10);
e->curx=strtol(ptr,&ptr,10);
}
else
{
ptr=strchr(str,'.');
if(!ptr)
{//try htm file first if no file extension
strcpy(fname,str);strcat(fname,".htm");
}
if(*fname){buf=(CH*)uploadfile(fname,&sp);}
if(!buf){strcpy(fname,str);}
e->wx=0;
e->wy=0;
e->curx=0;
e->cury=0;
}
if(!buf){buf=(CH*)uploadfile(fname,&sp);}
if(!buf)
{
//clidisplay("File %s not found",fname);return 1;
return 1;
}
strcpy(e->name,fname);
e->buf=buf;
// memcpy(e->sp,&sp,512); //should be e->sp=sp, but A10 won't compile it yet
e->sp=sp; //yes it will
if(patch(e,sp.len)){return 1;}
// if(createeditbuffer(e)){return 1;}
e->modified=0;
return 0;
}
VD destroy(E3* e)
{
if(e->loaded)
{
free(e->buf);
}
memset(e,0,sizeof(E3));
}
EX CH incpath[64];
E3* loadincludefile(E3* e)
{
CH* text=e->buf+e->cury*MEMLINELEN;
CH ifname[256];
ifname[0]=0;
CH* ptr=text;
CH* ptr1;
if(memcmp(ptr,"#include",8)){return NULL;}
ptr=strchr(ptr+8,'{');
if(!ptr){return NULL;}
ptr1=strchr(ptr+1,'}');
if(!ptr1){return NULL;}
else{}
#pragma breakpoint
// ENV* env=findenvironmentstring("include");
// if(env){strcpy(ifname,env->equ);}
strcpy(ifname,incpath);
strncpy(ifname+strlen(ifname),ptr+1,ptr1-ptr-1);
//#pragma breakpoint
E3* e1;
UL n=alreadyedited(&ectl,ifname);
if(n!=-1)
{
e1=E+n;
if(e1->loaded){return e1;}
ptr=ectl.buf+n*MEMLINELEN;
if(!loadE3(ptr,e1,1))
{
efiles++;return e1;
}
return NULL;
}
e1=E+efiles;
if(!loadE3(ifname,e1,0))
{
#pragma breakpoint
ectl.cury=0;
insertblankline(&ectl);
memcpy(ectl.buf,ifname,strlen(ifname));
ecur=0;
efiles++;return e1;
}
return NULL;
}
VD cls(VD)
{
UL n;
for(n=clistartline;nname,&e->wy,&e->wx,&e->cury,&e->curx,&e->lines);
// UL archno=e->cf.archive&~0x80000000;
UL archno=e->sp.archno;
displayat(48,0,"|c2%25sc2 (%4lc2,%3lc2) %5lc2 lines %Dc2 %Tc2 v(%5lc2) %4lc2",e->name,&e->cury,&e->curx,&e->lines,&e->sp.date,&e->sp.time,&archno,&udidx);
// if(e->argtoggle)
// {
// displayat(1,60,"%3l %3l %3lw%3lh",&e->argy,&e->argx,&e->argw,&e->argh);
// }
// else
// {
// displayat(1,60,"|c2 ");
// }
if(erroronscreen){return;}
// displayat(49,0,"|c2 ");
SL n,x=0;
n=e->braces;
if(n>0) {while(n--)displayat(49,x++,"|c2%{");}
else if(n<0){while(n++)displayat(49,x++,"|c2%}");}
x++;
n=e->brackets;
if(n>0) {while(n--)displayat(49,x++,"|c2[");}
else if(n<0){while(n++)displayat(49,x++,"|c2]");}
x++;
n=e->parentheses;
if(n>0) {while(n--)displayat(49,x++,"|c2(");}
else if(n<0){while(n++)displayat(49,x++,"|c2)");}
x++;
n=e->quotes;
if(n>0){while(n--)displayat(49,x++,"|c2\"");}
}
UL linelength(CH* str,UL maxlen)
{
SL n;
for(n=maxlen-1;n>=0;n--)
{
if(str[n]!=0x20){return n+1;}
}
return 0;
}
//UL lflinelength(CH* str,UL maxlen)
//{
// SL n;
// for(n=maxlen-1;n>=0;n--)
// {
// if(str[n]!=0x0a)
// {
// if(str[n]!=0x20){return n+1;}
// }
// }
// return 0;
//}
SL scan(E3* e,UL errorbreak)
{
UL n,m,o;
CH* text=e->buf;
CH* ptr;
e->braces=0;
e->brackets=0;
e->parentheses=0;
e->quotes=0;
UL incomment=0,incppcomment,inquote=0,inccs=0;
for(n=0;nlines;n++)
{
o=linelength(text,MAXLINELEN);
ptr=text;
incppcomment=0;
for(m=0;mbraces++;break;
case '}':
if(!e->braces)
{
if(errorbreak)
{
errordisplay("Closing brace before opening brace");
e->cury=n;
e->curx=ptr-text;
return 1;
}
}
e->braces--;
break;
case '[':e->brackets++;break;
case ']':
if(!e->brackets)
{
if(errorbreak)
{
errordisplay("Closing bracket before opening bracket");
e->cury=n;
e->curx=ptr-text;
return 1;
}
}
e->brackets--;
break;
case '(':
e->parentheses++;break;
case ')':
if(!e->parentheses)
{
if(errorbreak)
{
errordisplay("Closing parenthesis before opening parenthesis");
e->cury=n;
e->curx=ptr-text;
return 1;
}
}
e->parentheses--;
break;
case '"':
inquote=1;
break;
case ''':
inccs=1;
if(*(ptr+1)==''')
{//if character immediately following start
//of constant character string is apostrophe
//skip it
ptr++;m++;
}
break;
}
}
}
ptr++;
}
text+=MEMLINELEN;
}
e->quotes=inquote;
return 0;
}
VD highlight(UL row,UL col,UL colour,UL len);
VD displayE3(E3* e,UL h,SL yoff)
{
if(e->modified){scan(e,0);}
displayE3name(e);
//do autoscroll to bring line into view
if(e->cury>=e->wy+h)
{
while(e->cury>=e->wy+h)
{
e->wy+=AUTOSCROLL;
}
}
else if(e->curywy)
{
while(e->curywy)
{
if(e->wy>AUTOSCROLL)
{e->wy-=AUTOSCROLL;}
else{e->wy=0;}
}
}
//do autoscroll to bring column into view
if(e->curx>=e->wx+80)
{
while(e->curx>=e->wx+80)
{
e->wx+=10;
}
}
else if(e->curxwx)
{
while(e->curxwx)
{
if(e->wx>10)
{e->wx-=10;}
else{e->wx=0;}
}
}
AA->fgd=7;
CH* text=e->buf+e->wy*MEMLINELEN;
UL n;
SL len;
SL tlen;
UL hw;
for(n=0;nwy>=e->lines){break;}
len=linelength(text,MAXLINELEN);
tlen=len-e->wx;
if(tlen>80)
{
(*AA->putstrn)(AA->usr,text+e->wx,n+yoff,0,80);
}
else if(tlen>0)
{
(*AA->putstrn)(AA->usr,text+e->wx,n+yoff,0,tlen);
if(tlen<80)
{
(*AA->putstrn)(AA->usr,blankline,n+yoff,tlen,80-tlen);
}
}
else
{
(*AA->putstrn)(AA->usr,blankline,n+yoff,0,80);
}
if(e->argtoggle)
{
if(e->wy+n>=e->argy)
{
//if(e->wy+nargy+e->argh)
if(e->wy+n<=e->argh)
{
// brk
hw=e->argw-e->argx+1;
if(hw>128){hw=128;}
// highlight(n+yoff,e->argx-e->wx,0x70,hw);
AA->bgd=7;
AA->fgd=0;
(*AA->putstrn)(AA->usr,text+e->argx,n+yoff,e->argx,hw);
AA->bgd=0;
AA->fgd=7;
}
}
}
text+=MEMLINELEN;
}
while(nputstrn)(AA->usr,blankline,n+yoff,0,80);
n++;
}
(*AA->setcurpos)(AA->usr,e->cury-e->wy+yoff,e->curx-e->wx);
if(insert) //if insert on
{(*AA->setcursiz)(AA->usr,0x0007);} //set block cursor
else{(*AA->setcursiz)(AA->usr,0x0607);}
}
VD displaymacros(VD);
VD displayentb (VD);
VD displaysources(VD);
VD topascalstr(CH* str,CH* pstr);
CH findstring [64];
CH pfindstring[64];
CH repstring [64];
CH prepstring [64];
CH findproto [64];
CH pfindproto [64];
CH hlinktext [64];
CH hlinktarget [64];
SL command(UL argc,CH** argv,UL istsr,UL dbg,UL mp);
SL shellcompile(E3* e)
{
CH* argv[3];
argv[0]="cc";
argv[1]=e->name;
argv[2]=NULL;
return command(2,&argv,0,0,0);
}
SL shellhtml(E3* e)
{
CH* argv[3];
argv[0]="grtest";
argv[1]=e->name;
argv[2]=NULL;
return command(2,&argv,0,0,0);
}
E3* reload(E3* e)
{
//brk
if(e==&ectl){return e;}
BOX bp ={18, 8 ,26,62};
CH* ptr=dsavebox(&bp);
UL ecur;
dclear(&bp,0);
dbox1(&bp,-1,"Reload:",0x20);
E3 etmp;
memset(&etmp,0,sizeof(E3));
displayat(20, 9,"Revert to saved version of:");
displayat(21, 9," [%32s]?",e->name);
L01:
dvblit();
switch(getkey()&0xffff)
{
case 'y':
case 'Y':
case (SHIFT|'y'):
if(loadE3(e->name,&etmp,0))
{
displayat(23,9,"|c1500Couldn't reload file - continuing with current");
dvblit();
getkey();return e;
}
etmp.wx=e->wx;
etmp.wy=e->wy;
etmp.curx=e->curx;
etmp.cury=e->cury;
destroy(e);
*e=etmp;
e->loaded=1;
scan(e,0);
break;
case 'n':
case 'N':
case (SHIFT|'n'):
case ESC:
break;
default:
goto L01;
}
drestorebox(&bp, ptr);
return e;
}
VD dorevsearch(E3* e,CH* str)
{
CH* text=e->buf+e->cury*MEMLINELEN;
CH* end=e->buf+e->lines*MEMLINELEN;
UL wrap;
UL hit=0;
CH* ptr1;
if(str)
{
strcpy(findstring,str);
spacestonulls(findstring,32);
topascalstr(findstring,pfindstring);
ptr1=text+e->curx-1;
while(text>=e->buf)
{
while(ptr1>=text)
{
if(!memcmp(ptr1,findstring,*pfindstring))
{
e->curx=ptr1-text;
e->cury=(text-e->buf)/MEMLINELEN;
hit=1;e->argtoggle=0;return;
}
ptr1--;
}
text-=MEMLINELEN;
while(!linelength(text,MAXLINELEN))
{
if(text<=e->buf){break;}
text-=MEMLINELEN;
}
ptr1=text+linelength(text,MAXLINELEN)-1;
}
if(!hit)
{
errordisplay("Not found:");
dvblit();
getkey();
return;
}
}
}
VD dosearch(E3* e,CH* str)
{
CH* text=e->buf+e->cury*MEMLINELEN;
CH* end=e->buf+e->lines*MEMLINELEN;
UL wrap;
UL hit=0;
CH* ptr1;
if(str)
{
strcpy(findstring,str);
spacestonulls(findstring,32);
topascalstr(findstring,pfindstring);
ptr1=text+e->curx+1;
while(textcurx=ptr1-text;
e->cury=(text-e->buf)/MEMLINELEN;
hit=1;e->argtoggle=0;return;
}
ptr1++;
}
text+=MEMLINELEN;
ptr1=text;
}
if(!hit)
{
errordisplay("Not found:");
dvblit();
getkey();
return;
}
}
//brk
BOX bp ={18, 8 ,26,62};
CH* ptr=dsavebox(&bp);
dclear(&bp,0);
dbox1(&bp,-1,"Find:",0x20);
L01:
dvblit();
wrap=0;
if(!acceptat(20, 9,"Find string:[%32s]",findstring))
{
spacestonulls(findstring,32);
topascalstr(findstring,pfindstring);
ptr1=text+e->curx+1;
L02:
while(textcurx=ptr1-text;
e->cury=(text-e->buf)/MEMLINELEN;
hit=1;goto L03;
}
ptr1++;
}
text+=MEMLINELEN;
ptr1=text;
if(wrap){if(text>=e->buf){break;}}
}
if(!wrap)
{
if(text>=end){wrap=1;text=e->buf;goto L02;}
}
L03:
if(!hit)
{
displayat(25, 9,"|c1500%s not found: press a key",findstring);
dvblit();
getkey();
displayat(25, 9," ");
goto L01;
}
}
drestorebox(&bp, ptr);
}
SL optionkey(VD);
VD dosearchandreplace(E3* e,CH* str,UL global)
{
CH* text=e->buf+e->cury*MEMLINELEN;
CH* end=e->buf+e->lines*MEMLINELEN;
UL wrap=0;
SL hit=0,aut=0,n,m,o;
CH* ptr1;
if(global)
{
text=e->buf;
e->curx=e->cury=0;
goto L01a;
}
else if(str)
{
strcpy(findstring,str);
spacestonulls(findstring,32);
topascalstr(findstring,pfindstring);
ptr1=text+e->curx+1;
while(textcurx=ptr1-text;
e->cury=(text-e->buf)/MEMLINELEN;
hit=1;e->argtoggle=0;return;
}
ptr1++;
}
text+=MEMLINELEN;
ptr1=text;
}
if(!hit)
{
errordisplay("Not found:");
dvblit();
getkey();
return;
}
}
//brk
BOX bp ={18, 8 ,26,62};
L00:CH* ptr=dsavebox(&bp);
dclear(&bp,0);
dbox1(&bp,-1,"Find:",0x20);
// UL fsi=strtol(findstring,NULL,10);
// findstring[0]=0;fsi++;
// catprint(findstring,"%3l",&fsi);
// repstring[0]=0;fsi-=115;
// catprint(repstring,"F+%03l",&fsi);
L01:
dvblit();
wrap=0;
if(!accept("|p2010 Replace:[%32s]|p2110 With:[%32s]",findstring,repstring))
{
L01a: trailingspacestonulls(findstring,32);
topascalstr(findstring,pfindstring);
trailingspacestonulls(repstring,32);
topascalstr(repstring,prepstring);
ptr1=text+e->curx;
L02:
while(textcurx=ptr1-text;
e->cury=(text-e->buf)/MEMLINELEN;
hit=1;goto L03;
}
ptr1++;
}
text+=MEMLINELEN;
ptr1=text;
if(wrap){if(text>=e->buf){break;}}
}
if(!wrap)
{
if(text>=end){wrap=1;text=e->buf;goto L02;}
}
L03:
if(!hit)
{
if(aut)
{
if(!global){drestorebox(&bp,ptr);}
return;
}
dcat(49, 0,"|c1500%s not found: press a key",findstring);
dvblit();
// getkey();
if(!global){drestorebox(&bp,ptr);}
clearerrorline(e);
return;
}
else
{
if(!global){drestorebox(&bp,ptr);}
displayE3(e,43,2);
if(aut){goto L05;}
errordisplay("Replace (Y)es/(N)o/(A)ll/ESC");
L04: switch(optionkey())
{
case 'y':case 'Y':case (SHIFT|'y'):
L05: n=linelength(text,MAXLINELEN);
o=n-e->curx-*pfindstring;
if(o){memmove(text+e->curx+*prepstring,text+e->curx+*pfindstring,o);}
memcpy(text+e->curx,repstring,*prepstring);
o=*pfindstring-*prepstring;
//blanks over end of shortened line
if(o>0){memset(text+n-o,0x20,o);}
e->modified=1;
case 'n':case 'N':case (SHIFT|'n'):
e->curx+=*prepstring;
ptr1=text+e->curx;
if(!global){ptr=dsavebox(&bp);}
hit=0;goto L02;
break;
case ESC:
break;
case 'a':case 'A':case (SHIFT|'a'):
aut=1;
if(!global){ptr=dsavebox(&bp);}
hit=0;goto L02;
default:
goto L04;
}
return;
}
}
if(!global){drestorebox(&bp,ptr);}
}
EX UL OSbase;
SYMBOL* findglobalsymbol (CBJHEADER* c,CH* name);
SYMBOL* findnextglobalsymbol(SYMBOL* s,CH* name);
VD displaytype(CBJHEADER* c,UL typidx,CH* buf,UL flag);
TYPDEF* getusertype(CBJHEADER* c,UL typidx);
VD displayprototype(CBJHEADER* c,UL typidx,CH* buf,CH* name);
VD dofindprototype(E3* e)
{
BOX bp ={18, 8 ,26,62};
CH* ptr=dsavebox(&bp);
CH* text=e->buf+e->cury*MEMLINELEN;
CH* end=text+e->lines*MEMLINELEN;
CH* ptr1;
dclear(&bp,0);
dbox1(&bp,-1,"Find:",0x20);
UL wrap;
UL hit=0;
SYMBOL* s;
CBJHEADER* os=(CBJHEADER*)OSbase;
CH buf[1024];
TYPDEF* tn;
L01:
dvblit();
wrap=0;
if(!acceptat(20, 9,"Find prototype:[%32s]",findproto))
{
spacestonulls(findproto,32);
topascalstr(findproto,pfindproto);
s=findglobalsymbol(os,pfindproto);
if(s)
{
if(s->type&tFUNC)
{
L02:
displayprototype(os,s->type,buf,s->name);
displayat(23, 9,"|c1500%s",buf);
displayat(25, 9,"|c1500Copy prototype (Yes/Next/ESC)?");
dvblit();
switch(getkey()&0xffff)
{
case 'y':
insertblankline(e);
text=e->buf+e->cury*MEMLINELEN;
strcpy(text,buf);
UL n=strlen(text);
text[n]=0x20;
break;
case 'n':
while(s)
{
s=findnextglobalsymbol(s,pfindproto);
if(s->type&tFUNC){goto L02;}
}
displayat(25, 9,"No more matches: press a key");
dvblit();
getkey();goto DONE;
case ESC:
break;
}
}
goto DONE;
}
else
{
displayat(25, 9,"|c1500%s not found: press a key",findproto);
}
dvblit();
getkey();
}
DONE:
drestorebox(&bp, ptr);
}
VD revstrcpy(CH* str1,CH* str2)
{
UL len=strlen(str2);
str2+=len-1;
while(len--){*str1++=*str2--;}
*str1=0;
}
VD doinserthyperlink(E3* e)
{
BOX bp ={18, 8 ,26,62};
CH* ptr=dsavebox(&bp);
CH* text=e->buf+e->cury*MEMLINELEN;
CH* end=text+e->lines*MEMLINELEN;
CH* ptr1;
dclear(&bp,0);
dbox1(&bp,-1,"Insert Hyperlink:",0x20);
UL wrap;
UL hit=0;
SYMBOL* s;
CBJHEADER* os=(CBJHEADER*)OSbase;
CH buf[1024];
TYPDEF* tn;
L01:
dvblit();
if(!accept("|p2009Link text:[%32s]|p2109Target:[%32s]",hlinktext,hlinktarget))
{
spacestonulls(hlinktext,32);
spacestonulls(hlinktarget,32);
text=e->buf+e->cury*MEMLINELEN+e->curx;
revstrcpy(text,"//:ptth\x22=ferh \x22\x22=eltit a<");
strcat(text,hlinktarget);
strcat(text,"\x22>");
strcat(text,hlinktext);
strcat(text,"");
}
DONE:
drestorebox(&bp, ptr);
}
VD inserttext(E3* e,CH* text)
{
UL n=strlen(text);
CH* ptr=e->buf+e->cury*MEMLINELEN+e->curx;
UL tomove=MAXLINELEN-e->curx-n;
memmove(ptr+n,ptr,tomove);
memcpy(ptr,text,n);
e->curx+=n;
}
VD inserttextline(E3* e,CH* text)
{
insertblankline(e);
CH* ptr=e->buf+e->cury*MEMLINELEN;
UL n=strlen(text);
memcpy(ptr,text,n);
}
VD doinsertmainfunction(E3* e)
{
inserttextline(e,"}");
inserttextline(e," return 0;");
insertblankline(e);
inserttextline(e,"{");
inserttextline(e,"SL main(UL argc,CH* argv[])");
e->curx=0;
e->cury++;
e->cury++;
e->curx=4;
}
VD catline(E3* e,CH* ptr)
{
CH* text=e->buf+e->cury*MEMLINELEN;
text+=linelength(text,MAXLINELEN);
memcpy(text,ptr,strlen(ptr));
}
//functions which insert HTML tags into the source file:
//these are awkward as HTML browsers will locate any <...> pairs
//and try to interpret these as HTML tags. So a complete HTML tag
//never exists in the source code or data - it is built from smaller
//chunks at run-time
VD doinserthtmlprologue(E3* e)
{
//ant function which inserts html tags
inserttextline(e,"<");
catline(e,"html><");
catline(e,"head><");
catline(e,"title><");
catline(e,"/title><");
catline(e,"/head><");
catline(e,"body bgcolor=\"#99ccFF\"><");
catline(e,"pre><");
catline(e,"chaos ext=\"");
CH* ptr=strchr(e->name,'.');
if(ptr){catline(e,ptr);}
catline(e,"\">");
}
VD doinserthtmlepilogue(E3* e)
{
//ant function which inserts html tags
inserttextline(e,"<");
catline(e,"/chaos><");
catline(e,"/pre><");
catline(e,"/body><");
catline(e,"/html>");
}
VD dospecialfunction(E3* e)
{
CH* line=e->buf+e->cury*MEMLINELEN;
CH* ptr=line;
CH* str;
UL n;
CH newline[512];
memset(newline,0,512);
DB lat,lng;
for(n=0;n<5;n++)
{
lat=strtod(ptr,&ptr);
if(lat==-1){break;}
if(*ptr=='-'){lat=-lat;str="S";}else{str="N";}
catprint(newline,"{0,%05.2d%1s,",&lat,str);
ptr++;
lng=strtod(ptr,&ptr);
if(lng<=0){ str="W";}else{str="E";}
catprint(newline,"%06.2d%1s},",&lng,str);
}
nullstospaces(newline,MAXLINELEN);
memcpy(line,newline,MAXLINELEN);
e->cury++;
}
SL makehighlightbox(E3* e)
{
if(e->cury<=e->argy) {e->argy=e->cury;}
else {e->argh=e->cury;}
if(e->curx<=e->argx) {e->argx=e->curx;}
else if(e->argw!=MAXLINELEN){e->argw=e->curx;}
UL w=e->argw-e->argx+1;
UL h=e->argh-e->argy+1;
if(w>1){return 2;}
if(h>1){return 2;}
return 1;
}
VD saveargbuffer (E3* e);
VD insertargbuffer(E3* e);
VD deleteargbuffer(E3* e);
//VD printargbuffer (E3* e);
CH linearg[128];
CH* lineargptr=linearg;
VD handleargchar(E3* e,UL key)
{
switch(key)
{
case ENTER:
case NUMENTER:
case TAB:
case (SHIFT|TAB):
break;
case NDEL:
if(e->argtoggle==1)
{
if(lineargptr>linearg){lineargptr--;}
*lineargptr=0;
}
else if(e->argtoggle==2)
{
deleteargbuffer(e);
}
break;
case NLCUR:
case BACKSPACE:
if(e->argtoggle==1)
{
if(lineargptr>linearg){lineargptr--;}
*lineargptr=0;
}
break;
default:
e->argx=e->argw=e->curx;
e->argy=e->argh=e->cury;
*lineargptr++=key;
*lineargptr=0;
break;
}
}
EX CH scratch[2048];
SL viewE3(E3* e)
{
UL n,rows=46;
SL yoff=2;
E3* e1;
displayE3(e,rows,yoff);
UL key=1;
UL disp=0;
LINE* ls;
CH* ptr;
CH* text;
while(key)
{
// dvblit();
key=getkey()&0xffff;
disp=1;
switch(key)
{
// case BACKSPACE:
case (SHIFT|NLCUR):
if(e->argtoggle)
{
if(e->curx)
{
e->curx--;
e->argx--;
e->argw--;
break;
}
}
else if(e->wx>0)
{
e->wx--;
if(e->curx){e->curx--;}
}
// break;
case NLCUR:
if(e->curx)
{
if(e->argtoggle)
{
if(e->curx==e->argw){e->argw--;}
}
e->curx--;
}
else if(e->cury)
{
text=e->buf+e->cury*MEMLINELEN;
text-=MEMLINELEN;
n=linelength(text,MAXLINELEN);
e->cury--;
e->curx=n;
}
break;
case (SHIFT|NRCUR):
if(e->argtoggle)
{
if(e->curxcurx++;
e->argx++;
e->argw++;
break;
}
}
// else
// {
// e->wx++;
// e->curx++;
// }
// else if(e->curx-e->wx>70)
// {
// e->wx+=10;
// }
// break;
case NRCUR:
if(e->curxcurx++;
}
break;
case (SHIFT|NUCUR):
if(e->argtoggle)
{
if(e->cury)
{
e->argy--;
e->argh--;
e->cury--;
break;
}
}
case NUCUR:
if(e->cury)
{
if(e->argtoggle)
{
if(e->cury==e->argh){e->argh--;}
}
if(e->wy==e->cury)
{
if(e->wy>=AUTOSCROLL)
{
e->wy-=AUTOSCROLL;
}
else
{
e->wy=0;
}
}
e->cury--;
}
break;
case (SHIFT|NDCUR):
if(e->argtoggle)
{
e->cury++;
e->argy++;
e->argh++;
break;
}
case NDCUR:
DOWNCURSOR:
// if(e->curylines-1)
if(e->argtoggle)
{
if(e->argx==e->argw)
{
e->argx=0;
e->argw=MAXLINELEN;
}
}
if(e->curymaxlines)
{
if(e->wy+rows-1==e->cury)
{
e->wy+=AUTOSCROLL;
}
e->cury++;
}
break;
// case (SHIFT|NUCUR):
// if(e->wy){e->wy--;}
// break;
// case (SHIFT|NDCUR):
// e->wy++;
// break;
case NPGDN:
if(e->lines)
{
if(e->wylines-1)
{
e->wy+=VSCROLLINC;
e->cury+=VSCROLLINC;
}
}
break;
case NPGUP:
if(e->wy>=VSCROLLINC) {e->wy -=VSCROLLINC;}
else {e->wy =0;}
if(e->cury>=VSCROLLINC){e->cury-=VSCROLLINC;}
else {e->cury =0;}
break;
case NHOME:
if(e->curx){e->curx=0;}
else
{
e->cury=e->wy;
}
break;
case NEND:
text=e->buf+e->cury*MEMLINELEN;
e->curx=linelength(text,MAXLINELEN);
break;
case (CTRL|NHOME):
e->wy=e->wx=e->cury=e->curx=0;
break;
case (CTRL|NEND):
if(e->lines>VSCROLLINC)
{
e->wy=e->lines-VSCROLLINC;
}
else
{
e->wy=0;
}
e->wx=0;
e->cury=e->lines-1;
e->curx=0;
break;
case (CTRL|F1):
// text=e->buf+e->cury*MEMLINELEN+e->curx;
// memmove(text+2,text,MEMLINELEN-e->curx-2);
text=e->buf+e->cury*MEMLINELEN;
n=linelength(text,MAXLINELEN);
memmove(text+2,text,n);
*text++='/';
*text='/';
e->modified=1;
goto DOWNCURSOR;
break;
case (SHIFT|F1):
text=e->buf+e->cury*MEMLINELEN;
ptr=strchr(text,'/');
if(ptrmodified=1;
break;
case F3:
insertblankline(e);
break;
case F4:
deleteline(e);
break;
case F5:
if(e->argtoggle)
{
saveargbuffer(e);
e->argtoggle=0;
insertargbuffer(e);
}
else
{
repeatline(e);
}
break;
case F6:
retypeline(e);
break;
case F7:
insertblock(e);
break;
case (CTRL|F7):
clearundeletebuffer();
break;
// case F9:
// insertblankline(e);
// nullstospaces(scratch,MAXLINELEN);
// n=linelength(scratch,MAXLINELEN);
// text=e->buf+e->cury*MEMLINELEN;
// memcpy(text,scratch,n);
// trailingspacestonulls(scratch,MAXLINELEN);
// break;
case (ALT|F9):
dospecialfunction(e);e->modified=1;
break;
// case F11:
// printargbuffer(e);
// break;
case (ALT|F3):
e=reload(e);
break;
case F1:
if(e->argtoggle)
{
e->curx=e->argx;
e->cury=e->argy;
lineargptr=linearg;
*lineargptr=0;
e->argtoggle=0;
}
else
{
lineargptr=linearg;
*lineargptr=0;
e->argtoggle=1;
}
e->argx=e->argw=e->curx;
e->argy=e->argh=e->cury;
break;
// case (ALT|'m'):
// displaymacros();
// dvblit();
// getkey();
// break;
// case (ALT|'n'):
// displayentb();
// dvblit();
// getkey();
// break;
// case (ALT|'s'):
// displaysources();
// dvblit();
// getkey();
// break;
case (CTRL|'s'):
dosearch(e,NULL);
break;
case (CTRL|'r'):
dosearchandreplace(e,NULL,0);
break;
case (CTRL|F2):
e->argtoggle=0;
if(*linearg){dosearch(e,linearg);}
else if(*findstring){dosearch(e,findstring);}
else {errordisplay("No search string");}
break;
case (CTRL|F3):
e->argtoggle=0;
if(*linearg){dorevsearch(e,linearg);}
else if(*findstring){dorevsearch(e,findstring);}
else {errordisplay("No search string");}
break;
case (CTRL|F4):
doinserthtmlprologue(e);
break;
case (CTRL|F5):
doinserthtmlepilogue(e);
break;
case (CTRL|F6):
doinserthyperlink(e);
break;
case (CTRL|'f'):
inserttext(e,"for(n=0;n<;n++)");e->curx-=4;
e->curx--;
break;
case (CTRL|'p'):
dofindprototype(e);
break;
case (CTRL|'m'):
doinsertmainfunction(e);
break;
case (CTRL|'d'):
inserttextline(e,"#define ");
e->curx=8;
break;
// case (CTRL|'r'):
// inserttext(e,"return;");
// e->curx--;
// break;
case (CTRL|'i'):
inserttextline(e,"#include {.htm}");
e->curx=10;
break;
case (SHIFT|NUMENTER):
if(e->argtoggle)
{
saveargbuffer(e);
e->argtoggle=0;
}
else
{
insertargbuffer(e);
}
break;
case CTRL|'q':
dosearchandreplace(e,NULL,1);
break;
case ESC:
case F2: //return to compile file//
case F9: //return to view as html//
case F10:
case F12:
case F8:
return key;
case NINS:
insert^=1;
break;
case TAB:
case (SHIFT|TAB):
case ENTER:
case NUMENTER:
case NDEL:
case BACKSPACE:
if(e->argtoggle){handleargchar(e,key);}
else {handleeditchar(e,key);}
break;
// case LCTRLKEY:
case (CTRL|'`'):
n=viewE3(&ectl);
if(ectl.modified)
{
saveE3(&ectl,1);return F12;
}
break;
case LALTKEY:
break;
case (ALT|'i'):
e1=loadincludefile(e);
if(e1)
{
viewE3(e1);
}
break;
default:
if(isprint(key))
{
if(!e->argtoggle)
{
handleeditchar(e,key);
}
else
{
handleargchar(e,key);
}
}
break;
}
if(e->argtoggle)
{
e->argtoggle=makehighlightbox(e);
}
if(disp){displayE3(e,rows,yoff);}
clearerrorline(e);
erroronscreen++;
if(strlen(linearg))
{
errordisplay(linearg);
//erroronscreen--;
}
// text=e->buf+e->cury*MEMLINELEN;
// n=linelength(text,MAXLINELEN);
// (*AA->putstrn)(AA->usr,text,49,0,n);
// (*AA->putstrn)(AA->usr,"<-",49,n,2);
}
}
UC* scrnsave;
UL ginsert; //note global insert sense
EX UL kbdstate;
UC* vesasavescreen(VD);
VD vesarestorescreen(UC* mem);
SL savescreen(VD)
{
//allocate memory for undelete buffer, otherwise exit before altering screen
if(makeundeletebuffer()){return 1;}
//preserve cli() screen, and insert sense
scrnsave=vesasavescreen();
if(!scrnsave)
{
clidisplay("Insufficient memory");return 1;
}
displayat(0,0,banner);
displayat(1,0,"%80sc2",blankline);
ginsert=kbdstate&INSERT;
return 0;
}
SL restorescreen(VD)
{
//restore cli() screen, and insert sense
vesarestorescreen(scrnsave);
if(ginsert){kbdstate|=INSERT;}
else {kbdstate&=~INSERT;}
if(destroyundeletebuffer()){return 1;}
return 0;
}
CH* textcur(E3* e)
{
return e->buf+e->cury*MEMLINELEN;
}
//UC* loadfile(CH* fname,CHAOSFILE* cf,PATH* sp)
//{
// if(splitpath(fname,sp))
// {
// clidisplay("Illegal file name %s",fname);return NULL;
// }
// UL fsiz;
// return cfupload(cf,sp,&fsiz);
//}
SL loadfile(UL idx)
{
CH* ptr=ectl.buf+idx*MEMLINELEN;
E3* e1;
UL n;
if(*ptr)
{
n=alreadyedited(&ectl,ptr);
if(n!=-1)
{
e1=E+n;
if(e1->loaded){return n;}
if(!loadE3(ptr,e1,1))
{
efiles++;return n;
}
return ecur;
}
}
return -1;
}
SL choosefile(CH* name)
{
CH* ptr;
E3* e1;
UL n;
if(name)
{
n=alreadyedited(&ectl,name);
if(n!=-1)
{
e1=E+n;
if(e1->loaded){return n;}
ptr=ectl.buf+n*MEMLINELEN;
if(!loadE3(ptr,e1,1))
{
efiles++;return n;
}
return ecur;
}
else
{
// brk
e1=E+efiles;
if(!loadE3(name,e1,0))
{
if(ectl.lines==MAXEFILES)
{ectl.cury=ectl.lines-1;errordisplay("e.con file full");}
else {ectl.cury=ectl.lines;}
//insertblankline(&ectl);
ptr=textcur(&ectl);
memset(ptr,0x20,MAXLINELEN);
memcpy(ptr,name,strlen(name));
if(ectl.linesectl.lines){contents=ectl.lines;}
CH* text;
BOXCUR bc={contents,ectl.lines,10,0,ecur};
if(ecur>contents){bc.start=ecur-contents+1;}
hilite(&b,ecur-bc.start,0x70);
L01:
for(n=0;n=efiles){efiles=lastcur+1;}
return lastcur;
}
#include {i86.htm}
EX pdesc IDTcopy;
EX pdesc GDTcopy;
SL runcompiler(E3* ein);
SL main(UL argc,CH** argv)
{
CH* ptr;
UC* buf;
LSEQ* L;
LINE* li;
LDRIVE* l=LDcur;
PATH sp;
CHAOSFILE cf;
CH fname[256];
E3* e;
UL n,ret;
CH* text;
// strcpy(findstring,"114");
// strcpy(repstring,"F+000");
UL createfileonentry=0;
memset(blankline,0x20,255);
if(argc>2)
{
clidisplay("Too many arguments, Usage:ED ");return 1;
}
else if(argc==2)
{
// if(l->filesystem!=CHAOS)
// {
// clidisplay("Current drive %s is not a ChaOS drive",l->tag);
// return 1;
// }
e=E;
if(loadE3(argv[1],e,0))
{
// clidisplay("File %s not found",argv[1]);
clidisplay("File %s does not exist; create Y/N?",argv[1]);
switch(optionkey())
{
default:
return 1;
case 'y':
if(createnewE3(e,argv[1])){return 1;}
createfileonentry=1;
break;
}
}
e->loaded=1;
efiles++;
if(loadE3(ctfname,&ectl,0))
{
if(createcontrolfile(&ectl))
{
clidisplay("couldn't create control file");return 1;
}
else
{
strcpy(ectl.buf,argv[1]);ectl.lines=1;
}
}
else
{
ecur=alreadyedited(&ectl,argv[1]);
if(ecur==-1)
{
if(!insertblankline(&ectl))
{
strcpy(ectl.buf,argv[1]);
}
ecur=0;
}
else
{
if(!createfileonentry)
{
destroy(e);
efiles--;
e->loaded=0;
}
if(savescreen()){return 1;}
goto LOADNEXT;
}
}
if(savescreen()){return 1;}
goto VIEWNEXT;
}
else
{
// if(l->filesystem!=CHAOS)
// {
// clidisplay("Current drive %s is not a ChaOS drive",l->tag);
// return 1;
// }
if(loadE3(ctfname,&ectl,0))
{
clidisplay("No control file: use ED to edit a file");
return 1;
}
if(savescreen()){return 1;}
LOADNEXT:
e=E+ecur;
text=ectl.buf+ecur*MEMLINELEN;
if(!e->loaded)
{
if(loadE3(text,e,1))
{
// clidisplay("File %s not found",text);
ptr=strchr(text,' ');
if(!ptr){brk strcpy(fname,text);}
else {strncpy(fname,text,ptr-text);}
fname[ptr-text]=0;
displayat(49,0,"|c1500File %s does not exist; create Y/N/Quit?",fname);
switch(optionkey())
{
case 'y':
if(!createnewE3(e,fname)){break;}
default:
ecur++;
text=ectl.buf+ecur*MEMLINELEN;
if(*text==0x20){ecur=0;}
erroronscreen++;
clearerrorline(e);
goto LOADNEXT;
case ESC:
case 'q':
ectl.cury=ecur;
deleteline(&ectl);
ecur=0;
erroronscreen++;
restorescreen();
goto DONE;
}
}
e->loaded=1;
efiles++;
}
VIEWNEXT:
//scan(e,0);
// errordisplay("Press F10 to exit");
ret=viewE3(e);
switch(ret)
{
case F2:
if(e->modified){saveE3(e,1);}
if(scan(e,1))
{
}
else if(e->braces)
{
errordisplay("Can't compile: unbalanced braces");
}
else if(e->brackets)
{
errordisplay("Can't compile: unbalanced brackets");
}
else if(e->parentheses)
{
errordisplay("Can't compile: unbalanced parentheses");
}
else if(e->quotes)
{
errordisplay("Can't compile: unbalanced quotes");
}
else
{
if(!shellcompile(e))
{
errordisplay("Compiled OK");
}
// if(!runcompiler(e))
// {
// errordisplay("Compiled OK");
// }
// getkey();
}
goto VIEWNEXT;
break;
case F9:
if(e->modified){saveE3(e,1);}
shellhtml(e);
goto VIEWNEXT;
break;
case F10:
case F12:
break;
case ESC:
// if(ecurargtoggle=0;}
goto LOADNEXT;
break;
case F8:
if(efiles>1)
{
if(!ecur){ecur=loadfile(1);}
else {ecur=loadfile(0);}
}
goto LOADNEXT;
break;
}
restorescreen();
}
DONE:
if(ret!=F12)
{
// brk
if(savecontrolfile(&ectl))
{
clidisplay("Error saving control file %s",ectl.name);
}
}
e=E;
for(n=0;nloaded)
{
if(e->modified)
{
if(ret!=F12){saveE3(e,0);}
}
destroy(e);
}
e++;
}
ectl.loaded=1;//!otherwise destroy(ectl) doesn't free ectl.buf!
destroy(&ectl);
// cleanup();
return 0;
}
SL epatch(LSEQ* L,UL size)
{
UL ctr=0,n;
UI isrc;
CH* ptr=L->buf;
CH* end=L->buf+size;
LINE* l;
LINE* lp;
while(ptr!=end)
{
isrc=*(UI*)ptr;
if(isrc==ENDOFLINE){ctr++;ptr+=2;}
else if(*ptr==0x0a){ctr++;ptr++;}
else {ptr++;}
}
L->lines=ctr;
L->line=(LINE*)calloc(sizeof(LINE),L->lines+EDITEXTRAS);
if(L->line==NULL)
{
clidisplay("Insufficient memory");
free(L->buf);free(L);return 1;
}
lp=NULL;
l=L->line;
ptr=L->buf;
l->text=ptr;
while(ptr!=end)
{
isrc=*(UI*)ptr;
if(isrc==ENDOFLINE)
{
l->len=ptr-l->text;
*(l->text+l->len)=0;
l->prev=lp;
if(lp!=NULL){lp->next=l;}
lp=l;
l++;
ptr+=2;
l->text=ptr;
}
else if(*ptr==0x0a)
{
l->len=ptr-l->text;
*(l->text+l->len)=0;
l->prev=lp;
if(lp!=NULL){lp->next=l;}
lp=l;
l++;
ptr++;
l->text=ptr;
}
else {ptr++;}
}
return 0;
}
//SL createeditbuffer(E3* e)
//{
// LSEQ* L=e->L;
// CH* ptr;
// UL buflen=MEMLINELEN*(L->lines+EDITEXTRAS);
//
// CH* editbuf=(CH*)malloc(buflen);
// if(!editbuf)
// {
// clidisplay("Insufficient memory");
// free(L->line);
// free(L->buf);free(L);return 1;
// }
// memset(editbuf,0x20,buflen);
//
// LINE* l=L->line;
// ptr=editbuf;
// while(l)
// {
// memcpy(ptr,l->text,l->len);
// l->text=ptr;
// ptr+=MEMLINELEN;
// l=l->next;
// }
// free(L->buf);
// L->buf=editbuf;
// e->maxlines=L->lines+EDITEXTRAS;
// return 0;
//}
UC* dosuploadfile(CH* fname,UL* fsiz);
LSEQ* dosloadSEQ(CH* name)
{
CH path[64];
LSEQ* L=(LSEQ*)calloc(sizeof(LSEQ),1);
if(L==NULL){clidisplay("Insufficient memory");return NULL;}
UL fsiz;
L->buf=(CH*)dosuploadfile(name,&fsiz);
if(!L->buf)
{
clidisplay("Insufficient memory or zero file length");free(L);return NULL;
}
if(epatch(L,fsiz)){free(L);return NULL;}
return L;
}
SL patch(E3* e,UL size)
{
UL ctr=0,cctr=0,n;
UI isrc;
CH* ptr=e->buf;
CH* end=e->buf+size;
CH* ptr1;
CH* ptr2;
CH* ptr3;
//get line count in ctr
//note that ctr does not count last lint if 0x0a is missing from end of file
while(ptr!=end)
{
isrc=*(UI*)ptr;
if(isrc==ENDOFLINE) {ctr++;cctr=0;ptr+=2;}
else if(*ptr==0x0a) {ctr++;cctr=0;ptr++;}
else if(*ptr==0x0d) {ctr++;cctr=0;ptr++;}//PS files use single 0x0d
else if(cctr==MAXLINELEN){ctr++;cctr=0;}
else {ptr++;cctr++;} //as end of line marker
}
e->lines=ctr;
//allocate edit buffer filled with spaces
UL buflen=MEMLINELEN*(e->lines+EDITEXTRAS);
CH* editbuf=(CH*)malloc(buflen);
if(!editbuf){clidisplay("Insufficient memory");return 1;}
memset(editbuf,0x20,buflen);
ptr=e->buf;
ptr1=editbuf;
ptr2=editbuf;
ptr3=editbuf+MAXLINELEN;
UL lctr=0,col;
UL max=MAXLINELEN;
UL olctr=0;
while(ptr!=end)
{
isrc=*(UI*)ptr;
if(isrc==ENDOFLINE)
{
ptr+=2;
ptr1+=MEMLINELEN;
ptr3+=MEMLINELEN;
ptr2=ptr1;
lctr++;olctr++;
}
else if(*ptr==0x0a)
{
ptr++;
ptr1+=MEMLINELEN;
ptr3+=MEMLINELEN;
ptr2=ptr1;
lctr++;olctr++;
}
else if(*ptr==0x0d) //Postscript files use single 0x0d
{ //as end of line marker
ptr++;
ptr1+=MEMLINELEN;
ptr3+=MEMLINELEN;
ptr2=ptr1;
lctr++;olctr++;
}
else if(ptr2==ptr3)
{//line will exceed MAXLINELEN, so we break it here
clidisplay("|c700file %s line %5l too long, adding line break",e->name,&olctr);
ptr1+=MEMLINELEN;
ptr3+=MEMLINELEN;
ptr2=ptr1;
// e->lines++;
lctr++;
}
else if(*ptr==0x09)
{//TAB to column modulo 8
ptr++;
col=ptr2-ptr1;
col&=7;
do
{
*ptr2++=0x20;
col++;
}
while(col&7);
}
else{*ptr2++=*ptr++;}
}
if(e->buf){free(e->buf);}
e->buf=editbuf;
e->maxlines=e->lines+EDITEXTRAS;
if(lctr!=e->lines)
{
clidisplay("file %s line counter error e->lines=%5l, lctr=%5l",&e->lines,&lctr);
}
return 0;
}