blob: 1937f544dc66feeab25c6447efba4d8cde7825f6 [file] [log] [blame]
Jon Medhurstaaf37a32013-06-11 12:10:56 +01001%{
2/*
3 conf-parse.y - Part of libsensors, a Linux library for reading sensor data.
4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 MA 02110-1301 USA.
20*/
21
22#define YYERROR_VERBOSE
23
24#include <stdio.h>
25#include <string.h>
26#include <stdlib.h>
27
28#include "data.h"
29#include "general.h"
30#include "error.h"
31#include "conf.h"
32#include "access.h"
33#include "init.h"
34
35static void sensors_yyerror(const char *err);
36static sensors_expr *malloc_expr(void);
37
38static sensors_chip *current_chip = NULL;
39
40#define bus_add_el(el) sensors_add_array_el(el,\
41 &sensors_config_busses,\
42 &sensors_config_busses_count,\
43 &sensors_config_busses_max,\
44 sizeof(sensors_bus))
45#define label_add_el(el) sensors_add_array_el(el,\
46 &current_chip->labels,\
47 &current_chip->labels_count,\
48 &current_chip->labels_max,\
49 sizeof(sensors_label));
50#define set_add_el(el) sensors_add_array_el(el,\
51 &current_chip->sets,\
52 &current_chip->sets_count,\
53 &current_chip->sets_max,\
54 sizeof(sensors_set));
55#define compute_add_el(el) sensors_add_array_el(el,\
56 &current_chip->computes,\
57 &current_chip->computes_count,\
58 &current_chip->computes_max,\
59 sizeof(sensors_compute));
60#define ignore_add_el(el) sensors_add_array_el(el,\
61 &current_chip->ignores,\
62 &current_chip->ignores_count,\
63 &current_chip->ignores_max,\
64 sizeof(sensors_ignore));
65#define chip_add_el(el) sensors_add_array_el(el,\
66 &sensors_config_chips,\
67 &sensors_config_chips_count,\
68 &sensors_config_chips_max,\
69 sizeof(sensors_chip));
70
71#define fits_add_el(el,list) sensors_add_array_el(el,\
72 &(list).fits,\
73 &(list).fits_count,\
74 &(list).fits_max, \
75 sizeof(sensors_chip_name));
76
77%}
78
79%union {
80 double value;
81 char *name;
82 void *nothing;
83 sensors_chip_name_list chips;
84 sensors_expr *expr;
85 sensors_bus_id bus;
86 sensors_chip_name chip;
87 sensors_config_line line;
88}
89
90%left <nothing> '-' '+'
91%left <nothing> '*' '/'
92%left <nothing> NEG
93%right <nothing> '^' '`'
94
95%token <nothing> ','
96%token <nothing> EOL
97%token <line> BUS
98%token <line> LABEL
99%token <line> SET
100%token <line> CHIP
101%token <line> COMPUTE
102%token <line> IGNORE
103%token <value> FLOAT
104%token <name> NAME
105%token <nothing> ERROR
106
107%type <chips> chip_name_list
108%type <expr> expression
109%type <bus> bus_id
110%type <name> adapter_name
111%type <name> function_name
112%type <name> string
113%type <chip> chip_name
114
115%start input
116
117%%
118
119input: /* empty */
120 | input line
121;
122
123line: bus_statement EOL
124 | label_statement EOL
125 | set_statement EOL
126 | chip_statement EOL
127 | compute_statement EOL
128 | ignore_statement EOL
129 | error EOL
130;
131
132bus_statement: BUS bus_id adapter_name
133 { sensors_bus new_el;
134 new_el.line = $1;
135 new_el.bus = $2;
136 new_el.adapter = $3;
137 bus_add_el(&new_el);
138 }
139;
140
141label_statement: LABEL function_name string
142 { sensors_label new_el;
143 if (!current_chip) {
144 sensors_yyerror("Label statement before first chip statement");
145 free($2);
146 free($3);
147 YYERROR;
148 }
149 new_el.line = $1;
150 new_el.name = $2;
151 new_el.value = $3;
152 label_add_el(&new_el);
153 }
154;
155
156set_statement: SET function_name expression
157 { sensors_set new_el;
158 if (!current_chip) {
159 sensors_yyerror("Set statement before first chip statement");
160 free($2);
161 sensors_free_expr($3);
162 YYERROR;
163 }
164 new_el.line = $1;
165 new_el.name = $2;
166 new_el.value = $3;
167 set_add_el(&new_el);
168 }
169;
170
171compute_statement: COMPUTE function_name expression ',' expression
172 { sensors_compute new_el;
173 if (!current_chip) {
174 sensors_yyerror("Compute statement before first chip statement");
175 free($2);
176 sensors_free_expr($3);
177 sensors_free_expr($5);
178 YYERROR;
179 }
180 new_el.line = $1;
181 new_el.name = $2;
182 new_el.from_proc = $3;
183 new_el.to_proc = $5;
184 compute_add_el(&new_el);
185 }
186;
187
188ignore_statement: IGNORE function_name
189 { sensors_ignore new_el;
190 if (!current_chip) {
191 sensors_yyerror("Ignore statement before first chip statement");
192 free($2);
193 YYERROR;
194 }
195 new_el.line = $1;
196 new_el.name = $2;
197 ignore_add_el(&new_el);
198 }
199;
200
201chip_statement: CHIP chip_name_list
202 { sensors_chip new_el;
203 new_el.line = $1;
204 new_el.labels = NULL;
205 new_el.sets = NULL;
206 new_el.computes = NULL;
207 new_el.ignores = NULL;
208 new_el.labels_count = new_el.labels_max = 0;
209 new_el.sets_count = new_el.sets_max = 0;
210 new_el.computes_count = new_el.computes_max = 0;
211 new_el.ignores_count = new_el.ignores_max = 0;
212 new_el.chips = $2;
213 chip_add_el(&new_el);
214 current_chip = sensors_config_chips +
215 sensors_config_chips_count - 1;
216 }
217;
218
219chip_name_list: chip_name
220 {
221 $$.fits = NULL;
222 $$.fits_count = $$.fits_max = 0;
223 fits_add_el(&$1,$$);
224 }
225 | chip_name_list chip_name
226 { $$ = $1;
227 fits_add_el(&$2,$$);
228 }
229;
230
231expression: FLOAT
232 { $$ = malloc_expr();
233 $$->data.val = $1;
234 $$->kind = sensors_kind_val;
235 }
236 | NAME
237 { $$ = malloc_expr();
238 $$->data.var = $1;
239 $$->kind = sensors_kind_var;
240 }
241 | '@'
242 { $$ = malloc_expr();
243 $$->kind = sensors_kind_source;
244 }
245 | expression '+' expression
246 { $$ = malloc_expr();
247 $$->kind = sensors_kind_sub;
248 $$->data.subexpr.op = sensors_add;
249 $$->data.subexpr.sub1 = $1;
250 $$->data.subexpr.sub2 = $3;
251 }
252 | expression '-' expression
253 { $$ = malloc_expr();
254 $$->kind = sensors_kind_sub;
255 $$->data.subexpr.op = sensors_sub;
256 $$->data.subexpr.sub1 = $1;
257 $$->data.subexpr.sub2 = $3;
258 }
259 | expression '*' expression
260 { $$ = malloc_expr();
261 $$->kind = sensors_kind_sub;
262 $$->data.subexpr.op = sensors_multiply;
263 $$->data.subexpr.sub1 = $1;
264 $$->data.subexpr.sub2 = $3;
265 }
266 | expression '/' expression
267 { $$ = malloc_expr();
268 $$->kind = sensors_kind_sub;
269 $$->data.subexpr.op = sensors_divide;
270 $$->data.subexpr.sub1 = $1;
271 $$->data.subexpr.sub2 = $3;
272 }
273 | '-' expression %prec NEG
274 { $$ = malloc_expr();
275 $$->kind = sensors_kind_sub;
276 $$->data.subexpr.op = sensors_negate;
277 $$->data.subexpr.sub1 = $2;
278 $$->data.subexpr.sub2 = NULL;
279 }
280 | '(' expression ')'
281 { $$ = $2; }
282 | '^' expression
283 { $$ = malloc_expr();
284 $$->kind = sensors_kind_sub;
285 $$->data.subexpr.op = sensors_exp;
286 $$->data.subexpr.sub1 = $2;
287 $$->data.subexpr.sub2 = NULL;
288 }
289 | '`' expression
290 { $$ = malloc_expr();
291 $$->kind = sensors_kind_sub;
292 $$->data.subexpr.op = sensors_log;
293 $$->data.subexpr.sub1 = $2;
294 $$->data.subexpr.sub2 = NULL;
295 }
296;
297
298bus_id: NAME
299 { int res = sensors_parse_bus_id($1,&$$);
300 free($1);
301 if (res) {
302 sensors_yyerror("Parse error in bus id");
303 YYERROR;
304 }
305 }
306;
307
308adapter_name: NAME
309 { $$ = $1; }
310;
311
312function_name: NAME
313 { $$ = $1; }
314;
315
316string: NAME
317 { $$ = $1; }
318;
319
320chip_name: NAME
321 { int res = sensors_parse_chip_name($1,&$$);
322 free($1);
323 if (res) {
324 sensors_yyerror("Parse error in chip name");
325 YYERROR;
326 }
327 }
328;
329
330%%
331
332void sensors_yyerror(const char *err)
333{
334 if (sensors_lex_error[0]) {
335 sensors_parse_error_wfn(sensors_lex_error, sensors_yyfilename, sensors_yylineno);
336 sensors_lex_error[0] = '\0';
337 } else
338 sensors_parse_error_wfn(err, sensors_yyfilename, sensors_yylineno);
339}
340
341sensors_expr *malloc_expr(void)
342{
343 sensors_expr *res = malloc(sizeof(sensors_expr));
344 if (! res)
345 sensors_fatal_error(__func__, "Allocating a new expression");
346 return res;
347}