xref: /illumos-gate/usr/src/cmd/pools/poolcfg/poolcfg.l (revision e8d3efa1c56e5f2b5368600a2baeb7b1d54a07f8)
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 /*
28  * poolcfg.l
29  *
30  * Overview
31  * poolcfg.l implements a lexer for the poolcfg(1) utility.The lexer uses
32  * the token definitions generated by YACC in the file poolcfg_Grammar.h.
33  * To make token recognition simpler, the lexer uses a separate state for
34  * each of the different data types supported by poolcfg(1).
35  *
36  * States
37  * Lex provides the ability to minimise conflict between qualifying regexps
38  * by providing states. A regexp that is qualified by a state will only be
39  * used when the state is entered (using the BEGIN <state> command). (The
40  * exception to this rule, is that rules defined in the default state are
41  * available in all states.)
42  *
43  * poolcfg.l makes use of type states, one for each of the poolcfg(1)
44  * supported data types:
45  *
46  * ISTATE => int64_t
47  * USTATE => uint64_t
48  * BSTATE => uchar_t
49  * SSTATE => const char *
50  * DSTATE => double
51  *
52  * and a further state, CPUSTATE, to indicate the difference between matching
53  * a valid "name" (i.e. id) for a cpu and a valid name for other components of
54  * libpool.
55  *
56  * When a token indicating a variable declaration is matched, the corresponding
57  * state is saved in the state variable. Once the assignment ('=') token is
58  * matched, the stored state is entered and the additional state specific
59  * matching regular expressions become available. Once a state specific
60  * token is matched, the default state is restored.
61  *
62  */
63 #include <stdlib.h>
64 #include <sys/types.h>
65 #include <assert.h>
66 #include <string.h>
67 #include <errno.h>
68 #include <libintl.h>
69 
70 #include <pool.h>
71 #include "utils.h"
72 #include "poolcfg.h"
73 #include "poolcfg_grammar.h"
74 
75 static int lex_lineno = 1;		/* line-number for error reporting */
76 static int state = INITIAL;		/* state to be used */
77 extern int yyerror(const char *s);
78 extern int dofile;			/* are we processing a file? */
79 %}
80 
81 %s ISTATE
82 %s USTATE
83 %s BSTATE
84 %s SSTATE
85 %s DSTATE
86 %s CPUSTATE
87 
88 %%
89 
90 \n			lex_lineno++;
91 
92 [ \t]+			;
93 
94 #.*			;
95 
96 info			{ return PCC_INFO; }
97 
98 create			{ return PCC_CREATE; }
99 
100 destroy			{ return PCC_DESTROY; }
101 
102 modify			{ return PCC_MODIFY; }
103 
104 associate		{ return PCC_ASSOC; }
105 
106 transfer		{
107 				BEGIN USTATE;
108 				return PCC_TRANSFER;
109 			}
110 
111 discover		{ return PCC_DISC; }
112 
113 rename			{ return PCC_RENAME; }
114 
115 to			{ return PCK_TO; }
116 
117 from			{ return PCK_FROM; }
118 
119 int			{
120 				state=ISTATE;
121 				return PCT_INT;
122 			}
123 
124 uint			{
125 				state=USTATE;
126 				return PCT_UINT;
127 			}
128 
129 boolean			{
130 				state=BSTATE;
131 				return PCT_BOOLEAN;
132 			}
133 
134 string			{
135 				state=SSTATE;
136 				return PCT_STRING;
137 			}
138 
139 float			{
140 				state=DSTATE;
141 				return PCT_FLOAT;
142 			}
143 
144 cpu			{
145 				BEGIN CPUSTATE;
146 				return PCE_CPU;
147 			}
148 
149 pset			{ return PCE_PSET; }
150 
151 pool			{ return PCE_POOL; }
152 
153 system			{ return PCE_SYSTEM; }
154 
155 \(			{ return PCK_OPENLST; }
156 
157 \)			{ return PCK_CLOSELST; }
158 
159 =			{
160 				BEGIN state;
161 				return PCK_ASSIGN;
162 			}
163 
164 \;			{ return PCK_SEPLST; }
165 
166 ~			{ return PCK_UNDEF; }
167 
168 <ISTATE>-?[0-9]+	{
169 				yylval.ival = strtoll(yytext, NULL, 0);
170 				if (errno == EINVAL || errno == ERANGE) {
171 					(void) yyerror(gettext(
172 					    "Invalid value"));
173 					exit(E_ERROR);
174 				}
175 				BEGIN INITIAL;
176 				return PCV_VAL_INT;
177 			}
178 
179 <USTATE>[0-9]+		{
180 				yylval.uval = strtoull(yytext, NULL, 0);
181 				if (errno == EINVAL || errno == ERANGE) {
182 					(void) yyerror(gettext(
183 					    "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 					(void) yyerror(gettext(
203 					    "Out of memory"));
204 					exit(E_ERROR);
205 				}
206 				if (yylval.sval[yyleng-2] =='"')
207 					yylval.sval[yyleng-2] = 0;
208 				BEGIN INITIAL;
209 				return PCV_VAL_STRING;
210 			}
211 
212 <DSTATE>([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
213 				yylval.dval = strtod(yytext, (char **)NULL);
214 				if (errno == EINVAL || errno == ERANGE) {
215 					(void) yyerror(gettext(
216 					    "Invalid value"));
217 					exit(E_ERROR);
218 				}
219 				BEGIN INITIAL;
220 				return PCV_VAL_FLOAT;
221 			}
222 
223 [A-Za-z][A-Za-z0-9,._-]*	{
224 				if ((yylval.sval = strdup(yytext)) == NULL) {
225 					(void) yyerror(gettext(
226 					    "Out of memory"));
227 					exit(E_ERROR);
228 				}
229 				return PCV_SYMBOL;
230 			}
231 
232 <CPUSTATE>[0-9]+	{
233 				if ((yylval.sval = strdup(yytext)) == NULL) {
234 					(void) yyerror(gettext(
235 					    "Out of memory"));
236 					exit(E_ERROR);
237 				}
238 				BEGIN INITIAL;
239 				return PCV_SYMBOL;
240 			}
241 .			{
242 				(void) yyerror(gettext("Illegal character"));
243 				exit(E_ERROR);
244 			}
245 
246 %%
247 
248 int
249 yyerror(const char *s)
250 {
251 	if (dofile == PO_TRUE) {
252 		if (yytext[0] == '\0') {
253 			(void) warn(gettext("line %d, %s, token expected\n"),
254 			    lex_lineno, s);
255 			return (0);
256 		}
257 		(void) warn(gettext("line %d, %s at '%s'\n"), lex_lineno, s,
258 		    yytext);
259 	} else {
260 		if (yytext[0] == '\0') {
261 			(void) warn(gettext("%s, token expected\n"), s);
262 			return (0);
263 		}
264 		(void) warn(gettext("%s at '%s'\n"), s, yytext);
265 	}
266 	return (0);
267 }
268