Home | History | Annotate | Download | only in libpcap
      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 #
     16 if [ $# -eq 0 ]
     17 then
     18 	echo "Usage: runlex <lex/flex command to run> [ arguments ]" 1>&2
     19 	exit 1
     20 fi
     21 LEX="$1"
     22 shift
     23 
     24 #
     25 # Check whether we have Lex or Flex.
     26 #
     27 if [ -z "${LEX}" ]
     28 then
     29 	echo "Neither lex nor flex was found" 1>&2
     30 	exit 1
     31 fi
     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 #
     37 flags=""
     38 outfile=lex.yy.c
     39 while [ $# -ne 0 ]
     40 do
     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
     65 done
     66 
     67 #
     68 # Is it Lex, or is it Flex?
     69 #
     70 if [ "${LEX}" = flex ]
     71 then
     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
    101 else
    102 	#
    103 	# It's Lex.
    104 	#
    105 	have_flex=no
    106 fi
    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 #
    116 if [ $have_flex = yes ]
    117 then
    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
    162 else
    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
    197 fi
    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 #
    214 prefix=`sed -n 's/%option[ 	][ 	]*prefix="\(.*\)".*/\1/p' "$@" | tail -1`
    215 if [ ! -z "$prefix" ]
    216 then
    217 	prefixline="#define yylex ${prefix}lex"
    218 fi
    219 
    220 #
    221 # Construct the name of the header file.
    222 #
    223 header_file=`dirname "$outfile"`/`basename "$outfile" .c`.h
    224 
    225 #
    226 # Spew out the declaration.
    227 #
    228 cat <<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  
    234 YY_DECL;
    235 EOF
    236