11553Srgrimes%union { 21553Srgrimes char *str; 31553Srgrimes int val; 41553Srgrimes struct file_list *file; 51553Srgrimes} 61553Srgrimes 752653Smarcel%token ARCH 81553Srgrimes%token COMMA 946855Speter%token CONFIG 101553Srgrimes%token CPU 11152018Sru%token NOCPU 121553Srgrimes%token DEVICE 13111582Sru%token NODEVICE 1482393Speter%token ENV 151553Srgrimes%token EQUALS 16185186Sthompsa%token PLUSEQUALS 1761640Speter%token HINTS 181553Srgrimes%token IDENT 191553Srgrimes%token MAXUSERS 2067109Sphk%token PROFILE 211553Srgrimes%token OPTIONS 22111582Sru%token NOOPTION 231553Srgrimes%token MAKEOPTIONS 24111582Sru%token NOMAKEOPTION 251553Srgrimes%token SEMICOLON 2679607Sdd%token INCLUDE 27129073Scognet%token FILES 281553Srgrimes 291553Srgrimes%token <str> ID 301553Srgrimes%token <val> NUMBER 311553Srgrimes 321553Srgrimes%type <str> Save_id 3346104Sluoqi%type <str> Opt_value 341553Srgrimes%type <str> Dev 35180922Sobrien%token <str> PATH 361553Srgrimes 371553Srgrimes%{ 381553Srgrimes 391553Srgrimes/* 401553Srgrimes * Copyright (c) 1988, 1993 411553Srgrimes * The Regents of the University of California. All rights reserved. 421553Srgrimes * 431553Srgrimes * Redistribution and use in source and binary forms, with or without 441553Srgrimes * modification, are permitted provided that the following conditions 451553Srgrimes * are met: 461553Srgrimes * 1. Redistributions of source code must retain the above copyright 471553Srgrimes * notice, this list of conditions and the following disclaimer. 481553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 491553Srgrimes * notice, this list of conditions and the following disclaimer in the 501553Srgrimes * documentation and/or other materials provided with the distribution. 511553Srgrimes * 4. Neither the name of the University nor the names of its contributors 521553Srgrimes * may be used to endorse or promote products derived from this software 531553Srgrimes * without specific prior written permission. 541553Srgrimes * 551553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 561553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 571553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 581553Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 591553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 601553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 611553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 621553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 631553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 641553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 651553Srgrimes * SUCH DAMAGE. 661553Srgrimes * 671553Srgrimes * @(#)config.y 8.1 (Berkeley) 6/6/93 6852007Speter * $FreeBSD$ 691553Srgrimes */ 701553Srgrimes 71169507Swkoszek#include <assert.h> 721553Srgrimes#include <ctype.h> 7329451Scharnier#include <err.h> 741553Srgrimes#include <stdio.h> 7512772Speter#include <string.h> 761553Srgrimes 7745775Speter#include "config.h" 7845775Speter 79169647Simpstruct device_head dtab; 8045744Speterchar *ident; 8182393Speterchar *env; 8282393Speterint envmode; 8365091Speterint hintmode; 8445744Speterint yyline; 8579607Sddconst char *yyfile; 86110895Srustruct file_list_head ftab; 87129073Scognetstruct files_name_head fntab; 8845744Speterchar errbuf[80]; 8945744Speterint maxusers; 9045744Speter 9120458Sjoerg#define ns(s) strdup(s) 9279607Sddint include(const char *, int); 9379607Sddvoid yyerror(const char *s); 94151744Sjhbint yywrap(void); 9520458Sjoerg 96174892Simpstatic void newdev(char *name); 97174892Simpstatic void newfile(char *name); 98174892Simpstatic void rmdev_schedule(struct device_head *dh, char *name); 99185186Sthompsastatic void newopt(struct opt_head *list, char *name, char *value, int append); 100174892Simpstatic void rmopt_schedule(struct opt_head *list, char *name); 101174892Simp 10271251Speterstatic char * 10371251Speterdevopt(char *dev) 10471251Speter{ 10571251Speter char *ret = malloc(strlen(dev) + 5); 10671251Speter 10771251Speter sprintf(ret, "DEV_%s", dev); 10871251Speter raisestr(ret); 10971251Speter return ret; 11071251Speter} 11145775Speter 1121553Srgrimes%} 1131553Srgrimes%% 1141553SrgrimesConfiguration: 1151553Srgrimes Many_specs 1161553Srgrimes ; 1171553Srgrimes 1181553SrgrimesMany_specs: 1191553Srgrimes Many_specs Spec 1201553Srgrimes | 1211553Srgrimes /* lambda */ 1221553Srgrimes ; 1231553Srgrimes 1241553SrgrimesSpec: 1251553Srgrimes Device_spec SEMICOLON 12672841Speter | 1271553Srgrimes Config_spec SEMICOLON 1281553Srgrimes | 129180922Sobrien INCLUDE PATH SEMICOLON { 130180922Sobrien if (incignore == 0) 131180922Sobrien include($2, 0); 132180922Sobrien }; 133180922Sobrien | 134174892Simp INCLUDE ID SEMICOLON { 135169507Swkoszek if (incignore == 0) 136169507Swkoszek include($2, 0); 137169507Swkoszek }; 138122656Sbde | 139174892Simp FILES ID SEMICOLON { newfile($2); }; 140129073Scognet | 1411553Srgrimes SEMICOLON 1421553Srgrimes | 1431553Srgrimes error SEMICOLON 1441553Srgrimes ; 1451553Srgrimes 1461553SrgrimesConfig_spec: 147174892Simp ARCH Save_id { 148152865Sru if (machinename != NULL && !eq($2, machinename)) 149117269Sjkoshy errx(1, "%s:%d: only one machine directive is allowed", 150117269Sjkoshy yyfile, yyline); 15172000Speter machinename = $2; 152144509Simp machinearch = $2; 1531553Srgrimes } | 154174892Simp ARCH Save_id Save_id { 155152865Sru if (machinename != NULL && 156152865Sru !(eq($2, machinename) && eq($3, machinearch))) 157144509Simp errx(1, "%s:%d: only one machine directive is allowed", 158144509Simp yyfile, yyline); 159144509Simp machinename = $2; 160144509Simp machinearch = $3; 161144509Simp } | 162174892Simp CPU Save_id { 1631553Srgrimes struct cputype *cp = 164159362Sdelphij (struct cputype *)calloc(1, sizeof (struct cputype)); 165205880Sru if (cp == NULL) 166205880Sru err(EXIT_FAILURE, "calloc"); 16720458Sjoerg cp->cpu_name = $2; 168110895Sru SLIST_INSERT_HEAD(&cputype, cp, cpu_next); 1691553Srgrimes } | 170174892Simp NOCPU Save_id { 171152018Sru struct cputype *cp, *cp2; 172152018Sru SLIST_FOREACH_SAFE(cp, &cputype, cpu_next, cp2) { 173152024Sru if (eq(cp->cpu_name, $2)) { 174152024Sru SLIST_REMOVE(&cputype, cp, cputype, cpu_next); 175152024Sru free(cp); 176152024Sru } 177152018Sru } 178152018Sru } | 1791553Srgrimes OPTIONS Opt_list 1801553Srgrimes | 181174892Simp NOOPTION Save_id { rmopt_schedule(&opt, $2); } | 1821553Srgrimes MAKEOPTIONS Mkopt_list 1831553Srgrimes | 184174892Simp NOMAKEOPTION Save_id { rmopt_schedule(&mkopt, $2); } | 185174892Simp IDENT ID { ident = $2; } | 18646855Speter System_spec 18746855Speter | 188174892Simp MAXUSERS NUMBER { maxusers = $2; } | 189174892Simp PROFILE NUMBER { profiling = $2; } | 190174892Simp ENV ID { 191163637Simp env = $2; 192163637Simp envmode = 1; 19382393Speter } | 194174892Simp HINTS ID { 195163638Simp struct hint *hint; 196163638Simp 197163638Simp hint = (struct hint *)calloc(1, sizeof (struct hint)); 198205880Sru if (hint == NULL) 199205880Sru err(EXIT_FAILURE, "calloc"); 200163638Simp hint->hint_name = $2; 201163638Simp STAILQ_INSERT_TAIL(&hints, hint, hint_next); 202163637Simp hintmode = 1; 203122656Sbde } 2041553Srgrimes 20546855SpeterSystem_spec: 206174892Simp CONFIG System_id System_parameter_list { 207174892Simp errx(1, "%s:%d: root/dump/swap specifications obsolete", 208174892Simp yyfile, yyline); 209174892Simp } 21046855Speter | 21146855Speter CONFIG System_id 21246855Speter ; 21346855Speter 21446855SpeterSystem_id: 215185186Sthompsa Save_id { newopt(&mkopt, ns("KERNEL"), $1, 0); }; 21646855Speter 21746855SpeterSystem_parameter_list: 21846855Speter System_parameter_list ID 21946855Speter | ID 22046855Speter ; 22146855Speter 2221553SrgrimesOpt_list: 2231553Srgrimes Opt_list COMMA Option 2241553Srgrimes | 2251553Srgrimes Option 2261553Srgrimes ; 2271553Srgrimes 2281553SrgrimesOption: 229174892Simp Save_id { 230185186Sthompsa newopt(&opt, $1, NULL, 0); 231160522Sstefanf if (strchr($1, '=') != NULL) 23279607Sdd errx(1, "%s:%d: The `=' in options should not be " 23379607Sdd "quoted", yyfile, yyline); 2341553Srgrimes } | 235174892Simp Save_id EQUALS Opt_value { 236185186Sthompsa newopt(&opt, $1, $3, 0); 2371553Srgrimes } ; 2381553Srgrimes 23946104SluoqiOpt_value: 240174892Simp ID { $$ = $1; } | 241174892Simp NUMBER { 24246021Speter char buf[80]; 2431553Srgrimes 24446021Speter (void) snprintf(buf, sizeof(buf), "%d", $1); 24546021Speter $$ = ns(buf); 24646021Speter } ; 2471553Srgrimes 2481553SrgrimesSave_id: 249174892Simp ID { $$ = $1; } 2501553Srgrimes ; 2511553Srgrimes 2521553SrgrimesMkopt_list: 2531553Srgrimes Mkopt_list COMMA Mkoption 2541553Srgrimes | 2551553Srgrimes Mkoption 2561553Srgrimes ; 2571553Srgrimes 2581553SrgrimesMkoption: 259185186Sthompsa Save_id { newopt(&mkopt, $1, ns(""), 0); } | 260212570Semaste Save_id EQUALS { newopt(&mkopt, $1, ns(""), 0); } | 261185186Sthompsa Save_id EQUALS Opt_value { newopt(&mkopt, $1, $3, 0); } | 262185186Sthompsa Save_id PLUSEQUALS Opt_value { newopt(&mkopt, $1, $3, 1); } ; 2631553Srgrimes 2641553SrgrimesDev: 265174892Simp ID { $$ = $1; } 2661553Srgrimes ; 2671553Srgrimes 2681553SrgrimesDevice_spec: 269136880Sdes DEVICE Dev_list 270136880Sdes | 271136880Sdes NODEVICE NoDev_list 272136880Sdes ; 273136880Sdes 274136880SdesDev_list: 275136880Sdes Dev_list COMMA Device 276136880Sdes | 277136880Sdes Device 278136880Sdes ; 279136880Sdes 280136880SdesNoDev_list: 281136880Sdes NoDev_list COMMA NoDevice 282136880Sdes | 283136880Sdes NoDevice 284136880Sdes ; 285136880Sdes 286136880SdesDevice: 287174892Simp Dev { 288185186Sthompsa newopt(&opt, devopt($1), ns("1"), 0); 28971251Speter /* and the device part */ 290136880Sdes newdev($1); 291136880Sdes } 292136880Sdes 293136880SdesNoDevice: 294174892Simp Dev { 295136880Sdes char *s = devopt($1); 296111582Sru 297169647Simp rmopt_schedule(&opt, s); 298111582Sru free(s); 299110897Sru /* and the device part */ 300169647Simp rmdev_schedule(&dtab, $1); 30146021Speter } ; 3021553Srgrimes 3031553Srgrimes%% 3041553Srgrimes 30579607Sddvoid 30672684Speteryyerror(const char *s) 3071553Srgrimes{ 30829493Scharnier 30979607Sdd errx(1, "%s:%d: %s", yyfile, yyline + 1, s); 3101553Srgrimes} 3111553Srgrimes 312151744Sjhbint 313151744Sjhbyywrap(void) 314151744Sjhb{ 315169647Simp if (found_defaults) { 316169647Simp if (freopen(PREFIX, "r", stdin) == NULL) 317169647Simp err(2, "%s", PREFIX); 318169647Simp yyfile = PREFIX; 319151744Sjhb yyline = 0; 320169647Simp found_defaults = 0; 321151744Sjhb return 0; 322151744Sjhb } 323151744Sjhb return 1; 324151744Sjhb} 325151744Sjhb 3261553Srgrimes/* 327129073Scognet * Add a new file to the list of files. 328129073Scognet */ 329129073Scognetstatic void 330129073Scognetnewfile(char *name) 331129073Scognet{ 332129073Scognet struct files_name *nl; 333129073Scognet 334159362Sdelphij nl = (struct files_name *) calloc(1, sizeof *nl); 335205880Sru if (nl == NULL) 336205880Sru err(EXIT_FAILURE, "calloc"); 337129073Scognet nl->f_name = name; 338129073Scognet STAILQ_INSERT_TAIL(&fntab, nl, f_next); 339129073Scognet} 340129073Scognet 341129073Scognet/* 342153889Sru * Find a device in the list of devices. 3431553Srgrimes */ 344153889Srustatic struct device * 345169507Swkoszekfinddev(struct device_head *dlist, char *name) 346153889Sru{ 347153889Sru struct device *dp; 348153889Sru 349169507Swkoszek STAILQ_FOREACH(dp, dlist, d_next) 350153889Sru if (eq(dp->d_name, name)) 351153889Sru return (dp); 352153889Sru 353153889Sru return (NULL); 354153889Sru} 355153889Sru 356153889Sru/* 357153889Sru * Add a device to the list of devices. 358153889Sru */ 35945744Speterstatic void 360134542Speternewdev(char *name) 3611553Srgrimes{ 36261640Speter struct device *np; 3631553Srgrimes 364169507Swkoszek if (finddev(&dtab, name)) { 365210144Simp fprintf(stderr, 366210144Simp "WARNING: duplicate device `%s' encountered.\n", name); 367153889Sru return; 368153889Sru } 369153889Sru 370159362Sdelphij np = (struct device *) calloc(1, sizeof *np); 371205880Sru if (np == NULL) 372205880Sru err(EXIT_FAILURE, "calloc"); 37372841Speter np->d_name = name; 374110895Sru STAILQ_INSERT_TAIL(&dtab, np, d_next); 3751553Srgrimes} 37672841Speter 377110897Sru/* 378169507Swkoszek * Schedule a device to removal. 379110897Sru */ 38072841Speterstatic void 381169507Swkoszekrmdev_schedule(struct device_head *dh, char *name) 382110897Sru{ 383153889Sru struct device *dp; 384110897Sru 385169647Simp dp = finddev(dh, name); 386169647Simp if (dp != NULL) { 387169647Simp STAILQ_REMOVE(dh, dp, device, d_next); 388169647Simp free(dp->d_name); 389153889Sru free(dp); 390110897Sru } 391110897Sru} 392110897Sru 393153889Sru/* 394153889Sru * Find an option in the list of options. 395153889Sru */ 396153889Srustatic struct opt * 397153889Srufindopt(struct opt_head *list, char *name) 398153889Sru{ 399153889Sru struct opt *op; 400153889Sru 401153889Sru SLIST_FOREACH(op, list, op_next) 402153889Sru if (eq(op->op_name, name)) 403153889Sru return (op); 404153889Sru 405153889Sru return (NULL); 406153889Sru} 407153889Sru 408153889Sru/* 409153889Sru * Add an option to the list of options. 410153889Sru */ 411110897Srustatic void 412185186Sthompsanewopt(struct opt_head *list, char *name, char *value, int append) 41372841Speter{ 414185186Sthompsa struct opt *op, *op2; 41572841Speter 416169507Swkoszek /* 417169507Swkoszek * Ignore inclusions listed explicitly for configuration files. 418169507Swkoszek */ 419169507Swkoszek if (eq(name, OPT_AUTOGEN)) { 420169507Swkoszek incignore = 1; 421169507Swkoszek return; 422169507Swkoszek } 423169507Swkoszek 424185186Sthompsa op2 = findopt(list, name); 425185186Sthompsa if (op2 != NULL && !append) { 426210144Simp fprintf(stderr, 427210144Simp "WARNING: duplicate option `%s' encountered.\n", name); 428153889Sru return; 429153889Sru } 430153889Sru 431159362Sdelphij op = (struct opt *)calloc(1, sizeof (struct opt)); 432205880Sru if (op == NULL) 433205880Sru err(EXIT_FAILURE, "calloc"); 43472841Speter op->op_name = name; 43572841Speter op->op_ownfile = 0; 43672841Speter op->op_value = value; 437185186Sthompsa if (op2 != NULL) { 438185186Sthompsa while (SLIST_NEXT(op2, op_append) != NULL) 439185186Sthompsa op2 = SLIST_NEXT(op2, op_append); 440185186Sthompsa SLIST_NEXT(op2, op_append) = op; 441185186Sthompsa } else 442185186Sthompsa SLIST_INSERT_HEAD(list, op, op_next); 44372841Speter} 444110897Sru 445153889Sru/* 446153889Sru * Remove an option from the list of options. 447153889Sru */ 448110897Srustatic void 449169507Swkoszekrmopt_schedule(struct opt_head *list, char *name) 450110897Sru{ 451153889Sru struct opt *op; 452110897Sru 453169647Simp op = findopt(list, name); 454169647Simp if (op != NULL) { 455169647Simp SLIST_REMOVE(list, op, opt, op_next); 456169647Simp free(op->op_name); 457153889Sru free(op); 458110897Sru } 459110897Sru} 460