%{ #include #include #include #ifdef __cplusplus extern "C" { #endif #include "configrc.h" static int open_new_rcsection(); static int close_new_rcsection(); static int close_all_rcsection(); %} %union { struct rc_item_t *rc_item; unsigned int expr; } %token BEGIN_RC END_RC EQUAL %token KEYWORD %token NUMBER %token LSHIFT RSHIFT %left '-' '+' %left '*' '/' %nonassoc UMINUS %type expression %% rc_sections: rc_section | rc_sections rc_section rc_section: begin_rc rc_items end_rc; begin_rc: BEGIN_RC { printf("Open a new RC section\n");open_new_rcsection(); } end_rc: END_RC { printf("Close a new RC section\n");close_new_rcsection(); } rc_items: rc_item | rc_items rc_item; rc_item: KEYWORD EQUAL expression { printf("Change RC item %s to %d\n", $1->rc_item_name, $3); *$1->rc_item_ptr = $3; } expression: expression '+' expression { $$ = $1 + $3; } | expression '-' expression { $$ = $1 - $3; } | expression '*' expression { $$ = $1 * $3; } | expression '/' expression { if ($3 == 0.0) yyerror("divide by zero"); else $$ = $1 / $3; } | '-' expression %prec UMINUS { $$ = -$2; } | '(' expression ')' { $$ = $2; } | NUMBER; %% #ifdef __cplusplus } #endif struct rc_param_t *rc_params = NULL; struct rc_param_t *last_rcparam = NULL; char *config_fn = NULL; FILE *config_fp = NULL; int yywrap() { return (1); } static int open_new_rcsection() { int rcparam_number = 0; /* The first element of rc_params is always there even we don't have config file * If config file is set, the first element of rc_params will be reset */ if (last_rcparam != NULL) { rcparam_number = last_rcparam - rc_params + 1; rc_params = (struct rc_param_t *)realloc(rc_params, (rcparam_number + 1) * sizeof (struct rc_param_t)); } last_rcparam = rc_params + rcparam_number; if (rcparam_number >= 1) /* copy field from last rc_param */ memcpy(last_rcparam, last_rcparam - 1, sizeof(struct rc_param_t)); last_rcparam->mask = 0; return 0; } static int close_new_rcsection() { int rcparam_number = rc_params - last_rcparam; if (rcparam_number >= 2) { struct rc_param_t *prior_rcparam = last_rcparam - 1; /* make last rc param cover more frames if there is gap */ if (prior_rcparam->frame_end < (last_rcparam->frame_start - 1)) prior_rcparam->frame_end = last_rcparam->frame_start - 1; } if (last_rcparam->frame_end < last_rcparam->frame_start) last_rcparam->frame_end = last_rcparam->frame_start; return 0; }