summaryrefslogtreecommitdiff
path: root/utils/configrc.yacc.y
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;
}