Blame lib/conf-lex.l

Packit 53d5b6
%{
Packit 53d5b6
/*
Packit 53d5b6
    conf-lex.l - Part of libsensors, a Linux library for reading sensor data.
Packit 53d5b6
    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
Packit 53d5b6
Packit 53d5b6
    This library is free software; you can redistribute it and/or
Packit 53d5b6
    modify it under the terms of the GNU Lesser General Public
Packit 53d5b6
    License as published by the Free Software Foundation; either
Packit 53d5b6
    version 2.1 of the License, or (at your option) any later version.
Packit 53d5b6
Packit 53d5b6
    This library is distributed in the hope that it will be useful,
Packit 53d5b6
    but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 53d5b6
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 53d5b6
    GNU Lesser General Public License for more details.
Packit 53d5b6
Packit 53d5b6
    You should have received a copy of the GNU General Public License
Packit 53d5b6
    along with this program; if not, write to the Free Software
Packit 53d5b6
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
Packit 53d5b6
    MA 02110-1301 USA.
Packit 53d5b6
*/
Packit 53d5b6
Packit 53d5b6
#include <stdlib.h>
Packit 53d5b6
#include <string.h>
Packit 53d5b6
Packit 53d5b6
#include "general.h"
Packit 53d5b6
#include "data.h"
Packit 53d5b6
#include "conf-parse.h"
Packit 53d5b6
#include "error.h"
Packit 53d5b6
#include "scanner.h"
Packit 53d5b6
Packit 53d5b6
static int buffer_count;
Packit 53d5b6
static int buffer_max;
Packit 53d5b6
static char *buffer;
Packit 53d5b6
Packit 53d5b6
char sensors_lex_error[100];
Packit 53d5b6
Packit 53d5b6
const char *sensors_yyfilename;
Packit 53d5b6
int sensors_yylineno;
Packit 53d5b6
Packit 53d5b6
#define buffer_malloc() sensors_malloc_array(&buffer,&buffer_count,\
Packit 53d5b6
                                             &buffer_max,1)
Packit 53d5b6
#define buffer_free() sensors_free_array(&buffer,&buffer_count,\
Packit 53d5b6
                                         &buffer_max)
Packit 53d5b6
#define buffer_add_char(c) sensors_add_array_el(c,&buffer,\
Packit 53d5b6
                                                &buffer_count,\
Packit 53d5b6
                                                &buffer_max,1)
Packit 53d5b6
#define buffer_add_string(s) sensors_add_array_els(s,strlen(s),\
Packit 53d5b6
                                                   &buffer, \
Packit 53d5b6
                                                   &buffer_count,&buffer_max,1)
Packit 53d5b6
Packit 53d5b6
%}
Packit 53d5b6
Packit 53d5b6
 /* Scanner for configuration files */
Packit 53d5b6
Packit 53d5b6
%option nodefault
Packit 53d5b6
%option noyywrap
Packit 53d5b6
%option nounput
Packit 53d5b6
Packit 53d5b6
 /* All states are exclusive */
Packit 53d5b6
Packit 53d5b6
%x MIDDLE
Packit 53d5b6
%x STRING
Packit 53d5b6
%x ERR
Packit 53d5b6
Packit 53d5b6
 /* Any whitespace-like character */
Packit 53d5b6
Packit 53d5b6
BLANK		[ \f\r\t\v]
Packit 53d5b6
Packit 53d5b6
IDCHAR		[[:alnum:]_]
Packit 53d5b6
Packit 53d5b6
 /* Note: `10', `10.4' and `.4' are valid, `10.' is not */
Packit 53d5b6
Packit 53d5b6
FLOAT   [[:digit:]]*\.?[[:digit:]]+
Packit 53d5b6
Packit 53d5b6
 /* Only positive whole numbers are recognized here */
Packit 53d5b6
Packit 53d5b6
NUM	0|([1-9][[:digit:]]*)
Packit 53d5b6
Packit 53d5b6
Packit 53d5b6
%%
Packit 53d5b6
Packit 53d5b6
 /*
Packit 53d5b6
  * STATE: INITIAL
Packit 53d5b6
  */
