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