3 conf-lex.l - Part of libsensors, a Linux library for reading sensor data.
4 Copyright (c) 1998, 1999 Frodo Looijaard <frodol@dds.nl>
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.
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.
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,
27 #include "conf-parse.h"
31 static int buffer_count;
32 static int buffer_max;
35 char sensors_lex_error[100];
37 const char *sensors_yyfilename;
40 #define buffer_malloc() sensors_malloc_array(&buffer,&buffer_count,\
42 #define buffer_free() sensors_free_array(&buffer,&buffer_count,\
44 #define buffer_add_char(c) sensors_add_array_el(c,&buffer,\
47 #define buffer_add_string(s) sensors_add_array_els(s,strlen(s),\
49 &buffer_count,&buffer_max,1)
53 /* Scanner for configuration files */
59 /* All states are exclusive */
65 /* Any whitespace-like character */
71 /* Note: `10', `10.4' and `.4' are valid, `10.' is not */
73 FLOAT [[:digit:]]*\.?[[:digit:]]+
75 /* Only positive whole numbers are recognized here */
77 NUM 0|([1-9][[:digit:]]*)
88 <<EOF>> { /* EOF from this state terminates */
92 {BLANK}+ ; /* eat as many blanks as possible at once */
94 {BLANK}*\n { /* eat a bare newline (possibly preceded by blanks) */
100 #.* ; /* eat the rest of the line after comment char */
102 #.*\n { /* eat the rest of the line after comment char */
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.)
114 sensors_yylval.line.filename = sensors_yyfilename;
115 sensors_yylval.line.lineno = sensors_yylineno;
121 sensors_yylval.line.filename = sensors_yyfilename;
122 sensors_yylval.line.lineno = sensors_yylineno;
128 sensors_yylval.line.filename = sensors_yyfilename;
129 sensors_yylval.line.lineno = sensors_yylineno;
135 sensors_yylval.line.filename = sensors_yyfilename;
136 sensors_yylval.line.lineno = sensors_yylineno;
142 sensors_yylval.line.filename = sensors_yyfilename;
143 sensors_yylval.line.lineno = sensors_yylineno;
149 sensors_yylval.line.filename = sensors_yyfilename;
150 sensors_yylval.line.lineno = sensors_yylineno;
155 /* Anything else at the beginning of a line is an error */
160 strcpy(sensors_lex_error,"Invalid keyword");
171 .* ; /* eat whatever is left on this line */
186 {BLANK}+ ; /* eat as many blanks as possible at once */
188 \n { /* newline here sends EOL token to parser */
194 <<EOF>> { /* EOF here sends EOL token to parser also */
199 \\{BLANK}*\n { /* eat an escaped newline with no state change */
205 #.* ; /* eat the rest of the line after comment char */
207 #.*\n { /* eat the rest of the line after comment char */
216 sensors_yylval.value = atof(sensors_yytext);
240 /* A normal, unquoted identifier */
243 sensors_yylval.name = strdup(sensors_yytext);
244 if (! sensors_yylval.name)
245 sensors_fatal_error("conf-lex.l",
246 "Allocating a new string");
251 /* anything else is bogus */
267 /* Oops, newline or EOF while in a string is not good */
271 buffer_add_char("\0");
272 strcpy(sensors_lex_error,
273 "No matching double quote.");
281 strcpy(sensors_lex_error,
282 "Reached end-of-file without a matching double quote.");
291 buffer_add_char("\0");
292 strcpy(sensors_lex_error,
293 "Quoted strings must be separated by whitespace.");
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");
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");
318 /* Other escapes: just copy the character behind the slash */
321 buffer_add_char(&sensors_yytext[1]);
324 /* Anything else (including a bare '\' which may be followed by EOF) */
328 buffer_add_string(sensors_yytext);
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.
340 Returns 0 if successful, !0 otherwise.
343 static YY_BUFFER_STATE scan_buf = (YY_BUFFER_STATE)0;
345 int sensors_scanner_init(FILE *input, const char *filename)
348 if (!(scan_buf = sensors_yy_create_buffer(input, YY_BUF_SIZE)))
351 sensors_yy_switch_to_buffer(scan_buf);
352 sensors_yyfilename = filename;
353 sensors_yylineno = 1;
357 void sensors_scanner_exit(void)
359 sensors_yy_delete_buffer(scan_buf);
360 scan_buf = (YY_BUFFER_STATE)0;
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();