| %{ |
| /* |
| conf-parse.y - Part of libsensors, a Linux library for reading sensor data. |
| Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl> |
| |
| This library is free software; you can redistribute it and/or |
| modify it under the terms of the GNU Lesser General Public |
| License as published by the Free Software Foundation; either |
| version 2.1 of the License, or (at your option) any later version. |
| |
| This library is distributed in the hope that it will be useful, |
| but WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| GNU Lesser General Public License for more details. |
| |
| You should have received a copy of the GNU General Public License |
| along with this program; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
| MA 02110-1301 USA. |
| */ |
| |
| #define YYERROR_VERBOSE |
| |
| #include <stdio.h> |
| #include <string.h> |
| #include <stdlib.h> |
| |
| #include "data.h" |
| #include "general.h" |
| #include "error.h" |
| #include "conf.h" |
| #include "access.h" |
| #include "init.h" |
| |
| static void sensors_yyerror(const char *err); |
| static sensors_expr *malloc_expr(void); |
| |
| static sensors_chip *current_chip = NULL; |
| |
| #define bus_add_el(el) sensors_add_array_el(el,\ |
| &sensors_config_busses,\ |
| &sensors_config_busses_count,\ |
| &sensors_config_busses_max,\ |
| sizeof(sensors_bus)) |
| #define label_add_el(el) sensors_add_array_el(el,\ |
| ¤t_chip->labels,\ |
| ¤t_chip->labels_count,\ |
| ¤t_chip->labels_max,\ |
| sizeof(sensors_label)); |
| #define set_add_el(el) sensors_add_array_el(el,\ |
| ¤t_chip->sets,\ |
| ¤t_chip->sets_count,\ |
| ¤t_chip->sets_max,\ |
| sizeof(sensors_set)); |
| #define compute_add_el(el) sensors_add_array_el(el,\ |
| ¤t_chip->computes,\ |
| ¤t_chip->computes_count,\ |
| ¤t_chip->computes_max,\ |
| sizeof(sensors_compute)); |
| #define ignore_add_el(el) sensors_add_array_el(el,\ |
| ¤t_chip->ignores,\ |
| ¤t_chip->ignores_count,\ |
| ¤t_chip->ignores_max,\ |
| sizeof(sensors_ignore)); |
| #define chip_add_el(el) sensors_add_array_el(el,\ |
| &sensors_config_chips,\ |
| &sensors_config_chips_count,\ |
| &sensors_config_chips_max,\ |
| sizeof(sensors_chip)); |
| |
| #define fits_add_el(el,list) sensors_add_array_el(el,\ |
| &(list).fits,\ |
| &(list).fits_count,\ |
| &(list).fits_max, \ |
| sizeof(sensors_chip_name)); |
| |
| %} |
| |
| %union { |
| double value; |
| char *name; |
| void *nothing; |
| sensors_chip_name_list chips; |
| sensors_expr *expr; |
| sensors_bus_id bus; |
| sensors_chip_name chip; |
| sensors_config_line line; |
| } |
| |
| %left <nothing> '-' '+' |
| %left <nothing> '*' '/' |
| %left <nothing> NEG |
| %right <nothing> '^' '`' |
| |
| %token <nothing> ',' |
| %token <nothing> EOL |
| %token <line> BUS |
| %token <line> LABEL |
| %token <line> SET |
| %token <line> CHIP |
| %token <line> COMPUTE |
| %token <line> IGNORE |
| %token <value> FLOAT |
| %token <name> NAME |
| %token <nothing> ERROR |
| |
| %type <chips> chip_name_list |
| %type <expr> expression |
| %type <bus> bus_id |
| %type <name> adapter_name |
| %type <name> function_name |
| %type <name> string |
| %type <chip> chip_name |
| |
| %start input |
| |
| %% |
| |
| input: /* empty */ |
| | input line |
| ; |
| |
| line: bus_statement EOL |
| | label_statement EOL |
| | set_statement EOL |
| | chip_statement EOL |
| | compute_statement EOL |
| | ignore_statement EOL |
| | error EOL |
| ; |
| |
| bus_statement: BUS bus_id adapter_name |
| { sensors_bus new_el; |
| new_el.line = $1; |
| new_el.bus = $2; |
| new_el.adapter = $3; |
| bus_add_el(&new_el); |
| } |
| ; |
| |
| label_statement: LABEL function_name string |
| { sensors_label new_el; |
| if (!current_chip) { |
| sensors_yyerror("Label statement before first chip statement"); |
| free($2); |
| free($3); |
| YYERROR; |
| } |
| new_el.line = $1; |
| new_el.name = $2; |
| new_el.value = $3; |
| label_add_el(&new_el); |
| } |
| ; |
| |
| set_statement: SET function_name expression |
| { sensors_set new_el; |
| if (!current_chip) { |
| sensors_yyerror("Set statement before first chip statement"); |
| free($2); |
| sensors_free_expr($3); |
| YYERROR; |
| } |
| new_el.line = $1; |
| new_el.name = $2; |
| new_el.value = $3; |
| set_add_el(&new_el); |
| } |
| ; |
| |
| compute_statement: COMPUTE function_name expression ',' expression |
| { sensors_compute new_el; |
| if (!current_chip) { |
| sensors_yyerror("Compute statement before first chip statement"); |
| free($2); |
| sensors_free_expr($3); |
| sensors_free_expr($5); |
| YYERROR; |
| } |
| new_el.line = $1; |
| new_el.name = $2; |
| new_el.from_proc = $3; |
| new_el.to_proc = $5; |
| compute_add_el(&new_el); |
| } |
| ; |
| |
| ignore_statement: IGNORE function_name |
| { sensors_ignore new_el; |
| if (!current_chip) { |
| sensors_yyerror("Ignore statement before first chip statement"); |
| free($2); |
| YYERROR; |
| } |
| new_el.line = $1; |
| new_el.name = $2; |
| ignore_add_el(&new_el); |
| } |
| ; |
| |
| chip_statement: CHIP chip_name_list |
| { sensors_chip new_el; |
| new_el.line = $1; |
| new_el.labels = NULL; |
| new_el.sets = NULL; |
| new_el.computes = NULL; |
| new_el.ignores = NULL; |
| new_el.labels_count = new_el.labels_max = 0; |
| new_el.sets_count = new_el.sets_max = 0; |
| new_el.computes_count = new_el.computes_max = 0; |
| new_el.ignores_count = new_el.ignores_max = 0; |
| new_el.chips = $2; |
| chip_add_el(&new_el); |
| current_chip = sensors_config_chips + |
| sensors_config_chips_count - 1; |
| } |
| ; |
| |
| chip_name_list: chip_name |
| { |
| $$.fits = NULL; |
| $$.fits_count = $$.fits_max = 0; |
| fits_add_el(&$1,$$); |
| } |
| | chip_name_list chip_name |
| { $$ = $1; |
| fits_add_el(&$2,$$); |
| } |
| ; |
| |
| expression: FLOAT |
| { $$ = malloc_expr(); |
| $$->data.val = $1; |
| $$->kind = sensors_kind_val; |
| } |
| | NAME |
| { $$ = malloc_expr(); |
| $$->data.var = $1; |
| $$->kind = sensors_kind_var; |
| } |
| | '@' |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_source; |
| } |
| | expression '+' expression |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_sub; |
| $$->data.subexpr.op = sensors_add; |
| $$->data.subexpr.sub1 = $1; |
| $$->data.subexpr.sub2 = $3; |
| } |
| | expression '-' expression |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_sub; |
| $$->data.subexpr.op = sensors_sub; |
| $$->data.subexpr.sub1 = $1; |
| $$->data.subexpr.sub2 = $3; |
| } |
| | expression '*' expression |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_sub; |
| $$->data.subexpr.op = sensors_multiply; |
| $$->data.subexpr.sub1 = $1; |
| $$->data.subexpr.sub2 = $3; |
| } |
| | expression '/' expression |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_sub; |
| $$->data.subexpr.op = sensors_divide; |
| $$->data.subexpr.sub1 = $1; |
| $$->data.subexpr.sub2 = $3; |
| } |
| | '-' expression %prec NEG |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_sub; |
| $$->data.subexpr.op = sensors_negate; |
| $$->data.subexpr.sub1 = $2; |
| $$->data.subexpr.sub2 = NULL; |
| } |
| | '(' expression ')' |
| { $$ = $2; } |
| | '^' expression |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_sub; |
| $$->data.subexpr.op = sensors_exp; |
| $$->data.subexpr.sub1 = $2; |
| $$->data.subexpr.sub2 = NULL; |
| } |
| | '`' expression |
| { $$ = malloc_expr(); |
| $$->kind = sensors_kind_sub; |
| $$->data.subexpr.op = sensors_log; |
| $$->data.subexpr.sub1 = $2; |
| $$->data.subexpr.sub2 = NULL; |
| } |
| ; |
| |
| bus_id: NAME |
| { int res = sensors_parse_bus_id($1,&$$); |
| free($1); |
| if (res) { |
| sensors_yyerror("Parse error in bus id"); |
| YYERROR; |
| } |
| } |
| ; |
| |
| adapter_name: NAME |
| { $$ = $1; } |
| ; |
| |
| function_name: NAME |
| { $$ = $1; } |
| ; |
| |
| string: NAME |
| { $$ = $1; } |
| ; |
| |
| chip_name: NAME |
| { int res = sensors_parse_chip_name($1,&$$); |
| free($1); |
| if (res) { |
| sensors_yyerror("Parse error in chip name"); |
| YYERROR; |
| } |
| } |
| ; |
| |
| %% |
| |
| void sensors_yyerror(const char *err) |
| { |
| if (sensors_lex_error[0]) { |
| sensors_parse_error_wfn(sensors_lex_error, sensors_yyfilename, sensors_yylineno); |
| sensors_lex_error[0] = '\0'; |
| } else |
| sensors_parse_error_wfn(err, sensors_yyfilename, sensors_yylineno); |
| } |
| |
| sensors_expr *malloc_expr(void) |
| { |
| sensors_expr *res = malloc(sizeof(sensors_expr)); |
| if (! res) |
| sensors_fatal_error(__func__, "Allocating a new expression"); |
| return res; |
| } |