xref: /illumos-gate/usr/src/cmd/pools/poolcfg/poolcfg.l (revision 2a8bcb4e)
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