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