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

Revision 5844, 7.9 KB (checked in by khali, 4 years ago)

Change libsensors license from GPL to LGPL.

  • 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 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.
10
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.
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., 51 Franklin Street, Fifth Floor, Boston,
19    MA 02110-1301 USA.
20*/
21
22#include <stdlib.h>
23#include <string.h>
24
25#include "general.h"
26#include "data.h"
27#include "conf-parse.h"
28#include "error.h"
29#include "scanner.h"
30
31static int buffer_count;
32static int buffer_max;
33static char *buffer;
34
35char sensors_lex_error[100];
36
37const char *sensors_yyfilename;
38int sensors_yylineno;
39
40#define buffer_malloc() sensors_malloc_array(&buffer,&buffer_count,\
41                                             &buffer_max,1)
42#define buffer_free() sensors_free_array(&buffer,&buffer_count,\
43                                         &buffer_max)
44#define buffer_add_char(c) sensors_add_array_el(c,&buffer,\
45                                                &buffer_count,\
46                                                &buffer_max,1)
47#define buffer_add_string(s) sensors_add_array_els(s,strlen(s),\
48                                                   &buffer, \
49                                                   &buffer_count,&buffer_max,1)
50
51%}
52
53 /* Scanner for configuration files */
54
55%option nodefault
56%option noyywrap
57%option nounput
58
59 /* All states are exclusive */
60
61%x MIDDLE
62%x STRING
63%x ERR
64
65 /* Any whitespace-like character */
66
67BLANK           [ \f\r\t\v]
68
69IDCHAR          [[:alnum:]_]
70
71 /* Note: `10', `10.4' and `.4' are valid, `10.' is not */
72
73FLOAT   [[:digit:]]*\.?[[:digit:]]+
74
75 /* Only positive whole numbers are recognized here */
76
77NUM     0|([1-9][[:digit:]]*)
78
79
80%%
81
82 /*
83  * STATE: INITIAL
84  */
85
86<INITIAL>{
87
88<<EOF>>         { /* EOF from this state terminates */
89                  return 0;
90                }
91
92{BLANK}+        ; /* eat as many blanks as possible at once */
93
94{BLANK}*\n      { /* eat a bare newline (possibly preceded by blanks) */
95                  sensors_yylineno++;
96                }
97
98 /* comments */
99
100#.*             ; /* eat the rest of the line after comment char */
101
102#.*\n           { /* eat the rest of the line after comment char */
103                  sensors_yylineno++;
104                }
105
106 /*
107  * Keywords must be followed by whitespace - eat that too.
108  * If there isn't trailing whitespace, we still need to
109  * accept it as lexically correct (even though the parser
110  * will reject it anyway.)
111  */
112
113label{BLANK}*   {
114                  sensors_yylval.line.filename = sensors_yyfilename;
115                  sensors_yylval.line.lineno = sensors_yylineno;
116                  BEGIN(MIDDLE);
117                  return LABEL;
118                }
119
120set{BLANK}*     {
121                  sensors_yylval.line.filename = sensors_yyfilename;
122                  sensors_yylval.line.lineno = sensors_yylineno;
123                  BEGIN(MIDDLE);
124                  return SET;
125                }
126
127compute{BLANK}* {
128                  sensors_yylval.line.filename = sensors_yyfilename;
129                  sensors_yylval.line.lineno = sensors_yylineno;
130                  BEGIN(MIDDLE);
131                  return COMPUTE;
132                }
133
134bus{BLANK}*     {
135                  sensors_yylval.line.filename = sensors_yyfilename;
136                  sensors_yylval.line.lineno = sensors_yylineno;
137                  BEGIN(MIDDLE);
138                  return BUS;
139                }
140
141chip{BLANK}*    {
142                  sensors_yylval.line.filename = sensors_yyfilename;
143                  sensors_yylval.line.lineno = sensors_yylineno;
144                  BEGIN(MIDDLE);
145                  return CHIP;
146                }
147
148ignore{BLANK}*  {
149                  sensors_yylval.line.filename = sensors_yyfilename;
150                  sensors_yylval.line.lineno = sensors_yylineno;
151                  BEGIN(MIDDLE);
152                  return IGNORE;
153                }
154
155 /* Anything else at the beginning of a line is an error */
156
157[a-z]+          |
158.               {
159                  BEGIN(ERR);
160                  strcpy(sensors_lex_error,"Invalid keyword");
161                  return ERROR;
162                }
163}
164
165 /*
166  * STATE: ERROR
167  */
168
169<ERR>{
170
171.*              ; /* eat whatever is left on this line */
172
173\n              {
174                  BEGIN(INITIAL);
175                  sensors_yylineno++;
176                  return EOL;
177                }
178}
179
180 /*
181  * STATE: MIDDLE
182  */
183
184<MIDDLE>{
185
186{BLANK}+        ; /* eat as many blanks as possible at once */
187
188\n              { /* newline here sends EOL token to parser */
189                  BEGIN(INITIAL);
190                  sensors_yylineno++;
191                  return EOL;
192                }
193
194<<EOF>>         { /* EOF here sends EOL token to parser also */
195                  BEGIN(INITIAL);
196                  return EOL;
197                }
198
199\\{BLANK}*\n    { /* eat an escaped newline with no state change */
200                  sensors_yylineno++;
201                }
202
203 /* comments */
204
205#.*             ; /* eat the rest of the line after comment char */
206
207#.*\n           { /* eat the rest of the line after comment char */
208                  BEGIN(INITIAL);
209                  sensors_yylineno++;
210                  return EOL;
211                }
212
213 /* A number */
214
215{FLOAT}         {
216                  sensors_yylval.value = atof(sensors_yytext);
217                  return FLOAT;
218                }
219
220 /* Some operators */
221
222"+"             return '+';
223"-"             return '-';
224"*"             return '*';
225"/"             return '/';
226"("             return '(';
227")"             return ')';
228","             return ',';
229"@"             return '@';
230"^"             return '^';
231"`"             return '`';
232
233 /* Quoted string */
234
235\"              {
236                  buffer_malloc();
237                  BEGIN(STRING);
238                }
239
240 /* A normal, unquoted identifier */
241
242{IDCHAR}+       {
243                  sensors_yylval.name = strdup(sensors_yytext);
244                  if (! sensors_yylval.name)
245                    sensors_fatal_error("conf-lex.l",
246                                        "Allocating a new string");
247                 
248                  return NAME;
249                }
250
251 /* anything else is bogus */
252
253.               |
254[[:digit:]]*\.  |
255\\{BLANK}*      {
256                  BEGIN(ERR);
257                  return ERROR;
258                }
259}
260
261 /*
262  * STATE: STRING
263  */
264
265<STRING>{
266
267 /* Oops, newline or EOF while in a string is not good */
268
269\n              |
270\\\n            {
271                  buffer_add_char("\0");
272                  strcpy(sensors_lex_error,
273                        "No matching double quote.");
274                  buffer_free();
275                  yyless(0);
276                  BEGIN(ERR);
277                  return ERROR;
278                }
279
280<<EOF>>         {
281                  strcpy(sensors_lex_error,
282                        "Reached end-of-file without a matching double quote.");
283                  buffer_free();
284                  BEGIN(MIDDLE);
285                  return ERROR;
286                }
287
288 /* At the end */
289
290\"\"            {
291                  buffer_add_char("\0");
292                  strcpy(sensors_lex_error,
293                        "Quoted strings must be separated by whitespace.");
294                  buffer_free();
295                  BEGIN(ERR);
296                  return ERROR;
297                }
298               
299\"              {
300                  buffer_add_char("\0");
301                  sensors_yylval.name = strdup(buffer);
302                  if (! sensors_yylval.name)
303                    sensors_fatal_error("conf-lex.l",
304                                        "Allocating a new string");
305                  buffer_free();
306                  BEGIN(MIDDLE);
307                  return NAME;
308                }
309
310\\a             buffer_add_char("\a");
311\\b             buffer_add_char("\b");
312\\f             buffer_add_char("\f");
313\\n             buffer_add_char("\n");
314\\r             buffer_add_char("\r");
315\\t             buffer_add_char("\t");
316\\v             buffer_add_char("\v");
317
318 /* Other escapes: just copy the character behind the slash */
319
320\\.             {
321                  buffer_add_char(&sensors_yytext[1]);
322                }
323
324 /* Anything else (including a bare '\' which may be followed by EOF) */
325
326\\              |
327[^\\\n\"]+      {
328                  buffer_add_string(sensors_yytext);
329                }
330}
331
332%%
333
334/*
335        Do the buffer handling manually.  This allows us to scan as many
336        config files as we need to, while cleaning up properly after each
337        one.  The "BEGIN(0)" line ensures that we start in the default state,
338        even if e.g. the previous config file was syntactically broken.
339
340        Returns 0 if successful, !0 otherwise.
341*/
342
343static YY_BUFFER_STATE scan_buf = (YY_BUFFER_STATE)0;
344
345int sensors_scanner_init(FILE *input, const char *filename)
346{
347        BEGIN(0);
348        if (!(scan_buf = sensors_yy_create_buffer(input, YY_BUF_SIZE)))
349                return -1;
350
351        sensors_yy_switch_to_buffer(scan_buf);
352        sensors_yyfilename = filename;
353        sensors_yylineno = 1;
354        return 0;
355}
356
357void sensors_scanner_exit(void)
358{
359        sensors_yy_delete_buffer(scan_buf);
360        scan_buf = (YY_BUFFER_STATE)0;
361
362/* As of flex 2.5.9, yylex_destroy() must be called when done with the
363   scaller, otherwise we'll leak memory. */
364#if defined(YY_FLEX_MAJOR_VERSION) && defined(YY_FLEX_MINOR_VERSION) && defined(YY_FLEX_SUBMINOR_VERSION)
365#if YY_FLEX_MAJOR_VERSION > 2 || \
366    (YY_FLEX_MAJOR_VERSION == 2 && (YY_FLEX_MINOR_VERSION > 5 || \
367                                    (YY_FLEX_MINOR_VERSION == 5 && YY_FLEX_SUBMINOR_VERSION >= 9)))
368        sensors_yylex_destroy();
369#endif
370#endif
371}
372
Note: See TracBrowser for help on using the browser.