1 %{ 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License, Version 1.0 only 7 * (the "License"). You may not use this file except in compliance 8 * with the License. 9 * 10 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 11 * or http://www.opensolaris.org/os/licensing. 12 * See the License for the specific language governing permissions 13 * and limitations under the License. 14 * 15 * When distributing Covered Code, include this CDDL HEADER in each 16 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 17 * If applicable, add the following below this CDDL HEADER, with the 18 * fields enclosed by brackets "[]" replaced with your own identifying 19 * information: Portions Copyright [yyyy] [name of copyright owner] 20 * 21 * CDDL HEADER END 22 * 23 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma error_messages(off, E_STATEMENT_NOT_REACHED) 28 29 /* 30 * poolcfg.l 31 * 32 * Overview 33 * poolcfg.l implements a lexer for the poolcfg(1) utility.The lexer uses 34 * the token definitions generated by YACC in the file poolcfg_Grammar.h. 35 * To make token recognition simpler, the lexer uses a separate state for 36 * each of the different data types supported by poolcfg(1). 37 * 38 * States 39 * Lex provides the ability to minimise conflict between qualifying regexps 40 * by providing states. A regexp that is qualified by a state will only be 41 * used when the state is entered (using the BEGIN <state> command). (The 42 * exception to this rule, is that rules defined in the default state are 43 * available in all states.) 44 * 45 * poolcfg.l makes use of type states, one for each of the poolcfg(1) 46 * supported data types: 47 * 48 * ISTATE => int64_t 49 * USTATE => uint64_t 50 * BSTATE => uchar_t 51 * SSTATE => const char * 52 * DSTATE => double 53 * 54 * and a further state, CPUSTATE, to indicate the difference between matching 55 * a valid "name" (i.e. id) for a cpu and a valid name for other components of 56 * libpool. 57 * 58 * When a token indicating a variable declaration is matched, the corresponding 59 * state is saved in the state variable. Once the assignment ('=') token is 60 * matched, the stored state is entered and the additional state specific 61 * matching regular expressions become available. Once a state specific 62 * token is matched, the default state is restored. 63 * 64 */ 65 #include <stdlib.h> 66 #include <sys/types.h> 67 #include <assert.h> 68 #include <string.h> 69 #include <errno.h> 70 #include <libintl.h> 71 72 #include <pool.h> 73 #include "utils.h" 74 #include "poolcfg.h" 75 #include "poolcfg_grammar.h" 76 77 static int lex_lineno = 1; /* line-number for error reporting */ 78 static int state = INITIAL; /* state to be used */ 79 extern void yyerror(char *s); 80 extern int dofile; /* are we processing a file? */ 81 %} 82 83 %s ISTATE 84 %s USTATE 85 %s BSTATE 86 %s SSTATE 87 %s DSTATE 88 %s CPUSTATE 89 90 %% 91 92 \n lex_lineno++; 93 94 [ \t]+ ; 95 96 #.* ; 97 98 info { return PCC_INFO; } 99 100 create { return PCC_CREATE; } 101 102 destroy { return PCC_DESTROY; } 103 104 modify { return PCC_MODIFY; } 105 106 associate { return PCC_ASSOC; } 107 108 transfer { 109 BEGIN USTATE; 110 return PCC_TRANSFER; 111 } 112 113 discover { return PCC_DISC; } 114 115 rename { return PCC_RENAME; } 116 117 to { return PCK_TO; } 118 119 from { return PCK_FROM; } 120 121 int { 122 state=ISTATE; 123 return PCT_INT; 124 } 125 126 uint { 127 state=USTATE; 128 return PCT_UINT; 129 } 130 131 boolean { 132 state=BSTATE; 133 return PCT_BOOLEAN; 134 } 135 136 string { 137 state=SSTATE; 138 return PCT_STRING; 139 } 140 141 float { 142 state=DSTATE; 143 return PCT_FLOAT; 144 } 145 146 cpu { 147 BEGIN CPUSTATE; 148 return PCE_CPU; 149 } 150 151 pset { return PCE_PSET; } 152 153 pool { return PCE_POOL; } 154 155 system { return PCE_SYSTEM; } 156 157 \( { return PCK_OPENLST; } 158 159 \) { return PCK_CLOSELST; } 160 161 = { 162 BEGIN state; 163 return PCK_ASSIGN; 164 } 165 166 \; { return PCK_SEPLST; } 167 168 ~ { return PCK_UNDEF; } 169 170 <ISTATE>-?[0-9]+ { 171 yylval.ival = strtoll(yytext, NULL, 0); 172 if (errno == EINVAL || errno == ERANGE) { 173 yyerror(gettext("Invalid value")); 174 exit(E_ERROR); 175 } 176 BEGIN INITIAL; 177 return PCV_VAL_INT; 178 } 179 180 <USTATE>[0-9]+ { 181 yylval.uval = strtoull(yytext, NULL, 0); 182 if (errno == EINVAL || errno == ERANGE) { 183 yyerror(gettext("Invalid value")); 184 exit(E_ERROR); 185 } 186 BEGIN INITIAL; 187 return PCV_VAL_UINT; 188 } 189 190 191 <BSTATE>true|false { 192 if (strcmp(yytext, "true") == 0) 193 yylval.bval = 1; 194 else 195 yylval.bval = 0; 196 BEGIN INITIAL; 197 return PCV_VAL_BOOLEAN; 198 } 199 200 <SSTATE>\"[^\"\n]*[\"\n] { 201 if((yylval.sval = strdup(yytext+1)) == NULL) { 202 yyerror(gettext("Out of memory")); 203 exit(E_ERROR); 204 } 205 if (yylval.sval[yyleng-2] =='"') 206 yylval.sval[yyleng-2] = 0; 207 BEGIN INITIAL; 208 return PCV_VAL_STRING; 209 } 210 211 <DSTATE>([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) { 212 yylval.dval = strtod(yytext, (char **)NULL); 213 if (errno == EINVAL || errno == ERANGE) { 214 yyerror(gettext("Invalid value")); 215 exit(E_ERROR); 216 } 217 BEGIN INITIAL; 218 return PCV_VAL_FLOAT; 219 } 220 221 [A-Za-z][A-Za-z0-9,._-]* { 222 if ((yylval.sval = strdup(yytext)) == NULL) { 223 yyerror(gettext("Out of memory")); 224 exit(E_ERROR); 225 } 226 return PCV_SYMBOL; 227 } 228 229 <CPUSTATE>[0-9]+ { 230 if ((yylval.sval = strdup(yytext)) == NULL) { 231 yyerror(gettext("Out of memory")); 232 exit(E_ERROR); 233 } 234 BEGIN INITIAL; 235 return PCV_SYMBOL; 236 } 237 . { 238 yyerror(gettext("Illegal character")); 239 exit(E_ERROR); 240 } 241 242 %% 243 244 void 245 yyerror(char *s) 246 { 247 if (dofile == PO_TRUE) { 248 if (yytext[0] == '\0') { 249 (void) warn(gettext("line %d, %s, token expected\n"), 250 lex_lineno, s); 251 return; 252 } 253 (void) warn(gettext("line %d, %s at '%s'\n"), lex_lineno, s, 254 yytext); 255 } else { 256 if (yytext[0] == '\0') { 257 (void) warn(gettext("%s, token expected\n"), s); 258 return; 259 } 260 (void) warn(gettext("%s at '%s'\n"), s, yytext); 261 } 262 } 263 264