1 %{
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>
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.
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.
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 */
22 #define YYERROR_VERBOSE
24 #include <stdio.h>
25 #include <string.h>
26 #include <stdlib.h>
28 #include "data.h"
29 #include "general.h"
30 #include "error.h"
31 #include "conf.h"
32 #include "access.h"
33 #include "init.h"
35 static void sensors_yyerror(const char *err);
36 static sensors_expr *malloc_expr(void);
38 static sensors_chip *current_chip = NULL;
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 ¤t_chip->labels,\
47 ¤t_chip->labels_count,\
48 ¤t_chip->labels_max,\
49 sizeof(sensors_label));
50 #define set_add_el(el) sensors_add_array_el(el,\
51 ¤t_chip->sets,\
52 ¤t_chip->sets_count,\
53 ¤t_chip->sets_max,\
54 sizeof(sensors_set));
55 #define compute_add_el(el) sensors_add_array_el(el,\
56 ¤t_chip->computes,\
57 ¤t_chip->computes_count,\
58 ¤t_chip->computes_max,\
59 sizeof(sensors_compute));
60 #define ignore_add_el(el) sensors_add_array_el(el,\
61 ¤t_chip->ignores,\
62 ¤t_chip->ignores_count,\
63 ¤t_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));
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));
77 %}
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 }
90 %left <nothing> '-' '+'
91 %left <nothing> '*' '/'
92 %left <nothing> NEG
93 %right <nothing> '^' '`'
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
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
115 %start input
117 %%
119 input: /* empty */
120 | input line
121 ;
123 line: 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 ;
132 bus_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 ;
141 label_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 ;
156 set_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 ;
171 compute_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 ;
188 ignore_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 ;
201 chip_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 ;
219 chip_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 ;
231 expression: 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 ;
298 bus_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 ;
308 adapter_name: NAME
309 { $$ = $1; }
310 ;
312 function_name: NAME
313 { $$ = $1; }
314 ;
316 string: NAME
317 { $$ = $1; }
318 ;
320 chip_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 ;
330 %%
332 void 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 }
341 sensors_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 }