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