diff --git a/src/dbtools/dbLoadTemplate.html b/src/dbtools/dbLoadTemplate.html
deleted file mode 100644
index 4943b8c6f..000000000
--- a/src/dbtools/dbLoadTemplate.html
+++ /dev/null
@@ -1,137 +0,0 @@
-/*************************************************************************\
-* Copyright (c) 2002 The University of Chicago, as Operator of Argonne
-* National Laboratory.
-* Copyright (c) 2002 The Regents of the University of California, as
-* Operator of Los Alamos National Laboratory.
-* EPICS BASE Versions 3.13.7
-* and higher are distributed subject to a Software License Agreement found
-* in file LICENSE that is included with this distribution.
-\*************************************************************************/
-
-
-
-
-
-
-NAME
- dbLoadRecords, dbLoadTemplate - load ascii database records
- into an IOC
-
-
-
-SYNOPSIS
- dbLoadRecords(char* db_file, char* substitutions)
-
- dbLoadTemplate(char* template_file)
-
-
-
-DESCRIPTION
- These routines are available from IOC core on the vxWorks
- command line. Both provide a way to load ascii ".db" files
- (usually created by gdct(1) ) into the IOC. The ".db" files
- contain ascii versions of record instances and are described
- in more detail in dbfile(5). In addition to loading the
- ".db" ascii files into the IOC, both routines provide a
- method of performing variable substitution on record names
- and field values.
-
- dbLoadRecords() reads the ".db" file db_file performing sub-
- stitutions specified in string substitutions. The substitu-
- tion must be a string specified as follows:
-
- "var1=sub1,var2=sub3,..."
-
- Variables are specified in the ".db" file as
- $(variable_name). If the substitution string
- "a=1,b=2,c=\"this is a test\"" were used, any variables
- $(a), $(b), or $(c) would be substituted with the appropri-
- ate data. See the EXAMPLES section for more details.
-
- dbLoadTemplate() will read a template_file. The
- template_file resides in the your IOC boot directory and
- contains rules about loading ".db" files and performing sub-
- stitutions. The template_file must be in the form used by
- an IOC and is described in templatefile(5). The EXAMPLES
- section descibes how it can be used.
-
-
-
-EXAMPLES
- The next two examples of dbLoadRecords() and dbLoadTem-
- plate() will use the following ".db" file named test.db :
-
- database(test)
- {
- record(ai,"$(pre)testrec1")
- record(ai,"$(pre)testrec2")
- record(stringout,"$(pre)testrec3")
- {
- field(VAL,"$(STRING)")
- field(SCAN,"$(SCAN)")
- }
- }
- Running dbLoadRecords ("test.db","pre=TEST,STRING=\"this is
- a test\",SCAN=Passive") will produce the following records
- in the IOC's database:
-
- TESTtestrec1
- TESTtestrec2
- TESTtestrec3
-
- The third record will have VAL set to "this is a test" and
- SCAN set to "Passive".
-
- Running dbLoadTemplate ("test.template") with test.template
- containing:
- file test.db
- {
- {pre=TEST1, STRING = "this is a test two", SCAN="1 Second" }
- {pre=TEST2, STRING = "this is a test one", SCAN=Passive }
- {pre=TEST3, STRING = "this is a test three", SCAN=Passive }
- }
- will produce a total of nine records in the IOC's database:
- TEST1testrec1
- TEST1testrec2
- TEST1testrec3 - (VAL="this is a test two", SCAN="1 Second")
- TEST2testrec1
- TEST2testrec2
- TEST2testrec3 - (VAL="this is a test one", SCAN="Passive")
- TEST3testrec1
- TEST3testrec2
- TEST3testrec3 - (VAL="this is a test three", SCAN="Passive")
-
-
-
-NOTES
- The binary file default.dctsdr must be loaded prior to run-
- ning either of these routines. This file contains the rules
- on how to construct records and change field values.
-
- After the default.dctsdr file is loaded, these routines can
- be run as many times as desired until iocInit is run.
-
-
-
-SEE ALSO
- gdct(1), templatefile(5), dbfile(5)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-Man(1) output converted with
-man2html
-
-
-
diff --git a/src/dbtools/dbLoadTemplate.y b/src/dbtools/dbLoadTemplate.y
index a9d8d2eb8..1364e1978 100644
--- a/src/dbtools/dbLoadTemplate.y
+++ b/src/dbtools/dbLoadTemplate.y
@@ -27,15 +27,15 @@ static int yyerror(char* str);
#define VAR_MAX_VAR_STRING 5000
#define VAR_MAX_VARS 100
-static char *sub_collect = NULL;
-static char *gbl_collect;
+static char *sub_collect;
+static char *sub_locals;
static char** vars = NULL;
static char* db_file_name = NULL;
static int var_count, sub_count;
%}
-%start template
+%start substitution_file
%token WORD QUOTE
%token DBFILE
@@ -55,67 +55,83 @@ static int var_count, sub_count;
%%
-template: templs
- | subst
+substitution_file: global_or_template
+ | substitution_file global_or_template
;
-templs: templs templ
- | templ
+global_or_template: global_definitions
+ | template_substitutions
;
-templ: templ_head O_BRACE subst C_BRACE
- | templ_head
+global_definitions: GLOBAL O_BRACE C_BRACE
+ | GLOBAL O_BRACE variable_definitions C_BRACE
{
- if (db_file_name)
- dbLoadRecords(db_file_name, NULL);
- else
- fprintf(stderr, "Error: no db file name given\n");
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "global_definitions: %s\n", sub_collect+1);
+ #endif
+ sub_locals += strlen(sub_locals);
}
;
-templ_head: DBFILE WORD
+template_substitutions: template_filename O_BRACE C_BRACE
{
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "template_substitutions: %s unused\n", db_file_name);
+ #endif
+ dbmfFree(db_file_name);
+ db_file_name = NULL;
+ }
+ | template_filename O_BRACE substitutions C_BRACE
+ {
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "template_substitutions: %s finished\n", db_file_name);
+ #endif
+ dbmfFree(db_file_name);
+ db_file_name = NULL;
+ }
+ ;
+
+template_filename: DBFILE WORD
+ {
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "template_filename: %s\n", $2);
+ #endif
var_count = 0;
- if (db_file_name)
- dbmfFree(db_file_name);
db_file_name = dbmfMalloc(strlen($2)+1);
strcpy(db_file_name, $2);
dbmfFree($2);
}
| DBFILE QUOTE
{
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "template_filename: \"%s\"\n", $2);
+ #endif
var_count = 0;
- if (db_file_name)
- dbmfFree(db_file_name);
db_file_name = dbmfMalloc(strlen($2)+1);
strcpy(db_file_name, $2);
dbmfFree($2);
}
;
-subst: PATTERN pattern subs
- | PATTERN pattern
- | var_subs
+substitutions: pattern_substitutions
+ | variable_substitutions
;
-pattern: O_BRACE vars C_BRACE
- {
-#ifdef ERROR_STUFF
- int i;
- for (i = 0; i < var_count; i++)
- fprintf(stderr, "variable = (%s)\n", vars[i]);
- fprintf(stderr, "var_count = %d\n", var_count);
-#endif
- }
- ;
-
-vars: vars var
- | vars COMMA var
- | var
- ;
-
-var: WORD
+pattern_substitutions: PATTERN O_BRACE C_BRACE
+ | PATTERN O_BRACE pattern_names C_BRACE
+ | PATTERN O_BRACE pattern_names C_BRACE pattern_definitions
+ ;
+
+pattern_names: pattern_name
+ | pattern_names COMMA
+ | pattern_names pattern_name
+ ;
+
+pattern_name: WORD
{
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "pattern_name: [%d] = %s\n", var_count, $1);
+ #endif
vars[var_count] = dbmfMalloc(strlen($1)+1);
strcpy(vars[var_count], $1);
var_count++;
@@ -123,123 +139,153 @@ var: WORD
}
;
-subs: subs sub
- | sub
+pattern_definitions: pattern_definition
+ | pattern_definitions pattern_definition
;
-sub: WORD O_BRACE vals C_BRACE
+pattern_definition: O_BRACE C_BRACE
{
- gbl_collect[strlen(gbl_collect) - 1] = '\0'; /* drop ',' */
-#ifdef ERROR_STUFF
- fprintf(stderr, "dbLoadRecords(%s)\n", sub_collect);
-#endif
- if (db_file_name)
- dbLoadRecords(db_file_name, sub_collect);
- else
- fprintf(stderr, "Error: no db file name given\n");
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "pattern_definition: pattern_values empty\n");
+ fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
+ #endif
+ dbLoadRecords(db_file_name, sub_collect+1);
+ }
+ | O_BRACE pattern_values C_BRACE
+ {
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "pattern_definition:\n");
+ fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
+ #endif
+ dbLoadRecords(db_file_name, sub_collect+1);
+ *sub_locals = '\0';
+ sub_count = 0;
+ }
+ | WORD O_BRACE pattern_values C_BRACE
+ { /* DEPRECATED SYNTAX */
+ fprintf(stderr,
+ "dbLoadTemplate: Substitution file uses deprecated syntax.\n"
+ " the string '%s' on line %d that comes just before the\n"
+ " '{' character is extraneous and should be removed.\n",
+ $1, line_num);
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "pattern_definition:\n");
+ fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
+ #endif
+ dbLoadRecords(db_file_name, sub_collect+1);
dbmfFree($1);
- *gbl_collect = '\0';
- sub_count = 0;
- }
- | O_BRACE vals C_BRACE
- {
- gbl_collect[strlen(gbl_collect) - 1] = '\0'; /* drop ',' */
-#ifdef ERROR_STUFF
- fprintf(stderr, "dbLoadRecords(%s)\n", sub_collect);
-#endif
- if (db_file_name)
- dbLoadRecords(db_file_name, sub_collect);
- else
- fprintf(stderr, "Error: no db file name given\n");
- *gbl_collect = '\0';
+ *sub_locals = '\0';
sub_count = 0;
}
;
-vals: vals val
- | vals COMMA val
- | val
+pattern_values: pattern_value
+ | pattern_values COMMA
+ | pattern_values pattern_value
;
-val: QUOTE
+pattern_value: QUOTE
{
- if (sub_count <= var_count) {
- strcat(gbl_collect, vars[sub_count]);
- strcat(gbl_collect, "=\"");
- strcat(gbl_collect, $1);
- strcat(gbl_collect, "\",");
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "pattern_value: [%d] = \"%s\"\n", sub_count, $1);
+ #endif
+ if (sub_count < var_count) {
+ strcat(sub_locals, ",");
+ strcat(sub_locals, vars[sub_count]);
+ strcat(sub_locals, "=\"");
+ strcat(sub_locals, $1);
+ strcat(sub_locals, "\"");
sub_count++;
+ } else {
+ fprintf(stderr, "dbLoadTemplate: Too many values given, line %d.\n",
+ line_num);
}
dbmfFree($1);
}
| WORD
{
- if (sub_count <= var_count) {
- strcat(gbl_collect, vars[sub_count]);
- strcat(gbl_collect, "=");
- strcat(gbl_collect, $1);
- strcat(gbl_collect, ",");
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "pattern_value: [%d] = %s\n", sub_count, $1);
+ #endif
+ if (sub_count < var_count) {
+ strcat(sub_locals, ",");
+ strcat(sub_locals, vars[sub_count]);
+ strcat(sub_locals, "=");
+ strcat(sub_locals, $1);
sub_count++;
+ } else {
+ fprintf(stderr, "dbLoadTemplate: Too many values given, line %d.\n",
+ line_num);
}
dbmfFree($1);
}
;
-var_subs: var_subs var_sub
- | var_sub
+variable_substitutions: variable_substitution
+ | variable_substitutions variable_substitution
;
-var_sub: WORD O_BRACE sub_pats C_BRACE
+variable_substitution: O_BRACE C_BRACE
{
- gbl_collect[strlen(gbl_collect) - 1] = '\0'; /* drop ',' */
-#ifdef ERROR_STUFF
- fprintf(stderr, "dbLoadRecords(%s)\n", sub_collect);
-#endif
- if (db_file_name)
- dbLoadRecords(db_file_name, sub_collect);
- else
- fprintf(stderr, "Error: no db file name given\n");
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "variable_substitution: variable_definitions empty\n");
+ fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
+ #endif
+ dbLoadRecords(db_file_name, sub_collect+1);
+ }
+ | O_BRACE variable_definitions C_BRACE
+ {
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "variable_substitution:\n");
+ fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
+ #endif
+ dbLoadRecords(db_file_name, sub_collect+1);
+ *sub_locals = '\0';
+ }
+ | WORD O_BRACE variable_definitions C_BRACE
+ { /* DEPRECATED SYNTAX */
+ fprintf(stderr,
+ "dbLoadTemplate: Substitution file uses deprecated syntax.\n"
+ " the string '%s' on line %d that comes just before the\n"
+ " '{' character is extraneous and should be removed.\n",
+ $1, line_num);
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "variable_substitution:\n");
+ fprintf(stderr, " dbLoadRecords(%s)\n", sub_collect+1);
+ #endif
+ dbLoadRecords(db_file_name, sub_collect+1);
dbmfFree($1);
- *gbl_collect = '\0';
- sub_count = 0;
- }
- | O_BRACE sub_pats C_BRACE
- {
- gbl_collect[strlen(gbl_collect) - 1] = '\0'; /* drop ',' */
-#ifdef ERROR_STUFF
- fprintf(stderr, "dbLoadRecords(%s)\n", sub_collect);
-#endif
- if (db_file_name)
- dbLoadRecords(db_file_name, sub_collect);
- else
- fprintf(stderr, "Error: no db file name given\n");
- *gbl_collect = '\0';
- sub_count = 0;
+ *sub_locals = '\0';
}
;
-sub_pats: sub_pats sub_pat
- | sub_pats COMMA sub_pat
- | sub_pat
+variable_definitions: variable_definition
+ | variable_definitions COMMA
+ | variable_definitions variable_definition
;
-sub_pat: WORD EQUALS WORD
+variable_definition: WORD EQUALS WORD
{
- strcat(gbl_collect, $1);
- strcat(gbl_collect, "=");
- strcat(gbl_collect, $3);
- strcat(gbl_collect, ",");
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "variable_definition: %s = %s\n", $1, $3);
+ #endif
+ strcat(sub_locals, ",");
+ strcat(sub_locals, $1);
+ strcat(sub_locals, "=");
+ strcat(sub_locals, $3);
dbmfFree($1); dbmfFree($3);
- sub_count++;
}
| WORD EQUALS QUOTE
{
- strcat(gbl_collect, $1);
- strcat(gbl_collect, "=\"");
- strcat(gbl_collect, $3);
- strcat(gbl_collect, "\",");
+ #ifdef ERROR_STUFF
+ fprintf(stderr, "variable_definition: %s = \"%s\"\n", $1, $3);
+ #endif
+ strcat(sub_locals, ",");
+ strcat(sub_locals, $1);
+ strcat(sub_locals, "=\"");
+ strcat(sub_locals, $3);
+ strcat(sub_locals, "\"");
dbmfFree($1); dbmfFree($3);
- sub_count++;
}
;
@@ -262,7 +308,7 @@ static int is_not_inited = 1;
int epicsShareAPI dbLoadTemplate(const char *sub_file, const char *cmd_collect)
{
FILE *fp;
- int ind;
+ int i;
line_num = 1;
@@ -286,14 +332,14 @@ int epicsShareAPI dbLoadTemplate(const char *sub_file, const char *cmd_collect)
fprintf(stderr, "dbLoadTemplate: Out of memory!\n");
return -1;
}
+ strcpy(sub_collect, ",");
if (cmd_collect && *cmd_collect) {
- strcpy(sub_collect, cmd_collect);
- strcat(sub_collect, ",");
- gbl_collect = sub_collect + strlen(sub_collect);
+ strcat(sub_collect, cmd_collect);
+ sub_locals = sub_collect + strlen(sub_collect);
} else {
- gbl_collect = sub_collect;
- *gbl_collect = '\0';
+ sub_locals = sub_collect;
+ *sub_locals = '\0';
}
var_count = 0;
sub_count = 0;
@@ -307,8 +353,8 @@ int epicsShareAPI dbLoadTemplate(const char *sub_file, const char *cmd_collect)
yyparse();
- for (ind = 0; ind < var_count; ind++) {
- dbmfFree(vars[ind]);
+ for (i = 0; i < var_count; i++) {
+ dbmfFree(vars[i]);
}
free(vars);
free(sub_collect);