Merge branch 'linux-3.10.y' of git://git.kernel.org/pub/scm/linux/kernel/git/stable...
[firefly-linux-kernel-4.4.55.git] / tools / gator / daemon / libsensors / conf-lex.l
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
31 static int buffer_count;
32 static int buffer_max;
33 static char *buffer;
34
35 char sensors_lex_error[100];
36
37 const char *sensors_yyfilename;
38 int 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
67 BLANK           [ \f\r\t\v]
68
69 IDCHAR          [[:alnum:]_]
70
71  /* Note: `10', `10.4' and `.4' are valid, `10.' is not */
72
73 FLOAT   [[:digit:]]*\.?[[:digit:]]+
74
75  /* Only positive whole numbers are recognized here */
76
77 NUM     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
113 label{BLANK}*   {
114                   sensors_yylval.line.filename = sensors_yyfilename;
115                   sensors_yylval.line.lineno = sensors_yylineno;
116                   BEGIN(MIDDLE);
117                   return LABEL;
118                 }
119
120 set{BLANK}*     {
121                   sensors_yylval.line.filename = sensors_yyfilename;
122                   sensors_yylval.line.lineno = sensors_yylineno;
123                   BEGIN(MIDDLE);
124                   return SET;
125                 }
126
127 compute{BLANK}* {
128                   sensors_yylval.line.filename = sensors_yyfilename;
129                   sensors_yylval.line.lineno = sensors_yylineno;
130                   BEGIN(MIDDLE);
131                   return COMPUTE;
132                 }
133
134 bus{BLANK}*     {
135                   sensors_yylval.line.filename = sensors_yyfilename;
136                   sensors_yylval.line.lineno = sensors_yylineno;
137                   BEGIN(MIDDLE);
138                   return BUS;
139                 }
140
141 chip{BLANK}*    {
142                   sensors_yylval.line.filename = sensors_yyfilename;
143                   sensors_yylval.line.lineno = sensors_yylineno;
144                   BEGIN(MIDDLE);
145                   return CHIP;
146                 }
147
148 ignore{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
343 static YY_BUFFER_STATE scan_buf = (YY_BUFFER_STATE)0;
344
345 int 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
357 void 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