| %{ |
| #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; |
| } |
| |