Initial revision
This commit is contained in:
@@ -0,0 +1,308 @@
|
||||
%{
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Author: Jim Kowalkowski
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 10-29-93 jbk initial version
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <memLib.h>
|
||||
#else
|
||||
#include <memory.h>
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "dbVarSub.h"
|
||||
#include <dbStaticLib.h>
|
||||
#include <epicsVersion.h>
|
||||
|
||||
static char subst_buffer[VAR_MAX_SUB_SIZE];
|
||||
static int subst_used;
|
||||
static int line_num;
|
||||
|
||||
static int yyerror();
|
||||
static void sub_pvname(char*,char*);
|
||||
|
||||
#ifdef vxWorks
|
||||
static DBENTRY* pdbentry;
|
||||
extern struct dbBase *pdbBase;
|
||||
#endif
|
||||
|
||||
%}
|
||||
|
||||
%start database
|
||||
|
||||
%token <Str> COMMA
|
||||
%token <Str> WORD VALUE
|
||||
%token <Str> FIELD
|
||||
%left O_BRACE C_BRACE O_PAREN C_PAREN
|
||||
%left DATABASE CONTAINER RECORD
|
||||
%left NOWHERE
|
||||
|
||||
%union
|
||||
{
|
||||
int Int;
|
||||
char Char;
|
||||
char *Str;
|
||||
double Real;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
database: DATABASE d_head d_body
|
||||
{
|
||||
#ifdef vxWorks
|
||||
dbFreeEntry(pdbentry);
|
||||
#endif
|
||||
}
|
||||
| DATABASE d_head /* jbk added for graphical thing */
|
||||
{
|
||||
#ifdef vxWorks
|
||||
dbFreeEntry(pdbentry);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
|
||||
d_head: O_PAREN WORD C_PAREN
|
||||
{
|
||||
#ifdef vxWorks
|
||||
fprintf(stderr,"Warning: No EPICS version information in db file\n");
|
||||
pdbentry=dbAllocEntry(pdbBase);
|
||||
free($2);
|
||||
#endif
|
||||
}
|
||||
| O_PAREN WORD COMMA VALUE C_PAREN
|
||||
{
|
||||
#ifdef vxWorks
|
||||
int version,revision;
|
||||
char* v;
|
||||
|
||||
v=strtok($4," ."); sscanf(v,"%d",&version);
|
||||
v=strtok(NULL," ."); sscanf(v,"%d",&revision);
|
||||
|
||||
if(version!=EPICS_VERSION || revision!=EPICS_REVISION)
|
||||
fprintf(stderr,"Warning: Database not created with same version\n");
|
||||
|
||||
pdbentry=dbAllocEntry(pdbBase);
|
||||
free($2); free($4);
|
||||
#endif
|
||||
}
|
||||
;
|
||||
|
||||
d_body: O_BRACE nowhere_records db_components C_BRACE
|
||||
;
|
||||
|
||||
/* nowhere is here for back compatability */
|
||||
|
||||
nowhere_records: /* null */
|
||||
| NOWHERE n_head n_body
|
||||
;
|
||||
|
||||
n_head: O_PAREN C_PAREN
|
||||
;
|
||||
|
||||
n_body: O_BRACE records C_BRACE
|
||||
;
|
||||
|
||||
db_components: /* null */
|
||||
| db_components container
|
||||
| db_components record
|
||||
;
|
||||
|
||||
container: CONTAINER c_head c_body
|
||||
;
|
||||
|
||||
c_head: O_PAREN WORD C_PAREN
|
||||
{
|
||||
free($2);
|
||||
}
|
||||
;
|
||||
|
||||
c_body: O_BRACE db_components C_BRACE
|
||||
;
|
||||
|
||||
records: /* null */
|
||||
| records record
|
||||
;
|
||||
|
||||
record: RECORD r_head r_body
|
||||
{
|
||||
#ifndef vxWorks
|
||||
printf(" }\n");
|
||||
#endif
|
||||
}
|
||||
;
|
||||
|
||||
r_head: O_PAREN WORD COMMA WORD C_PAREN
|
||||
{
|
||||
sub_pvname($2,$4);
|
||||
free($2); free($4);
|
||||
}
|
||||
| O_PAREN WORD COMMA VALUE C_PAREN
|
||||
{
|
||||
sub_pvname($2,$4);
|
||||
free($2); free($4);
|
||||
}
|
||||
;
|
||||
|
||||
r_body: /* null */
|
||||
| O_BRACE fields C_BRACE
|
||||
;
|
||||
|
||||
fields: /* null */
|
||||
| fields field
|
||||
;
|
||||
|
||||
field: FIELD O_PAREN WORD COMMA VALUE C_PAREN
|
||||
{
|
||||
#ifdef vxWorks
|
||||
if( dbFindField(pdbentry,$<Str>3) )
|
||||
fprintf(stderr,"Cannot find field %s\n",$<Str>3);
|
||||
#endif
|
||||
if(subst_used)
|
||||
{
|
||||
strcpy(subst_buffer,$<Str>5);
|
||||
if(dbDoSubst(subst_buffer,sizeof(subst_buffer),NULL)!=0)
|
||||
fprintf(stderr,"dbDoSubst failed\n");
|
||||
#ifdef vxWorks
|
||||
if( dbPutString(pdbentry, subst_buffer) )
|
||||
fprintf(stderr,"Cannot set field %s to %s\n",
|
||||
$<Str>3,subst_buffer);
|
||||
#else
|
||||
printf("\n\t\tfield(%s, \"%s\")",$<Str>3,subst_buffer);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef vxWorks
|
||||
if( dbPutString(pdbentry, $<Str>5) )
|
||||
fprintf(stderr,"Cannot set field %s to %s\n",$<Str>3,$<Str>5);
|
||||
#else
|
||||
printf("\n\t\tfield(%s, \"%s\")",$<Str>3,$<Str>5);
|
||||
#endif
|
||||
}
|
||||
free($3); free($5);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
#include "dbLoadRecords_lex.c"
|
||||
|
||||
static int yyerror(str)
|
||||
char *str;
|
||||
{ fprintf(stderr,"db file parse, Error line %d : %s\n",line_num, yytext); }
|
||||
|
||||
static int is_not_inited = 1;
|
||||
|
||||
int dbLoadRecords(char* pfilename, char* pattern, char* container)
|
||||
{
|
||||
FILE* fp;
|
||||
long status;
|
||||
|
||||
#ifdef vxWorks
|
||||
if(pdbBase==NULL)
|
||||
{
|
||||
fprintf(stderr,"dbLoadRecords: default.dctsdr file not loaded\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if( pattern && *pattern )
|
||||
{
|
||||
subst_used = 1;
|
||||
dbInitSubst(pattern);
|
||||
}
|
||||
else
|
||||
subst_used = 0;
|
||||
|
||||
if( !(fp=fopen(pfilename,"r")) )
|
||||
{
|
||||
fprintf(stderr,"dbLoadRecords: error opening file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef vxWorks
|
||||
/* if(container) printf(" %s {\n",container); */
|
||||
#endif
|
||||
|
||||
if(is_not_inited)
|
||||
{
|
||||
yyin=fp;
|
||||
is_not_inited=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
yyrestart(fp);
|
||||
}
|
||||
yyparse();
|
||||
|
||||
#ifndef vxWorks
|
||||
/* if(container) printf(" }\n"); */
|
||||
#endif
|
||||
|
||||
if(subst_used) dbFreeSubst();
|
||||
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sub_pvname(char* type, char* name)
|
||||
{
|
||||
#ifdef vxWorks
|
||||
if( dbFindRecdes(pdbentry,type) )
|
||||
fprintf(stderr,"Cannot find record type %s\n",type);
|
||||
#endif
|
||||
|
||||
if(subst_used)
|
||||
{
|
||||
strcpy(subst_buffer,name);
|
||||
if(dbDoSubst(subst_buffer,PVNAME_STRINGSZ,NULL)!=0)
|
||||
fprintf(stderr,"dbDoSubst failed\n");
|
||||
#ifdef vxWorks
|
||||
if( dbCreateRecord(pdbentry,subst_buffer) )
|
||||
fprintf(stderr,"Cannot create record %s\n",subst_buffer);
|
||||
#else
|
||||
printf("\trecord(%s, \"%s\") {",type,subst_buffer);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef vxWorks
|
||||
if( dbCreateRecord(pdbentry,name) )
|
||||
fprintf(stderr,"Cannot create record %s\n",name);
|
||||
#else
|
||||
printf("\trecord(%s, \"%s\") {",type,name);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
pvname [a-zA-Z0-9_\-:\.\[\]<>]
|
||||
value [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\'\-&\(\)@\?\+<>=\$\{\}]
|
||||
|
||||
%{
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
"field" { return(FIELD); }
|
||||
"record" { return(RECORD); }
|
||||
"container" { return(CONTAINER); }
|
||||
"database" { return(DATABASE); }
|
||||
"nowhere" { return(NOWHERE); }
|
||||
|
||||
\"{value}*\" { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext+1); yylval.Str[strlen(yylval.Str)-1] = '\0'; return(VALUE); }
|
||||
|
||||
{pvname}+ { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext); return(WORD); }
|
||||
|
||||
"{" { return(O_BRACE); }
|
||||
"}" { return(C_BRACE); }
|
||||
"(" { return(O_PAREN); }
|
||||
")" { return(C_PAREN); }
|
||||
"," { return(COMMA); }
|
||||
|
||||
. ;
|
||||
\n { line_num ++;}
|
||||
|
||||
%%
|
||||
@@ -0,0 +1,396 @@
|
||||
%{
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Author: Jim Kowalkowski
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 10-29-93 jbk initial version
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#ifdef vxWorks
|
||||
#include <memLib.h>
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <memory.h>
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#include "dbVarSub.h"
|
||||
#include <epicsVersion.h>
|
||||
|
||||
static int line_num;
|
||||
static int yyerror();
|
||||
int dbLoadTemplate(char* sub_file);
|
||||
|
||||
#ifdef SUB_TOOL
|
||||
static int sub_it();
|
||||
#else
|
||||
int dbLoadRecords(char* pfilename, char* pattern, char* container);
|
||||
#endif
|
||||
|
||||
static char sub_collect[VAR_MAX_VAR_STRING];
|
||||
static char** vars;
|
||||
static char* db_file_name = (char*)NULL;
|
||||
static int var_count,sub_count;
|
||||
|
||||
%}
|
||||
|
||||
%start template
|
||||
|
||||
%token <Str> WORD QUOTE
|
||||
%token DBFILE
|
||||
%token PATTERN
|
||||
%token EQUALS
|
||||
%left O_PAREN C_PAREN
|
||||
%left O_BRACE C_BRACE
|
||||
|
||||
%union
|
||||
{
|
||||
int Int;
|
||||
char Char;
|
||||
char *Str;
|
||||
double Real;
|
||||
}
|
||||
|
||||
%%
|
||||
|
||||
template: templs
|
||||
| subst
|
||||
;
|
||||
|
||||
templs: templs templ
|
||||
| templ
|
||||
;
|
||||
|
||||
templ: templ_head O_BRACE subst C_BRACE
|
||||
;
|
||||
|
||||
templ_head: DBFILE WORD
|
||||
{
|
||||
var_count=0;
|
||||
if(db_file_name) free(db_file_name);
|
||||
db_file_name=$2;
|
||||
}
|
||||
;
|
||||
|
||||
subst: PATTERN pattern subs
|
||||
| var_subs
|
||||
;
|
||||
|
||||
pattern: O_BRACE vars C_BRACE
|
||||
{
|
||||
/*
|
||||
int i;
|
||||
for(i=0;i<var_count;i++) fprintf(stderr,"variable=(%s)\n",vars[i]);
|
||||
fprintf(stderr,"var_count=%d\n",var_count);
|
||||
*/
|
||||
}
|
||||
;
|
||||
|
||||
vars: vars var
|
||||
| var
|
||||
;
|
||||
|
||||
var: WORD
|
||||
{
|
||||
vars[var_count++]=$1;
|
||||
}
|
||||
;
|
||||
|
||||
subs: subs sub
|
||||
| sub
|
||||
;
|
||||
|
||||
sub: WORD O_BRACE vals C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,$1);
|
||||
else
|
||||
fprintf(stderr,"Error: no db file name given\n");
|
||||
#else
|
||||
sub_it();
|
||||
#endif
|
||||
|
||||
free($1);
|
||||
sub_collect[0]='\0';
|
||||
sub_count=0;
|
||||
}
|
||||
| O_BRACE vals C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,NULL);
|
||||
else
|
||||
fprintf(stderr,"Error: no db file name given\n");
|
||||
#else
|
||||
sub_it();
|
||||
#endif
|
||||
|
||||
sub_collect[0]='\0';
|
||||
sub_count=0;
|
||||
}
|
||||
;
|
||||
|
||||
vals: vals val
|
||||
| val
|
||||
;
|
||||
|
||||
val: QUOTE
|
||||
{
|
||||
if(sub_count<=var_count)
|
||||
{
|
||||
strcat(sub_collect,vars[sub_count]);
|
||||
strcat(sub_collect,"=\"");
|
||||
strcat(sub_collect,$1);
|
||||
strcat(sub_collect,"\",");
|
||||
free($1);
|
||||
sub_count++;
|
||||
}
|
||||
}
|
||||
| WORD
|
||||
{
|
||||
if(sub_count<=var_count)
|
||||
{
|
||||
strcat(sub_collect,vars[sub_count]);
|
||||
strcat(sub_collect,"=");
|
||||
strcat(sub_collect,$1);
|
||||
strcat(sub_collect,",");
|
||||
free($1);
|
||||
sub_count++;
|
||||
}
|
||||
}
|
||||
;
|
||||
|
||||
var_subs: var_subs var_sub
|
||||
| var_sub
|
||||
;
|
||||
|
||||
var_sub: WORD O_BRACE sub_pats C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,$1);
|
||||
else
|
||||
fprintf(stderr,"Error: no db file name given\n");
|
||||
#else
|
||||
sub_it();
|
||||
#endif
|
||||
|
||||
free($1);
|
||||
sub_collect[0]='\0';
|
||||
sub_count=0;
|
||||
}
|
||||
| O_BRACE sub_pats C_BRACE
|
||||
{
|
||||
sub_collect[strlen(sub_collect)-1]='\0';
|
||||
/* fprintf(stderr,"dbLoadRecords(%s)\n",sub_collect); */
|
||||
#ifndef SUB_TOOL
|
||||
if(db_file_name)
|
||||
dbLoadRecords(db_file_name,sub_collect,NULL);
|
||||
else
|
||||
fprintf(stderr,"Error: no db file name given\n");
|
||||
#else
|
||||
sub_it();
|
||||
#endif
|
||||
|
||||
sub_collect[0]='\0';
|
||||
sub_count=0;
|
||||
}
|
||||
;
|
||||
|
||||
sub_pats: sub_pats sub_pat
|
||||
| sub_pat
|
||||
;
|
||||
|
||||
sub_pat: WORD EQUALS WORD
|
||||
{
|
||||
strcat(sub_collect,$1);
|
||||
strcat(sub_collect,"=");
|
||||
strcat(sub_collect,$3);
|
||||
strcat(sub_collect,",");
|
||||
free($1); free($3);
|
||||
sub_count++;
|
||||
}
|
||||
| WORD EQUALS QUOTE
|
||||
{
|
||||
strcat(sub_collect,$1);
|
||||
strcat(sub_collect,"=\"");
|
||||
strcat(sub_collect,$3);
|
||||
strcat(sub_collect,"\",");
|
||||
free($1); free($3);
|
||||
sub_count++;
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
#include "dbLoadTemplate_lex.c"
|
||||
|
||||
static int yyerror(str)
|
||||
char *str;
|
||||
{ fprintf(stderr,"templ file parse, Error line %d : %s\n",line_num, yytext); }
|
||||
|
||||
static int is_not_inited = 1;
|
||||
|
||||
int dbLoadTemplate(char* sub_file)
|
||||
{
|
||||
FILE *fp;
|
||||
long status;
|
||||
|
||||
if( !sub_file || !*sub_file)
|
||||
{
|
||||
fprintf(stderr,"must specify variable substitution file\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if( !(fp=fopen(sub_file,"r")) )
|
||||
{
|
||||
fprintf(stderr,"dbLoadTemplate: error opening sub file %s\n",sub_file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
vars = (char**)malloc(VAR_MAX_VARS * sizeof(char*));
|
||||
sub_collect[0]='\0';
|
||||
var_count=0;
|
||||
sub_count=0;
|
||||
|
||||
if(is_not_inited)
|
||||
{
|
||||
yyin=fp;
|
||||
is_not_inited=0;
|
||||
}
|
||||
else yyrestart(fp);
|
||||
|
||||
yyparse();
|
||||
|
||||
free(vars);
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef vxWorks
|
||||
#ifdef SUB_TOOL
|
||||
/* this is generic substitution on any file */
|
||||
|
||||
char* dbfile;
|
||||
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
if(argc!=3)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s file sub_file\n",argv[0]);
|
||||
fprintf(stderr,"\n\twhere file is any ascii text file\n");
|
||||
fprintf(stderr,"\tsub_file in the variable substitution file\n");
|
||||
fprintf(stderr,"\n\tThis program uses the sub_file to perform\n");
|
||||
fprintf(stderr,"\tsubstitutions on to standard out.\n");
|
||||
exit(1);
|
||||
}
|
||||
dbfile = argv[1];
|
||||
dbLoadTemplate(argv[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* use sub_collect and db_file_name to do work */
|
||||
int sub_it()
|
||||
{
|
||||
FILE* fp;
|
||||
char var_buff[500];
|
||||
if( *sub_collect )
|
||||
dbInitSubst(sub_collect);
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"No valid substitutions found in table\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if( !(fp=fopen(dbfile,"r")) )
|
||||
{
|
||||
fprintf(stderr,"sub_tool: error opening file\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* do the work here */
|
||||
while( fgets(var_buff,200,fp)!=(char*)NULL )
|
||||
{
|
||||
dbDoSubst(var_buff,500,NULL);
|
||||
fputs(var_buff,stdout);
|
||||
}
|
||||
|
||||
dbFreeSubst();
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
/* this is template loader similar to vxWorks one for .db files */
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
extern char* optarg;
|
||||
extern int optind;
|
||||
char* name = (char*)NULL;
|
||||
int no_error = 1;
|
||||
int c;
|
||||
|
||||
while(no_error && (c=getopt(argc,argv,"s:"))!=-1)
|
||||
{
|
||||
switch(c)
|
||||
{
|
||||
case 's':
|
||||
if(name) free(name);
|
||||
name = strdup(optarg);
|
||||
break;
|
||||
default: no_error=0; break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!no_error || optind>=argc)
|
||||
{
|
||||
fprintf(stderr,"Usage: %s <-s name> sub_file\n",argv[0]);
|
||||
fprintf(stderr,"\n\twhere name is the output database name and\n");
|
||||
fprintf(stderr,"\tsub_file in the variable substitution file\n");
|
||||
fprintf(stderr,"\n\tThis program used the sub_file to produce a\n");
|
||||
fprintf(stderr,"\tdatabase of name name to standard out.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(!name) name = "Composite";
|
||||
|
||||
printf("database(name,\"%d.%d\") {\n",EPICS_VERSION,EPICS_REVISION,name);
|
||||
dbLoadTemplate(argv[1]);
|
||||
printf("}\n");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,27 @@
|
||||
|
||||
value [a-zA-Z0-9_\,\./\*#\[\]%: ;!|\-&\(\)@\?\+<>=\$]
|
||||
word [a-zA-Z0-9_\./\*#\[\]%:;!|\-&\$\(\)@\?\+<>]
|
||||
par [\"\']
|
||||
|
||||
%{
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
"pattern" { return(PATTERN); }
|
||||
"file" { return(DBFILE); }
|
||||
"=" { return(EQUALS); }
|
||||
|
||||
{par}{value}*{par} { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext+1); yylval.Str[strlen(yylval.Str)-1] = '\0'; return(QUOTE); }
|
||||
|
||||
{word}+ { yylval.Str=(char *)malloc(strlen(yytext)+1); strcpy(yylval.Str,yytext); return(WORD); }
|
||||
|
||||
"(" { return(O_PAREN); }
|
||||
")" { return(C_PAREN); }
|
||||
"{" { return(O_BRACE); }
|
||||
"}" { return(C_BRACE); }
|
||||
|
||||
. ;
|
||||
\n { line_num ++;}
|
||||
|
||||
%%
|
||||
@@ -0,0 +1,317 @@
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* Author: Jim Kowalkowski
|
||||
*
|
||||
* Experimental Physics and Industrial Control System (EPICS)
|
||||
*
|
||||
* Copyright 1991, the Regents of the University of California,
|
||||
* and the University of Chicago Board of Governors.
|
||||
*
|
||||
* This software was produced under U.S. Government contracts:
|
||||
* (W-7405-ENG-36) at the Los Alamos National Laboratory,
|
||||
* and (W-31-109-ENG-38) at Argonne National Laboratory.
|
||||
*
|
||||
* Initial development by:
|
||||
* The Controls and Automation Group (AT-8)
|
||||
* Ground Test Accelerator
|
||||
* Accelerator Technology Division
|
||||
* Los Alamos National Laboratory
|
||||
*
|
||||
* Co-developed with
|
||||
* The Controls and Computing Group
|
||||
* Accelerator Systems Division
|
||||
* Advanced Photon Source
|
||||
* Argonne National Laboratory
|
||||
*
|
||||
* Modification Log:
|
||||
* -----------------
|
||||
* .01 10-29-93 jbk initial version
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef vxWorks
|
||||
#include <memLib.h>
|
||||
#endif
|
||||
|
||||
#include "dbVarSub.h"
|
||||
#include <dbStaticLib.h>
|
||||
|
||||
static int subst_total;
|
||||
static struct var_sub *subst = (struct var_sub*)NULL;
|
||||
static char* pattern;
|
||||
|
||||
static char* get_var(char**, char*);
|
||||
static char* get_sub(char*, char*);
|
||||
|
||||
/* ------------------ variable substitution routines --------------*/
|
||||
#ifdef vxWorks
|
||||
static char* strdup(char*p) { return strcpy((char*)malloc(strlen(p)+1),p); }
|
||||
#endif
|
||||
|
||||
void dbFreeSubst()
|
||||
{
|
||||
int i;
|
||||
|
||||
if(subst)
|
||||
{
|
||||
free(pattern);
|
||||
free(subst);
|
||||
subst = (struct var_sub*)NULL;
|
||||
subst_total = 0;
|
||||
}
|
||||
}
|
||||
|
||||
long dbDoSubst(char* replace, int size, struct var_tree* par)
|
||||
{
|
||||
/* perform substitution */
|
||||
char preal[VAR_MAX_SUB_SIZE];
|
||||
char pvar[VAR_MAX_SUB_SIZE];
|
||||
char *to,*from,*pp;
|
||||
char *hold = NULL;
|
||||
int i,num_chars;
|
||||
struct var_tree* test_var;
|
||||
struct var_tree my_tree;
|
||||
int l;
|
||||
|
||||
my_tree.parent = par;
|
||||
l = strlen(replace);
|
||||
|
||||
for(num_chars=0,to=preal,from=replace;from<=(replace+l);)
|
||||
{
|
||||
/* see if this is really a variable */
|
||||
if(from[0]==VAR_START_IND && from[1]==VAR_LEFT_IND)
|
||||
{
|
||||
/* found a variable */
|
||||
from += 2;
|
||||
if( !(pp=strchr(from,VAR_RIGHT_IND)) )
|
||||
{
|
||||
fprintf(stderr,
|
||||
"dbDoSubst: Improper variable specification: %s\n",
|
||||
from);
|
||||
return -1;
|
||||
}
|
||||
*pp++ = '\0'; /* clear the closing paren for variable */
|
||||
for(i=0;i<subst_total&&strcmp(subst[i].var,from);i++);
|
||||
if(i<subst_total)
|
||||
{
|
||||
/* found a substitution */
|
||||
strcpy(pvar,subst[i].sub);
|
||||
|
||||
/* check for looping in substitution */
|
||||
my_tree.me=i;
|
||||
for(test_var=par;test_var;test_var=test_var->parent)
|
||||
{
|
||||
if(test_var->me==i)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"dbDoSubst: recursive definition of variable %s\n",
|
||||
from);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check for successful substitution */
|
||||
if(dbDoSubst(pvar,sizeof(pvar),&my_tree)<0) return -1;
|
||||
|
||||
/* copy substitution to output string */
|
||||
for(hold=pvar;*to=*hold++;num_chars++,to++)
|
||||
{
|
||||
if(num_chars>size)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"dbDoSubst: substitution to long: %s), max=%d (r)\n",
|
||||
replace,size);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* did not find a substitution */
|
||||
#ifdef vxWorks
|
||||
fprintf(stderr,"dbDoSubst: did not find sub for %s\n",from);
|
||||
#endif
|
||||
/* copy substitution to output string - this sucks */
|
||||
/* the "$()" part of the variable must be re-added */
|
||||
num_chars+=3; /* adjust for $() part */
|
||||
*to++='$'; /* put the variable $ back in */
|
||||
*to++='('; /* put the variable openning paren back in */
|
||||
for(hold=from;*to=*hold++;num_chars++,to++)
|
||||
{
|
||||
if(num_chars>size)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"dbDoSubst: substitution to long: %s), max=%d (e)\n",
|
||||
replace,size);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
*to++=')'; /* put the variable closing paren back in */
|
||||
}
|
||||
from = pp;
|
||||
}
|
||||
else
|
||||
{
|
||||
*to++ = *from++;
|
||||
if(num_chars++>size)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"dbDoSubst: substitution to long for %s\n",
|
||||
replace);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
strcpy(replace,preal);
|
||||
return 0;
|
||||
}
|
||||
|
||||
long dbInitSubst(char* parm_pattern)
|
||||
{
|
||||
char *pp,*hold;
|
||||
int rc,pi,pass;
|
||||
enum { var,sub } state;
|
||||
|
||||
/* --------- parse the pattern --------- */
|
||||
|
||||
rc=0;
|
||||
if(parm_pattern && *parm_pattern)
|
||||
{
|
||||
pattern = strdup(parm_pattern);
|
||||
|
||||
dbFreeSubst();
|
||||
|
||||
/* count the number of variables in the pattern (use the = sign) */
|
||||
for(subst_total=0,pp=pattern; *pp ;pp++)
|
||||
{
|
||||
/* find vars and subs */
|
||||
switch(*pp)
|
||||
{
|
||||
case '\\': pp++; break;
|
||||
case '=': subst_total++; break;
|
||||
case '\"': for(++pp;*pp!='\"';pp++) if(*pp=='\\') pp++; pp++; break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
/* fprintf(stderr,"total = %d\n",subst_total); */
|
||||
|
||||
/* allocate the substitution table */
|
||||
subst = (struct var_sub*)malloc( sizeof(struct var_sub)*subst_total );
|
||||
|
||||
/* fill table from pattern - this is kind-of putrid */
|
||||
subst_total=0;
|
||||
pp=pattern;
|
||||
state=var;
|
||||
while(*pp)
|
||||
{
|
||||
switch(*pp)
|
||||
{
|
||||
case ' ':
|
||||
case ',':
|
||||
case '\t': pp++; break;
|
||||
case '\\': pp+=2; break;
|
||||
case '=':
|
||||
case '\"':
|
||||
pp=get_sub(subst[subst_total++].sub,pp);
|
||||
state=var;
|
||||
break;
|
||||
default:
|
||||
if(state==var)
|
||||
{
|
||||
pp=get_var(&subst[subst_total].var,pp);
|
||||
state=sub;
|
||||
}
|
||||
else
|
||||
{
|
||||
pp=get_sub(subst[subst_total++].sub,pp);
|
||||
state=var;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* debug code */
|
||||
/*
|
||||
for(pi=0;pi<subst_total;pi++)
|
||||
{
|
||||
printf("table[%d]=(%s,%s)\n",pi,subst[pi].var,subst[pi].sub);
|
||||
}
|
||||
*/
|
||||
|
||||
/* resolve the multiple substitutions now */
|
||||
for(pi=0;pi<subst_total;pi++)
|
||||
{
|
||||
if(dbDoSubst(subst[pi].sub,VAR_MAX_SUB_SIZE,(struct var_tree*)NULL)<0)
|
||||
{
|
||||
fprintf(stderr, "dbInitSubst: failed to build variable substitution table (%s)\n",subst[pi].sub);
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* more debug code */
|
||||
/*
|
||||
for(pi=0;pi<subst_total;pi++)
|
||||
{
|
||||
printf("table[%d]=(%s,%s)\n",pi,subst[pi].var,subst[pi].sub);
|
||||
}
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
subst_total=0;
|
||||
subst=(struct var_sub*)NULL;
|
||||
}
|
||||
return(rc);
|
||||
}
|
||||
|
||||
/* put the pointer to the variable in "from" into "to" */
|
||||
static char* get_var(char** to, char* from)
|
||||
{
|
||||
char* pp;
|
||||
|
||||
pp = strpbrk(from," \t=");
|
||||
*pp = '\0';
|
||||
pp++;
|
||||
/* fprintf(stderr,"get_var: (%s)\n",from); */
|
||||
*to=from;
|
||||
return pp;
|
||||
}
|
||||
|
||||
/* copy the substitution in "from" into "to" */
|
||||
static char* get_sub(char* to, char* from)
|
||||
{
|
||||
char *pp,*hold;
|
||||
char* cp = to;
|
||||
|
||||
for(pp=from;*pp==' ' || *pp=='\t' || *pp=='=';pp++);
|
||||
|
||||
if(*pp=='\"')
|
||||
{
|
||||
for(++pp;*pp!='\"';pp++)
|
||||
{
|
||||
if(*pp=='\\') pp++;
|
||||
else *cp++ = *pp;
|
||||
}
|
||||
*cp='\0';
|
||||
/* fprintf(stderr,"get_sub: quote (%s)\n",to); */
|
||||
pp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(hold=pp;*hold && *hold!=',';hold++);
|
||||
if(*hold)
|
||||
{
|
||||
*hold = '\0';
|
||||
hold++;
|
||||
/* fprintf(stderr,"get_sub: regular (%s)\n",pp); */
|
||||
}
|
||||
|
||||
strcpy(to,pp);
|
||||
pp=hold;
|
||||
}
|
||||
return pp;
|
||||
}
|
||||
Reference in New Issue
Block a user