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

Revision 3300, 6.3 KB (checked in by mmh, 7 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
30static int buffer_count;
31static int buffer_max;
32static char *buffer;
33
34char 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 */
63BLANK           [[:space:]]
64
65IDCHAR          [[:alnum:]_]
66
67/* Note: `10', `10.4' and `.4' are valid, `10.' is not */
68FLOAT   [[:digit:]]*\.?[[:digit:]]+
69
70/* Only positive whole numbers are recognized here */
71NUM     0|([1-9][[:digit:]]*)
72
73/* Only number between 1 and 255, octally represented. */
74OCTESC          (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
283static YY_BUFFER_STATE scan_buf = (YY_BUFFER_STATE)0;
284
285int 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
295void 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.