config.y revision 174892
185965Sbrian%union { 277690Sbrian char *str; 320365Sjkh int val; 477690Sbrian struct file_list *file; 577690Sbrian} 677690Sbrian 777690Sbrian%token ARCH 877690Sbrian%token COMMA 977690Sbrian%token CONFIG 1077690Sbrian%token CPU 1177690Sbrian%token NOCPU 1226031Sbrian%token DEVICE 1377690Sbrian%token NODEVICE 1477690Sbrian%token ENV 1577690Sbrian%token EQUALS 1677690Sbrian%token HINTS 1777690Sbrian%token IDENT 1877690Sbrian%token MAXUSERS 1977690Sbrian%token PROFILE 2077690Sbrian%token OPTIONS 2177690Sbrian%token NOOPTION 2277690Sbrian%token MAKEOPTIONS 2377690Sbrian%token NOMAKEOPTION 2426031Sbrian%token SEMICOLON 2577690Sbrian%token INCLUDE 2677690Sbrian%token FILES 2777690Sbrian 2877690Sbrian%token <str> ID 2977690Sbrian%token <val> NUMBER 3077690Sbrian 3120365Sjkh%type <str> Save_id 3220365Sjkh%type <str> Opt_value 3320365Sjkh%type <str> Dev 3426031Sbrian 3526031Sbrian%{ 3636466Sbrian 3726031Sbrian/* 3820365Sjkh * Copyright (c) 1988, 1993 3920365Sjkh * The Regents of the University of California. All rights reserved. 4026031Sbrian * 4120365Sjkh * Redistribution and use in source and binary forms, with or without 4220365Sjkh * modification, are permitted provided that the following conditions 4377690Sbrian * are met: 4477690Sbrian * 1. Redistributions of source code must retain the above copyright 4577690Sbrian * notice, this list of conditions and the following disclaimer. 4677690Sbrian * 2. Redistributions in binary form must reproduce the above copyright 4726031Sbrian * notice, this list of conditions and the following disclaimer in the 4877690Sbrian * documentation and/or other materials provided with the distribution. 4920365Sjkh * 3. All advertising materials mentioning features or use of this software 5077690Sbrian * must display the following acknowledgement: 5177690Sbrian * This product includes software developed by the University of 5226031Sbrian * California, Berkeley and its contributors. 5326031Sbrian * 4. Neither the name of the University nor the names of its contributors 5426031Sbrian * may be used to endorse or promote products derived from this software 5520365Sjkh * without specific prior written permission. 5620365Sjkh * 5726031Sbrian * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 5826031Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 5926031Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 6026031Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 6126031Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 6226031Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 6320365Sjkh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 6477690Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 6526031Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 6626031Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 6726031Sbrian * SUCH DAMAGE. 6826031Sbrian * 6926031Sbrian * @(#)config.y 8.1 (Berkeley) 6/6/93 7020365Sjkh * $FreeBSD: head/usr.sbin/config/config.y 174892 2007-12-25 06:22:33Z imp $ 7126031Sbrian */ 7226031Sbrian 7326031Sbrian#include <assert.h> 7426031Sbrian#include <ctype.h> 7526031Sbrian#include <err.h> 7626031Sbrian#include <stdio.h> 7726031Sbrian#include <string.h> 7820365Sjkh 7926031Sbrian#include "config.h" 8026031Sbrian 8136466Sbrianstruct device_head dtab; 8226031Sbrianchar *ident; 8320365Sjkhchar *env; 8477690Sbrianint envmode; 8526031Sbrianint hintmode; 8620365Sjkhint yyline; 8720365Sjkhconst char *yyfile; 8820365Sjkhstruct file_list_head ftab; 8920365Sjkhstruct files_name_head fntab; 9020365Sjkhchar errbuf[80]; 9126031Sbrianint maxusers; 9277690Sbrian 9326031Sbrian#define ns(s) strdup(s) 9477690Sbrianint include(const char *, int); 9577690Sbrianvoid yyerror(const char *s); 9626031Sbrianint yywrap(void); 9726031Sbrian 9820365Sjkhstatic void newdev(char *name); 9977690Sbrianstatic void newfile(char *name); 10026031Sbrianstatic void rmdev_schedule(struct device_head *dh, char *name); 10126031Sbrianstatic void newopt(struct opt_head *list, char *name, char *value); 10226031Sbrianstatic void rmopt_schedule(struct opt_head *list, char *name); 10320365Sjkh 10426031Sbrianstatic char * 10526031Sbriandevopt(char *dev) 10626031Sbrian{ 10726031Sbrian char *ret = malloc(strlen(dev) + 5); 10826031Sbrian 10926031Sbrian sprintf(ret, "DEV_%s", dev); 11020365Sjkh raisestr(ret); 11120365Sjkh return ret; 11220365Sjkh} 11326031Sbrian 11420365Sjkh%} 11577690Sbrian%% 11677690SbrianConfiguration: 11777690Sbrian Many_specs 11836466Sbrian ; 11977690Sbrian 12036466SbrianMany_specs: 12120365Sjkh Many_specs Spec 12226031Sbrian | 12377690Sbrian /* lambda */ 12420365Sjkh ; 12577690Sbrian 12620365SjkhSpec: 12777690Sbrian Device_spec SEMICOLON 12820365Sjkh | 12926031Sbrian Config_spec SEMICOLON 13020365Sjkh | 13126031Sbrian INCLUDE ID SEMICOLON { 13277690Sbrian if (incignore == 0) 13326031Sbrian include($2, 0); 13477690Sbrian }; 13577690Sbrian | 13626031Sbrian FILES ID SEMICOLON { newfile($2); }; 13726031Sbrian | 13877690Sbrian SEMICOLON 13926031Sbrian | 14026031Sbrian error SEMICOLON 14126031Sbrian ; 14277690Sbrian 14326031SbrianConfig_spec: 14426031Sbrian ARCH Save_id { 14577690Sbrian if (machinename != NULL && !eq($2, machinename)) 14626031Sbrian errx(1, "%s:%d: only one machine directive is allowed", 14777690Sbrian yyfile, yyline); 14836466Sbrian machinename = $2; 14926031Sbrian machinearch = $2; 15026031Sbrian } | 15126031Sbrian ARCH Save_id Save_id { 15277690Sbrian if (machinename != NULL && 15326031Sbrian !(eq($2, machinename) && eq($3, machinearch))) 15477690Sbrian errx(1, "%s:%d: only one machine directive is allowed", 15526031Sbrian yyfile, yyline); 15677690Sbrian machinename = $2; 15777690Sbrian machinearch = $3; 15826031Sbrian } | 15926031Sbrian CPU Save_id { 16077690Sbrian struct cputype *cp = 16126031Sbrian (struct cputype *)calloc(1, sizeof (struct cputype)); 16277690Sbrian cp->cpu_name = $2; 16326031Sbrian SLIST_INSERT_HEAD(&cputype, cp, cpu_next); 16477690Sbrian } | 16526031Sbrian NOCPU Save_id { 16636466Sbrian struct cputype *cp, *cp2; 16726031Sbrian SLIST_FOREACH_SAFE(cp, &cputype, cpu_next, cp2) { 16826031Sbrian if (eq(cp->cpu_name, $2)) { 16977690Sbrian SLIST_REMOVE(&cputype, cp, cputype, cpu_next); 17026031Sbrian free(cp); 17126031Sbrian } 17226031Sbrian } 17377690Sbrian } | 17426031Sbrian OPTIONS Opt_list 17577690Sbrian | 17677690Sbrian NOOPTION Save_id { rmopt_schedule(&opt, $2); } | 17777690Sbrian MAKEOPTIONS Mkopt_list 17836466Sbrian | 17926031Sbrian NOMAKEOPTION Save_id { rmopt_schedule(&mkopt, $2); } | 18026031Sbrian IDENT ID { ident = $2; } | 18126031Sbrian System_spec 18236466Sbrian | 18326031Sbrian MAXUSERS NUMBER { maxusers = $2; } | 18426031Sbrian PROFILE NUMBER { profiling = $2; } | 18526031Sbrian ENV ID { 18626031Sbrian env = $2; 18726031Sbrian envmode = 1; 18877690Sbrian } | 18926031Sbrian HINTS ID { 19077690Sbrian struct hint *hint; 19126031Sbrian 19226031Sbrian hint = (struct hint *)calloc(1, sizeof (struct hint)); 19326031Sbrian hint->hint_name = $2; 19426031Sbrian STAILQ_INSERT_TAIL(&hints, hint, hint_next); 19526031Sbrian hintmode = 1; 19626031Sbrian } 19726031Sbrian 19826031SbrianSystem_spec: 19926031Sbrian CONFIG System_id System_parameter_list { 20026031Sbrian errx(1, "%s:%d: root/dump/swap specifications obsolete", 20177690Sbrian yyfile, yyline); 20226031Sbrian } 20326031Sbrian | 20477690Sbrian CONFIG System_id 20526031Sbrian ; 20698243Sbrian 20726031SbrianSystem_id: 20826031Sbrian Save_id { newopt(&mkopt, ns("KERNEL"), $1); }; 20926031Sbrian 21077690SbrianSystem_parameter_list: 21126031Sbrian System_parameter_list ID 21236466Sbrian | ID 21326031Sbrian ; 21426031Sbrian 21526031SbrianOpt_list: 21626031Sbrian Opt_list COMMA Option 21726031Sbrian | 21826031Sbrian Option 21977690Sbrian ; 22026031Sbrian 22126031SbrianOption: 22226031Sbrian Save_id { 22326031Sbrian newopt(&opt, $1, NULL); 22426031Sbrian if (strchr($1, '=') != NULL) 22526031Sbrian errx(1, "%s:%d: The `=' in options should not be " 22626031Sbrian "quoted", yyfile, yyline); 22726031Sbrian } | 22826031Sbrian Save_id EQUALS Opt_value { 22977690Sbrian newopt(&opt, $1, $3); 23026031Sbrian } ; 23126031Sbrian 23298243SbrianOpt_value: 23326031Sbrian ID { $$ = $1; } | 23477690Sbrian NUMBER { 23526031Sbrian char buf[80]; 23626031Sbrian 23777690Sbrian (void) snprintf(buf, sizeof(buf), "%d", $1); 23877690Sbrian $$ = ns(buf); 23977690Sbrian } ; 24026031Sbrian 24136466SbrianSave_id: 24226031Sbrian ID { $$ = $1; } 24377690Sbrian ; 24426031Sbrian 24526031SbrianMkopt_list: 24626031Sbrian Mkopt_list COMMA Mkoption 24726031Sbrian | 24826031Sbrian Mkoption 24926031Sbrian ; 25077690Sbrian 25177690SbrianMkoption: 25277690Sbrian Save_id { newopt(&mkopt, $1, ns("")); } | 25377690Sbrian Save_id EQUALS Opt_value { newopt(&mkopt, $1, $3); } ; 25477690Sbrian 25526031SbrianDev: 25626031Sbrian ID { $$ = $1; } 25726031Sbrian ; 25877690Sbrian 25926031SbrianDevice_spec: 26026031Sbrian DEVICE Dev_list 26126031Sbrian | 26226031Sbrian NODEVICE NoDev_list 26326031Sbrian ; 26426031Sbrian 26577690SbrianDev_list: 26626031Sbrian Dev_list COMMA Device 26726031Sbrian | 26836466Sbrian Device 26977690Sbrian ; 27026031Sbrian 27126031SbrianNoDev_list: 27226031Sbrian NoDev_list COMMA NoDevice 27336466Sbrian | 27426031Sbrian NoDevice 27586806Sbrian ; 27626031Sbrian 27726031SbrianDevice: 27826031Sbrian Dev { 27926031Sbrian newopt(&opt, devopt($1), ns("1")); 28026031Sbrian /* and the device part */ 28126031Sbrian newdev($1); 28226031Sbrian } 28326031Sbrian 28426031SbrianNoDevice: 28526031Sbrian Dev { 28626031Sbrian char *s = devopt($1); 28726031Sbrian 28826031Sbrian rmopt_schedule(&opt, s); 28926031Sbrian free(s); 29026031Sbrian /* and the device part */ 29126031Sbrian rmdev_schedule(&dtab, $1); 29226031Sbrian } ; 29326031Sbrian 29426031Sbrian%% 29526031Sbrian 29626031Sbrianvoid 29726031Sbrianyyerror(const char *s) 29826031Sbrian{ 29926031Sbrian 30026031Sbrian errx(1, "%s:%d: %s", yyfile, yyline + 1, s); 30126031Sbrian} 30226031Sbrian 30326031Sbrianint 30436466Sbrianyywrap(void) 30526031Sbrian{ 30626031Sbrian if (found_defaults) { 30726031Sbrian if (freopen(PREFIX, "r", stdin) == NULL) 30826031Sbrian err(2, "%s", PREFIX); 30926031Sbrian yyfile = PREFIX; 31026031Sbrian yyline = 0; 31126031Sbrian found_defaults = 0; 31226031Sbrian return 0; 31326031Sbrian } 31426031Sbrian return 1; 31526031Sbrian} 31626031Sbrian 31726031Sbrian/* 31826031Sbrian * Add a new file to the list of files. 31926031Sbrian */ 32036466Sbrianstatic void 32198243Sbriannewfile(char *name) 32226031Sbrian{ 32326031Sbrian struct files_name *nl; 32426031Sbrian 32526031Sbrian nl = (struct files_name *) calloc(1, sizeof *nl); 32626031Sbrian nl->f_name = name; 32726031Sbrian STAILQ_INSERT_TAIL(&fntab, nl, f_next); 32826031Sbrian} 32926031Sbrian 33026031Sbrian/* 33126031Sbrian * Find a device in the list of devices. 33236466Sbrian */ 33326031Sbrianstatic struct device * 33426031Sbrianfinddev(struct device_head *dlist, char *name) 33526031Sbrian{ 33626031Sbrian struct device *dp; 33736466Sbrian 33826031Sbrian STAILQ_FOREACH(dp, dlist, d_next) 33926031Sbrian if (eq(dp->d_name, name)) 34026031Sbrian return (dp); 34126031Sbrian 34226031Sbrian return (NULL); 34326031Sbrian} 34426031Sbrian 34526031Sbrian/* 34626031Sbrian * Add a device to the list of devices. 34726031Sbrian */ 34826031Sbrianstatic void 34926031Sbriannewdev(char *name) 35026031Sbrian{ 35126031Sbrian struct device *np; 35226031Sbrian 35326031Sbrian if (finddev(&dtab, name)) { 35426031Sbrian printf("WARNING: duplicate device `%s' encountered.\n", name); 35526031Sbrian return; 35626031Sbrian } 35726031Sbrian 35826031Sbrian np = (struct device *) calloc(1, sizeof *np); 35998243Sbrian np->d_name = name; 36026031Sbrian STAILQ_INSERT_TAIL(&dtab, np, d_next); 36126031Sbrian} 36226031Sbrian 36326031Sbrian/* 36436466Sbrian * Schedule a device to removal. 36526031Sbrian */ 36626031Sbrianstatic void 36736466Sbrianrmdev_schedule(struct device_head *dh, char *name) 36826031Sbrian{ 36926031Sbrian struct device *dp; 37026031Sbrian 37126031Sbrian dp = finddev(dh, name); 37226031Sbrian if (dp != NULL) { 37326031Sbrian STAILQ_REMOVE(dh, dp, device, d_next); 37426031Sbrian free(dp->d_name); 37526031Sbrian free(dp); 37636466Sbrian } 37726031Sbrian} 37826031Sbrian 379/* 380 * Find an option in the list of options. 381 */ 382static struct opt * 383findopt(struct opt_head *list, char *name) 384{ 385 struct opt *op; 386 387 SLIST_FOREACH(op, list, op_next) 388 if (eq(op->op_name, name)) 389 return (op); 390 391 return (NULL); 392} 393 394/* 395 * Add an option to the list of options. 396 */ 397static void 398newopt(struct opt_head *list, char *name, char *value) 399{ 400 struct opt *op; 401 402 /* 403 * Ignore inclusions listed explicitly for configuration files. 404 */ 405 if (eq(name, OPT_AUTOGEN)) { 406 incignore = 1; 407 return; 408 } 409 410 if (findopt(list, name)) { 411 printf("WARNING: duplicate option `%s' encountered.\n", name); 412 return; 413 } 414 415 op = (struct opt *)calloc(1, sizeof (struct opt)); 416 op->op_name = name; 417 op->op_ownfile = 0; 418 op->op_value = value; 419 SLIST_INSERT_HEAD(list, op, op_next); 420} 421 422/* 423 * Remove an option from the list of options. 424 */ 425static void 426rmopt_schedule(struct opt_head *list, char *name) 427{ 428 struct opt *op; 429 430 op = findopt(list, name); 431 if (op != NULL) { 432 SLIST_REMOVE(list, op, opt, op_next); 433 free(op->op_name); 434 free(op); 435 } 436} 437