1 %union { 2 char *str; 3 int val; 4 struct file_list *file; 5 } 6 7 %token ARCH 8 %token COMMA 9 %token CONFIG 10 %token CPU 11 %token DEVICE 12 %token NODEVICE 13 %token ENV 14 %token EQUALS 15 %token HINTS 16 %token IDENT 17 %token MAXUSERS 18 %token PROFILE 19 %token OPTIONS 20 %token NOOPTION 21 %token MAKEOPTIONS 22 %token NOMAKEOPTION 23 %token SEMICOLON 24 %token INCLUDE 25 26 %token <str> ID 27 %token <val> NUMBER 28 29 %type <str> Save_id 30 %type <str> Opt_value 31 %type <str> Dev 32 33 %{ 34 35 /* 36 * Copyright (c) 1988, 1993 37 * The Regents of the University of California. All rights reserved. 38 * 39 * Redistribution and use in source and binary forms, with or without 40 * modification, are permitted provided that the following conditions 41 * are met: 42 * 1. Redistributions of source code must retain the above copyright 43 * notice, this list of conditions and the following disclaimer. 44 * 2. Redistributions in binary form must reproduce the above copyright 45 * notice, this list of conditions and the following disclaimer in the 46 * documentation and/or other materials provided with the distribution. 47 * 3. All advertising materials mentioning features or use of this software 48 * must display the following acknowledgement: 49 * This product includes software developed by the University of 50 * California, Berkeley and its contributors. 51 * 4. Neither the name of the University nor the names of its contributors 52 * may be used to endorse or promote products derived from this software 53 * without specific prior written permission. 54 * 55 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 56 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 57 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 58 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 59 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 60 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 61 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 62 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 63 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 64 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 65 * SUCH DAMAGE. 66 * 67 * @(#)config.y 8.1 (Berkeley) 6/6/93 68 * $FreeBSD$ 69 */ 70 71 #include <ctype.h> 72 #include <err.h> 73 #include <stdio.h> 74 #include <string.h> 75 76 #include "config.h" 77 78 struct device_head dtab; 79 char *ident; 80 char *env; 81 int envmode; 82 char *hints; 83 int hintmode; 84 int yyline; 85 const char *yyfile; 86 struct file_list_head ftab; 87 char errbuf[80]; 88 int maxusers; 89 90 #define ns(s) strdup(s) 91 int include(const char *, int); 92 void yyerror(const char *s); 93 94 static char * 95 devopt(char *dev) 96 { 97 char *ret = malloc(strlen(dev) + 5); 98 99 sprintf(ret, "DEV_%s", dev); 100 raisestr(ret); 101 return ret; 102 } 103 104 %} 105 %% 106 Configuration: 107 Many_specs 108 ; 109 110 Many_specs: 111 Many_specs Spec 112 | 113 /* lambda */ 114 ; 115 116 Spec: 117 Device_spec SEMICOLON 118 | 119 Config_spec SEMICOLON 120 | 121 INCLUDE ID SEMICOLON 122 = { include($2, 0); }; 123 | 124 SEMICOLON 125 | 126 error SEMICOLON 127 ; 128 129 Config_spec: 130 ARCH Save_id 131 = { 132 if (machinename != NULL) 133 errx(1, "%s:%d: only one machine directive is allowed", 134 yyfile, yyline); 135 machinename = $2; 136 } | 137 CPU Save_id 138 = { 139 struct cputype *cp = 140 (struct cputype *)malloc(sizeof (struct cputype)); 141 memset(cp, 0, sizeof(*cp)); 142 cp->cpu_name = $2; 143 SLIST_INSERT_HEAD(&cputype, cp, cpu_next); 144 } | 145 OPTIONS Opt_list 146 | 147 NOOPTION Save_id 148 = { rmopt(&opt, $2); } | 149 MAKEOPTIONS Mkopt_list 150 | 151 NOMAKEOPTION Save_id 152 = { rmopt(&mkopt, $2); } | 153 IDENT ID 154 = { ident = $2; } | 155 System_spec 156 | 157 MAXUSERS NUMBER 158 = { maxusers = $2; } | 159 PROFILE NUMBER 160 = { profiling = $2; } | 161 ENV ID 162 = { 163 env = $2; 164 envmode = 1; 165 } | 166 HINTS ID 167 = { 168 hints = $2; 169 hintmode = 1; 170 } 171 172 System_spec: 173 CONFIG System_id System_parameter_list 174 = { errx(1, "%s:%d: root/dump/swap specifications obsolete", 175 yyfile, yyline);} 176 | 177 CONFIG System_id 178 ; 179 180 System_id: 181 Save_id 182 = { newopt(&mkopt, ns("KERNEL"), $1); }; 183 184 System_parameter_list: 185 System_parameter_list ID 186 | ID 187 ; 188 189 Opt_list: 190 Opt_list COMMA Option 191 | 192 Option 193 ; 194 195 Option: 196 Save_id 197 = { 198 char *s; 199 200 newopt(&opt, $1, NULL); 201 if ((s = strchr($1, '='))) 202 errx(1, "%s:%d: The `=' in options should not be " 203 "quoted", yyfile, yyline); 204 } | 205 Save_id EQUALS Opt_value 206 = { 207 newopt(&opt, $1, $3); 208 } ; 209 210 Opt_value: 211 ID 212 = { $$ = $1; } | 213 NUMBER 214 = { 215 char buf[80]; 216 217 (void) snprintf(buf, sizeof(buf), "%d", $1); 218 $$ = ns(buf); 219 } ; 220 221 Save_id: 222 ID 223 = { $$ = $1; } 224 ; 225 226 Mkopt_list: 227 Mkopt_list COMMA Mkoption 228 | 229 Mkoption 230 ; 231 232 Mkoption: 233 Save_id 234 = { newopt(&mkopt, $1, ns("")); } | 235 Save_id EQUALS Opt_value 236 = { newopt(&mkopt, $1, $3); } ; 237 238 Dev: 239 ID 240 = { $$ = $1; } 241 ; 242 243 Device_spec: 244 DEVICE Dev 245 = { 246 newopt(&opt, devopt($2), ns("1")); 247 /* and the device part */ 248 newdev($2, UNKNOWN); 249 } | 250 DEVICE Dev NUMBER 251 = { 252 newopt(&opt, devopt($2), ns("1")); 253 /* and the device part */ 254 newdev($2, $3); 255 if ($3 == 0) 256 errx(1, "%s:%d: devices with zero units are not " 257 "likely to be correct", yyfile, yyline); 258 } | 259 NODEVICE Dev 260 = { 261 char *s = devopt($2); 262 263 rmopt(&opt, s); 264 free(s); 265 /* and the device part */ 266 rmdev($2); 267 } ; 268 269 %% 270 271 void 272 yyerror(const char *s) 273 { 274 275 errx(1, "%s:%d: %s", yyfile, yyline + 1, s); 276 } 277 278 /* 279 * add a device to the list of devices 280 */ 281 static void 282 newdev(char *name, int count) 283 { 284 struct device *np; 285 286 np = (struct device *) malloc(sizeof *np); 287 memset(np, 0, sizeof(*np)); 288 np->d_name = name; 289 np->d_count = count; 290 STAILQ_INSERT_TAIL(&dtab, np, d_next); 291 } 292 293 /* 294 * remove a device from the list of devices 295 */ 296 static void 297 rmdev(char *name) 298 { 299 struct device *dp, *rmdp; 300 301 STAILQ_FOREACH(dp, &dtab, d_next) { 302 if (eq(dp->d_name, name)) { 303 rmdp = dp; 304 dp = STAILQ_NEXT(dp, d_next); 305 STAILQ_REMOVE(&dtab, rmdp, device, d_next); 306 free(rmdp->d_name); 307 free(rmdp); 308 if (dp == NULL) 309 break; 310 } 311 } 312 } 313 314 static void 315 newopt(struct opt_head *list, char *name, char *value) 316 { 317 struct opt *op; 318 319 op = (struct opt *)malloc(sizeof (struct opt)); 320 memset(op, 0, sizeof(*op)); 321 op->op_name = name; 322 op->op_ownfile = 0; 323 op->op_value = value; 324 SLIST_INSERT_HEAD(list, op, op_next); 325 } 326 327 static void 328 rmopt(struct opt_head *list, char *name) 329 { 330 struct opt *op, *rmop; 331 332 SLIST_FOREACH(op, list, op_next) { 333 if (eq(op->op_name, name)) { 334 rmop = op; 335 op = SLIST_NEXT(op, op_next); 336 SLIST_REMOVE(list, rmop, opt, op_next); 337 free(rmop->op_name); 338 if (rmop->op_value != NULL) 339 free(rmop->op_value); 340 free(rmop); 341 if (op == NULL) 342 break; 343 } 344 } 345 } 346