Packit 53d5b6
Packit 53d5b6
<INITIAL>{
Packit 53d5b6
Packit 53d5b6
<<EOF>>		{ /* EOF from this state terminates */
Packit 53d5b6
		  return 0;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
{BLANK}+	; /* eat as many blanks as possible at once */
Packit 53d5b6
Packit 53d5b6
{BLANK}*\n	{ /* eat a bare newline (possibly preceded by blanks) */
Packit 53d5b6
		  sensors_yylineno++;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* comments */
Packit 53d5b6
Packit 53d5b6
#.*		; /* eat the rest of the line after comment char */
Packit 53d5b6
Packit 53d5b6
#.*\n		{ /* eat the rest of the line after comment char */
Packit 53d5b6
		  sensors_yylineno++;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /*
Packit 53d5b6
  * Keywords must be followed by whitespace - eat that too.
Packit 53d5b6
  * If there isn't trailing whitespace, we still need to
Packit 53d5b6
  * accept it as lexically correct (even though the parser
Packit 53d5b6
  * will reject it anyway.)
Packit 53d5b6
  */
Packit 53d5b6
Packit 53d5b6
label{BLANK}*	{
Packit 53d5b6
		  sensors_yylval.line.filename = sensors_yyfilename;
Packit 53d5b6
		  sensors_yylval.line.lineno = sensors_yylineno;
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return LABEL;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
set{BLANK}*	{
Packit 53d5b6
		  sensors_yylval.line.filename = sensors_yyfilename;
Packit 53d5b6
		  sensors_yylval.line.lineno = sensors_yylineno;
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return SET;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
compute{BLANK}*	{
Packit 53d5b6
		  sensors_yylval.line.filename = sensors_yyfilename;
Packit 53d5b6
		  sensors_yylval.line.lineno = sensors_yylineno;
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return COMPUTE;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
bus{BLANK}*	{
Packit 53d5b6
		  sensors_yylval.line.filename = sensors_yyfilename;
Packit 53d5b6
		  sensors_yylval.line.lineno = sensors_yylineno;
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return BUS;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
chip{BLANK}*	{
Packit 53d5b6
		  sensors_yylval.line.filename = sensors_yyfilename;
Packit 53d5b6
		  sensors_yylval.line.lineno = sensors_yylineno;
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return CHIP;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
ignore{BLANK}*	{
Packit 53d5b6
		  sensors_yylval.line.filename = sensors_yyfilename;
Packit 53d5b6
		  sensors_yylval.line.lineno = sensors_yylineno;
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return IGNORE;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* Anything else at the beginning of a line is an error */
Packit 53d5b6
Packit 53d5b6
[a-z]+		|
Packit 53d5b6
.		{
Packit 53d5b6
		  BEGIN(ERR);
Packit 53d5b6
		  strcpy(sensors_lex_error,"Invalid keyword");
Packit 53d5b6
		  return ERROR;
Packit 53d5b6
		}
Packit 53d5b6
}
Packit 53d5b6
Packit 53d5b6
 /*
Packit 53d5b6
  * STATE: ERROR
Packit 53d5b6
  */
Packit 53d5b6
Packit 53d5b6
<ERR>{
Packit 53d5b6
Packit 53d5b6
.*		; /* eat whatever is left on this line */
Packit 53d5b6
Packit 53d5b6
\n		{
Packit 53d5b6
		  BEGIN(INITIAL);
Packit 53d5b6
		  sensors_yylineno++;
Packit 53d5b6
		  return EOL;
Packit 53d5b6
		}
Packit 53d5b6
}
Packit 53d5b6
Packit 53d5b6
 /*
Packit 53d5b6
  * STATE: MIDDLE
Packit 53d5b6
  */
Packit 53d5b6
Packit 53d5b6
<MIDDLE>{
Packit 53d5b6
Packit 53d5b6
{BLANK}+	; /* eat as many blanks as possible at once */
Packit 53d5b6
Packit 53d5b6
\n		{ /* newline here sends EOL token to parser */
Packit 53d5b6
		  BEGIN(INITIAL);
Packit 53d5b6
		  sensors_yylineno++;
Packit 53d5b6
		  return EOL;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
<<EOF>>		{ /* EOF here sends EOL token to parser also */
Packit 53d5b6
		  BEGIN(INITIAL);
Packit 53d5b6
		  return EOL;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
\\{BLANK}*\n	{ /* eat an escaped newline with no state change */
Packit 53d5b6
		  sensors_yylineno++;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* comments */
Packit 53d5b6
Packit 53d5b6
#.*		; /* eat the rest of the line after comment char */
Packit 53d5b6
Packit 53d5b6
#.*\n		{ /* eat the rest of the line after comment char */
Packit 53d5b6
		  BEGIN(INITIAL);
Packit 53d5b6
		  sensors_yylineno++;
Packit 53d5b6
		  return EOL;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* A number */
Packit 53d5b6
Packit 53d5b6
{FLOAT}		{
Packit 53d5b6
		  sensors_yylval.value = atof(sensors_yytext);
Packit 53d5b6
		  return FLOAT;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* Some operators */
Packit 53d5b6
Packit 53d5b6
"+"		return '+';
Packit 53d5b6
"-"		return '-';
Packit 53d5b6
"*"		return '*';
Packit 53d5b6
"/"		return '/';
Packit 53d5b6
"("		return '(';
Packit 53d5b6
")"		return ')';
Packit 53d5b6
","		return ',';
Packit 53d5b6
"@"		return '@';
Packit 53d5b6
"^"		return '^';
Packit 53d5b6
"`"		return '`';
Packit 53d5b6
Packit 53d5b6
 /* Quoted string */
Packit 53d5b6
Packit 53d5b6
\"		{
Packit 53d5b6
		  buffer_malloc();
Packit 53d5b6
		  BEGIN(STRING);
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* A normal, unquoted identifier */
Packit 53d5b6
Packit 53d5b6
{IDCHAR}+	{
Packit 53d5b6
		  sensors_yylval.name = strdup(sensors_yytext);
Packit 53d5b6
		  if (! sensors_yylval.name)
Packit 53d5b6
		    sensors_fatal_error("conf-lex.l",
Packit 53d5b6
                                        "Allocating a new string");
Packit 53d5b6
		  
Packit 53d5b6
		  return NAME;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* anything else is bogus */
Packit 53d5b6
Packit 53d5b6
.		|
Packit 53d5b6
[[:digit:]]*\.	|
Packit 53d5b6
\\{BLANK}*	{
Packit 53d5b6
		  BEGIN(ERR);
Packit 53d5b6
		  return ERROR;
Packit 53d5b6
		}
Packit 53d5b6
}
Packit 53d5b6
Packit 53d5b6
 /*
Packit 53d5b6
  * STATE: STRING
Packit 53d5b6
  */
Packit 53d5b6
Packit 53d5b6
<STRING>{
Packit 53d5b6
Packit 53d5b6
 /* Oops, newline or EOF while in a string is not good */
Packit 53d5b6
Packit 53d5b6
\n		|
Packit 53d5b6
\\\n		{
Packit 53d5b6
		  buffer_add_char("\0");
Packit 53d5b6
		  strcpy(sensors_lex_error,
Packit 53d5b6
			"No matching double quote.");
Packit 53d5b6
		  buffer_free();
Packit 53d5b6
		  yyless(0);
Packit 53d5b6
		  BEGIN(ERR);
Packit 53d5b6
		  return ERROR;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
<<EOF>>		{
Packit 53d5b6
		  strcpy(sensors_lex_error,
Packit 53d5b6
			"Reached end-of-file without a matching double quote.");
Packit 53d5b6
		  buffer_free();
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return ERROR;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* At the end */
Packit 53d5b6
Packit 53d5b6
\"\"		{
Packit 53d5b6
		  buffer_add_char("\0");
Packit 53d5b6
		  strcpy(sensors_lex_error,
Packit 53d5b6
			"Quoted strings must be separated by whitespace.");
Packit 53d5b6
		  buffer_free();
Packit 53d5b6
		  BEGIN(ERR);
Packit 53d5b6
		  return ERROR;
Packit 53d5b6
		}
Packit 53d5b6
		
Packit 53d5b6
\"		{
Packit 53d5b6
		  buffer_add_char("\0");
Packit 53d5b6
		  sensors_yylval.name = strdup(buffer);
Packit 53d5b6
		  if (! sensors_yylval.name)
Packit 53d5b6
		    sensors_fatal_error("conf-lex.l",
Packit 53d5b6
                                        "Allocating a new string");
Packit 53d5b6
		  buffer_free();
Packit 53d5b6
		  BEGIN(MIDDLE);
Packit 53d5b6
		  return NAME;
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
\\a		buffer_add_char("\a");
Packit 53d5b6
\\b		buffer_add_char("\b");
Packit 53d5b6
\\f		buffer_add_char("\f");
Packit 53d5b6
\\n		buffer_add_char("\n");
Packit 53d5b6
\\r		buffer_add_char("\r");
Packit 53d5b6
\\t		buffer_add_char("\t");
Packit 53d5b6
\\v		buffer_add_char("\v");
Packit 53d5b6
Packit 53d5b6
 /* Other escapes: just copy the character behind the slash */
Packit 53d5b6
Packit 53d5b6
\\.		{
Packit 53d5b6
		  buffer_add_char(&sensors_yytext[1]);
Packit 53d5b6
		}
Packit 53d5b6
Packit 53d5b6
 /* Anything else (including a bare '\' which may be followed by EOF) */
Packit 53d5b6
Packit 53d5b6
\\		|
Packit 53d5b6
[^\\\n\"]+	{
Packit 53d5b6
		  buffer_add_string(sensors_yytext);
Packit 53d5b6
		}
Packit 53d5b6
}
Packit 53d5b6
Packit 53d5b6
%%
Packit 53d5b6
Packit 53d5b6
/*
Packit 53d5b6
	Do the buffer handling manually.  This allows us to scan as many
Packit 53d5b6
	config files as we need to, while cleaning up properly after each
Packit 53d5b6
	one.  The "BEGIN(0)" line ensures that we start in the default state,
Packit 53d5b6
	even if e.g. the previous config file was syntactically broken.
Packit 53d5b6
Packit 53d5b6
	Returns 0 if successful, !0 otherwise.
Packit 53d5b6
*/
Packit 53d5b6
Packit 53d5b6
static YY_BUFFER_STATE scan_buf = (YY_BUFFER_STATE)0;
Packit 53d5b6
Packit 53d5b6
int sensors_scanner_init(FILE *input, const char *filename)
Packit 53d5b6
{
Packit 53d5b6
	BEGIN(0);
Packit 53d5b6
	if (!(scan_buf = sensors_yy_create_buffer(input, YY_BUF_SIZE)))
Packit 53d5b6
		return -1;
Packit 53d5b6
Packit 53d5b6
	sensors_yy_switch_to_buffer(scan_buf);
Packit 53d5b6
	sensors_yyfilename = filename;
Packit 53d5b6
	sensors_yylineno = 1;
Packit 53d5b6
	return 0;
Packit 53d5b6
}
Packit 53d5b6
Packit 53d5b6
void sensors_scanner_exit(void)
Packit 53d5b6
{
Packit 53d5b6
	sensors_yy_delete_buffer(scan_buf);
Packit 53d5b6
	scan_buf = (YY_BUFFER_STATE)0;
Packit 53d5b6
Packit 53d5b6
/* As of flex 2.5.9, yylex_destroy() must be called when done with the
Packit 53d5b6
   scaller, otherwise we'll leak memory. */
Packit 53d5b6
#if defined(YY_FLEX_MAJOR_VERSION) && defined(YY_FLEX_MINOR_VERSION) && defined(YY_FLEX_SUBMINOR_VERSION)
Packit 53d5b6
#if YY_FLEX_MAJOR_VERSION > 2 || \
Packit 53d5b6
    (YY_FLEX_MAJOR_VERSION == 2 && (YY_FLEX_MINOR_VERSION > 5 || \
Packit 53d5b6
				    (YY_FLEX_MINOR_VERSION == 5 && YY_FLEX_SUBMINOR_VERSION >= 9)))
Packit 53d5b6
	sensors_yylex_destroy();
Packit 53d5b6
#endif
Packit 53d5b6
#endif
Packit 53d5b6
}
Packit 53d5b6