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 (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 25 */ 26 27 28 #pragma error_messages(off, E_BLOCK_DECL_UNUSED) 29 #pragma error_messages(off, E_EQUALITY_NOT_ASSIGNMENT) 30 #pragma error_messages(off, E_FUNC_RET_MAYBE_IGNORED2) 31 #pragma error_messages(off, E_STMT_NOT_REACHED) 32 33 #include <libintl.h> 34 #include <string.h> 35 36 #include "svccfg.h" 37 #include "svccfg_grammar.h" 38 39 /* 40 * We need to undefine lex's input, unput, and output macros so that references 41 * to these call the functions we provide at the end of this source file, 42 * instead of the default versions based on libc's stdio. 43 */ 44 #ifdef input 45 #undef input 46 #endif 47 48 #ifdef unput 49 #undef unput 50 #endif 51 52 #ifdef output 53 #undef output 54 #endif 55 56 static int input(void); 57 static void unput(int); 58 static void output(int); 59 60 int parens = 0; 61 62 extern int yyerror(const char *); 63 64 %} 65 66 /* 67 * Since command tokens are only valid at the beginning of the command (or 68 * after help), we'll only return them in the INITIAL state, and report them 69 * as SCV_WORDs afterwards. 70 */ 71 %Start WORD 72 73 /* 74 * The default value of lex for transitions is 2000 and it seems we reached it. 75 * So we are bumping it up! 76 */ 77 %a 3000 78 79 %% 80 81 #.*$ ; /* comments */ 82 83 <INITIAL>validate { BEGIN WORD; return (SCC_VALIDATE); } 84 <INITIAL>import { BEGIN WORD; return (SCC_IMPORT); } 85 <INITIAL>cleanup { BEGIN WORD; return (SCC_CLEANUP); } 86 <INITIAL>export { BEGIN WORD; return (SCC_EXPORT); } 87 <INITIAL>archive { BEGIN WORD; return (SCC_ARCHIVE); } 88 <INITIAL>restore { BEGIN WORD; return (SCC_RESTORE); } 89 <INITIAL>apply { BEGIN WORD; return (SCC_APPLY); } 90 <INITIAL>extract { BEGIN WORD; return (SCC_EXTRACT); } 91 <INITIAL>repository { BEGIN WORD; return (SCC_REPOSITORY); } 92 <INITIAL>inventory { BEGIN WORD; return (SCC_INVENTORY); } 93 <INITIAL>set { BEGIN WORD; return (SCC_SET); } 94 <INITIAL>end { BEGIN WORD; return (SCC_END); } 95 <INITIAL>exit { BEGIN WORD; return (SCC_END); } 96 <INITIAL>quit { BEGIN WORD; return (SCC_END); } 97 <INITIAL>help { return (SCC_HELP); } 98 99 <INITIAL>list { BEGIN WORD; return (SCC_LIST); } 100 <INITIAL>add { BEGIN WORD; return (SCC_ADD); } 101 <INITIAL>delete { BEGIN WORD; return (SCC_DELETE); } 102 <INITIAL>select { BEGIN WORD; return (SCC_SELECT); } 103 <INITIAL>unselect { BEGIN WORD; return (SCC_UNSELECT); } 104 105 <INITIAL>listpg { BEGIN WORD; return (SCC_LISTPG); } 106 <INITIAL>addpg { BEGIN WORD; return (SCC_ADDPG); } 107 <INITIAL>delpg { BEGIN WORD; return (SCC_DELPG); } 108 <INITIAL>delhash { BEGIN WORD; return (SCC_DELHASH); } 109 <INITIAL>listprop { BEGIN WORD; return (SCC_LISTPROP); } 110 <INITIAL>setprop { BEGIN WORD; return (SCC_SETPROP); } 111 <INITIAL>delprop { BEGIN WORD; return (SCC_DELPROP); } 112 <INITIAL>editprop { BEGIN WORD; return (SCC_EDITPROP); } 113 <INITIAL>describe { BEGIN WORD; return (SCC_DESCRIBE); } 114 <INITIAL>addpropvalue { BEGIN WORD; return (SCC_ADDPROPVALUE); } 115 <INITIAL>delpropvalue { BEGIN WORD; return (SCC_DELPROPVALUE); } 116 <INITIAL>setenv { BEGIN WORD; return (SCC_SETENV); } 117 <INITIAL>unsetenv { BEGIN WORD; return (SCC_UNSETENV); } 118 119 <INITIAL>listsnap { BEGIN WORD; return (SCC_LISTSNAP); } 120 <INITIAL>selectsnap { BEGIN WORD; return (SCC_SELECTSNAP); } 121 <INITIAL>revert { BEGIN WORD; return (SCC_REVERT); } 122 <INITIAL>refresh { BEGIN WORD; return (SCC_REFRESH); } 123 124 <INITIAL>delnotify { BEGIN WORD; return (SCC_DELNOTIFY); } 125 <INITIAL>listnotify { BEGIN WORD; return (SCC_LISTNOTIFY); } 126 <INITIAL>setnotify { BEGIN WORD; return (SCC_SETNOTIFY); } 127 128 [^ \t\n">=()]+ { 129 if ((yylval.str = strdup(yytext)) == NULL) { 130 yyerror(gettext("Out of memory")); 131 exit(UU_EXIT_FATAL); 132 } 133 134 return SCV_WORD; 135 } 136 137 \"([^"\\]|\\.)*\" { 138 /* 139 * double-quoted strings start at a 140 * double-quote, include characters other than 141 * double-quote and backslash, and 142 * backslashed-characters, and end with a 143 * double-quote. 144 */ 145 146 char *str, *cp; 147 int shift; 148 149 if ((str = strdup(yytext)) == NULL) { 150 yyerror(gettext("Out of memory")); 151 exit(UU_EXIT_FATAL); 152 } 153 154 /* Strip out the backslashes. */ 155 for (cp = str, shift = 0; *cp != '\0'; ++cp) { 156 if (*cp == '\\') { 157 ++cp; 158 159 /* 160 * This can't be null because 161 * the string always ends with 162 * a double-quote. 163 */ 164 165 ++shift; 166 *(cp - shift) = *cp; 167 } else if (shift != 0) 168 *(cp - shift) = *cp; 169 } 170 171 /* Nullify everything after trailing quote */ 172 *(cp - shift) = '\0'; 173 174 yylval.str = str; 175 return SCV_STRING; 176 } 177 178 \n { 179 est->sc_cmd_lineno++; 180 BEGIN INITIAL; 181 return (SCS_NEWLINE); 182 } 183 184 [ \t]+ ; 185 186 ">" { return SCS_REDIRECT; } 187 "=" { return SCS_EQUALS; } 188 "(" { ++parens; return SCS_LPAREN; } 189 ")" { --parens; return SCS_RPAREN; } 190 191 . { 192 uu_die(gettext("unrecognized character %s\n"), 193 yytext); 194 } 195 196 %% 197 198 int 199 yyerror(const char *s) 200 { 201 return (0); 202 } 203 204 static int 205 input(void) 206 { 207 static int saw_eof = 0; 208 209 int c = engine_cmd_getc(est); 210 211 /* 212 * To ensure input is terminated, slip in a newline on EOF. 213 */ 214 if (c == EOF) { 215 if (saw_eof) 216 return (0); 217 218 saw_eof = 1; 219 return ('\n'); 220 } else 221 saw_eof = 0; 222 223 if (c == '\n') 224 yylineno++; 225 226 return (c); 227 } 228 229 static void 230 unput(int c) 231 { 232 if (c == '\n') 233 yylineno--; 234 235 (void) engine_cmd_ungetc(est, c == 0 ? EOF : c); 236 } 237 238 static void 239 output(int c) 240 { 241 char ch = c; 242 engine_cmd_nputs(est, &ch, sizeof (ch)); 243 } 244