Added support for 'info' items in database records - named strings that
are saved & loaded in the .db file, with an API for access at runtime and
the ability to associate a void* pointer with each at runtime.
Also added a capability to dbToRecordTypeH allowing a record type's .dbd
file to add lines to the generated .h file. The C code should be placed
inside the recordtype's braces {} and each line must start with a '%'.
This facility is not currently accessible through a dbStaticLib API.
This commit is contained in:
@@ -107,10 +107,18 @@ typedef struct dbFldDes{ /* field description */
|
||||
short offset; /*Offset in bytes from beginning of record*/
|
||||
}dbFldDes;
|
||||
|
||||
typedef struct dbInfoNode { /*non-field per-record information*/
|
||||
ELLNODE node;
|
||||
char *name;
|
||||
char *string;
|
||||
void *pointer;
|
||||
}dbInfoNode;
|
||||
|
||||
typedef struct dbRecordNode {
|
||||
ELLNODE node;
|
||||
void *precord;
|
||||
char *recordname;
|
||||
ELLLIST infoList; /*LIST head of info nodes*/
|
||||
int visible;
|
||||
}dbRecordNode;
|
||||
|
||||
@@ -124,11 +132,17 @@ typedef struct dbRecordAttribute {
|
||||
char value[MAX_STRING_SIZE];
|
||||
}dbRecordAttribute;
|
||||
|
||||
typedef struct dbCdefText {
|
||||
ELLNODE node;
|
||||
char *text;
|
||||
}dbCdefText;
|
||||
|
||||
typedef struct dbRecordType {
|
||||
ELLNODE node;
|
||||
ELLLIST attributeList; /*LIST head of attributes*/
|
||||
ELLLIST recList; /*LIST head of sorted dbRecordNodes*/
|
||||
ELLLIST devList; /*List of associated device support*/
|
||||
ELLLIST cdefList; /*LIST of Cdef text items*/
|
||||
char *name;
|
||||
short no_fields; /* number of fields defined */
|
||||
short no_prompt; /* number of fields to configure*/
|
||||
@@ -153,5 +167,6 @@ typedef struct dbBase {
|
||||
void *ppvd; /* pointer to process variable directory*/
|
||||
void *pgpHash; /*General purpose Hash Table*/
|
||||
short ignoreMissingMenus;
|
||||
short loadCdefs;
|
||||
}dbBase;
|
||||
#endif
|
||||
|
||||
+43
-34
@@ -18,24 +18,25 @@ static int yyreset(void)
|
||||
|
||||
%%
|
||||
|
||||
"include" {return(tokenINCLUDE);}
|
||||
"path" {return(tokenPATH);}
|
||||
"addpath" {return(tokenADDPATH);}
|
||||
"menu" {return(tokenMENU);}
|
||||
"choice" {return(tokenCHOICE);}
|
||||
"recordtype" {return(tokenRECORDTYPE);}
|
||||
"field" {return(tokenFIELD);}
|
||||
"device" {return(tokenDEVICE);}
|
||||
"driver" {return(tokenDRIVER);}
|
||||
"breaktable" {return(tokenBREAKTABLE);}
|
||||
"record" {return(tokenRECORD);}
|
||||
"grecord" {return(tokenGRECORD);}
|
||||
"include" return(tokenINCLUDE);
|
||||
"path" return(tokenPATH);
|
||||
"addpath" return(tokenADDPATH);
|
||||
"menu" return(tokenMENU);
|
||||
"choice" return(tokenCHOICE);
|
||||
"recordtype" return(tokenRECORDTYPE);
|
||||
"field" return(tokenFIELD);
|
||||
"device" return(tokenDEVICE);
|
||||
"driver" return(tokenDRIVER);
|
||||
"breaktable" return(tokenBREAKTABLE);
|
||||
"record" return(tokenRECORD);
|
||||
"grecord" return(tokenGRECORD);
|
||||
"info" return(tokenINFO);
|
||||
|
||||
[0-9]+ { /*integer number*/
|
||||
yylval.Str = (char *)dbmfMalloc(strlen(yytext)+1);
|
||||
strcpy(yylval.Str,yytext);
|
||||
return(tokenSTRING);
|
||||
}
|
||||
}
|
||||
|
||||
-?(([0-9]+)|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { /*real number*/
|
||||
yylval.Str = (char *)dbmfMalloc(strlen(yytext)+1);
|
||||
@@ -51,29 +52,37 @@ static int yyreset(void)
|
||||
}
|
||||
|
||||
\"{string}*\" { /*quoted string*/
|
||||
yylval.Str = (char *)dbmfMalloc(strlen(yytext)+1);
|
||||
strcpy(yylval.Str,yytext+1);
|
||||
yylval.Str[strlen(yylval.Str)-1] = '\0';
|
||||
return(tokenSTRING);
|
||||
int nchars=strlen(yytext);
|
||||
yylval.Str = (char *)dbmfMalloc(nchars-1);
|
||||
strncpy(yylval.Str, yytext+1, nchars-2);
|
||||
yylval.Str[nchars-2] = '\0';
|
||||
return(tokenSTRING);
|
||||
}
|
||||
|
||||
"{" { return(yytext[0]); }
|
||||
"}" { return(yytext[0]); }
|
||||
"(" { return(yytext[0]); }
|
||||
")" { return(yytext[0]); }
|
||||
"," { return(yytext[0]); }
|
||||
#.* { ;}
|
||||
%.* { /*C definition in recordtype*/
|
||||
yylval.Str = (char *)dbmfMalloc(strlen(yytext));
|
||||
strcpy(yylval.Str,yytext+1);
|
||||
return(tokenCDEFS);
|
||||
}
|
||||
|
||||
"{" return(yytext[0]);
|
||||
"}" return(yytext[0]);
|
||||
"(" return(yytext[0]);
|
||||
")" return(yytext[0]);
|
||||
"," return(yytext[0]);
|
||||
\#.* ;
|
||||
[ \t\r] ;
|
||||
\n { ;}
|
||||
. {
|
||||
char message[20];
|
||||
YY_BUFFER_STATE *dummy=0;
|
||||
|
||||
sprintf(message,"invalid character '%c'",yytext[0]);
|
||||
yyerror(message);
|
||||
/*The following suppresses compiler warning messages*/
|
||||
if(FALSE) yyunput('c',message);
|
||||
if(FALSE) yy_switch_to_buffer(*dummy);
|
||||
}
|
||||
\n ;
|
||||
|
||||
. {
|
||||
char message[20];
|
||||
YY_BUFFER_STATE *dummy=0;
|
||||
|
||||
sprintf(message,"invalid character '%c'",yytext[0]);
|
||||
yyerror(message);
|
||||
/*The following suppresses compiler warning messages*/
|
||||
if(FALSE) yyunput('c',message);
|
||||
if(FALSE) yy_switch_to_buffer(*dummy);
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
@@ -467,6 +467,7 @@ static void dbRecordtypeHead(char *name)
|
||||
}
|
||||
pdbRecordType = dbCalloc(1,sizeof(dbRecordType));
|
||||
pdbRecordType->name = strduplicate(name);
|
||||
if (pdbbase->loadCdefs) ellInit(&pdbRecordType->cdefList);
|
||||
if(ellCount(&tempList))
|
||||
yyerrorAbort("dbRecordtypeHead tempList not empty");
|
||||
allocTemp(pdbRecordType);
|
||||
@@ -582,6 +583,22 @@ static void dbRecordtypeFieldItem(char *name,char *value)
|
||||
}
|
||||
}
|
||||
|
||||
static void dbRecordtypeCdef(char *text) {
|
||||
dbCdefText *pdbCdef;
|
||||
tempListNode *ptempListNode;
|
||||
dbRecordType *pdbRecordType;
|
||||
|
||||
if (!pdbbase->loadCdefs || duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbRecordType = ptempListNode->item;
|
||||
|
||||
pdbCdef = dbCalloc(1,sizeof(dbCdefText));
|
||||
if (text[0] == ' ') text++; /* strip leading space if present */
|
||||
pdbCdef->text = strduplicate(text);
|
||||
ellAdd(&pdbRecordType->cdefList, &pdbCdef->node);
|
||||
return;
|
||||
}
|
||||
|
||||
static void dbRecordtypeBody(void)
|
||||
{
|
||||
dbRecordType *pdbRecordType;
|
||||
@@ -866,6 +883,23 @@ static void dbRecordField(char *name,char *value)
|
||||
}
|
||||
}
|
||||
|
||||
static void dbRecordInfo(char *name, char *value)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
tempListNode *ptempListNode;
|
||||
long status;
|
||||
|
||||
if(duplicate) return;
|
||||
ptempListNode = (tempListNode *)ellFirst(&tempList);
|
||||
pdbentry = ptempListNode->item;
|
||||
status = dbPutInfo(pdbentry,name,value);
|
||||
if(status) {
|
||||
errMessage(status,"");
|
||||
yyerror(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void dbRecordBody(void)
|
||||
{
|
||||
DBENTRY *pdbentry;
|
||||
|
||||
@@ -923,6 +923,12 @@ long epicsShareAPI dbWriteRecordFP(DBBASE *pdbbase,FILE *fp,char *precordTypenam
|
||||
}
|
||||
status=dbNextField(pdbentry,dctonly);
|
||||
}
|
||||
status = dbFirstInfo(pdbentry);
|
||||
while(!status) {
|
||||
fprintf(fp,"\tinfo(\"%s\",\"%s\")\n",
|
||||
dbGetInfoName(pdbentry), dbGetInfoString(pdbentry));
|
||||
status=dbNextInfo(pdbentry);
|
||||
}
|
||||
fprintf(fp,"}\n");
|
||||
status = dbNextRecord(pdbentry);
|
||||
}
|
||||
@@ -1441,6 +1447,7 @@ long epicsShareAPI dbCreateRecord(DBENTRY *pdbentry,char *precordName)
|
||||
pdbentry->precnode = pNewRecNode;
|
||||
if((status = dbAllocRecord(pdbentry,precordName))) return(status);
|
||||
pNewRecNode->recordname = dbRecordName(pdbentry);
|
||||
ellInit(&pNewRecNode->infoList);
|
||||
/* install record node in list in sorted postion */
|
||||
status = dbFirstRecord(pdbentry);
|
||||
while(status==0) {
|
||||
@@ -1471,6 +1478,9 @@ long epicsShareAPI dbDeleteRecord(DBENTRY *pdbentry)
|
||||
preclist = &precordType->recList;
|
||||
ellDelete(preclist,&precnode->node);
|
||||
dbPvdDelete(pdbbase,precnode);
|
||||
while (!dbFirstInfo(pdbentry)) {
|
||||
dbDeleteInfo(pdbentry);
|
||||
}
|
||||
if((status = dbFreeRecord(pdbentry))) return(status);
|
||||
free((void *)precnode);
|
||||
pdbentry->precnode = NULL;
|
||||
@@ -1680,6 +1690,13 @@ long epicsShareAPI dbCopyRecord(DBENTRY *pdbentry,char *newRecordName,int overWr
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
/*Copy the info strings too*/
|
||||
status = dbFirstInfo(pdbentry);
|
||||
while (!status) {
|
||||
status = dbPutInfo(&dbentry, dbGetInfoName(pdbentry), dbGetInfoString(pdbentry));
|
||||
if (status) return (status);
|
||||
status = dbNextInfo(pdbentry);
|
||||
}
|
||||
/*Leave pdbentry pointing to newRecordName*/
|
||||
return(dbFindRecord(pdbentry,newRecordName));
|
||||
}
|
||||
@@ -2484,6 +2501,143 @@ char *epicsShareAPI dbGetRange(DBENTRY *pdbentry)
|
||||
strcpy(message,"Not a valid field type");
|
||||
return (message);
|
||||
}
|
||||
|
||||
long epicsShareAPI dbFirstInfo(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
|
||||
pdbentry->pinfonode = NULL;
|
||||
if (!precnode) return (S_dbLib_recNotFound);
|
||||
|
||||
pdbentry->pinfonode = (dbInfoNode *)ellFirst(&precnode->infoList);
|
||||
return (pdbentry->pinfonode ? 0 : S_dbLib_infoNotFound);
|
||||
}
|
||||
|
||||
long epicsShareAPI dbNextInfo(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbInfoNode *pinfo;
|
||||
|
||||
if (!precnode) return (S_dbLib_recNotFound);
|
||||
pinfo = pdbentry->pinfonode;
|
||||
if (!pinfo) return (S_dbLib_infoNotFound);
|
||||
|
||||
pinfo = (dbInfoNode *)ellNext(&pinfo->node);
|
||||
pdbentry->pinfonode = pinfo;
|
||||
return (pinfo ? 0 : S_dbLib_infoNotFound);
|
||||
}
|
||||
|
||||
long epicsShareAPI dbFindInfo(DBENTRY *pdbentry,const char *name)
|
||||
{
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbInfoNode *pinfo;
|
||||
|
||||
pdbentry->pinfonode = NULL;
|
||||
if (!precnode) return(S_dbLib_recNotFound);
|
||||
|
||||
pinfo = (dbInfoNode *)ellFirst(&precnode->infoList);
|
||||
while (pinfo) {
|
||||
if (!strcmp(pinfo->name, name)) {
|
||||
pdbentry->pinfonode = pinfo;
|
||||
return (0);
|
||||
}
|
||||
pinfo = (dbInfoNode *)ellNext(&pinfo->node);
|
||||
}
|
||||
return (S_dbLib_infoNotFound);
|
||||
}
|
||||
|
||||
long epicsShareAPI dbDeleteInfo(DBENTRY *pdbentry)
|
||||
{
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
dbInfoNode *pinfo = pdbentry->pinfonode;
|
||||
|
||||
if (!precnode) return (S_dbLib_recNotFound);
|
||||
if (!pinfo) return (S_dbLib_infoNotFound);
|
||||
ellDelete(&precnode->infoList,&pinfo->node);
|
||||
free(pinfo->name);
|
||||
free(pinfo->string);
|
||||
free(pinfo);
|
||||
pdbentry->pinfonode = NULL;
|
||||
return (0);
|
||||
}
|
||||
|
||||
const char * epicsShareAPI dbGetInfoName(DBENTRY *pdbentry)
|
||||
{
|
||||
dbInfoNode *pinfo = pdbentry->pinfonode;
|
||||
if (!pinfo) return (NULL);
|
||||
return (pinfo->name);
|
||||
}
|
||||
|
||||
const char * epicsShareAPI dbGetInfoString(DBENTRY *pdbentry)
|
||||
{
|
||||
dbInfoNode *pinfo = pdbentry->pinfonode;
|
||||
if (!pinfo) return (NULL);
|
||||
return (pinfo->string);
|
||||
}
|
||||
|
||||
long epicsShareAPI dbPutInfoString(DBENTRY *pdbentry,const char *string)
|
||||
{
|
||||
dbInfoNode *pinfo = pdbentry->pinfonode;
|
||||
char *newstring;
|
||||
if (!pinfo) return (S_dbLib_infoNotFound);
|
||||
newstring = realloc(pinfo->string,1+strlen(string));
|
||||
if (!newstring) return (S_dbLib_outMem);
|
||||
strcpy(newstring, string);
|
||||
pinfo->string = newstring;
|
||||
return (0);
|
||||
}
|
||||
|
||||
long epicsShareAPI dbPutInfoPointer(DBENTRY *pdbentry, void *pointer)
|
||||
{
|
||||
dbInfoNode *pinfo = pdbentry->pinfonode;
|
||||
if (!pinfo) return (S_dbLib_infoNotFound);
|
||||
pinfo->pointer = pointer;
|
||||
return (0);
|
||||
}
|
||||
|
||||
const char * epicsShareAPI dbGetInfoPointer(DBENTRY *pdbentry)
|
||||
{
|
||||
dbInfoNode *pinfo = pdbentry->pinfonode;
|
||||
if (!pinfo) return (NULL);
|
||||
return (pinfo->pointer);
|
||||
}
|
||||
|
||||
const char * epicsShareAPI dbGetInfo(DBENTRY *pdbentry,const char *name)
|
||||
{
|
||||
dbFindInfo(pdbentry, name);
|
||||
return (dbGetInfoString(pdbentry));
|
||||
}
|
||||
|
||||
long epicsShareAPI dbPutInfo(DBENTRY *pdbentry,const char *name,const char *string)
|
||||
{
|
||||
dbInfoNode *pinfo;
|
||||
dbRecordNode *precnode = pdbentry->precnode;
|
||||
if (!precnode) return (S_dbLib_recNotFound);
|
||||
|
||||
dbFindInfo(pdbentry, name);
|
||||
pinfo = pdbentry->pinfonode;
|
||||
if (pinfo) return (dbPutInfoString(pdbentry, string));
|
||||
|
||||
/*Create new info node*/
|
||||
pinfo = calloc(1,sizeof(dbInfoNode));
|
||||
if (!pinfo) return (S_dbLib_outMem);
|
||||
pinfo->name = calloc(1,1+strlen(name));
|
||||
if (!pinfo->name) {
|
||||
free(pinfo);
|
||||
return (S_dbLib_outMem);
|
||||
}
|
||||
strcpy(pinfo->name, name);
|
||||
pinfo->string = calloc(1,1+strlen(string));
|
||||
if (!pinfo->string) {
|
||||
free(pinfo->name);
|
||||
free(pinfo);
|
||||
return (S_dbLib_outMem);
|
||||
}
|
||||
strcpy(pinfo->string, string);
|
||||
ellAdd(&precnode->infoList,&pinfo->node);
|
||||
pdbentry->pinfonode = pinfo;
|
||||
return (0);
|
||||
}
|
||||
|
||||
brkTable * epicsShareAPI dbFindBrkTable(dbBase *pdbbase,char *name)
|
||||
{
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef struct{
|
||||
dbRecordType *precordType;
|
||||
dbFldDes *pflddes;
|
||||
dbRecordNode *precnode;
|
||||
dbInfoNode *pinfonode;
|
||||
void *pfield;
|
||||
char *message;
|
||||
short indfield;
|
||||
@@ -159,6 +160,18 @@ epicsShareFunc char * epicsShareAPI dbVerify(DBENTRY *pdbentry,char *pstring);
|
||||
epicsShareFunc char * epicsShareAPI dbGetRange(DBENTRY *pdbentry);
|
||||
epicsShareFunc int epicsShareAPI dbIsDefaultValue(DBENTRY *pdbentry);
|
||||
|
||||
epicsShareFunc long epicsShareAPI dbFirstInfo(DBENTRY *pdbentry);
|
||||
epicsShareFunc long epicsShareAPI dbNextInfo(DBENTRY *pdbentry);
|
||||
epicsShareFunc long epicsShareAPI dbFindInfo(DBENTRY *pdbentry,const char *name);
|
||||
epicsShareFunc long epicsShareAPI dbDeleteInfo(DBENTRY *pdbentry);
|
||||
epicsShareFunc const char * epicsShareAPI dbGetInfoName(DBENTRY *pdbentry);
|
||||
epicsShareFunc const char * epicsShareAPI dbGetInfoString(DBENTRY *pdbentry);
|
||||
epicsShareFunc long epicsShareAPI dbPutInfoString(DBENTRY *pdbentry,const char *string);
|
||||
epicsShareFunc long epicsShareAPI dbPutInfoPointer(DBENTRY *pdbentry, void *pointer);
|
||||
epicsShareFunc const char * epicsShareAPI dbGetInfoPointer(DBENTRY *pdbentry);
|
||||
epicsShareFunc const char * epicsShareAPI dbGetInfo(DBENTRY *pdbentry,const char *name);
|
||||
epicsShareFunc long epicsShareAPI dbPutInfo(DBENTRY *pdbentry,const char *name,const char *string);
|
||||
|
||||
epicsShareFunc brkTable * epicsShareAPI dbFindBrkTable(DBBASE *pdbbase,char *name);
|
||||
|
||||
epicsShareFunc dbMenu * epicsShareAPI dbFindMenu(DBBASE *pdbbase,char *name);
|
||||
@@ -196,7 +209,7 @@ epicsShareFunc void epicsShareAPI dbPvdDump(DBBASE *pdbbase,int verbose);
|
||||
epicsShareFunc void epicsShareAPI dbReportDeviceConfig(DBBASE *pdbbase,FILE *report);
|
||||
|
||||
/* Misc useful routines*/
|
||||
/*general purpose allocation routines to invoke calloc and maloc */
|
||||
/*general purpose allocation routines to invoke calloc and malloc */
|
||||
/* NOTE: These routines do NOT return if they fail. */
|
||||
epicsShareFunc void * epicsShareAPI dbCalloc(size_t nobj,size_t size);
|
||||
epicsShareFunc void * epicsShareAPI dbMalloc(size_t size);
|
||||
@@ -217,4 +230,6 @@ extern int dbStaticDebug;
|
||||
#define S_dbLib_strLen (M_dbLib|21) /*String is too long*/
|
||||
#define S_dbLib_noSizeOffset (M_dbLib|23) /*Missing SizeOffset Routine - No record support?*/
|
||||
#define S_dbLib_noForm (M_dbLib|25) /*dbAllocForm was not called*/
|
||||
#define S_dbLib_outMem (M_dbLib|27) /*Out of memory*/
|
||||
#define S_dbLib_infoNotFound (M_dbLib|29) /*Info item Not Found*/
|
||||
#endif /*INCdbStaticLibh*/
|
||||
|
||||
@@ -42,6 +42,7 @@ int main(int argc,char **argv)
|
||||
dbMenu *pdbMenu;
|
||||
dbRecordType *pdbRecordType;
|
||||
dbFldDes *pdbFldDes;
|
||||
dbCdefText *pdbCdef;
|
||||
int isdbCommonRecord = FALSE;
|
||||
char *plastSlash;
|
||||
int strip;
|
||||
@@ -117,6 +118,7 @@ int main(int argc,char **argv)
|
||||
}
|
||||
pdbbase = dbAllocBase();
|
||||
pdbbase->ignoreMissingMenus = TRUE;
|
||||
pdbbase->loadCdefs = TRUE;
|
||||
status = dbReadDatabase(&pdbbase,argv[1],path,sub);
|
||||
if(status) {
|
||||
fprintf(stderr,"Terminal error For input file %s\n",argv[1]);
|
||||
@@ -221,6 +223,11 @@ int main(int argc,char **argv)
|
||||
fprintf(outFile,"#define %sRecord%s\t%d\n",
|
||||
pdbRecordType->name,pdbFldDes->name,pdbFldDes->indRecordType);
|
||||
}
|
||||
pdbCdef = (dbCdefText *)ellFirst(&pdbRecordType->cdefList);
|
||||
while (pdbCdef) {
|
||||
fprintf(outFile,"%s\n",pdbCdef->text);
|
||||
pdbCdef = (dbCdefText *)ellNext(&pdbCdef->node);
|
||||
}
|
||||
}
|
||||
fprintf(outFile,"#endif /*INC%sH*/\n",pdbRecordType->name);
|
||||
pdbRecordType = (dbRecordType *)ellNext(&pdbRecordType->node);
|
||||
|
||||
+14
-3
@@ -10,10 +10,11 @@ static int yyAbort = 0;
|
||||
%start database
|
||||
|
||||
%token tokenINCLUDE tokenPATH tokenADDPATH
|
||||
%token tokenMENU tokenCHOICE tokenRECORDTYPE tokenFIELD
|
||||
%token tokenMENU tokenCHOICE tokenRECORDTYPE
|
||||
%token tokenFIELD tokenINFO
|
||||
%token tokenDEVICE tokenDRIVER tokenBREAKTABLE
|
||||
%token tokenRECORD tokenGRECORD
|
||||
%token <Str> tokenSTRING
|
||||
%token <Str> tokenSTRING tokenCDEFS
|
||||
|
||||
%union
|
||||
{
|
||||
@@ -88,9 +89,14 @@ recordtype_body: '{' recordtype_field_list '}'
|
||||
};
|
||||
|
||||
recordtype_field_list: recordtype_field_list recordtype_field
|
||||
| recordtype_field;
|
||||
| recordtype_field;
|
||||
|
||||
recordtype_field: tokenFIELD recordtype_field_head recordtype_field_body
|
||||
| tokenCDEFS
|
||||
{
|
||||
if(dbStaticDebug>2) printf("recordtype_cdef %s", $1);
|
||||
dbRecordtypeCdef($1);
|
||||
}
|
||||
| include ;
|
||||
|
||||
recordtype_field_head: '(' tokenSTRING ',' tokenSTRING ')'
|
||||
@@ -191,6 +197,11 @@ record_field: tokenFIELD '(' tokenSTRING ',' tokenSTRING ')'
|
||||
{
|
||||
if(dbStaticDebug>2) printf("record_field %s %s\n",$3,$5);
|
||||
dbRecordField($3,$5); dbmfFree($3); dbmfFree($5);
|
||||
}
|
||||
| tokenINFO '(' tokenSTRING ',' tokenSTRING ')'
|
||||
{
|
||||
if(dbStaticDebug>2) printf("record_info %s %s\n",$3,$5);
|
||||
dbRecordInfo($3,$5); dbmfFree($3); dbmfFree($5);
|
||||
}
|
||||
| include ;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user