poolcfg.l revision 7c478bd95313f5f23a4c958a745db2134aa03244
%{
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#pragma error_messages(off, E_STATEMENT_NOT_REACHED)
/*
* poolcfg.l
*
* Overview
* poolcfg.l implements a lexer for the poolcfg(1) utility.The lexer uses
* the token definitions generated by YACC in the file poolcfg_Grammar.h.
* To make token recognition simpler, the lexer uses a separate state for
* each of the different data types supported by poolcfg(1).
*
* States
* Lex provides the ability to minimise conflict between qualifying regexps
* by providing states. A regexp that is qualified by a state will only be
* used when the state is entered (using the BEGIN <state> command). (The
* exception to this rule, is that rules defined in the default state are
* available in all states.)
*
* poolcfg.l makes use of type states, one for each of the poolcfg(1)
* supported data types:
*
* ISTATE => int64_t
* USTATE => uint64_t
* BSTATE => uchar_t
* SSTATE => const char *
* DSTATE => double
*
* and a further state, CPUSTATE, to indicate the difference between matching
* a valid "name" (i.e. id) for a cpu and a valid name for other components of
* libpool.
*
* When a token indicating a variable declaration is matched, the corresponding
* state is saved in the state variable. Once the assignment ('=') token is
* matched, the stored state is entered and the additional state specific
* matching regular expressions become available. Once a state specific
* token is matched, the default state is restored.
*
*/
#include <stdlib.h>
#include <sys/types.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
#include <libintl.h>
#include <pool.h>
#include "utils.h"
#include "poolcfg.h"
#include "poolcfg_grammar.h"
static int lex_lineno = 1; /* line-number for error reporting */
static int state = INITIAL; /* state to be used */
extern void yyerror(char *s);
extern int dofile; /* are we processing a file? */
%}
%s ISTATE
%s USTATE
%s BSTATE
%s SSTATE
%s DSTATE
%s CPUSTATE
%%
\n lex_lineno++;
[ \t]+ ;
#.* ;
info { return PCC_INFO; }
create { return PCC_CREATE; }
destroy { return PCC_DESTROY; }
modify { return PCC_MODIFY; }
associate { return PCC_ASSOC; }
transfer {
BEGIN USTATE;
return PCC_TRANSFER;
}
discover { return PCC_DISC; }
rename { return PCC_RENAME; }
to { return PCK_TO; }
from { return PCK_FROM; }
int {
state=ISTATE;
return PCT_INT;
}
uint {
state=USTATE;
return PCT_UINT;
}
boolean {
state=BSTATE;
return PCT_BOOLEAN;
}
string {
state=SSTATE;
return PCT_STRING;
}
float {
state=DSTATE;
return PCT_FLOAT;
}
cpu {
BEGIN CPUSTATE;
return PCE_CPU;
}
pset { return PCE_PSET; }
pool { return PCE_POOL; }
system { return PCE_SYSTEM; }
\( { return PCK_OPENLST; }
\) { return PCK_CLOSELST; }
= {
BEGIN state;
return PCK_ASSIGN;
}
\; { return PCK_SEPLST; }
~ { return PCK_UNDEF; }
<ISTATE>-?[0-9]+ {
yylval.ival = strtoll(yytext, NULL, 0);
if (errno == EINVAL || errno == ERANGE) {
yyerror(gettext("Invalid value"));
exit(E_ERROR);
}
BEGIN INITIAL;
return PCV_VAL_INT;
}
<USTATE>[0-9]+ {
yylval.uval = strtoull(yytext, NULL, 0);
if (errno == EINVAL || errno == ERANGE) {
yyerror(gettext("Invalid value"));
exit(E_ERROR);
}
BEGIN INITIAL;
return PCV_VAL_UINT;
}
<BSTATE>true|false {
if (strcmp(yytext, "true") == 0)
yylval.bval = 1;
else
yylval.bval = 0;
BEGIN INITIAL;
return PCV_VAL_BOOLEAN;
}
<SSTATE>\"[^\"\n]*[\"\n] {
if((yylval.sval = strdup(yytext+1)) == NULL) {
yyerror(gettext("Out of memory"));
exit(E_ERROR);
}
if (yylval.sval[yyleng-2] =='"')
yylval.sval[yyleng-2] = 0;
BEGIN INITIAL;
return PCV_VAL_STRING;
}
<DSTATE>([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
yylval.dval = strtod(yytext, (char **)NULL);
if (errno == EINVAL || errno == ERANGE) {
yyerror(gettext("Invalid value"));
exit(E_ERROR);
}
BEGIN INITIAL;
return PCV_VAL_FLOAT;
}
[A-Za-z][A-Za-z0-9,._-]* {
if ((yylval.sval = strdup(yytext)) == NULL) {
yyerror(gettext("Out of memory"));
exit(E_ERROR);
}
return PCV_SYMBOL;
}
<CPUSTATE>[0-9]+ {
if ((yylval.sval = strdup(yytext)) == NULL) {
yyerror(gettext("Out of memory"));
exit(E_ERROR);
}
BEGIN INITIAL;
return PCV_SYMBOL;
}
. {
yyerror(gettext("Illegal character"));
exit(E_ERROR);
}
%%
void
yyerror(char *s)
{
if (dofile == PO_TRUE) {
if (yytext[0] == '\0') {
(void) warn(gettext("line %d, %s, token expected\n"),
lex_lineno, s);
return;
}
(void) warn(gettext("line %d, %s at '%s'\n"), lex_lineno, s,
yytext);
} else {
if (yytext[0] == '\0') {
(void) warn(gettext("%s, token expected\n"), s);
return;
}
(void) warn(gettext("%s at '%s'\n"), s, yytext);
}
}