xref: /illumos-gate/usr/src/cmd/pools/poolcfg/poolcfg.l (revision 1a90c98d7539778aeb0a1d20f735b66aaba17fca)
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 int yyerror(const 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 					(void) yyerror(gettext(
174 					    "Invalid value"));
175 					exit(E_ERROR);
176 				}
177 				BEGIN INITIAL;
178 				return PCV_VAL_INT;
179 			}
180 
181 <USTATE>[0-9]+		{
182 				yylval.uval = strtoull(yytext, NULL, 0);
183 				if (errno == EINVAL || errno == ERANGE) {
184 					(void) yyerror(gettext(
185 					    "Invalid value"));
186 					exit(E_ERROR);
187 				}
188 				BEGIN INITIAL;
189 				return PCV_VAL_UINT;
190 			}
191 
192 
193 <BSTATE>true|false	{
194 				if (strcmp(yytext, "true") == 0)
195 					yylval.bval = 1;
196 				else
197 					yylval.bval = 0;
198 				BEGIN INITIAL;
199 				return PCV_VAL_BOOLEAN;
200 			}
201 
202 <SSTATE>\"[^\"\n]*[\"\n] {
203 				if((yylval.sval = strdup(yytext+1)) == NULL) {
204 					(void) yyerror(gettext(
205 					    "Out of memory"));
206 					exit(E_ERROR);
207 				}
208 				if (yylval.sval[yyleng-2] =='"')
209 					yylval.sval[yyleng-2] = 0;
210 				BEGIN INITIAL;
211 				return PCV_VAL_STRING;
212 			}
213 
214 <DSTATE>([0-9]+|([0-9]*\.[0-9]+)([eE][-+]?[0-9]+)?) {
215 				yylval.dval = strtod(yytext, (char **)NULL);
216 				if (errno == EINVAL || errno == ERANGE) {
217 					(void) yyerror(gettext(
218 					    "Invalid value"));
219 					exit(E_ERROR);
220 				}
221 				BEGIN INITIAL;
222 				return PCV_VAL_FLOAT;
223 			}
224 
225 [A-Za-z][A-Za-z0-9,._-]*	{
226 				if ((yylval.sval = strdup(yytext)) == NULL) {
227 					(void) yyerror(gettext(
228 					    "Out of memory"));
229 					exit(E_ERROR);
230 				}
231 				return PCV_SYMBOL;
232 			}
233 
234 <CPUSTATE>[0-9]+	{
235 				if ((yylval.sval = strdup(yytext)) == NULL) {
236 					(void) yyerror(gettext(
237 					    "Out of memory"));
238 					exit(E_ERROR);
239 				}
240 				BEGIN INITIAL;
241 				return PCV_SYMBOL;
242 			}
243 .			{
244 				(void) yyerror(gettext("Illegal character"));
245 				exit(E_ERROR);
246 			}
247 
248 %%
249 
250 int
251 yyerror(const char *s)
252 {
253 	if (dofile == PO_TRUE) {
254 		if (yytext[0] == '\0') {
255 			(void) warn(gettext("line %d, %s, token expected\n"),
256 			    lex_lineno, s);
257 			return (0);
258 		}
259 		(void) warn(gettext("line %d, %s at '%s'\n"), lex_lineno, s,
260 		    yytext);
261 	} else {
262 		if (yytext[0] == '\0') {
263 			(void) warn(gettext("%s, token expected\n"), s);
264 			return (0);
265 		}
266 		(void) warn(gettext("%s at '%s'\n"), s, yytext);
267 	}
268 	return (0);
269 }
270