root/lm-sensors/tags/V3-0-1/lib/conf-lex.l

Revision 4797, 7.0 kB (checked in by mmh, 1 year ago)

The sensors.conf file syntax currently allows for octal escape sequences, which
nobody uses. This feature is not even mentioned in the sensors.conf man page.
Kill it.

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