blob: 691053328cdedc05dbaa99ac4f98c643a1133e26 [file] [log] [blame]
%{
#include <crm_internal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <crm/crm.h>
#include <standalone_config.h>
extern int _line_count;
extern int yylex (void);
extern void yyset_in (FILE * in_str );
int yyerror(const char *foo);
static void handle_line_value(void);
static void reset_line(void);
static void add_line_value(char *key, char *val);
enum line_type {
STANDALONE_LINE_DEVICE = 0,
STANDALONE_LINE_OPTION,
STANDALONE_LINE_PRIORITY,
STANDALONE_LINE_PORT
};
static struct {
enum line_type type;
char *name;
char *agent;
char *keys[STANDALONE_CFG_MAX_KEYVALS];
char *vals[STANDALONE_CFG_MAX_KEYVALS];
int val_count;
unsigned int priority;
} line_val = { 0, };
%}
%token <sval> T_VAL
%token T_DEVICE T_CONNECT T_PORTMAP T_PRIO
%token T_EQ T_ENDL T_UNFENCE T_OPTIONS
%left T_VAL
%start stuff
%union {
char *sval;
int ival;
}
%%
devline:
T_DEVICE T_VAL T_VAL T_ENDL {
line_val.name = $2;
line_val.agent = $3;
line_val.type = STANDALONE_LINE_DEVICE;
handle_line_value();
} |
T_DEVICE T_VAL T_VAL assigns T_ENDL {
line_val.name = $2;
line_val.agent = $3;
line_val.type = STANDALONE_LINE_DEVICE;
handle_line_value();
}
;
optline:
T_OPTIONS T_VAL assigns T_ENDL {
line_val.name = $2;
line_val.type = STANDALONE_LINE_OPTION;
handle_line_value();
}
;
prioline:
T_PRIO T_VAL T_VAL vals T_ENDL {
int priority = crm_atoi($3, NULL);
if (priority != -1) {
line_val.name = $2;
line_val.priority = priority;
line_val.type = STANDALONE_LINE_PRIORITY;
handle_line_value();
} else {
crm_err("Standalone Config parser error: priority value, %s, on line %d is not a valid positive integer", $3, _line_count);
reset_line();
}
}
;
portline:
T_PORTMAP T_VAL portinfo T_ENDL {
line_val.name = $2;
line_val.type = STANDALONE_LINE_PORT;
handle_line_value();
}
;
val:
T_VAL {
add_line_value(NULL, $1);
}
;
vals:
vals val |
val
;
portinfo:
assigns |
vals
;
assign:
T_VAL T_EQ T_VAL {
add_line_value($1, $3);
}
;
assigns:
assigns assign |
assign
;
stuff:
T_ENDL stuff |
//unfline stuff |
devline stuff |
portline stuff |
optline stuff |
prioline stuff |
//unfline |
portline |
devline |
optline |
prioline |
T_ENDL
;
%%
int
yyerror(const char *foo)
{
crm_err("Standalone Config parser error: %s on line %d", foo, _line_count);
return 0;
}
static void
add_line_value(char *key, char *val)
{
if (line_val.val_count < STANDALONE_CFG_MAX_KEYVALS) {
line_val.keys[line_val.val_count] = key;
line_val.vals[line_val.val_count] = val;
line_val.val_count++;
}
}
static void
reset_line()
{
int i;
crm_free(line_val.name);
crm_free(line_val.agent);
for (i = 0; i < line_val.val_count; i++) {
crm_free(line_val.keys[i]);
crm_free(line_val.vals[i]);
}
memset(&line_val, 0, sizeof(line_val));
}
static void
handle_line_value(void)
{
int i;
int res = 0;
switch (line_val.type) {
case STANDALONE_LINE_DEVICE:
res |= standalone_cfg_add_device(line_val.name, line_val.agent);
/* fall through */
case STANDALONE_LINE_OPTION:
for (i = 0; i < line_val.val_count; i++) {
res |= standalone_cfg_add_device_options(line_val.name,
line_val.keys[i],
line_val.vals[i]);
}
break;
case STANDALONE_LINE_PRIORITY:
for (i = 0; i < line_val.val_count; i++) {
res |= standalone_cfg_add_node_priority(line_val.name,
line_val.vals[i], /* fence device name */
line_val.priority);
}
break;
case STANDALONE_LINE_PORT:
for (i = 0; i < line_val.val_count; i++) {
if (line_val.keys[i]) {
res |= standalone_cfg_add_node(line_val.keys[i],
line_val.name,
line_val.vals[i]);
} else {
/* if value only, that means it is just a node name */
res |= standalone_cfg_add_node(line_val.vals[i],
line_val.name,
NULL);
}
}
break;
}
if (res) {
crm_err("Standalone Config parser error on line %d", _line_count);
}
reset_line();
}
int
standalone_cfg_read_file(const char *file_path)
{
FILE *fp = fopen(file_path, "r");
if (!fp) {
return -1;
}
/* redirect parse input from stdin to our file */
yyset_in(fp);
yyparse();
fclose(fp);
return 0;
}