369 lines
7.8 KiB
Plaintext
369 lines
7.8 KiB
Plaintext
/*************************************************************************\
|
|
* 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.
|
|
* SPDX-License-Identifier: EPICS
|
|
* EPICS BASE is distributed subject to a Software License Agreement found
|
|
* in file LICENSE that is included with this distribution.
|
|
\*************************************************************************/
|
|
%{
|
|
static int yyerror(char *);
|
|
static int yy_start;
|
|
#include "asLibRoutines.c"
|
|
static int yyFailed = FALSE;
|
|
static int yyWarned = FALSE;
|
|
static int line_num=1;
|
|
static UAG *yyUag=NULL;
|
|
static HAG *yyHag=NULL;
|
|
static ASG *yyAsg=NULL;
|
|
static ASGRULE *yyAsgRule=NULL;
|
|
|
|
static
|
|
char* yystrdup(const char *inp) {
|
|
char* ret = strdup(inp);
|
|
if(!ret)
|
|
yyerror("MALLOC");
|
|
return ret;
|
|
}
|
|
|
|
%}
|
|
|
|
%start asconfig
|
|
|
|
%token tokenUAG tokenHAG tokenASG tokenRULE tokenCALC
|
|
%token <Str> tokenSTRING
|
|
%token <Int64> tokenINT64 tokenINP
|
|
%token <Float64> tokenFLOAT64
|
|
|
|
%union
|
|
{
|
|
epicsInt64 Int64;
|
|
epicsFloat64 Float64;
|
|
char *Str;
|
|
}
|
|
|
|
%type <Str> non_rule_keyword
|
|
%type <Str> generic_block_elem_name
|
|
%type <Str> generic_block_elem
|
|
%type <Str> rule_generic_block_elem
|
|
%type <Str> rule_generic_block_elem_name
|
|
%type <Str> keyword
|
|
|
|
%%
|
|
|
|
asconfig: asconfig asconfig_item
|
|
| asconfig_item
|
|
|
|
asconfig_item: tokenUAG uag_head uag_body
|
|
| tokenUAG uag_head
|
|
| tokenHAG hag_head hag_body
|
|
| tokenHAG hag_head
|
|
| tokenASG asg_head asg_body
|
|
| tokenASG asg_head
|
|
| generic_item
|
|
;
|
|
|
|
/* uniformally yield a string for use in warning messages */
|
|
keyword: tokenUAG
|
|
{ $$ = yystrdup("UAG"); }
|
|
| tokenHAG
|
|
{ $$ = yystrdup("HAG"); }
|
|
| tokenCALC
|
|
{ $$ = yystrdup("CALC"); }
|
|
| non_rule_keyword
|
|
;
|
|
|
|
non_rule_keyword: tokenASG
|
|
{ $$ = yystrdup("ASG"); }
|
|
| tokenRULE
|
|
{ $$ = yystrdup("RULE"); }
|
|
| tokenINP
|
|
{
|
|
if(!!($$ = yystrdup("INPA")))
|
|
$$[3] += $1; /* 'A' + input number */
|
|
}
|
|
;
|
|
|
|
generic_item: tokenSTRING generic_head generic_list_block
|
|
{
|
|
yywarn("Ignoring unsupported TOP LEVEL nested block", $1);
|
|
free($1);
|
|
}
|
|
| tokenSTRING generic_head generic_block
|
|
{
|
|
yywarn("Ignoring unsupported TOP LEVEL block", $1);
|
|
free($1);
|
|
}
|
|
| tokenSTRING generic_head
|
|
{
|
|
yywarn("Ignoring unsupported TOP LEVEL bare block", $1);
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
generic_head: '(' ')'
|
|
| '(' generic_element ')'
|
|
| '(' generic_list ')'
|
|
;
|
|
|
|
generic_list_block: '{' generic_element '}'
|
|
'{' generic_list '}'
|
|
;
|
|
|
|
generic_list: generic_list ',' generic_element
|
|
| generic_element ',' generic_element
|
|
;
|
|
|
|
generic_element: keyword
|
|
| tokenSTRING
|
|
{
|
|
free($1);
|
|
}
|
|
| tokenINT64
|
|
| tokenFLOAT64
|
|
;
|
|
|
|
generic_block: '{' generic_element '}'
|
|
| '{' generic_list '}'
|
|
| '{' generic_block_list '}'
|
|
;
|
|
|
|
generic_block_list: generic_block_list generic_block_elem
|
|
{
|
|
free($2);
|
|
}
|
|
| generic_block_elem
|
|
{
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
generic_block_elem: generic_block_elem_name generic_head generic_block
|
|
{
|
|
$$ = $1;
|
|
}
|
|
| generic_block_elem_name generic_head
|
|
{
|
|
$$ = $1;
|
|
}
|
|
;
|
|
|
|
generic_block_elem_name: keyword
|
|
| tokenSTRING
|
|
;
|
|
|
|
rule_generic_block_elem: rule_generic_block_elem_name generic_head generic_block
|
|
{
|
|
$$ = $1;
|
|
}
|
|
| rule_generic_block_elem_name generic_head
|
|
{
|
|
$$ = $1;
|
|
}
|
|
;
|
|
|
|
rule_generic_block_elem_name: non_rule_keyword
|
|
| tokenSTRING
|
|
;
|
|
|
|
uag_head: '(' tokenSTRING ')'
|
|
{
|
|
yyUag = asUagAdd($2);
|
|
if(!yyUag) yyerror("");
|
|
free($2);
|
|
}
|
|
;
|
|
|
|
uag_body: '{' uag_user_list '}'
|
|
{
|
|
;
|
|
}
|
|
;
|
|
|
|
uag_user_list: uag_user_list ',' uag_user_list_name
|
|
| uag_user_list_name
|
|
;
|
|
|
|
uag_user_list_name: tokenSTRING
|
|
{
|
|
if (asUagAddUser(yyUag,$1))
|
|
yyerror("");
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
hag_head: '(' tokenSTRING ')'
|
|
{
|
|
yyHag = asHagAdd($2);
|
|
if(!yyHag) yyerror("");
|
|
free($2);
|
|
}
|
|
;
|
|
|
|
hag_body: '{' hag_host_list '}'
|
|
;
|
|
|
|
hag_host_list: hag_host_list ',' hag_host_list_name
|
|
| hag_host_list_name
|
|
;
|
|
|
|
hag_host_list_name: tokenSTRING
|
|
{
|
|
if (asHagAddHost(yyHag,$1))
|
|
yyerror("");
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
asg_head: '(' tokenSTRING ')'
|
|
{
|
|
yyAsg = asAsgAdd($2);
|
|
if(!yyAsg) yyerror("");
|
|
free($2);
|
|
}
|
|
;
|
|
|
|
asg_body: '{' asg_body_list '}'
|
|
{
|
|
}
|
|
|
|
asg_body_list: asg_body_list asg_body_item
|
|
| asg_body_item
|
|
|
|
asg_body_item: inp_config | rule_config
|
|
;
|
|
|
|
inp_config: tokenINP '(' tokenSTRING ')'
|
|
{
|
|
if (asAsgAddInp(yyAsg,$3,(int)$<Int64>1))
|
|
yyerror("");
|
|
free($3);
|
|
}
|
|
;
|
|
|
|
rule_config: tokenRULE rule_head rule_body
|
|
| tokenRULE rule_head
|
|
|
|
rule_head: '(' rule_head_mandatory ',' rule_log_option ')'
|
|
| '(' rule_head_mandatory ')'
|
|
;
|
|
|
|
|
|
rule_head_mandatory: tokenINT64 ',' tokenSTRING
|
|
{
|
|
if ($1 < 0) {
|
|
char message[60];
|
|
sprintf(message, "RULE: LEVEL must be positive: %lld", $1);
|
|
yyerror(message);
|
|
} else if((strcmp($3,"NONE")==0)) {
|
|
yyAsgRule = asAsgAddRule(yyAsg,asNOACCESS,(int)$1);
|
|
} else if((strcmp($3,"READ")==0)) {
|
|
yyAsgRule = asAsgAddRule(yyAsg,asREAD,(int)$1);
|
|
} else if((strcmp($3,"WRITE")==0)) {
|
|
yyAsgRule = asAsgAddRule(yyAsg,asWRITE,(int)$1);
|
|
} else {
|
|
yywarn("Ignoring RULE that contains an unsupported keyword", $3);
|
|
}
|
|
free($3);
|
|
}
|
|
;
|
|
|
|
rule_log_option: tokenSTRING
|
|
{
|
|
if((strcmp($1,"TRAPWRITE")==0)) {
|
|
long status;
|
|
status = asAsgAddRuleOptions(yyAsgRule,AS_TRAP_WRITE);
|
|
if(status) yyerror("");
|
|
} else if((strcmp($1,"NOTRAPWRITE")!=0)) {
|
|
yyerror("Log options must be TRAPWRITE or NOTRAPWRITE");
|
|
}
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
rule_body: '{' rule_list '}'
|
|
;
|
|
|
|
rule_list: rule_list rule_list_item
|
|
| rule_list_item
|
|
;
|
|
|
|
rule_list_item: tokenUAG '(' rule_uag_list ')'
|
|
| tokenHAG '(' rule_hag_list ')'
|
|
| tokenCALC '(' tokenSTRING ')'
|
|
{
|
|
if (asAsgRuleCalc(yyAsgRule,$3))
|
|
yyerror("");
|
|
free($3);
|
|
}
|
|
| rule_generic_block_elem
|
|
{
|
|
yywarn("Ignoring RULE that contains an unsupported keyword", $1);
|
|
free($1);
|
|
if (asAsgRuleDisable(yyAsgRule))
|
|
yyerror("");
|
|
}
|
|
;
|
|
|
|
rule_uag_list: rule_uag_list ',' rule_uag_list_name
|
|
| rule_uag_list_name
|
|
;
|
|
|
|
rule_uag_list_name: tokenSTRING
|
|
{
|
|
if (asAsgRuleUagAdd(yyAsgRule,$1))
|
|
yyerror("");
|
|
free($1);
|
|
}
|
|
;
|
|
|
|
rule_hag_list: rule_hag_list ',' rule_hag_list_name
|
|
| rule_hag_list_name
|
|
;
|
|
|
|
rule_hag_list_name: tokenSTRING
|
|
{
|
|
if (asAsgRuleHagAdd(yyAsgRule,$1))
|
|
yyerror("");
|
|
free($1);
|
|
}
|
|
;
|
|
%%
|
|
|
|
#include "asLib_lex.c"
|
|
|
|
static int yyerror(char *str)
|
|
{
|
|
if (strlen(str))
|
|
fprintf(stderr, ERL_ERROR " %s at line %d\n", str, line_num);
|
|
else
|
|
fprintf(stderr, ERL_ERROR " at line %d\n", line_num);
|
|
yyFailed = TRUE;
|
|
return 0;
|
|
}
|
|
static int yywarn(char *str, char *token)
|
|
{
|
|
if (!yyWarned && strlen(str) && strlen(token))
|
|
fprintf(stderr, ERL_WARNING " %s at line %d: %s\n", str, line_num, token);
|
|
yyWarned = TRUE;
|
|
return 0;
|
|
}
|
|
static int myParse(ASINPUTFUNCPTR inputfunction)
|
|
{
|
|
static int FirstFlag = 1;
|
|
int rtnval;
|
|
|
|
my_yyinput = &inputfunction;
|
|
if (!FirstFlag) {
|
|
line_num=1;
|
|
yyFailed = FALSE;
|
|
yyWarned = FALSE;
|
|
yyreset();
|
|
yyrestart(NULL);
|
|
}
|
|
FirstFlag = 0;
|
|
rtnval = yyparse();
|
|
if(rtnval!=0 || yyFailed) return(-1); else return(0);
|
|
}
|