138494Sobrien%{
238494Sobrien/*
3174294Sobrien * Copyright (c) 1997-2006 Erez Zadok
438494Sobrien * Copyright (c) 1989 Jan-Simon Pendry
538494Sobrien * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
638494Sobrien * Copyright (c) 1989 The Regents of the University of California.
738494Sobrien * All rights reserved.
838494Sobrien *
938494Sobrien * This code is derived from software contributed to Berkeley by
1038494Sobrien * Jan-Simon Pendry at Imperial College, London.
1138494Sobrien *
1238494Sobrien * Redistribution and use in source and binary forms, with or without
1338494Sobrien * modification, are permitted provided that the following conditions
1438494Sobrien * are met:
1538494Sobrien * 1. Redistributions of source code must retain the above copyright
1638494Sobrien *    notice, this list of conditions and the following disclaimer.
1738494Sobrien * 2. Redistributions in binary form must reproduce the above copyright
1838494Sobrien *    notice, this list of conditions and the following disclaimer in the
1938494Sobrien *    documentation and/or other materials provided with the distribution.
2038494Sobrien * 3. All advertising materials mentioning features or use of this software
2142629Sobrien *    must display the following acknowledgment:
2238494Sobrien *      This product includes software developed by the University of
2338494Sobrien *      California, Berkeley and its contributors.
2438494Sobrien * 4. Neither the name of the University nor the names of its contributors
2538494Sobrien *    may be used to endorse or promote products derived from this software
2638494Sobrien *    without specific prior written permission.
2738494Sobrien *
2838494Sobrien * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2938494Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
3038494Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
3138494Sobrien * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
3238494Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
3338494Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
3438494Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3538494Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3638494Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3738494Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3838494Sobrien * SUCH DAMAGE.
3938494Sobrien *
4038494Sobrien *
41174294Sobrien * File: am-utils/fsinfo/fsi_lex.l
4238494Sobrien *
4338494Sobrien */
4438494Sobrien
4538494Sobrien/*
4638494Sobrien * Lexical analyzer for fsinfo.
4738494Sobrien * TODO: Needs rewriting.
4838494Sobrien */
4938494Sobrien
50131702Smbrstatic int ayylineno;
51131702Smbr
5238494Sobrien#ifdef FLEX_SCANNER
5338494Sobrien# define INIT_STATE {				\
5438494Sobrien		switch ((yy_start - 1) / 2) {	\
5538494Sobrien		case 0:				\
5638494Sobrien			BEGIN F;		\
5738494Sobrien			break;			\
5838494Sobrien		}				\
5938494Sobrien}
6038494Sobrien
6138494Sobrien#else /* not FLEX_SCANNER */
6238494Sobrien
6338494Sobrien/*
6438494Sobrien * Using old lex...
6538494Sobrien */
6638494Sobrien# define	INIT_STATE {			\
6738494Sobrien		switch (yybgin - yysvec - 1) {	\
6838494Sobrien		case 0:				\
6938494Sobrien			BEGIN F;		\
7038494Sobrien			break;			\
7138494Sobrien		}				\
7238494Sobrien}
7338494Sobrien
7438494Sobrien#endif /* end FLEX_SCANNER */
7538494Sobrien
7638494Sobrien#ifdef HAVE_CONFIG_H
7738494Sobrien# include <config.h>
7838494Sobrien#endif /* HAVE_CONFIG_H */
7938494Sobrien/*
8038494Sobrien * Some systems include a definition for the macro ECHO in <sys/ioctl.h>,
8138494Sobrien * and their (bad) version of lex defines it too at the very beginning of
8238494Sobrien * the generated lex.yy.c file (before it can be easily undefined),
8338494Sobrien * resulting in a conflict.  So undefine it here before needed.
8438494Sobrien * Luckily, it does not appear that this macro is actually used in the rest
8538494Sobrien * of the generated lex.yy.c file.
8638494Sobrien */
8738494Sobrien#ifdef ECHO
8838494Sobrien# undef ECHO
8938494Sobrien#endif /* ECHO */
9038494Sobrien#include <am_defs.h>
9138494Sobrien#include <fsi_data.h>
9238494Sobrien#include <fsinfo.h>
9338494Sobrien#include <fsi_gram.h>
9438494Sobrien/* and once again undefine this, just in case */
9538494Sobrien#ifdef ECHO
9638494Sobrien# undef ECHO
9738494Sobrien#endif /* ECHO */
9838494Sobrien
9938494Sobrien/*
10042629Sobrien * There are some things that need to be defined only if using GNU flex.
10138494Sobrien * These must not be defined if using standard lex
10238494Sobrien */
10338494Sobrien#ifdef FLEX_SCANNER
10438494Sobrien# ifndef ECHO
10538494Sobrien#  define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
10638494Sobrien# endif /* not ECHO */
10738494Sobrien#endif /* FLEX_SCANNER */
10838494Sobrien
10938494Sobrien/*
11038494Sobrien * some systems such as DU-4.x have a different GNU flex in /usr/bin
11138494Sobrien * which automatically generates yywrap macros and symbols.  So I must
11238494Sobrien * distinguish between them and when yywrap is actually needed.
11338494Sobrien */
11438494Sobrien#ifndef yywrap
11538494Sobrienint yywrap(void);
11638494Sobrien#endif /* not yywrap */
11738494Sobrien
11838494SobrienYYSTYPE yylval;
11938494Sobrienstatic char *fsi_filename;
12038494Sobrienstatic char *optr;
12138494Sobrienstatic char ostr[1024];
12238494Sobrienstatic int find_resword(char *);
12338494Sobrienstatic int quoted;
12438494Sobrien
12538494Sobrienstruct r {
12638494Sobrien  char *rw;
12738494Sobrien  int tok;
12838494Sobrien} rr[] = {
12938494Sobrien  { "->", tEQ },
13038494Sobrien  { "arch", tARCH },
13138494Sobrien  { "as", tAS },
13238494Sobrien  { "automount", tAUTOMOUNT },
13338494Sobrien  { "cluster", tCLUSTER },
13438494Sobrien  { "config", tCONFIG },
13538494Sobrien  { "direct", tDIRECT },
13638494Sobrien  { "dumpset", tDUMPSET },
13738494Sobrien  { "exportfs", tEXPORTFS },
13838494Sobrien  { "freq", tFREQ },
13938494Sobrien  { "from", tFROM },
14038494Sobrien  { "fs", tFS },
14138494Sobrien  { "fstype", tFSTYPE },
14238494Sobrien  { "host", tHOST },
14338494Sobrien  { "hwaddr", tHWADDR },
14438494Sobrien  { "inaddr", tINADDR },
14538494Sobrien  { "localhost", tLOCALHOST },
14638494Sobrien  { "log", tLOG },
14738494Sobrien  { "mount", tMOUNT },
14838494Sobrien  { "netif", tNETIF },
14938494Sobrien  { "netmask", tNETMASK },
15038494Sobrien  { "nfsalias", tNFSEQ },
15138494Sobrien  { "opts", tOPTS },
15238494Sobrien  { "os", tOS },
15338494Sobrien  { "passno", tPASSNO },
15438494Sobrien  { "sel", tSEL },
15538494Sobrien  { "volname", tVOLNAME },
15638494Sobrien  { 0, 0 },
15738494Sobrien};
15838494Sobrien#define	NRES_WORDS (sizeof(rr)/sizeof(rr[0])-1)
15938494Sobrien
16038494Sobrien%}
16138494Sobrien
162131702Smbr/* This option causes Solaris lex to fail.  Use flex.  See BUGS file */
163131702Smbr/* no need to use yyunput() */
164131702Smbr%option nounput
165131702Smbr
166131702Smbr/* allocate more output slots so lex scanners don't run out of mem */
167131702Smbr%o 1024
168131702Smbr
16938494Sobrien%start F Q
17038494Sobrien
17138494Sobrien%%
17238494Sobrien		INIT_STATE;	/* witchcraft */
17338494Sobrien
17438494Sobrien<F>[^ \t\n"={}]+	{ return find_resword(yytext); } /* dummy " */
17538494Sobrien<F>[ \t]		;
176131702Smbr<F>"\n"			{ ayylineno++; }
17738494Sobrien<F>[={}]		{ return *yytext; }
17838494Sobrien
17938494Sobrien<F>\"			{ BEGIN Q; optr = ostr; quoted = 1; }
180131702Smbr<Q>\n			{ ayylineno++; yyerror("\" expected"); BEGIN F; }
18138494Sobrien<Q>\\b			{ *optr++ = '\b'; /* escape */ }
18238494Sobrien<Q>\\t			{ *optr++ = '\t'; /* escape */ }
18338494Sobrien<Q>\\\"			{ *optr++ = '\"'; /* escape */ }
18438494Sobrien<Q>\\\\			{ *optr++ = '\\'; /* escape */ }
185131702Smbr<Q>\\\n			{ ayylineno++; /* continue */ }
18638494Sobrien<Q>\\r			{ *optr++ = '\r'; /* escape */ }
18738494Sobrien<Q>\\n			{ *optr++ = '\n'; /* escape */ }
18838494Sobrien<Q>\\f			{ *optr++ = '\f'; /* escape */ }
18938494Sobrien<Q>"\\ "		{ *optr++ = ' '; /* force space */ }
19038494Sobrien<Q>\\.			{ yyerror("Unknown \\ sequence"); }
191131702Smbr<Q>([ \t]|"\\\n"){2,}	{ char *p = (char *) yytext-1; while ((p = strchr(p+1, '\n'))) ayylineno++; }
19238494Sobrien<Q>\"			{ BEGIN F; quoted = 0;
19338494Sobrien				*optr = '\0';
19438494Sobrien				yylval.s = strdup(ostr);
19538494Sobrien				return tSTR;
19638494Sobrien			}
19738494Sobrien<Q>.			{ *optr++ = *yytext; }
19838494Sobrien
19938494Sobrien%%
20038494Sobrien
20138494Sobrien
20238494Sobrienstatic int
20338494Sobrienfind_resword(char *s)
20438494Sobrien{
20538494Sobrien  int tok = 0;
20638494Sobrien  int l = 0, m = NRES_WORDS/2, h = NRES_WORDS-1;
20738494Sobrien  int rc = 0;
20838494Sobrien
20938494Sobrien  m = NRES_WORDS/2;
21038494Sobrien
21138494Sobrien#define FSTRCMP(p, q) ((*(p) == *(q)) ? strcmp((p)+1, (q)+1) : *(p) - *(q))
21238494Sobrien
21338494Sobrien  while ((l <= h) && (rc = FSTRCMP(s, rr[m].rw))) {
21438494Sobrien    if (rc < 0)
21538494Sobrien      h = m - 1;
21638494Sobrien    else
21738494Sobrien      l = m + 1;
21838494Sobrien    m = (h + l) / 2;
21938494Sobrien  }
22038494Sobrien
22138494Sobrien  if (rc == 0)
22238494Sobrien    tok = rr[m].tok;
22338494Sobrien
22438494Sobrien  switch (tok) {
22538494Sobrien  case tLOCALHOST:
22638494Sobrien    s = "${host}";
22738494Sobrien    /* fall through... */
22838494Sobrien  case 0:
22938494Sobrien    yylval.s = strdup(s);
23038494Sobrien    tok = tSTR;
23138494Sobrien    /* fall through... */
23238494Sobrien  default:
23338494Sobrien    return tok;
23438494Sobrien  }
23538494Sobrien}
23638494Sobrien
23738494Sobrien
23838494Sobrienint
23938494Sobrienyyerror(char *fmt, ...)
24038494Sobrien{
24138494Sobrien  va_list ap;
24238494Sobrien
24338494Sobrien  va_start(ap, fmt);
24438494Sobrien  col_cleanup(0);
245131702Smbr  fprintf(stderr, "%s:%d: ", fsi_filename ? fsi_filename : "/dev/stdin", ayylineno);
24682794Sobrien  vfprintf(stderr, fmt, ap);
24738494Sobrien  fputc('\n', stderr);
24838494Sobrien  parse_errors++;
24938494Sobrien  va_end(ap);
25038494Sobrien  return 0;
25138494Sobrien}
25238494Sobrien
25338494Sobrien
25438494Sobrienioloc *
25538494Sobriencurrent_location(void)
25638494Sobrien{
25738494Sobrien  ioloc *ip = CALLOC(struct ioloc);
258131702Smbr  ip->i_line = ayylineno;
25938494Sobrien  ip->i_file = fsi_filename;
26038494Sobrien  return ip;
26138494Sobrien}
26238494Sobrien
26338494Sobrien
26438494Sobrien/*
26538494Sobrien * some systems such as DU-4.x have a different GNU flex in /usr/bin
26638494Sobrien * which automatically generates yywrap macros and symbols.  So I must
26738494Sobrien * distinguish between them and when yywrap is actually needed.
26838494Sobrien */
26938494Sobrien#ifndef yywrap
27038494Sobrienint yywrap(void)
27138494Sobrien{
27238494Sobrien  return 1;
27338494Sobrien}
27438494Sobrien#endif /* not yywrap */
275