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$ 321553Srgrimes */ 331553Srgrimes 3479607Sdd#include <assert.h> 351553Srgrimes#include <ctype.h> 36205880Sru#include <err.h> 37264325Sasomers#include <stdlib.h> 386494Sbde#include <string.h> 3916073Sphk#include "y.tab.h" 401553Srgrimes#include "config.h" 411553Srgrimes 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 }, 65152018Sru { "nocpu", NOCPU }, 661553Srgrimes { "device", DEVICE }, 67141615Sdes { "devices", DEVICE }, 68111582Sru { "nodevice", NODEVICE }, 69141615Sdes { "nodevices", NODEVICE }, 7082393Speter { "env", ENV }, 7161640Speter { "hints", HINTS }, 721553Srgrimes { "ident", IDENT }, 7352653Smarcel { "machine", ARCH }, /* MACHINE is defined in /sys/param.h */ 74153063Sru { "makeoption", MAKEOPTIONS }, 751553Srgrimes { "makeoptions", MAKEOPTIONS }, 76111582Sru { "nomakeoption", NOMAKEOPTION }, 77152023Sru { "nomakeoptions", NOMAKEOPTION }, 781553Srgrimes { "maxusers", MAXUSERS }, 7967109Sphk { "profile", PROFILE }, 8048402Speter { "option", OPTIONS }, 811553Srgrimes { "options", OPTIONS }, 82111582Sru { "nooption", NOOPTION }, 83136429Sphk { "nooptions", NOOPTION }, 8479607Sdd { "include", INCLUDE }, 85129073Scognet { "files", FILES }, 861553Srgrimes { 0, 0 }, 871553Srgrimes}; 8829451Scharnier 8929451Scharnier 9079607Sddstatic int endinclude(void); 9179607Sddint include(const char *, int); 9261640Speterint kw_lookup(char *); 9398555Sjmallettunsigned int octal(const char *); 9498555Sjmallettunsigned int hex(const char *); 9579607Sddint yyerror(const char *); 9629451Scharnier 97250926Sjkim#define YY_DECL int yylex(void) 981553Srgrimes%} 99250227Sjkim 100250227Sjkim%option nounput 101250227Sjkim%option noinput 102250227Sjkim 10346104SluoqiID [A-Za-z_][-A-Za-z_0-9]* 104180922SobrienPATH [./][-/.%^A-Za-z_0-9]+ 105134542Speter%START TOEOL 1061553Srgrimes%% 107134542Speter{ID} { 1081553Srgrimes int i; 1091553Srgrimes 11046104Sluoqi BEGIN 0; 1111553Srgrimes if ((i = kw_lookup(yytext)) == -1) 1121553Srgrimes { 1136494Sbde yylval.str = strdup(yytext); 1141553Srgrimes return ID; 1151553Srgrimes } 1161553Srgrimes return i; 1171553Srgrimes } 11812772Speter\\\"[^"]+\\\" { 11946104Sluoqi BEGIN 0; 12046104Sluoqi yytext[yyleng-2] = '"'; 12146104Sluoqi yytext[yyleng-1] = '\0'; 12212772Speter yylval.str = strdup(yytext + 1); 12312772Speter return ID; 12412772Speter } 1251553Srgrimes\"[^"]+\" { 12646104Sluoqi BEGIN 0; 12746104Sluoqi yytext[yyleng-1] = '\0'; 1286494Sbde yylval.str = strdup(yytext + 1); 1291553Srgrimes return ID; 1301553Srgrimes } 13148402Speter<TOEOL>[^# \t\n]* { 13246104Sluoqi BEGIN 0; 13346104Sluoqi yylval.str = strdup(yytext); 13446104Sluoqi return ID; 13546104Sluoqi } 1361553Srgrimes0[0-7]* { 1371553Srgrimes yylval.val = octal(yytext); 1381553Srgrimes return NUMBER; 1391553Srgrimes } 1401553Srgrimes0x[0-9a-fA-F]+ { 1411553Srgrimes yylval.val = hex(yytext); 1421553Srgrimes return NUMBER; 1431553Srgrimes } 14446104Sluoqi-?[1-9][0-9]* { 14546021Speter yylval.val = atoi(yytext); 14646021Speter return NUMBER; 14746021Speter } 1481553Srgrimes"?" { 1491553Srgrimes yylval.val = -1; 1501553Srgrimes return NUMBER; 1511553Srgrimes } 1521553Srgrimes\n/[ \t] { 1531553Srgrimes yyline++; 1541553Srgrimes } 1551553Srgrimes\n { 1561553Srgrimes yyline++; 1571553Srgrimes return SEMICOLON; 1581553Srgrimes } 1591553Srgrimes#.* { /* Ignored (comment) */; } 1604242Swollman[ \t\f]* { /* Ignored (white space) */; } 1611553Srgrimes";" { return SEMICOLON; } 1621553Srgrimes"," { return COMMA; } 16346104Sluoqi"=" { BEGIN TOEOL; return EQUALS; } 164185186Sthompsa"+=" { BEGIN TOEOL; return PLUSEQUALS; } 16579607Sdd<<EOF>> { 16679607Sdd int tok; 16779607Sdd 16879607Sdd if (inclp == NULL) 16979607Sdd return YY_NULL; 17079607Sdd tok = endinclude(); 17179607Sdd if (tok != 0) 17279607Sdd return tok; 17379607Sdd /* otherwise continue scanning */ 17479607Sdd } 175180922Sobrien{PATH} { 176180922Sobrien BEGIN 0; 177180922Sobrien yylval.str = strdup(yytext); 178180922Sobrien return PATH; 179180922Sobrien } 1801553Srgrimes. { return yytext[0]; } 1811553Srgrimes 1821553Srgrimes%% 1831553Srgrimes/* 1841553Srgrimes * kw_lookup 1851553Srgrimes * Look up a string in the keyword table. Returns a -1 if the 1861553Srgrimes * string is not a keyword otherwise it returns the keyword number 1871553Srgrimes */ 1881553Srgrimes 18929451Scharnierint 19061640Speterkw_lookup(char *word) 1911553Srgrimes{ 19261640Speter struct kt *kp; 1931553Srgrimes 1941553Srgrimes for (kp = key_words; kp->kt_name != 0; kp++) 1951553Srgrimes if (eq(word, kp->kt_name)) 1961553Srgrimes return kp->kt_val; 1971553Srgrimes return -1; 1981553Srgrimes} 1991553Srgrimes 2001553Srgrimes/* 2011553Srgrimes * Number conversion routines 2021553Srgrimes */ 2031553Srgrimes 20498555Sjmallettunsigned int 20598555Sjmallettoctal(const char *str) 2061553Srgrimes{ 20798555Sjmallett unsigned int num; 2081553Srgrimes 2091553Srgrimes (void) sscanf(str, "%o", &num); 2101553Srgrimes return num; 2111553Srgrimes} 2121553Srgrimes 21398555Sjmallettunsigned int 21498555Sjmalletthex(const char *str) 2151553Srgrimes{ 21698555Sjmallett unsigned int num; 2171553Srgrimes 2181553Srgrimes (void) sscanf(str+2, "%x", &num); 2191553Srgrimes return num; 2201553Srgrimes} 22179607Sdd 222169507Swkoszekvoid 223169507Swkoszekcfgfile_add(const char *fname) 224169507Swkoszek{ 225169507Swkoszek struct cfgfile *cf; 22679607Sdd 227169507Swkoszek cf = calloc(1, sizeof(*cf)); 228205880Sru if (cf == NULL) 229205880Sru err(EXIT_FAILURE, "calloc"); 230169507Swkoszek assert(cf != NULL); 231169507Swkoszek asprintf(&cf->cfg_path, "%s", fname); 232169507Swkoszek STAILQ_INSERT_TAIL(&cfgfiles, cf, cfg_next); 233169507Swkoszek} 234169507Swkoszek 235169507Swkoszekvoid 236169507Swkoszekcfgfile_removeall(void) 237169507Swkoszek{ 238169507Swkoszek struct cfgfile *cf; 239169507Swkoszek 240169507Swkoszek while (!STAILQ_EMPTY(&cfgfiles)) { 241169507Swkoszek cf = STAILQ_FIRST(&cfgfiles); 242169507Swkoszek STAILQ_REMOVE_HEAD(&cfgfiles, cfg_next); 243169507Swkoszek if (cf->cfg_path != NULL) 244169507Swkoszek free(cf->cfg_path); 245169507Swkoszek free(cf); 246169507Swkoszek } 247169507Swkoszek} 248169507Swkoszek 24979607Sdd/* 25079607Sdd * Open the named file for inclusion at the current point. Returns 0 on 25179607Sdd * success (file opened and previous state pushed), nonzero on failure 25279607Sdd * (fopen failed, complaint made). The `ateof' parameter controls the 25379607Sdd * token to be inserted at the end of the include file. If ateof == 0, 25479607Sdd * then nothing is inserted. 25579607Sdd */ 25679607Sddint 25779607Sddinclude(const char *fname, int ateof) 25879607Sdd{ 25979607Sdd FILE *fp; 26079607Sdd struct incl *in; 261264325Sasomers struct includepath* ipath; 262136872Sdes char *fnamebuf; 26379607Sdd 264169507Swkoszek fnamebuf = NULL; 26579607Sdd fp = fopen(fname, "r"); 266136872Sdes if (fp == NULL && fname[0] != '.' && fname[0] != '/') { 267136872Sdes asprintf(&fnamebuf, "../../conf/%s", fname); 268136872Sdes if (fnamebuf != NULL) { 269136872Sdes fp = fopen(fnamebuf, "r"); 270136872Sdes free(fnamebuf); 271136872Sdes } 272136872Sdes } 27379607Sdd if (fp == NULL) { 274264325Sasomers SLIST_FOREACH(ipath, &includepath, path_next) { 275264325Sasomers asprintf(&fnamebuf, "%s/%s", ipath->path, fname); 276264325Sasomers if (fnamebuf != NULL) { 277264325Sasomers fp = fopen(fnamebuf, "r"); 278264325Sasomers free(fnamebuf); 279264325Sasomers } 280264325Sasomers if (fp != NULL) 281264325Sasomers break; 282264325Sasomers } 283264325Sasomers } 284264325Sasomers if (fp == NULL) { 285136872Sdes yyerror("cannot open included file"); 28679607Sdd return (-1); 28779607Sdd } 288169507Swkoszek cfgfile_add(fnamebuf == NULL ? fname : fnamebuf); 28979607Sdd in = malloc(sizeof(*in)); 29079607Sdd assert(in != NULL); 29179607Sdd in->in_prev = inclp; 29279607Sdd in->in_buf = YY_CURRENT_BUFFER; 29379607Sdd in->in_fname = yyfile; 29479607Sdd in->in_lineno = yyline; 29579607Sdd in->in_ateof = ateof; 29679607Sdd inclp = in; 29779607Sdd yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); 29879607Sdd yyfile = fname; 29979607Sdd yyline = 0; 30079607Sdd return (0); 30179607Sdd} 30279607Sdd 30379607Sdd/* 30479607Sdd * Terminate the most recent inclusion. 30579607Sdd */ 30679607Sddstatic int 307201227Sedendinclude(void) 30879607Sdd{ 30979607Sdd struct incl *in; 31079607Sdd int ateof; 31179607Sdd 31279607Sdd in = inclp; 31379607Sdd assert(in != NULL); 31479607Sdd inclp = in->in_prev; 31579607Sdd lastfile = yyfile; 31679607Sdd yy_delete_buffer(YY_CURRENT_BUFFER); 31779607Sdd (void)fclose(yyin); 31879607Sdd yy_switch_to_buffer(in->in_buf); 31979607Sdd yyfile = in->in_fname; 32079607Sdd yyline = in->in_lineno; 32179607Sdd ateof = in->in_ateof; 32279607Sdd free(in); 32379607Sdd 32479607Sdd return (ateof); 32579607Sdd} 326