NetBSD/dist/am-utils/fsinfo/fsi_lex.l

271 lines
6.9 KiB
Plaintext

/* $NetBSD: fsi_lex.l,v 1.3 2001/05/13 18:06:59 veego Exp $ */
%{
/*
* Copyright (c) 1997-2001 Erez Zadok
* Copyright (c) 1989 Jan-Simon Pendry
* Copyright (c) 1989 Imperial College of Science, Technology & Medicine
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Jan-Simon Pendry at Imperial College, London.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgment:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* %W% (Berkeley) %G%
*
* Id: fsi_lex.l,v 1.4.2.2 2001/01/10 03:23:33 ezk Exp
*
*/
/*
* Lexical analyzer for fsinfo.
* TODO: Needs rewriting.
*/
#ifdef FLEX_SCANNER
static int yylineno;
# define INIT_STATE { \
switch ((yy_start - 1) / 2) { \
case 0: \
BEGIN F; \
break; \
} \
}
#else /* not FLEX_SCANNER */
/*
* Using old lex...
*/
# define INIT_STATE { \
switch (yybgin - yysvec - 1) { \
case 0: \
BEGIN F; \
break; \
} \
}
#endif /* end FLEX_SCANNER */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif /* HAVE_CONFIG_H */
/*
* Some systems include a definition for the macro ECHO in <sys/ioctl.h>,
* and their (bad) version of lex defines it too at the very beginning of
* the generated lex.yy.c file (before it can be easily undefined),
* resulting in a conflict. So undefine it here before needed.
* Luckily, it does not appear that this macro is actually used in the rest
* of the generated lex.yy.c file.
*/
#ifdef ECHO
# undef ECHO
#endif /* ECHO */
#include <am_defs.h>
#include <fsi_data.h>
#include <fsinfo.h>
#include <fsi_gram.h>
/* and once again undefine this, just in case */
#ifdef ECHO
# undef ECHO
#endif /* ECHO */
/*
* There are some things that need to be defined only if using GNU flex.
* These must not be defined if using standard lex
*/
#ifdef FLEX_SCANNER
# ifndef ECHO
# define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
# endif /* not ECHO */
#endif /* FLEX_SCANNER */
/*
* some systems such as DU-4.x have a different GNU flex in /usr/bin
* which automatically generates yywrap macros and symbols. So I must
* distinguish between them and when yywrap is actually needed.
*/
#ifndef yywrap
int yywrap(void);
#endif /* not yywrap */
YYSTYPE yylval;
static char *fsi_filename;
static char *optr;
static char ostr[1024];
static int find_resword(char *);
static int quoted;
struct r {
char *rw;
int tok;
} rr[] = {
{ "->", tEQ },
{ "arch", tARCH },
{ "as", tAS },
{ "automount", tAUTOMOUNT },
{ "cluster", tCLUSTER },
{ "config", tCONFIG },
{ "direct", tDIRECT },
{ "dumpset", tDUMPSET },
{ "exportfs", tEXPORTFS },
{ "freq", tFREQ },
{ "from", tFROM },
{ "fs", tFS },
{ "fstype", tFSTYPE },
{ "host", tHOST },
{ "hwaddr", tHWADDR },
{ "inaddr", tINADDR },
{ "localhost", tLOCALHOST },
{ "log", tLOG },
{ "mount", tMOUNT },
{ "netif", tNETIF },
{ "netmask", tNETMASK },
{ "nfsalias", tNFSEQ },
{ "opts", tOPTS },
{ "os", tOS },
{ "passno", tPASSNO },
{ "sel", tSEL },
{ "volname", tVOLNAME },
{ 0, 0 },
};
#define NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1)
%}
%start F Q
%%
INIT_STATE; /* witchcraft */
<F>[^ \t\n"={}]+ { return find_resword(yytext); } /* dummy " */
<F>[ \t] ;
<F>"\n" { yylineno++; }
<F>[={}] { return *yytext; }
<F>\" { BEGIN Q; optr = ostr; quoted = 1; }
<Q>\n { yylineno++; yyerror("\" expected"); BEGIN F; }
<Q>\\b { *optr++ = '\b'; /* escape */ }
<Q>\\t { *optr++ = '\t'; /* escape */ }
<Q>\\\" { *optr++ = '\"'; /* escape */ }
<Q>\\\\ { *optr++ = '\\'; /* escape */ }
<Q>\\\n { yylineno++; /* continue */ }
<Q>\\r { *optr++ = '\r'; /* escape */ }
<Q>\\n { *optr++ = '\n'; /* escape */ }
<Q>\\f { *optr++ = '\f'; /* escape */ }
<Q>"\\ " { *optr++ = ' '; /* force space */ }
<Q>\\. { yyerror("Unknown \\ sequence"); }
<Q>([ \t]|"\\\n"){2,} { char *p = (char *) yytext-1; while ((p = strchr(p+1, '\n'))) yylineno++; }
<Q>\" { BEGIN F; quoted = 0;
*optr = '\0';
yylval.s = strdup(ostr);
return tSTR;
}
<Q>. { *optr++ = *yytext; }
%%
static int
find_resword(char *s)
{
int tok = 0;
int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1;
int rc = 0;
m = NRES_WORDS/2;
#define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q))
while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) {
if (rc < 0)
h = m - 1;
else
l = m + 1;
m = (h + l) / 2;
}
if (rc == 0)
tok = rr[m].tok;
switch (tok) {
case tLOCALHOST:
s = "${host}";
/* fall through... */
case 0:
yylval.s = strdup(s);
tok = tSTR;
/* fall through... */
default:
return tok;
}
}
int
yyerror(char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
col_cleanup(0);
fprintf(stderr, "%s:%d: ", fsi_filename ? fsi_filename : "/dev/stdin", yylineno);
vfprintf(stderr, fmt, ap);
fputc('\n', stderr);
parse_errors++;
va_end(ap);
if (0) unput(0);/* dummy to shut gcc up: "unput defined but not used" */
return 0;
}
ioloc *
current_location(void)
{
ioloc *ip = CALLOC(struct ioloc);
ip->i_line = yylineno;
ip->i_file = fsi_filename;
return ip;
}
/*
* some systems such as DU-4.x have a different GNU flex in /usr/bin
* which automatically generates yywrap macros and symbols. So I must
* distinguish between them and when yywrap is actually needed.
*/
#ifndef yywrap
int yywrap(void)
{
return 1;
}
#endif /* not yywrap */