root/lm-sensors/trunk/lib/conf-lex.l @ 3296

Revision 3296, 5.7 KB (checked in by mmh, 7 years ago)

Allow the config file scanner to release its buffers upon EOF.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1%{
2/*
3    conf-lex.l - Part of libsensors, a Linux library for reading sensor data.
4    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10
11    This program 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <stdlib.h>
22#include <string.h>
23
24#include "general.h"
25#include "data.h"
26#include "conf-parse.h"
27#include "error.h"
28
29static int buffer_count;
30static int buffer_max;
31static char *buffer;
32
33char sensors_lex_error[100];
34
35#define buffer_malloc() sensors_malloc_array(&buffer,&buffer_count,\
36                                             &buffer_max,1)
37#define buffer_free() sensors_free_array(&buffer,&buffer_count,\
38                                         &buffer_max)
39#define buffer_add_char(c) sensors_add_array_el(c,&buffer,\
40                                                &buffer_count,\
41                                                &buffer_max,1)
42#define buffer_add_string(s) sensors_add_array_els(s,strlen(s),\
43                                                   &buffer, \
44                                                   &buffer_count,&buffer_max,1)
45
46%}
47
48/* Scanner for configuration files */
49
50%option nodefault
51%option yylineno
52%option nounput
53
54/* States. 'Normal' states STRING and MIDDLE share some rules; other states
55   have only their own rules */
56%s MIDDLE
57%x STRING
58%x ERR
59
60/* Any whitespace-like character */
61BLANK           [[:space:]]
62
63IDCHAR          [[:alnum:]_]
64
65/* Note: `10', `10.4' and `.4' are valid, `10.' is not */
66FLOAT   [[:digit:]]*\.?[[:digit:]]+
67
68/* Only positive whole numbers are recognized here */
69NUM     0|([1-9][[:digit:]]*)
70
71/* Only number between 1 and 255, octally represented. */
72OCTESC          (1[0-7]{0,2})|([2-7][0-7]?)|(0[1-7][0-7]?)|(00[1-7])
73
74
75%%
76
77
78 /* End of line: It may be the end of this line. Same for End of file. */
79<MIDDLE>\n      |
80<MIDDLE><<EOF>> {
81                  BEGIN(INITIAL);
82                  return EOL;
83                }
84
85 /* We want to match any blank, except End of line; that is why we have to
86    match whitespace one by one! */
87{BLANK}         /* Eat up a blank */
88
89 /* Escaped End of line: eat and be happy */
90<MIDDLE>\\\n    /* Eat this! */
91
92 /* Remove a comment; we do not change the state, this is done when the \n is
93    eaten */
94#[^\n]*         /* Eat this! */
95
96 /* Some keywords at the beginning of lines */
97<INITIAL>"label" {
98                  sensors_yylval.line = sensors_yylineno;
99                  BEGIN(MIDDLE);
100                  return LABEL;
101                }
102
103<INITIAL>"set"  {
104                  sensors_yylval.line = sensors_yylineno;
105                  BEGIN(MIDDLE);
106                  return SET;
107                }
108
109<INITIAL>"compute" {
110                  sensors_yylval.line = sensors_yylineno;
111                  BEGIN(MIDDLE);
112                  return COMPUTE;
113                }
114
115<INITIAL>"bus"  {
116                  sensors_yylval.line = sensors_yylineno;
117                  BEGIN(MIDDLE);
118                  return BUS;
119                }
120
121<INITIAL>"chip" {
122                  sensors_yylval.line = sensors_yylineno;
123                  BEGIN(MIDDLE);
124                  return CHIP;
125                }
126<INITIAL>"ignore" {
127                  sensors_yylval.line = sensors_yylineno;
128                  BEGIN(MIDDLE);
129                  return IGNORE;
130                }
131
132 /* Anything else at the beginning of a line is an error */
133<INITIAL>.      {
134                  yymore();
135                  BEGIN(ERR);
136                }
137
138<ERR>[^\n]*\n   {
139                  BEGIN(INITIAL);
140                  strcpy(sensors_lex_error,"Invalid keyword");
141                  return ERROR;
142                }
143
144 /* A number */
145<MIDDLE>{FLOAT} {
146                  sensors_yylval.value = atof(sensors_yytext);
147                  return FLOAT;
148                }
149
150 /* Some operators */
151<MIDDLE>"+"     {
152                  return '+';
153                }
154
155<MIDDLE>"-"     {
156                  return '-';
157                }
158
159<MIDDLE>"*"     {
160                  return '*';
161                }
162
163<MIDDLE>"/"     {
164                  return '/';
165                }
166
167<MIDDLE>"("     {
168                  return '(';
169                }
170
171<MIDDLE>")"     {
172                  return ')';
173                }
174<MIDDLE>","     {
175                  return ',';
176                }
177<MIDDLE>"@"     {
178                  return '@';
179                }
180<MIDDLE>"^"     {
181                  return '^';
182                }
183<MIDDLE>"`"     {
184                  return '`';
185                }
186
187 /* Quoted string */
188<MIDDLE>\"      {
189                  buffer_malloc();
190                  BEGIN(STRING);
191                }
192
193 /* Oops, newline while in a string is not good */
194<STRING>\n      |
195<STRING>\\\n    {
196                  buffer_add_char("\0");
197                  strcpy(sensors_lex_error,"No matching double quote");
198                  buffer_free();
199                  BEGIN(INITIAL);
200                  return ERROR;
201                }
202
203 /* At the end */
204<STRING>\"      {
205                  buffer_add_char("\0");
206                  sensors_yylval.name = strdup(buffer);
207                  if (! sensors_yylval.name)
208                    sensors_fatal_error("conf-lex.l",
209                                        "Allocating a new string");
210                  buffer_free();
211                  BEGIN(MIDDLE);
212                  return NAME;
213                }
214
215<STRING>\\a     {
216                  buffer_add_char("\a");
217                }
218
219<STRING>\\b     {
220                  buffer_add_char("\b");
221                }
222
223<STRING>\\f     {
224                  buffer_add_char("\f");
225                }
226
227<STRING>\\n     {
228                  buffer_add_char("\n");
229                }
230
231<STRING>\\r     {
232                  buffer_add_char("\r");
233                }
234
235<STRING>\\t     {
236                  buffer_add_char("\t");
237                }
238
239<STRING>\\v     {
240                  buffer_add_char("\v");
241                }
242
243 /* We can't support \0, this would cause havoc! */
244<STRING>\\{OCTESC} {
245                  int res;
246                  sscanf(sensors_yytext+1,"%o",&res);
247                  buffer_add_char(&res);
248                }
249
250 /* Other escapes: just copy the character behind the slash */
251<STRING>\\.     {
252                  buffer_add_char(&sensors_yytext[1]);
253                }
254
255 /* Anything else */
256<STRING>[^\\\n\"]+ {
257                  buffer_add_string(sensors_yytext);
258                }
259
260 /* A normal, unquoted identifier */
261<MIDDLE>{IDCHAR}+ {
262                  sensors_yylval.name = strdup(sensors_yytext);
263                  if (! sensors_yylval.name)
264                    sensors_fatal_error("conf-lex.l",
265                                        "Allocating a new string");
266                 
267                  return NAME;
268                }
269
270%%
271
272int sensors_yywrap(void)
273{
274  yy_delete_buffer(YY_CURRENT_BUFFER);
275  return 1;
276}
277
Note: See TracBrowser for help on using the browser.