root/lm-sensors/tags/V2-10-1/lib/conf-lex.l

Revision 3300, 6.3 kB (checked in by mmh, 3 years ago)

Previous leak fix caused multiple sensors_init() calls to break.
This patch fixes that by managing the scanner buffers manually.

  • 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 #include "scanner.h"
29
30 static int buffer_count;
31 static int buffer_max;
32 static char *buffer;
33
34 char sensors_lex_error[100];
35
36 #define buffer_malloc() sensors_malloc_array(&buffer,&buffer_count,\
37                                              &buffer_max,1)
38 #define buffer_free() sensors_free_array(&buffer,&buffer_count,\
39                                          &buffer_max)
40 #define buffer_add_char(c) sensors_add_array_el(c,&buffer,\
41                                                 &buffer_count,\
42                                                 &buffer_max,1)
43 #define buffer_add_string(s) sensors_add_array_els(s,strlen(s),\
44                                                    &buffer, \
45                                                    &buffer_count,&buffer_max,1)
46
47 %}
48
49 /* Scanner for configuration files */
50
51 %option nodefault
52 %option noyywrap
53 %option yylineno
54 %option nounput
55
56 /* States. 'Normal' states STRING and MIDDLE share some rules; other states
57    have only their own rules */
58 %s MIDDLE
59 %x STRING
60 %x ERR
61
62 /* Any whitespace-like character */
63 BLANK           [[:space:]]
64
65 IDCHAR          [[:alnum:]_]
66
67 /* Note: `10', `10.4' and `.4' are valid, `10.' is not */
68 FLOAT   [[:digit:]]*\.?[[:digit:]]+
69
70 /* Only positive whole numbers are recognized here */
71 NUM     0|([1-9][[:digit:]]*)
72
73 /* Only number between 1 and 255, octally represented. */
74 OCTESC          (1[0-7]{0,2})|([2-7][0-7]?)|(0[1-7][0-7]?)|(00[1-7])
75
76
77 %%
78
79
80  /* End of line: It may be the end of this line. Same for End of file. */
81 <MIDDLE>\n      |
82 <MIDDLE><<EOF>> {
83                   BEGIN(INITIAL);
84                   return EOL;
85                 }
86
87  /* We want to match any blank, except End of line; that is why we have to
88     match whitespace one by one! */
89 {BLANK}         /* Eat up a blank */
90
91  /* Escaped End of line: eat and be happy */
92 <MIDDLE>\\\n    /* Eat this! */
93
94  /* Remove a comment; we do not change the state, this is done when the \n is
95     eaten */
96 #[^\n]*         /* Eat this! */
97
98  /* Some keywords at the beginning of lines */
99 <INITIAL>"label" {
100                   sensors_yylval.line = sensors_yylineno;
101                   BEGIN(MIDDLE);
102                   return LABEL;
103                 }
104
105 <INITIAL>"set"  {
106                   sensors_yylval.line = sensors_yylineno;
107                   BEGIN(MIDDLE);
108                   return SET;
109                 }
110
111 <INITIAL>"compute" {
112                   sensors_yylval.line = sensors_yylineno;
113                   BEGIN(MIDDLE);
114                   return COMPUTE;
115                 }
116
117 <INITIAL>"bus"  {
118                   sensors_yylval.line = sensors_yylineno;
119                   BEGIN(MIDDLE);
120                   return BUS;
121                 }
122
123 <INITIAL>"chip" {
124                   sensors_yylval.line = sensors_yylineno;
125                   BEGIN(MIDDLE);
126                   return CHIP;
127                 }
128 <INITIAL>"ignore" {
129                   sensors_yylval.line = sensors_yylineno;
130                   BEGIN(MIDDLE);
131                   return IGNORE;
132                 }
133
134  /* Anything else at the beginning of a line is an error */
135 <INITIAL>.      {
136                   yymore();
137                   BEGIN(ERR);
138                 }
139
140 <ERR>[^\n]*\n   {
141                   BEGIN(INITIAL);
142                   strcpy(sensors_lex_error,"Invalid keyword");
143                   return ERROR;
144                 }
145
146  /* A number */
147 <MIDDLE>{FLOAT} {
148                   sensors_yylval.value = atof(sensors_yytext);
149                   return FLOAT;
150                 }
151
152  /* Some operators */
153 <MIDDLE>"+"     {
154                   return '+';
155                 }
156
157 <MIDDLE>"-"     {
158                   return '-';
159                 }
160
161 <MIDDLE>"*"     {
162                   return '*';
163                 }
164
165 <MIDDLE>"/"     {
166                   return '/';
167                 }
168
169 <MIDDLE>"("     {
170                   return '(';
171                 }
172
173 <MIDDLE>")"     {
174                   return ')';
175                 }
176 <MIDDLE>","     {
177                   return ',';
178                 }
179 <MIDDLE>"@"     {
180                   return '@';
181                 }
182 <MIDDLE>"^"     {
183                   return '^';
184                 }
185 <MIDDLE>"`"     {
186                   return '`';
187                 }
188
189  /* Quoted string */
190 <MIDDLE>\"      {
191                   buffer_malloc();
192                   BEGIN(STRING);
193                 }
194
195  /* Oops, newline while in a string is not good */
196 <STRING>\n      |
197 <STRING>\\\n    {
198                   buffer_add_char("\0");
199                   strcpy(sensors_lex_error,"No matching double quote");
200                   buffer_free();
201                   BEGIN(INITIAL);
202                   return ERROR;
203                 }
204
205  /* At the end */
206 <STRING>\"      {
207                   buffer_add_char("\0");
208                   sensors_yylval.name = strdup(buffer);
209                   if (! sensors_yylval.name)
210                     sensors_fatal_error("conf-lex.l",
211                                         "Allocating a new string");
212                   buffer_free();
213                   BEGIN(MIDDLE);
214                   return NAME;
215                 }
216
217 <STRING>\\a     {
218                   buffer_add_char("\a");
219                 }
220
221 <STRING>\\b     {
222                   buffer_add_char("\b");
223                 }
224
225 <STRING>\\f     {
226                   buffer_add_char("\f");
227                 }
228
229 <STRING>\\n     {
230                   buffer_add_char("\n");
231                 }
232
233 <STRING>\\r     {
234                   buffer_add_char("\r");
235                 }
236
237 <STRING>\\t     {
238                   buffer_add_char("\t");
239                 }
240
241 <STRING>\\v     {
242                   buffer_add_char("\v");
243                 }
244
245  /* We can't support \0, this would cause havoc! */
246 <STRING>\\{OCTESC} {
247                   int res;
248                   sscanf(sensors_yytext+1,"%o",&res);
249                   buffer_add_char(&res);
250                 }
251
252  /* Other escapes: just copy the character behind the slash */
253 <STRING>\\.     {
254                   buffer_add_char(&sensors_yytext[1]);
255                 }
256
257  /* Anything else */
258 <STRING>[^\\\n\"]+ {
259                   buffer_add_string(sensors_yytext);
260                 }
261
262  /* A normal, unquoted identifier */
263 <MIDDLE>{IDCHAR}+ {
264                   sensors_yylval.name = strdup(sensors_yytext);
265                   if (! sensors_yylval.name)
266                     sensors_fatal_error("conf-lex.l",
267                                         "Allocating a new string");
268                  
269                   return NAME;
270                 }
271
272 %%
273
274 /*
275         Do the buffer handling manually.  This allows us to scan as many
276         config files as we need to, while cleaning up properly after each
277         one.  The "BEGIN(0)" line ensures that we start in the default state,
278         even if e.g. the previous config file was syntactically broken.
279
280         Returns 0 if successful, !0 otherwise.
281 */
282
283 static YY_BUFFER_STATE scan_buf = (YY_BUFFER_STATE)0;
284
285 int sensors_scanner_init(FILE *input)
286 {
287         BEGIN(0);
288         if (!(scan_buf = sensors_yy_create_buffer(input, YY_BUF_SIZE)))
289                 return -1;
290
291         sensors_yy_switch_to_buffer(scan_buf);
292         return 0;
293 }
294
295 void sensors_scanner_exit(void)
296 {
297         sensors_yy_delete_buffer(scan_buf);
298         scan_buf = (YY_BUFFER_STATE)0;
299 }
300
Note: See TracBrowser for help on using the browser.