home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Archive Magazine 1995
/
ARCHIVE95.iso
/
discs
/
shareware
/
share_40
/
star
/
!Star
/
c
/
Star
Wrap
Text File
|
1990-09-21
|
14KB
|
538 lines
/* Star IconBar menu
Fri,21 Sep 1990
Copyright C.T.Stretch 1990
*/
#include "wimp.h"
#include "wimpt.h"
#include "win.h"
#include "event.h"
#include "res.h"
#include "menu.h"
#include "template.h"
#include "dbox.h"
#include "dboxquery.h"
#include "werr.h"
#include "xferrecv.h"
#include "flex.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define MAXM 16
#define FIRSTITEM 2
#define MAXF 16
#define CMAX 255
#define EDNLEN 64
#define DEFTYPE 0x123456
#define TRANS 0
#define NOBAR (1<<30)
#define NOTRANS -1
#define SKIP for(;*s&&s<e;s++)
typedef struct comstr
{ char *fp;
int co,mo,len,mn;
} comstr;
typedef struct fstr
{ char fn[CMAX+1];
int type;
} fstr;
static comstr cd[MAXM];
static fstr files[MAXF];
static int fno=0;
static menu barmenu,starmenu,unmenu;
static int nextitem,nextmn;
static int ino;
static char icbuf[12]="0";
static char cbuf[CMAX+1],kbuf[CMAX+1];
static char *bufp;
static char *ce=cbuf+CMAX,*ke=kbuf+CMAX;
static int frep=0;
static char *openbr=0;
static int edhand=0;
static char edname[EDNLEN];
static BOOL ok=TRUE;
static int barend=-1;
static int trans;
static void barmenuproc(void *,char *);
static void err(char *m)
{ ok=FALSE;
os_swi6(0x24,(int)"Star$Error",(int)m,strlen(m),0,0,0);
}
static int flen(char *fn)
{ os_filestr fstr;
fstr.action=17;
fstr.name=fn;
if(os_file(&fstr)) return -1;
return fstr.start;
}
static void setmf(menu m,int n,int f)
{ int p=(int)menu_syshandle(m)+sizeof(wimp_menuhdr);
wimp_menuitem *mi=(wimp_menuitem*)p;
mi[n-1].flags=f;
}
static BOOL newmenus(void)
{ barmenu=menu_new("Star","Star");
starmenu=menu_new("Star",">Info,Load,Unload,>Error,Quit");
unmenu=menu_new("UnloadMenu","All,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16");
menu_submenu(starmenu,3,unmenu);
menu_submenu(barmenu,1,starmenu);
nextitem=FIRSTITEM;nextmn=FIRSTITEM;
setmf(unmenu,1,wimp_MLAST);
if(!event_attachmenu(win_ICONBAR,barmenu,barmenuproc,0)) return FALSE;
return TRUE;
}
static char *additems(char *s,char *e,menu m,int *off)
{ int n;
menu sub=0;
for(;s<e;s++)
{ switch(*s)
{ case ':':menu_extend(m,++s);(*off)++;
SKIP;
break;
case '{':menu_extend(m,++s);
sub=menu_new(s,"");
SKIP;n=1;
s=additems(++s,e,sub,&n);
menu_submenu(m,(*off)++,sub);
break;
case '}':SKIP;return s;
case ';':case 0 :case ' ':case '*':case '>':case '+':
case '?':case '|':case '(':case ')':case '[':
case ']':case '<':case '#':case '!':
SKIP;break;
default:werr(0,"odd line |%s| %d",s,*s);SKIP;
}
}
return e;
}
static void nullify(char *s,char *e)
{ for(;s<e;s++) if(*s==10||*s==13) *s=0;
}
static void setmenu(comstr *cs)
{ char *c,*s;
int bar=nextitem;
cs->mn=nextmn++;
cs->mo=nextitem;
additems(cs->fp+cs->co,cs->fp+cs->len,barmenu,&nextitem);
c=(char*)&(((wimp_menuitem*)
((int)(menu_syshandle(unmenu))+sizeof(wimp_menuhdr)))[cs->mn-1].data);
for(s=cs->fp+strlen(cs->fp);*s!='.';s--);strncpy(c,s+1,12);
setmf(unmenu,cs->mn-1,0);setmf(unmenu,cs->mn,wimp_MLAST);
if(nextitem>bar) setmf(barmenu,bar-1,wimp_MSEPARATE);
}
static void addmenu(char *fn)
{ int n,len;
FILE *file;
comstr *cs;
for(n=0;n<MAXM;n++) if(!cd[n].mo)break;
if(n>=MAXM) return;
cs=cd+n;
cs->co=strlen(fn)+1;
len=flen(fn);
if(len<=0) return;
if(!flex_alloc((flex_ptr)&(cs->fp),cs->co+len+1)) return;
strcpy(cs->fp,fn);
file=fopen(fn,"rb");
fread(cs->fp+cs->co,1,len,file);
fclose(file);
cs->len=cs->co+len;
if(cs->fp[cs->len-1]!=10) cs->fp[cs->len++]=10;
nullify(cs->fp+cs->co,cs->fp+cs->len);
setmenu(cs);
}
static char *skipsub(char *s,char *e)
{ for(;s<e;s++)
{ switch(*s)
{ case '{':SKIP;
s=skipsub(++s,e);
break;
case '}':SKIP;return s;
default:SKIP;
}
}
return e;
}
static char *findentry(char *h,char *s,char *e)
{ int n=0;
for(;s<e&&ok;s++)
{ switch(*s)
{ case ':':n+=1;
SKIP;
if(n>=h[0]) return ++s;
break;
case '{':n+=1;
SKIP;
if(n>=h[0]) return findentry((*h)?h+1:h,++s,e);
s=skipsub(++s,e);
break;
case '}':return 0;
default:SKIP;
}
}
return 0;
}
static void add(char c)
{ if(bufp<ke) *bufp++=c;
else err("Line too long");
}
static void adds(char *s)
{ if(bufp+strlen(s)<=ke)
{ strcpy(bufp,s);
bufp+=strlen(s);
}
else err("Line too long");
}
static void addf(int n,char *p)
{ char *f=files[n].fn;
char *e=f+strlen(f);
char *q,c;
for(;*p=='<'||*p=='>';p++)
{ for(q=e-1;q>f;q--) if(*q=='.')break;
if(*p=='<') e=q; else f=q+1;
}
if(f>=e) { err("Bad file part");return;}
c=*e;*e=0;adds(f);*e=c;
}
static void subst(char *s,char *t)
{ int n;
char *c,*p,tbuf[CMAX];
dbox d;
bufp=kbuf;
for(;*s&&ok;s++)
{ if(*s=='%')
{ for(p=++s;*s=='<'||*s=='>';s++);
switch(*s)
{ case '!':for(n=0;n<fno;n++){ addf(n,p);add(' ');}
break;
case '?':if(!openbr) err("? not in brackets");
if(ok) addf(frep,p);
break;
case '"':for(c=++s;*s;s++) if(*s=='"') break;
if(*s!='"'){err("missing \"");break;}
d=dbox_new("prompt");
if(!d) {err("Cant open prompt box");break;};
*s=0;dbox_setfield(d,2,c);*s='"';
dbox_show(d);
if(dbox_fillin(d)) { dbox_dispose(&d);err("Canceled");break;}
dbox_getfield(d,1,tbuf,CMAX);adds(tbuf);
dbox_dispose(&d);
break;
case '%':add('%');break;
default:n=*s-'0';
if(n>=0&&n<=9)
{ if(files[n].type>=0) addf(n,p);
else err("Too few files");
}
else err("Odd % substitution");
}
}
else add(*s);
}
add(0);
if(ok)
{ if(trans!=NOTRANS)
{ os_swi3r(0x27,(int)kbuf,(int)t,(ce-t)|trans,0,0,&n);
if(n>ce-t) err("Line too long");
}
else
{ if(strlen(kbuf)<ce-t) strcpy(t,kbuf);else err("Line too long");
}
}
}
static char *nextopen(char *s,char *e)
{ for(;s<e&&*s!=')';s++) SKIP;
if(*s!=')') err("Missing close bracket");
return s;
}
static char *dofile(char *s,char *e)
{ BOOL manyfile=(openbr!=0);
FILE *file=fopen("<Star$Scrap>.Temp","wb");
if(!file) {err("Cant open scrap file");return 0;}
for(;s<e&&ok;s++)
{ trans=NOTRANS;
if(*s=='|'){trans=TRANS;s++;}
if(*s=='!'){trans=NOBAR;s++;}
switch(*s)
{ case '*':subst(++s,cbuf);
if(ok) { fputs(cbuf,file);fputc(10,file);}
SKIP;break;
case '(':if(manyfile||openbr) err("Odd open bracket");
if(isdigit(s[1])) frep=*(++s)-'0';
else frep=0;
if(frep>=fno) s=nextopen(s,e);
openbr=++s;SKIP;
break;
case ')':if(manyfile||!openbr) err("Odd close bracket");
if(++frep<fno) s=openbr;else openbr=0;
SKIP;break;
case ']':fclose(file);
system("settype <Star$Scrap>.Temp FEB");
strcpy(cbuf,"Obey <Star$Scrap>.Temp ");
subst(++s,cbuf+strlen(cbuf));
if(ok) wimp_starttask(cbuf);
SKIP;return s;
case ':':case '{':case '}':s=e;break;;
case ';':case ' ':case 0:SKIP;break;
default:err("Strange line");
}
}
fclose(file);
return 0;
}
static void edfile(char *s)
{ wimp_msgstr m;
subst(s,cbuf);
if(ok)
{ if(edhand)
{ m.hdr.size=256;
m.hdr.your_ref=0;
m.hdr.action=wimp_MDATALOAD;
m.data.dataload.w=(wimp_w)-1;
m.data.dataload.i=0;
m.data.dataload.x=0;
m.data.dataload.y=0;
m.data.dataload.size=0;
m.data.dataload.type=0xFFF;
strcpy(m.data.dataload.name,cbuf);
wimpt_noerr(wimp_sendmessage(wimp_ESENDWANTACK,&m,edhand));
}
else
{ if(strlen(cbuf)<252)
{ sprintf(kbuf,"run %s",cbuf);
wimp_starttask(kbuf);
}
else err("Line too long");
}
}
}
static void key(char *s)
{ char *c;
int b,n=0;
subst(s,cbuf);
if(ok) for(c=cbuf;*c;c++){ b=*c; os_byte(138,&n,&b);}
}
static void typecheck(char *s,int n)
{ int t=files[n].type;
for(;*s;s++) if(strtol(s,&s,16)==t) return;
err("Bad file type");
}
static void checktype(char *s)
{ int n;
switch(*s)
{ case '?':typecheck(++s,frep);break;
case '!':for(n=0;n<fno;n++) typecheck(++s,n);break;
default:if(isdigit(*s)) typecheck(++s,*s-'0');else err("Bad # suffix");
}
}
static void doit(char *s,char *e)
{ int m,n;
openbr=0;
for(;s<e&&ok;s++)
{ trans=NOTRANS;
if(*s=='|'){trans=TRANS;s++;}
if(*s=='!'){trans=NOBAR;s++;}
switch(*s)
{ case '*':subst(++s,cbuf);
if(ok) wimp_starttask(cbuf);
break;
case '>':edfile(++s);break;
case '<':n=s[1];m=n-'0';
if(!isdigit(n)) err("Bad default");
else if(files[m].type<0)
{ subst(s+2,cbuf);
if(ok)
{ strcpy(files[m].fn,cbuf);
files[m].type=DEFTYPE;
}
}
break;
case '+':key(++s);break;
case '#':checktype(++s);break;
case '?':subst(++s,cbuf);
if(ok&&dboxquery(cbuf)!=dboxquery_YES) err("Canceled");
break;
case '(':if(openbr) err("Odd open bracket\n");
if(isdigit(s[1])) frep=*(++s)-'0';
else frep=0;
if(frep>=fno) s=nextopen(s,e);
openbr=++s;break;
case ')':if(!openbr) err("Odd close bracket\n");
if(++frep<fno)s=openbr;else openbr=0;
break;
case '[':SKIP;s=dofile(s,e);
break;
case ':':case '{':case '}':s=e;break;;
case ';':case ' ':case 0:break;
default:err("Strange line");
}
SKIP;
}
}
static void findcom(char *h)
{ int n,k=0;
char *s;
comstr *cs=0;
for(n=0;n<MAXM;n++) if(cd[n].mo&&cd[n].mo<=h[0])
if(cd[n].mo>k) { cs=cd+n;k=cs->mo;}
if(!k) { werr(0,"Can't find comstr %d",h[0]);return;}
h[0]-=k-1;
s=findentry(h,cs->fp+cs->co,cs->fp+cs->len);
if(!s){ werr(0,"not found");return;}
doit(s,cs->fp+cs->len);
}
static BOOL barhand(wimp_eventstr *e,void *v)
{ char *fn;
int ftype;
v=v;
switch(e->e)
{ case wimp_ESEND:case wimp_ESENDWANTACK:
switch(e->data.msg.hdr.action)
{ case wimp_MDATALOAD:ftype=xferrecv_checkinsert(&fn);
if(strlen(fn)>CMAX||fno>=MAXF) break;
strcpy(files[fno].fn,fn);files[fno].type=ftype;
sprintf(icbuf,"%d",++fno);
wimpt_noerr(wimp_set_icon_state((wimp_w)-1,ino,0,0));
break;
case wimp_MINITTASK:if(!strcmp(edname,e->data.msg.data.chars+8))
edhand=e->data.msg.hdr.task;
return TRUE;
case wimp_MCLOSETASK:if(e->data.msg.hdr.task==edhand) edhand=0;
}
break;
}
return FALSE;
}
static void barclick(wimp_eventstr *e,void *h) { e=e;h=h;}
static void unload(int n)
{ int m;
event_attachmenu(win_ICONBAR,0,barmenuproc,0);
if(n==1)
{ for(m=0;m<MAXM;m++) if(cd[m].mo)
{ flex_free((flex_ptr)&(cd[m].fp));
cd[m].mo=0;
}
}
else
{ for(m=0;m<MAXM;m++)if(cd[m].mo&&cd[m].mn==n)
{ flex_free((flex_ptr)&(cd[m].fp));
cd[m].mo=0;
}
}
menu_dispose(&barmenu,TRUE);
newmenus();
for(m=0;m<MAXM;m++) if(cd[m].mo) setmenu(cd+m);
}
static void starmenuproc(char *h)
{ dbox db;
int n;
switch (h[1])
{ case 1:if(!h[2])break;
db=dbox_new("Info");
if(db)
{ dbox_setfield(db,4,"0.0 "__DATE__);
dbox_show(db);dbox_fillin(db);
dbox_dispose(&db);
}
break;
case 2:for(n=0;n<fno;n++) if(files[n].type==0xFFF) addmenu(files[n].fn);
break;
case 3:unload(h[2]);break;
case 4:if(!h[2]) break;
db=dbox_new("error");
if(db)
{ os_read_var_val("Star$Error",cbuf,CMAX);
dbox_setfield(db,0,cbuf);
dbox_show(db);dbox_fillin(db);
dbox_dispose(&db);
}
break;
case 5:exit(0);
}
}
static void barmenuproc(void *wh,char *h)
{ int n;
wh=wh;
if(h[0]<FIRSTITEM) starmenuproc(h);
else findcom(h);
fno=0;strcpy(icbuf,ok?"0":"!?");
for(n=0;n<MAXF;n++) files[n].type=-1;
wimpt_noerr(wimp_set_icon_state((wimp_w)-1,ino,0,0));
ok=TRUE;
}
static void mybaricon(void)
{ wimp_icreate cr[1];
cr->w=(wimp_w)barend;
cr->i.box.x0=0;cr->i.box.x1=68;
cr->i.box.y0=-16;cr->i.box.y1=84;
cr->i.flags=wimp_ISPRITE|wimp_INDIRECT|(wimp_IBTYPE*wimp_BCLICKDEBOUNCE);
cr->i.flags|=wimp_ITEXT|(wimp_IFORECOL*7)|wimp_IFILLED|wimp_IHCENTRE;
cr->i.flags|=wimp_IBACKCOL;
cr->i.data.indirecttext.buffer=icbuf;
cr->i.data.indirecttext.validstring="S!star";
cr->i.data.indirecttext.bufflen=12;
wimpt_noerr(wimp_create_icon(cr,&ino));
win_register_event_handler(win_ICONBAR,barclick,0);
win_activeinc();
}
static BOOL init(void)
{ wimpt_init("Star");
res_init("Star");
template_init();
dbox_init();
flex_init();
mybaricon();
if(!newmenus())werr(0,"Failed");
win_register_event_handler(win_ICONBARLOAD,(win_event_handler)barhand,0);
win_add_unknown_event_processor(barhand,0);
os_read_var_val("Star$Ed",edname,EDNLEN);
if(!edname[0]) strcpy(edname,"Edit");
return TRUE;
}
int main(int n,char **c)
{ int i=1;
if(n>1&&*(c[1])=='-') {i++;barend=-2;}
if(!init()) return 0;
for(;i<n;i++) addmenu(c[i]);
for(;;) event_process();
return 0;
}