%{ /* * 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 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 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 #include #include #include #include #include #include #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 int yyerror(const 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; } -?[0-9]+ { yylval.ival = strtoll(yytext, NULL, 0); if (errno == EINVAL || errno == ERANGE) { (void) yyerror(gettext( "Invalid value")); exit(E_ERROR); } BEGIN INITIAL; return PCV_VAL_INT; } [0-9]+ { yylval.uval = strtoull(yytext, NULL, 0); if (errno == EINVAL || errno == ERANGE) { (void) yyerror(gettext( "Invalid value")); exit(E_ERROR); } BEGIN INITIAL; return PCV_VAL_UINT; } true|false { if (strcmp(yytext, "true") == 0) yylval.bval = 1; else yylval.bval = 0; BEGIN INITIAL; return PCV_VAL_BOOLEAN; } \"[^\"\n]*[\"\n] { if((yylval.sval = strdup(yytext+1)) == NULL) { (void) yyerror(gettext( "Out of memory")); exit(E_ERROR); } if (yylval.sval[yyleng-2] =='"') yylval.sval[yyleng-2] = 0; BEGIN INITIAL; return PCV_VAL_STRING; } ([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { yylval.dval = strtod(yytext, (char **)NULL); if (errno == EINVAL || errno == ERANGE) { (void) 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) { (void) yyerror(gettext( "Out of memory")); exit(E_ERROR); } return PCV_SYMBOL; } [0-9]+ { if ((yylval.sval = strdup(yytext)) == NULL) { (void) yyerror(gettext( "Out of memory")); exit(E_ERROR); } BEGIN INITIAL; return PCV_SYMBOL; } . { (void) yyerror(gettext("Illegal character")); exit(E_ERROR); } %% int yyerror(const char *s) { if (dofile == PO_TRUE) { if (yytext[0] == '\0') { (void) warn(gettext("line %d, %s, token expected\n"), lex_lineno, s); return (0); } (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 (0); } (void) warn(gettext("%s at '%s'\n"), s, yytext); } return (0); }