From 96fb364371ded6a9fc7f69da338396fd02966709 Mon Sep 17 00:00:00 2001 From: Jim Kowalkowski Date: Fri, 6 May 1994 10:38:38 +0000 Subject: [PATCH] Initial revision --- src/dbtools/dbLoadRecords.y | 308 ++++++++++++++++++++++++ src/dbtools/dbLoadRecords_lex.l | 29 +++ src/dbtools/dbLoadTemplate.y | 396 +++++++++++++++++++++++++++++++ src/dbtools/dbLoadTemplate_lex.l | 27 +++ src/dbtools/dbVarSub.c | 317 +++++++++++++++++++++++++ 5 files changed, 1077 insertions(+) create mode 100644 src/dbtools/dbLoadRecords.y create mode 100644 src/dbtools/dbLoadRecords_lex.l create mode 100644 src/dbtools/dbLoadTemplate.y create mode 100644 src/dbtools/dbLoadTemplate_lex.l create mode 100644 src/dbtools/dbVarSub.c diff --git a/src/dbtools/dbLoadRecords.y b/src/dbtools/dbLoadRecords.y new file mode 100644 index 000000000..9dde4b2ac --- /dev/null +++ b/src/dbtools/dbLoadRecords.y @@ -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 +#include + +#ifdef vxWorks +#include +#else +#include +#include +#endif + +#include "dbVarSub.h" +#include +#include + +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 COMMA +%token WORD VALUE +%token 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,$3) ) + fprintf(stderr,"Cannot find field %s\n",$3); +#endif + if(subst_used) + { + strcpy(subst_buffer,$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", + $3,subst_buffer); +#else + printf("\n\t\tfield(%s, \"%s\")",$3,subst_buffer); +#endif + } + else + { +#ifdef vxWorks + if( dbPutString(pdbentry, $5) ) + fprintf(stderr,"Cannot set field %s to %s\n",$3,$5); +#else + printf("\n\t\tfield(%s, \"%s\")",$3,$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 + } +} + diff --git a/src/dbtools/dbLoadRecords_lex.l b/src/dbtools/dbLoadRecords_lex.l new file mode 100644 index 000000000..ed2816e6a --- /dev/null +++ b/src/dbtools/dbLoadRecords_lex.l @@ -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 ++;} + +%% diff --git a/src/dbtools/dbLoadTemplate.y b/src/dbtools/dbLoadTemplate.y new file mode 100644 index 000000000..d57eff7eb --- /dev/null +++ b/src/dbtools/dbLoadTemplate.y @@ -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 +#include +#ifdef vxWorks +#include +#include +#else +#include +#include +#endif + +#include "dbVarSub.h" +#include + +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 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=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 diff --git a/src/dbtools/dbLoadTemplate_lex.l b/src/dbtools/dbLoadTemplate_lex.l new file mode 100644 index 000000000..4970477cd --- /dev/null +++ b/src/dbtools/dbLoadTemplate_lex.l @@ -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 ++;} + +%% diff --git a/src/dbtools/dbVarSub.c b/src/dbtools/dbVarSub.c new file mode 100644 index 000000000..f36abb34d --- /dev/null +++ b/src/dbtools/dbVarSub.c @@ -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 +#include + +#ifdef vxWorks +#include +#endif + +#include "dbVarSub.h" +#include + +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;iparent) + { + 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