blob: dd30a95a590a8182efcebf0115e4e0097a58b798 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
%{
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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 <rc_item> KEYWORD
%token <expr> NUMBER
%token LSHIFT RSHIFT
%left '-' '+'
%left '*' '/'
%nonassoc UMINUS
%type <expr> 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;
}
|