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
];
struct menu menutable
[MAXMENUS
];
char *filetable
[MAXFILETABLE
];
int maxfileindex
=0;
long varhelp
[MAXVARIABLES
];
char helpfilename
[FILENAME_MAX
];
#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
;
}
int findvarindex
(struct variable
*var
)
{
return (var
-vartable
);
}
struct variable
*newvar
(char *s
, int type
)
{
struct variable
*var
;
/* safety test */
var
=findvar
(s
);
if (var
!=NULL
) {
if (var
->type
==NOTYPEVAR
) var
->type
=type
;
else if (var
->type
!=type
) return NULL
;
return var
;
}
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;
vartable
[nextvariable
].
fileindex=NOFILEINDEX
;
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 newfile
(char *s
)
{
if (maxfileindex
==MAXFILETABLE
) return NOFILEINDEX
;
filetable
[maxfileindex
]=malloc(strlen(s
)+1);
if (filetable
[maxfileindex
]==NULL
) return NOFILEINDEX
;
strcpy(filetable
[maxfileindex
],s
);
maxfileindex
++;
return maxfileindex
-1;
}
/*
*
*
*
*/
/*
*
*
*
*/
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 parsefile
(void)
{
struct variable
*var
;
char *s
;
int index
;
int ret
;
printd
("start parsefile()\n");
ret
=0;
s
=gettoken
();
if (s
==NULL
) return -112;
index
=newfile
(s
);
if (index
==-1) return -115;
for (;;) {
s
=gettoken
();
if (!strcmp(s
,"endfile")) return 0;
var
=newvar
(s
,NOTYPEVAR
);
if (var
==NULL
) return -117;
var
->fileindex
=index
;
}
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 if (!strcmp(s
,"file")) ret
=parsefile
();
else ret
=-1;
if (ret
) break;
}
return ret
;
}
int parsehelp
(char *filename
)
{
struct variable
*var
;
char buffer
[256];
FILE
*fin
;
char *s
;
int i
;
fin
=fopen(filename
,"rt");
if (fin
==NULL
) return 0;
while (fgets(buffer
,sizeof(buffer
),fin
)!=NULL
)
if (*buffer
=='@') {
s
=strchr(buffer
,'\n');
if (s
!=NULL
) *s
='\0';
var
=findvar
(buffer
+1);
if (var
==NULL
) {
fprintf(stderr
,"help var %s not found config file",buffer
);
return -845;
}
i
=findvarindex
(var
);
varhelp
[i
]=ftell(fin
);
}
fclose(fin
);
return 0;
}
int readconfigin
(char *filename
)
{
char *ptr
;
int res
;
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(helpfilename
,filename
);
strcat(helpfilename
,".hlp");
res
=parsehelp
(helpfilename
);
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