xref: /illumos-gate/usr/src/cmd/svc/svccfg/svccfg.l (revision 4de2612967d06c4fdbf524a62556a1e8118a006f)
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 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 #pragma error_messages(off, E_BLOCK_DECL_UNUSED)
30 #pragma error_messages(off, E_EQUALITY_NOT_ASSIGNMENT)
31 #pragma error_messages(off, E_FUNC_RET_MAYBE_IGNORED2)
32 #pragma error_messages(off, E_STMT_NOT_REACHED)
33 
34 #include <libintl.h>
35 #include <string.h>
36 
37 #include "svccfg.h"
38 #include "svccfg_grammar.h"
39 
40 /*
41  * We need to undefine lex's input, unput, and output macros so that references
42  * to these call the functions we provide at the end of this source file,
43  * instead of the default versions based on libc's stdio.
44  */
45 #ifdef input
46 #undef input
47 #endif
48 
49 #ifdef unput
50 #undef unput
51 #endif
52 
53 #ifdef output
54 #undef output
55 #endif
56 
57 static int input(void);
58 static void unput(int);
59 static void output(int);
60 
61 int parens = 0;
62 
63 extern int yyerror(const char *);
64 
65 %}
66 
67 /*
68  * Since command tokens are only valid at the beginning of the command (or
69  * after help), we'll only return them in the INITIAL state, and report them
70  * as SCV_WORDs afterwards.
71  */
72 %Start	WORD
73 
74 %%
75 
76 #.*$			;	/* comments */
77 
78 <INITIAL>validate	{ BEGIN WORD; return (SCC_VALIDATE); }
79 <INITIAL>import		{ BEGIN WORD; return (SCC_IMPORT); }
80 <INITIAL>export		{ BEGIN WORD; return (SCC_EXPORT); }
81 <INITIAL>archive	{ BEGIN WORD; return (SCC_ARCHIVE); }
82 <INITIAL>apply		{ BEGIN WORD; return (SCC_APPLY); }
83 <INITIAL>extract	{ BEGIN WORD; return (SCC_EXTRACT); }
84 <INITIAL>repository	{ BEGIN WORD; return (SCC_REPOSITORY); }
85 <INITIAL>inventory	{ BEGIN WORD; return (SCC_INVENTORY); }
86 <INITIAL>set		{ BEGIN WORD; return (SCC_SET); }
87 <INITIAL>end		{ BEGIN WORD; return (SCC_END); }
88 <INITIAL>exit		{ BEGIN WORD; return (SCC_END); }
89 <INITIAL>quit		{ BEGIN WORD; return (SCC_END); }
90 <INITIAL>help		{ return (SCC_HELP); }
91 
92 <INITIAL>list		{ BEGIN WORD; return (SCC_LIST); }
93 <INITIAL>add		{ BEGIN WORD; return (SCC_ADD); }
94 <INITIAL>delete		{ BEGIN WORD; return (SCC_DELETE); }
95 <INITIAL>select		{ BEGIN WORD; return (SCC_SELECT); }
96 <INITIAL>unselect	{ BEGIN WORD; return (SCC_UNSELECT); }
97 
98 <INITIAL>listpg		{ BEGIN WORD; return (SCC_LISTPG); }
99 <INITIAL>addpg		{ BEGIN WORD; return (SCC_ADDPG); }
100 <INITIAL>delpg		{ BEGIN WORD; return (SCC_DELPG); }
101 <INITIAL>listprop	{ BEGIN WORD; return (SCC_LISTPROP); }
102 <INITIAL>setprop	{ BEGIN WORD; return (SCC_SETPROP); }
103 <INITIAL>delprop	{ BEGIN WORD; return (SCC_DELPROP); }
104 <INITIAL>editprop	{ BEGIN WORD; return (SCC_EDITPROP); }
105 <INITIAL>addpropvalue	{ BEGIN WORD; return (SCC_ADDPROPVALUE); }
106 <INITIAL>delpropvalue	{ BEGIN WORD; return (SCC_DELPROPVALUE); }
107 <INITIAL>setenv		{ BEGIN WORD; return (SCC_SETENV); }
108 <INITIAL>unsetenv	{ BEGIN WORD; return (SCC_UNSETENV); }
109 
110 <INITIAL>listsnap	{ BEGIN WORD; return (SCC_LISTSNAP); }
111 <INITIAL>selectsnap	{ BEGIN WORD; return (SCC_SELECTSNAP); }
112 <INITIAL>revert		{ BEGIN WORD; return (SCC_REVERT); }
113 
114 [^ \t\n">=()]+		{
115 				if ((yylval.str = strdup(yytext)) == NULL) {
116 					yyerror(gettext("Out of memory"));
117 					exit(UU_EXIT_FATAL);
118 				}
119 
120 				return SCV_WORD;
121 			}
122 
123 \"([^"\\]|\\.)*\"	{
124 				/*
125 				 * double-quoted strings start at a
126 				 * double-quote, include characters other than
127 				 * double-quote and backslash, and
128 				 * backslashed-characters, and end with a
129 				 * double-quote.
130 				 */
131 
132 				char *str, *cp;
133 				int shift;
134 
135 				if ((str = strdup(yytext)) == NULL) {
136 					yyerror(gettext("Out of memory"));
137 					exit(UU_EXIT_FATAL);
138 				}
139 
140 				/* Strip out the backslashes. */
141 				for (cp = str, shift = 0; *cp != '\0'; ++cp) {
142 					if (*cp == '\\') {
143 						++cp;
144 
145 						/*
146 						 * This can't be null because
147 						 * the string always ends with
148 						 * a double-quote.
149 						 */
150 
151 						++shift;
152 						*(cp - shift) = *cp;
153 					} else if (shift != 0)
154 						*(cp - shift) = *cp;
155 				}
156 
157 				/* Nullify everything after trailing quote */
158 				*(cp - shift) = '\0';
159 
160 				yylval.str = str;
161 				return SCV_STRING;
162 			}
163 
164 \n			{
165 				est->sc_cmd_lineno++;
166 				BEGIN INITIAL;
167 				return (SCS_NEWLINE);
168 			}
169 
170 [ \t]+			;
171 
172 ">"			{ return SCS_REDIRECT; }
173 "="			{ return SCS_EQUALS; }
174 "("			{ ++parens; return SCS_LPAREN; }
175 ")"			{ --parens; return SCS_RPAREN; }
176 
177 .			{
178 				uu_die(gettext("unrecognized character %s\n"),
179 				    yytext);
180 			}
181 
182 %%
183 
184 int
185 yyerror(const char *s)
186 {
187 	return (0);
188 }
189 
190 static int
191 input(void)
192 {
193 	static int saw_eof = 0;
194 
195 	int c = engine_cmd_getc(est);
196 
197 	/*
198 	 * To ensure input is terminated, slip in a newline on EOF.
199 	 */
200 	if (c == EOF) {
201 		if (saw_eof)
202 			return (0);
203 
204 		saw_eof = 1;
205 		return ('\n');
206 	} else
207 		saw_eof = 0;
208 
209 	if (c == '\n')
210 		yylineno++;
211 
212 	return (c);
213 }
214 
215 static void
216 unput(int c)
217 {
218 	if (c == '\n')
219 		yylineno--;
220 
221 	(void) engine_cmd_ungetc(est, c == 0 ? EOF : c);
222 }
223 
224 static void
225 output(int c)
226 {
227 	char ch = c;
228 	engine_cmd_nputs(est, &ch, sizeof (ch));
229 }
230