1#! /bin/sh 2 3# 4# runlex.sh 5# Script to run Lex/Flex. 6# First argument is the (quoted) name of the command; if it's null, that 7# means that neither Flex nor Lex was found, so we report an error and 8# quit. 9# 10# @(#) $Header: /tcpdump/master/libpcap/runlex.sh,v 1.4 2007-12-31 03:38:39 guy Exp $ 11# 12 13# 14# Get the name of the command to run, and then shift to get the arguments. 15# 16if [ $# -eq 0 ] 17then 18 echo "Usage: runlex <lex/flex command to run> [ arguments ]" 1>&2 19 exit 1 20fi 21LEX="$1" 22shift 23 24# 25# Check whether we have Lex or Flex. 26# 27if [ -z "${LEX}" ] 28then 29 echo "Neither lex nor flex was found" 1>&2 30 exit 1 31fi 32 33# 34# Process the flags. We don't use getopt because we don't want to 35# embed complete knowledge of what options are supported by Lex/Flex. 36# 37flags="" 38outfile=lex.yy.c 39while [ $# -ne 0 ] 40do 41 case "$1" in 42 43 -o*) 44 # 45 # Set the output file name. 46 # 47 outfile=`echo "$1" | sed 's/-o\(.*\)/\1/'` 48 ;; 49 50 -*) 51 # 52 # Add this to the list of flags. 53 # 54 flags="$flags $1" 55 ;; 56 57 --|*) 58 # 59 # End of flags. 60 # 61 break 62 ;; 63 esac 64 shift 65done 66 67# 68# Is it Lex, or is it Flex? 69# 70if [ "${LEX}" = flex ] 71then 72 # 73 # It's Flex. 74 # 75 have_flex=yes 76 77 # 78 # Does it support the --noFUNCTION options? If so, we pass 79 # --nounput, as at least some versions that support those 80 # options don't support disabling yyunput by defining 81 # YY_NO_UNPUT. 82 # 83 if flex --help | egrep noFUNCTION >/dev/null 84 then 85 flags="$flags --nounput" 86 87 # 88 # Does it support -R, for generating reentrant scanners? 89 # If so, we're not currently using that feature, but 90 # it'll generate some unused functions anyway - and there 91 # won't be any header file declaring them, so there'll be 92 # defined-but-not-declared warnings. Therefore, we use 93 # --noFUNCTION options to suppress generating those 94 # functions. 95 # 96 if flex --help | egrep reentrant >/dev/null 97 then 98 flags="$flags --noyyget_lineno --noyyget_in --noyyget_out --noyyget_leng --noyyget_text --noyyset_lineno --noyyset_in --noyyset_out" 99 fi 100 fi 101else 102 # 103 # It's Lex. 104 # 105 have_flex=no 106fi 107 108# 109# OK, run it. 110# If it's lex, it doesn't support -o, so we just write to 111# lex.yy.c and, if it succeeds, rename it to the right name, 112# otherwise we remove lex.yy.c. 113# If it's flex, it supports -o, so we use that - flex with -P doesn't 114# write to lex.yy.c, it writes to a lex.{prefix from -P}.c. 115# 116if [ $have_flex = yes ] 117then 118 ${LEX} $flags -o"$outfile" "$@" 119 120 # 121 # Did it succeed? 122 # 123 status=$? 124 if [ $status -ne 0 ] 125 then 126 # 127 # No. Exit with the failing exit status. 128 # 129 exit $status 130 fi 131 132 # 133 # Flex has the annoying habit of stripping all but the last 134 # component of the "-o" flag argument and using that as the 135 # place to put the output. This gets in the way of building 136 # in a directory different from the source directory. Try 137 # to work around this. 138 # 139 # Is the outfile where we think it is? 140 # 141 outfile_base=`basename "$outfile"` 142 if [ "$outfile_base" != "$outfile" -a \( ! -r "$outfile" \) -a -r "$outfile_base" ] 143 then 144 # 145 # No, it's not, but it is in the current directory. Put it 146 # where it's supposed to be. 147 # 148 mv "$outfile_base" "$outfile" 149 150 # 151 # Did that succeed? 152 # 153 status=$? 154 if [ $status -ne 0 ] 155 then 156 # 157 # No. Exit with the failing exit status. 158 # 159 exit $status 160 fi 161 fi 162else 163 ${LEX} $flags "$@" 164 165 # 166 # Did it succeed? 167 # 168 status=$? 169 if [ $status -ne 0 ] 170 then 171 # 172 # No. Get rid of any lex.yy.c file we generated, and 173 # exit with the failing exit status. 174 # 175 rm -f lex.yy.c 176 exit $status 177 fi 178 179 # 180 # OK, rename lex.yy.c to the right output file. 181 # 182 mv lex.yy.c "$outfile" 183 184 # 185 # Did that succeed? 186 # 187 status=$? 188 if [ $status -ne 0 ] 189 then 190 # 191 # No. Get rid of any lex.yy.c file we generated, and 192 # exit with the failing exit status. 193 # 194 rm -f lex.yy.c 195 exit $status 196 fi 197fi 198 199# 200# OK, now let's generate a header file declaring the relevant functions 201# defined by the .c file; if the .c file is .../foo.c, the header file 202# will be .../foo.h. 203# 204# This works around some other Flex suckage, wherein it doesn't declare 205# the lex routine before defining it, causing compiler warnings. 206# XXX - newer versions of Flex support --header-file=, to generate the 207# appropriate header file. With those versions, we should use that option. 208# 209 210# 211# Get the name of the prefix; scan the source files for a %option prefix 212# line. We use the last one. 213# 214prefix=`sed -n 's/%option[ ][ ]*prefix="\(.*\)".*/\1/p' "$@" | tail -1` 215if [ ! -z "$prefix" ] 216then 217 prefixline="#define yylex ${prefix}lex" 218fi 219 220# 221# Construct the name of the header file. 222# 223header_file=`dirname "$outfile"`/`basename "$outfile" .c`.h 224 225# 226# Spew out the declaration. 227# 228cat <<EOF >$header_file 229/* This is generated by runlex.sh. Do not edit it. */ 230$prefixline 231#ifndef YY_DECL 232#define YY_DECL int yylex(void) 233#endif 234YY_DECL; 235EOF 236