Blame | Last modification | View Log | RSS feed
/*
*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "hconf.h"
struct variable vartable[MAXVARIABLES];
long varhelp[MAXVARIABLES];
struct menu menutable[MAXMENUS];
#if 0
#define printd(fmt,args...) fprintf(stderr,fmt,##args)
#else
#define printd(fmt,args...)
#endif
struct menu *mainmenu=NULL;
char *caption=NULL;
/*
*
*/
int copystring(char **dstptr, char *src)
{
int sz;
if (*dstptr!=NULL) free(*dstptr);
sz=strlen(src)+1;
*dstptr=(char*)malloc(sz);
if (*dstptr==NULL) return -100;
strcpy(*dstptr,src);
return 0;
}
/*
*
*/
int nextvariable=0;
struct variable *findvar(char *s)
{
int i;
i=0;
while (i<nextvariable) {
if (!strcmp(vartable[i].name,s)) return vartable+i;
i++;
}
return NULL;
}
struct variable *newvar(char *s, int type)
{
/* safety test */
if (findvar(s)!=NULL) return NULL;
if (nextvariable>=MAXVARIABLES) return NULL;
vartable[nextvariable].name=NULL;
copystring(&vartable[nextvariable].name,s);
vartable[nextvariable].type=type;
vartable[nextvariable].value=NULL;
vartable[nextvariable].flags=0;
return vartable+nextvariable++;
}
/* -- */
int nextmenu=0;
struct menu *findmenu(char *s)
{
int i;
i=0;
while (i<nextmenu) {
if (!strcmp(menutable[i].name,s)) return menutable+i;
i++;
}
return NULL;
}
struct menu *newmenu(char *s)
{
if (nextmenu>=MAXMENUS) return NULL;
menutable[nextmenu].name=NULL;
copystring(&menutable[nextmenu].name,s);
menutable[nextmenu].title=NULL;
menutable[nextmenu].entries=NULL;
return menutable+nextmenu++;
}
/*
*
*
*
*/
struct _case *newcase(struct menuentry *menuent)
{
struct _case *c;
struct _case *n;
c=malloc(sizeof(struct _case));
if (c==NULL) return NULL;
c->next=NULL;
c->value=NULL;
c->list=NULL;
if (menuent->x._case.list==NULL) {
menuent->x._case.list=c;
return c;
}
n=menuent->x._case.list;
for (;;) {
if (n->next==NULL) {
n->next=c;
return c;
}
n=n->next;
}
}
struct choice *newchoice(struct menuentry *menuent)
{
struct choice *c;
struct choice *n;
c=malloc(sizeof(struct choice));
if (c==NULL) return NULL;
c->next=NULL;
c->text=NULL;
c->var=NULL;
if (menuent->x.choice.list==NULL) {
menuent->x.choice.list=c;
return c;
}
n=menuent->x.choice.list;
for (;;) {
if (n->next==NULL) {
n->next=c;
return c;
}
n=n->next;
}
}
struct menuentry *newmenuentry(struct menuentry **ptr)
{
struct menuentry *n;
struct menuentry *p;
n=malloc(sizeof(struct menuentry));
if (n==NULL) return NULL;
n->next=NULL;
n->type=0;
if (*ptr==NULL) {
*ptr=n;
return n;
}
p=*ptr;
for (;;) {
if (p->next==NULL) {
p->next=n;
return n;
}
p=p->next;
}
}
/*
*
*
*
*/
/*
*
*
*
*/
int parsebool(struct menuentry **ptr);
int parsetristate(struct menuentry **ptr);
int parserange(struct menuentry **ptr);
int parsesubmenu(struct menuentry **ptr);
int parsecase(struct menuentry **ptr);
int parsechoice(struct menuentry **ptr);
int parseseparator(struct menuentry **ptr);
int parsemenufield(struct menuentry **ptr)
{
char *s;
s=gettoken();
if (s==NULL) return -999;
if (!strcmp(s,"bool")) return parsebool(ptr);
if (!strcmp(s,"tristate")) return parsetristate(ptr);
if (!strcmp(s,"range")) return parserange(ptr);
if (!strcmp(s,"submenu")) return parsesubmenu(ptr);
if (!strcmp(s,"switch")) return parsecase(ptr);
if (!strcmp(s,"choice")) return parsechoice(ptr);
if (!strcmp(s,"separator")) return parseseparator(ptr);
return -333;
}
/* --- */
int parsecase(struct menuentry **ptr)
{
char *s;
struct menuentry *ent;
struct _case *cas=NULL;
struct variable *v;
int res;
printd("start parseswitch()\n");
ent=newmenuentry(ptr);
if (ent==NULL) return -31;
ent->type=CASEENTRY;
ent->x._case.list=NULL;
s=gettoken();
if (s==NULL) return -32;
v=findvar(s);
if (v==NULL) return -36;
ent->x._case.var=v;
v->flags|=FLAG_M;
for (;;) {
s=gettoken();
if (!strcmp(s,"endswitch")) break;
if (!strcmp(s,"case")) {
cas=newcase(ent);
if (cas==NULL) return -34;
s=gettoken();
if (s==NULL) return -35;
if (*s!='\"') return -35;
cas->value=NULL;
copystring(&cas->value,s+1);
continue;
}
if (cas==NULL) return -39;
ungettoken();
res=parsemenufield(&cas->list);
if (res) return res;
}
return 0;
}
int parsechoice(struct menuentry **ptr)
{
struct menuentry *ent;
struct choice *cho;
struct variable *v;
char *def;
int defdone;
char *s;
printd("start parsechoice()\n");
ent=newmenuentry(ptr);
if (ent==NULL) return -31;
ent->type=CHOICEENTRY;
ent->x.choice.list=NULL;
ent->x.choice.act=NULL;
ent->x.choice.numchoices=0;
s=gettoken();
if (s==NULL) return -32;
if (*s!='\"') return -33;
ent->x.choice.text=NULL;
copystring(&ent->x.choice.text,s+1);
defdone=0;
def=NULL;
s=gettoken();
if (s==NULL) return -39;
if (*s!='\"') {
copystring(&def,s);
} else
ungettoken();
for (;;) {
s=gettoken();
if (s==NULL) return -34;
if (!strcmp(s,"endchoice")) {
if (def==NULL||!defdone) return -37;
free(def);
break;
}
if (*s!='\"') return -38;
cho=newchoice(ent);
ent->x.choice.numchoices++;
if (cho==NULL) return -33;
cho->text=NULL;
copystring(&cho->text,s+1);
s=gettoken();
if (s==NULL) return -34;
v=newvar(s,CHOICEVAR);
if (v==NULL) return -37;
cho->var=v;
v->value=NULL;
copystring(&v->value,"n");
if (def==NULL) {
ent->x.choice.act=cho;
copystring(&def,s);
defdone=1;
} else if (!strcmp(def,s)) {
ent->x.choice.act=cho;
defdone=1;
}
}
return 0;
}
int parsebool(struct menuentry **ptr)
{
struct menuentry *ent;
struct variable *var;
char *s;
printd("start parsebool()\n");
ent=newmenuentry(ptr);
if (ent==NULL) return -50;
ent->type=BOOLENTRY;
s=gettoken();
if (s==NULL) return -51;
if (*s!='\"') return -55;
ent->x.bool.text=NULL;
copystring(&ent->x.bool.text,s+1);
s=gettoken();
if (s==NULL) return -52;
var=newvar(s,BOOLVAR);
if (var==NULL) return -53;
ent->x.bool.var=var;
s=gettoken();
if (*s!='\"') {
ungettoken();
var->value=(char *)malloc(2);
var->value[0]='n';
var->value[1]='\0';
return 0;
}
if (*(s+1)=='\0') return -54;
var->value=NULL;
copystring(&var->value,s+1);
return 0;
}
int parseseparator(struct menuentry **ptr)
{
struct menuentry *ent;
printd("start parseseparator()\n");
ent=newmenuentry(ptr);
if (ent==NULL) return -50;
ent->type=SEPARATORENTRY;
return 0;
}
int parserange(struct menuentry **ptr)
{
struct menuentry *ent;
struct variable *var;
char *s;
int v;
printd("start parserange()\n");
ent=newmenuentry(ptr);
if (ent==NULL) return -60;
ent->type=RANGEENTRY;
s=gettoken();
if (s==NULL) return -61;
if (*s!='\"') return -65;
ent->x.range.text=NULL;
copystring(&ent->x.range.text,s+1);
s=gettoken();
if (s==NULL) return -62;
var=newvar(s,RANGEVAR);
if (var==NULL) return -63;
ent->x.range.var=var;
s=gettoken();
if (s==NULL) return -66;
ent->x.range.minval=atoi(s);
if (ent->x.range.minval==0&&strcmp(s,"0")) return -67;
s=gettoken();
if (s==NULL) return -66;
ent->x.range.maxval=atoi(s);
if (ent->x.range.maxval==0&&strcmp(s,"0")) return -68;
s=gettoken();
if (s==NULL) return -69;
v=atoi(s);
if (v==0&&strcmp(s,"0")) {
ungettoken();
v=ent->x.range.minval;
}
{
char buffer[256];
sprintf(buffer,"%i",v);
var->value=NULL;
copystring(&var->value,buffer);
}
return 0;
}
int parsetristate(struct menuentry **ptr)
{
struct menuentry *ent;
struct variable *var;
char *s;
printd("start parsetristate()\n");
ent=newmenuentry(ptr);
if (ent==NULL) return -50;
ent->type=TRISTATEENTRY;
s=gettoken();
if (s==NULL) return -51;
if (*s!='\"') return -55;
ent->x.tristate.text=NULL;
copystring(&ent->x.tristate.text,s+1);
s=gettoken();
if (s==NULL) return -52;
var=newvar(s,TRISTATEVAR);
if (var==NULL) return -53;
ent->x.tristate.var=var;
s=gettoken();
if (*s!='\"') {
ungettoken();
var->value=(char *)malloc(2);
var->value[0]='n';
var->value[1]='\0';
return 0;
}
if (*(s+1)=='\0') return -54;
var->value=NULL;
copystring(&var->value,s+1);
return 0;
}
int parsesubmenu(struct menuentry **ptr)
{
struct menuentry *ent;
char *s;
printd("start parsesubmenu()\n");
ent=newmenuentry(ptr);
if (ent==NULL) return -40;
ent->type=SUBMENUENTRY;
s=gettoken();
if (s==NULL) return -41;
if (*s!='\"') return -43;
ent->x.submenu.text=NULL;
copystring(&ent->x.submenu.text,s+1);
s=gettoken();
if (s==NULL) return -42;
ent->x.submenu.menuname=NULL;
ent->x.submenu.menu=NULL;
copystring(&ent->x.submenu.menuname,s);
return 0;
}
int parsetitle(struct menu *ptr)
{
char *s;
printd("start parsetitle()\n");
s=gettoken();
if (s==NULL) return -71;
ptr->title=NULL;
copystring(&ptr->title,s+1);
return 0;
}
int parsecaption(void)
{
char *s;
printd("start parsecaption()\n");
s=gettoken();
if (s==NULL) return -91;
caption=NULL;
copystring(&caption,s+1);
return 0;
}
int parsemenu(void)
{
struct menu *ptr;
char *s;
int ret;
printd("start parsemenu()\n");
ret=0;
s=gettoken();
if (s==NULL) return -12;
ptr=newmenu(s);
if (ptr==NULL) return -15;
for (;;) {
s=gettoken();
if (!strcmp(s,"endmenu")) return 0;
if (!strcmp(s,"title")) {
ret=parsetitle(ptr);
if (ret) return ret;
continue;
}
ungettoken();
ret=parsemenufield(&ptr->entries);
if (ret) break;
}
return ret;
}
/*
*
*/
int resolvmenuentries(struct menuentry *ptr)
{
struct _case *ca;
int res,i;
while (ptr!=NULL) {
switch(ptr->type) {
case BOOLENTRY:
break;
case TRISTATEENTRY:
break;
case SUBMENUENTRY:
ptr->x.submenu.menu=findmenu(ptr->x.submenu.menuname);
if (ptr->x.submenu.menu==NULL) return -10;
break;
case CHOICEENTRY:
break;
case CASEENTRY:
ca=ptr->x._case.list;
i=1;
while (ca!=NULL) {
res=resolvmenuentries(ca->list);
if (res) return res;
ca=ca->next;
i++;
}
break;
}
ptr=ptr->next;
}
return 0;
}
static int resolv(void)
{
int res,i;
i=0;
while (i<nextmenu) {
res=resolvmenuentries(menutable[i].entries);
if (res) return res;
i++;
}
return 0;
}
/*
*
*/
int parse(void)
{
char *s;
int ret;
ret=0;
while ((s=gettoken())!=NULL) {
if (!strcmp(s,"menu")) ret=parsemenu();
else if (!strcmp(s,"caption")) ret=parsecaption();
else ret=-1;
if (ret) break;
}
return ret;
}
int parsehelp(char *filename)
{
char buffer[256];
FILE *fin;
fin=fopen(filename,"rt");
if (fin==NULL) return 0;
fclose(fin);
}
int readconfigin(char *filename)
{
char buffer[256];
char *ptr;
int res,i;
for (i=0;i<MAXVARIABLES;i++)
varhelp[i]=0;
res=init_tokenizer(filename,0x01);
if (res) return res;
res=parse();
if (res) return res;
res=done_tokenizer();
if (res) return res;
res=resolv();
if (res) return res;
mainmenu=findmenu("main");
if (mainmenu==NULL) return -97;
/* -- */
ptr=strstr(filename,".in");
if (ptr!=NULL) *ptr='\0';
else {
ptr=strchr(filename,'.');
if (ptr!=NULL) *ptr='\0';
}
strcpy(buffer,filename);
strcat(buffer,".hlp");
res=parsehelp(buffer);
if (res) return res;
return 0;
}
/*
*
*
*
*/
void dumpvariables(void)
{
int i;
fprintf(stderr,"VARIABLES TABLE\n---------------\n\n");
i=0;
while (i<nextvariable) {
fprintf(stderr,"name: -%s-\n",vartable[i].name);
if (vartable[i].value!=NULL)
fprintf(stderr,"value: \"%s\"\n",vartable[i].value);
else
fprintf(stderr,"value: NO VALUE\n");
fprintf(stderr,"flags: 0x%04x\n",vartable[i].flags);
fputc('\n',stderr);
i++;
}
}
#if 0
void dumpmenuentrytype(struct menuentry *ptr,char *s)
{
fprintf(stderr,"%s entry type : ",s);
switch(ptr->type) {
case BOOLENTRY: fprintf(stderr,"bool\n"); break;
case SUBMENUENTRY: fprintf(stderr,"submenu\n"); break;
case TRISTATEENTRY: fprintf(stderr,"tristate\n"); break;
case CHOICEENTRY: fprintf(stderr,"choice\n"); break;
case CASEENTRY: fprintf(stderr,"case\n"); break;
default: fprintf(stderr,"unknown\n"); break;
}
}
void dumpmenuentries(struct menuentry *ptr,int x)
{
struct choice *cho;
struct _case *ca;
char blanks[64];
int i;
memset(blanks,' ',sizeof(blanks));
blanks[x-1]='\0';
while (ptr!=NULL) {
dumpmenuentrytype(ptr,blanks);
switch(ptr->type) {
case BOOLENTRY:
fprintf(stderr,"%s text : '%s'\n",blanks,ptr->x.bool.text);
fprintf(stderr,"%s variable : %s\n",blanks,ptr->x.bool.var->name);
break;
case TRISTATEENTRY:
fprintf(stderr,"%s text : '%s'\n",blanks,ptr->x.tristate.text);
fprintf(stderr,"%s variable : %s\n",blanks,ptr->x.tristate.var->name);
break;
case SUBMENUENTRY:
fprintf(stderr,"%s text : '%s'\n",blanks,ptr->x.submenu.text);
fprintf(stderr,"%s submenu : %s\n",blanks,ptr->x.submenu.menu->name);
break;
case CHOICEENTRY:
fprintf(stderr,"%s text : '%s'\n",blanks,ptr->x.choice.text);
fprintf(stderr,"%s def variable: %s\n",blanks,ptr->x.choice.act->var->name);
i=1;
cho=ptr->x.choice.list;
while (cho!=NULL) {
fprintf(stderr,"%s text %i : '%s'\n",blanks,i,cho->text);
fprintf(stderr,"%s variable %i : %s\n",blanks,i,cho->var->name);
i++;
cho=cho->next;
}
break;
case CASEENTRY:
fprintf(stderr,"%s variable : %s\n",blanks,ptr->x._case.var->name);
fputc('\n',stderr);
ca=ptr->x._case.list;
i=1;
while (ca!=NULL) {
fprintf(stderr,"%s value %i : '%s'\n",blanks,i,ca->value);
dumpmenuentries(ca->list,x+2);
ca=ca->next;
i++;
}
break;
}
fputc('\n',stderr);
ptr=ptr->next;
}
}
void dumpmenus(void)
{
int i;
fprintf(stderr,"MENUS TABLE\n-----------\n\n");
i=0;
while (i<nextmenu) {
fprintf(stderr,"name: %s\n",menutable[i].name);
fprintf(stderr,"text: '%s'\n",menutable[i].comment);
fputc('\n',stderr);
dumpmenuentries(menutable[i].entries,2);
//fputc('\n',stderr);
i++;
}
}
#endif