lang.l revision 141615
11553Srgrimes%{
21553Srgrimes/*-
31553Srgrimes * Copyright (c) 1980, 1993
41553Srgrimes *	The Regents of the University of California.  All rights reserved.
51553Srgrimes *
61553Srgrimes * Redistribution and use in source and binary forms, with or without
71553Srgrimes * modification, are permitted provided that the following conditions
81553Srgrimes * are met:
91553Srgrimes * 1. Redistributions of source code must retain the above copyright
101553Srgrimes *    notice, this list of conditions and the following disclaimer.
111553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
121553Srgrimes *    notice, this list of conditions and the following disclaimer in the
131553Srgrimes *    documentation and/or other materials provided with the distribution.
141553Srgrimes * 4. Neither the name of the University nor the names of its contributors
151553Srgrimes *    may be used to endorse or promote products derived from this software
161553Srgrimes *    without specific prior written permission.
171553Srgrimes *
181553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
191553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
201553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
211553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
221553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
231553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
241553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
251553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
261553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
271553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
281553Srgrimes * SUCH DAMAGE.
291553Srgrimes *
301553Srgrimes *	@(#)lang.l	8.1 (Berkeley) 6/6/93
3152007Speter * $FreeBSD: head/usr.sbin/config/lang.l 141615 2005-02-10 10:46:27Z des $
321553Srgrimes */
331553Srgrimes
3479607Sdd#include <assert.h>
351553Srgrimes#include <ctype.h>
366494Sbde#include <string.h>
3716073Sphk#include "y.tab.h"
381553Srgrimes#include "config.h"
391553Srgrimes
4045775Speter#define YY_NO_UNPUT
4145775Speter
421553Srgrimes/*
4379607Sdd * Data for returning to previous files from include files.
4479607Sdd */
4579607Sddstruct incl {
4679607Sdd	struct	incl *in_prev; 	/* previous includes in effect, if any */
4779607Sdd	YY_BUFFER_STATE in_buf;	/* previous lex state */
4879607Sdd	const	char *in_fname;	/* previous file name */
4979607Sdd	int	in_lineno;	/* previous line number */
5079607Sdd	int	in_ateof;	/* token to insert at EOF */
5179607Sdd};
5279607Sddstatic struct	incl *inclp;
5379607Sddstatic const	char *lastfile;
5479607Sdd
5579607Sdd/*
561553Srgrimes * Key word table
571553Srgrimes */
581553Srgrimes
591553Srgrimesstruct kt {
6072684Speter	const char *kt_name;
611553Srgrimes	int kt_val;
621553Srgrimes} key_words[] = {
6346855Speter	{ "config",	CONFIG },
641553Srgrimes	{ "cpu",	CPU },
651553Srgrimes	{ "device",	DEVICE },
66141615Sdes	{ "devices",	DEVICE },
67111582Sru	{ "nodevice",	NODEVICE },
68141615Sdes	{ "nodevices",	NODEVICE },
6982393Speter	{ "env",	ENV },
7061640Speter	{ "hints",	HINTS },
711553Srgrimes	{ "ident",	IDENT },
7252653Smarcel	{ "machine",	ARCH }, /* MACHINE is defined in /sys/param.h */
731553Srgrimes	{ "makeoptions", MAKEOPTIONS },
74111582Sru	{ "nomakeoption", NOMAKEOPTION },
751553Srgrimes	{ "maxusers",	MAXUSERS },
7667109Sphk	{ "profile",	PROFILE },
7748402Speter	{ "option",	OPTIONS },
781553Srgrimes	{ "options",	OPTIONS },
79111582Sru	{ "nooption",	NOOPTION },
80136429Sphk	{ "nooptions",	NOOPTION },
8179607Sdd	{ "include",	INCLUDE },
82129073Scognet	{ "files", 	FILES },
831553Srgrimes	{ 0, 0 },
841553Srgrimes};
8529451Scharnier
8629451Scharnier
8779607Sddstatic int endinclude(void);
8879607Sddint include(const char *, int);
8961640Speterint kw_lookup(char *);
9098555Sjmallettunsigned int octal(const char *);
9198555Sjmallettunsigned int hex(const char *);
9279607Sddint yyerror(const char *);
9329451Scharnier
941553Srgrimes%}
9546104SluoqiID	[A-Za-z_][-A-Za-z_0-9]*
96134542Speter%START TOEOL
971553Srgrimes%%
98134542Speter{ID}		{
991553Srgrimes			int i;
1001553Srgrimes
10146104Sluoqi			BEGIN 0;
1021553Srgrimes			if ((i = kw_lookup(yytext)) == -1)
1031553Srgrimes			{
1046494Sbde				yylval.str = strdup(yytext);
1051553Srgrimes				return ID;
1061553Srgrimes			}
1071553Srgrimes			return i;
1081553Srgrimes		}
10912772Speter\\\"[^"]+\\\"	{
11046104Sluoqi			BEGIN 0;
11146104Sluoqi			yytext[yyleng-2] = '"';
11246104Sluoqi			yytext[yyleng-1] = '\0';
11312772Speter			yylval.str = strdup(yytext + 1);
11412772Speter			return ID;
11512772Speter		}
1161553Srgrimes\"[^"]+\"	{
11746104Sluoqi			BEGIN 0;
11846104Sluoqi			yytext[yyleng-1] = '\0';
1196494Sbde			yylval.str = strdup(yytext + 1);
1201553Srgrimes			return ID;
1211553Srgrimes		}
12248402Speter<TOEOL>[^# \t\n]*	{
12346104Sluoqi			BEGIN 0;
12446104Sluoqi			yylval.str = strdup(yytext);
12546104Sluoqi			return ID;
12646104Sluoqi		}
1271553Srgrimes0[0-7]*		{
1281553Srgrimes			yylval.val = octal(yytext);
1291553Srgrimes			return NUMBER;
1301553Srgrimes		}
1311553Srgrimes0x[0-9a-fA-F]+	{
1321553Srgrimes			yylval.val = hex(yytext);
1331553Srgrimes			return NUMBER;
1341553Srgrimes		}
13546104Sluoqi-?[1-9][0-9]*	{
13646021Speter			yylval.val = atoi(yytext);
13746021Speter			return NUMBER;
13846021Speter		}
1391553Srgrimes"?"		{
1401553Srgrimes			yylval.val = -1;
1411553Srgrimes			return NUMBER;
1421553Srgrimes		}
1431553Srgrimes\n/[ \t]	{
1441553Srgrimes			yyline++;
1451553Srgrimes		}
1461553Srgrimes\n		{
1471553Srgrimes			yyline++;
1481553Srgrimes			return SEMICOLON;
1491553Srgrimes		}
1501553Srgrimes#.*		{	/* Ignored (comment) */;	}
1514242Swollman[ \t\f]*	{	/* Ignored (white space) */;	}
1521553Srgrimes";"		{	return SEMICOLON;		}
1531553Srgrimes","		{	return COMMA;			}
15446104Sluoqi"="		{	BEGIN TOEOL; return EQUALS;	}
15579607Sdd<<EOF>>		{
15679607Sdd			int tok;
15779607Sdd
15879607Sdd			if (inclp == NULL)
15979607Sdd				return YY_NULL;
16079607Sdd			tok = endinclude();
16179607Sdd			if (tok != 0)
16279607Sdd				return tok;
16379607Sdd			/* otherwise continue scanning */
16479607Sdd		}
1651553Srgrimes.		{	return yytext[0];		}
1661553Srgrimes
1671553Srgrimes%%
1681553Srgrimes/*
1691553Srgrimes * kw_lookup
1701553Srgrimes *	Look up a string in the keyword table.  Returns a -1 if the
1711553Srgrimes *	string is not a keyword otherwise it returns the keyword number
1721553Srgrimes */
1731553Srgrimes
17429451Scharnierint
17561640Speterkw_lookup(char *word)
1761553Srgrimes{
17761640Speter	struct kt *kp;
1781553Srgrimes
1791553Srgrimes	for (kp = key_words; kp->kt_name != 0; kp++)
1801553Srgrimes		if (eq(word, kp->kt_name))
1811553Srgrimes			return kp->kt_val;
1821553Srgrimes	return -1;
1831553Srgrimes}
1841553Srgrimes
1851553Srgrimes/*
1861553Srgrimes * Number conversion routines
1871553Srgrimes */
1881553Srgrimes
18998555Sjmallettunsigned int
19098555Sjmallettoctal(const char *str)
1911553Srgrimes{
19298555Sjmallett	unsigned int num;
1931553Srgrimes
1941553Srgrimes	(void) sscanf(str, "%o", &num);
1951553Srgrimes	return num;
1961553Srgrimes}
1971553Srgrimes
19898555Sjmallettunsigned int
19998555Sjmalletthex(const char *str)
2001553Srgrimes{
20198555Sjmallett	unsigned int num;
2021553Srgrimes
2031553Srgrimes	(void) sscanf(str+2, "%x", &num);
2041553Srgrimes	return num;
2051553Srgrimes}
20679607Sdd
20779607Sdd
20879607Sdd/*
20979607Sdd * Open the named file for inclusion at the current point.  Returns 0 on
21079607Sdd * success (file opened and previous state pushed), nonzero on failure
21179607Sdd * (fopen failed, complaint made).  The `ateof' parameter controls the
21279607Sdd * token to be inserted at the end of the include file. If ateof == 0,
21379607Sdd * then nothing is inserted.
21479607Sdd */
21579607Sddint
21679607Sddinclude(const char *fname, int ateof)
21779607Sdd{
21879607Sdd	FILE *fp;
21979607Sdd	struct incl *in;
220136872Sdes	char *fnamebuf;
22179607Sdd
22279607Sdd	fp = fopen(fname, "r");
223136872Sdes	if (fp == NULL && fname[0] != '.' && fname[0] != '/') {
224136872Sdes		asprintf(&fnamebuf, "../../conf/%s", fname);
225136872Sdes		if (fnamebuf != NULL) {
226136872Sdes			fp = fopen(fnamebuf, "r");
227136872Sdes			free(fnamebuf);
228136872Sdes		}
229136872Sdes	}
23079607Sdd	if (fp == NULL) {
231136872Sdes		yyerror("cannot open included file");
23279607Sdd		return (-1);
23379607Sdd	}
23479607Sdd	in = malloc(sizeof(*in));
23579607Sdd	assert(in != NULL);
23679607Sdd	in->in_prev = inclp;
23779607Sdd	in->in_buf = YY_CURRENT_BUFFER;
23879607Sdd	in->in_fname = yyfile;
23979607Sdd	in->in_lineno = yyline;
24079607Sdd	in->in_ateof = ateof;
24179607Sdd	inclp = in;
24279607Sdd	yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE));
24379607Sdd	yyfile = fname;
24479607Sdd	yyline = 0;
24579607Sdd	return (0);
24679607Sdd}
24779607Sdd
24879607Sdd/*
24979607Sdd * Terminate the most recent inclusion.
25079607Sdd */
25179607Sddstatic int
25279607Sddendinclude()
25379607Sdd{
25479607Sdd	struct incl *in;
25579607Sdd	int ateof;
25679607Sdd
25779607Sdd	in = inclp;
25879607Sdd	assert(in != NULL);
25979607Sdd	inclp = in->in_prev;
26079607Sdd	lastfile = yyfile;
26179607Sdd	yy_delete_buffer(YY_CURRENT_BUFFER);
26279607Sdd	(void)fclose(yyin);
26379607Sdd	yy_switch_to_buffer(in->in_buf);
26479607Sdd	yyfile = in->in_fname;
26579607Sdd	yyline = in->in_lineno;
26679607Sdd	ateof  = in->in_ateof;
26779607Sdd	free(in);
26879607Sdd
26979607Sdd	return (ateof);
27079607Sdd}
271