From b3a380d027135bff7d13a08557bd7db294d18f08 Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Tue, 4 Feb 2020 19:24:29 -0500 Subject: [PATCH] Add flex detection macro. --- m4/flex.m4 | 76 +++++++++++++++++++++++++++++++++++++++++++++++ m4/gob2.m4 | 2 +- t/flex.sh | 75 ++++++++++++++++++++++++++++++++++++++++++++++ tests/programs.at | 64 +++++++++++++++++++++------------------ 4 files changed, 187 insertions(+), 30 deletions(-) create mode 100644 m4/flex.m4 create mode 100755 t/flex.sh diff --git a/m4/flex.m4 b/m4/flex.m4 new file mode 100644 index 0000000..4e9b56f --- /dev/null +++ b/m4/flex.m4 @@ -0,0 +1,76 @@ +dnl Copyright © 2020 Nick Bowler +dnl License WTFPL2: Do What the Fuck You Want To Public License, version 2. +dnl This is free software: you are free to do what the fuck you want to. +dnl There is NO WARRANTY, to the extent permitted by law. + +dnl DX_PROG_FLEX([min-version], [action-if-found], [action-if-not-found]) +dnl +dnl Search PATH for a working flex utility with the given minimum version, +dnl which may be empty to accept any version. If found, the FLEX +dnl variable (which is substituted by AC_SUBST) is set with the result, +dnl and action-if-found is executed. Otherwise, action-if-not-found +dnl is executed if nonempty, else configure will exit with a fatal error. +AC_DEFUN([DX_PROG_FLEX], [AC_PREREQ([2.62])dnl +AC_ARG_VAR([FLEX], [Fast Lexical Analyzer command])dnl +AC_ARG_VAR([FLEXFLAGS], [Additional options to pass to flex])dnl +cat >conftest.l <<'EOF' +m4_apply([_DX_FLEX_TEST_PROGRAM], m4_split([$1], [\.])) +EOF +AC_CACHE_CHECK([for flex], [ac_cv_path_FLEX], +[dx_cv_flex_found=: +AC_PATH_PROGS_FEATURE_CHECK([FLEX], [flex lex], +[_DX_FLEX_DO_TEST([$ac_path_FLEX], +[flex_relcmd=${ac_path_FLEX##*/} +flex_bypath=`command -v "$flex_relcmd"` #'' +ac_cv_path_FLEX=$ac_path_FLEX +test x"$flex_bypath" = x"$ac_path_FLEX" && ac_cv_path_FLEX=$flex_relcmd +ac_path_FLEX_found=: +dx_cv_flex_works=yes])], [ac_cv_path_FLEX=no dx_cv_flex_found=false])]) +AS_IF([$dx_cv_flex_found], +[FLEX=$ac_cv_path_FLEX +AC_CACHE_CHECK([whether $FLEX works], [dx_cv_flex_works], +[_DX_FLEX_DO_TEST([$FLEX], [dx_cv_flex_works=yes], [dx_cv_flex_works=no])])]) +AS_IF([test x"$dx_cv_flex_works" = x"yes"], + [$2], [m4_default([$3], [AC_MSG_FAILURE( +[flex m4_ifnblank([$1], [version at least $1 ])is required. + +The latest version may be found at . +])])]) +rm -f conftest.c conftest.inc conftest.l +]) + +m4_define([_DX_FLEX_TEST_PROGRAM], +[%option noyywrap +%{ +#ifndef FLEX_SCANNER +DX_LIB_COMPILE_ERROR([FLEX_SCANNER not defined]) +#endif +m4_ifnblank([$1], [dnl +#if YY_FLEX_MAJOR_VERSION < $1 +DX_LIB_COMPILE_ERROR([major version insufficient]) +m4_ifnblank([$2], [dnl +#elif YY_FLEX_MAJOR_VERSION == $1 +# if YY_FLEX_MINOR_VERSION < $2 +DX_LIB_COMPILE_ERROR([minor version insufficient]) +m4_ifnblank([$3], [dnl +# elif YY_FLEX_MINOR_VERSION == $2 +# if YY_FLEX_SUBMINOR_VERSION < $3 +DX_LIB_COMPILE_ERROR([subminor version insufficient]) +# endif +])dnl +# endif +])dnl +#endif +])dnl +%} +%% +%% +int main(void) +{ + return yylex(); +}]) + +AC_DEFUN([_DX_FLEX_DO_TEST], [rm -f conftest.c +AS_IF([$1 -o conftest.inc conftest.l 2>&AS_MESSAGE_LOG_FD], +[AC_LINK_IFELSE([AC_LANG_SOURCE([[#include "conftest.inc"]])], [$2], [$3])], +[$3])]) diff --git a/m4/gob2.m4 b/m4/gob2.m4 index b508fae..5292c5c 100644 --- a/m4/gob2.m4 +++ b/m4/gob2.m4 @@ -48,5 +48,5 @@ AS_IF([test x"$dx_cv_gob_works" = x"yes"], The latest version may be found at . ])])]) -rm -f conftest* +rm -f conftest.c conftest.gob ]) diff --git a/t/flex.sh b/t/flex.sh new file mode 100755 index 0000000..f5fd649 --- /dev/null +++ b/t/flex.sh @@ -0,0 +1,75 @@ +#!/bin/sh +# +# Copyright © 2020 Nick Bowler +# +# Fake flex program for testing the flex detection macro. +# +# License WTFPL2: Do What The Fuck You Want To Public License, version 2. +# This is free software: you are free to do what the fuck you want to. +# There is NO WARRANTY, to the extent permitted by law. + +: "${FAKE_FLEX_VERSION=2.0.0}" + +argv0=$0 + +infile= +outfile=lex.yy.c +for arg +do + shift + + case $arg in + -o) outfile=$1; shift ;; + *) set x "$@" "$arg"; shift ;; + esac +done + +for arg +do + case $arg in + *.l) infile=$arg ;; + esac +done + +if test x"$infile" = x""; then + printf '%s: error: no input file\n' "$argv0" 1>&2 + exit 1 +fi + +copyout=false +exec 3<"$infile" 4>"$outfile" + +save_IFS=$IFS IFS=. +set x $FAKE_FLEX_VERSION 0 0 0; shift +IFS=$save_IFS + +cat >&4 <&4 ;; + esac +done + +cat >&4 <&4 diff --git a/tests/programs.at b/tests/programs.at index 0228ac3..b99fa82 100644 --- a/tests/programs.at +++ b/tests/programs.at @@ -6,24 +6,28 @@ dnl There is NO WARRANTY, to the extent permitted by law. AT_BANNER([Program tests]) -AT_SETUP([gob2 probes]) +m4_define([TEST_SIMPLE_PROGRAM_PROBES], + [TEST_SIMPLE_PROGRAM_PROBES_([$1], m4_toupper($1))]) +m4_define([TEST_SIMPLE_PROGRAM_PROBES_], +[AT_SETUP([$1 probes]) +AT_KEYWORDS([DX_PROG_$2 program])dnl mkdir bin -cp -P "$srcdir/t/gob2.sh" bin +cp -P "$srcdir/t/$1.sh" bin/$1 AT_DATA([test.in], -[[@HAVE_GOB2@ -@GOB2@ +[[@HAVE_$2@ +@$2@ ]]) # Unversioned tests -TEST_CONFIGURE_AC([[DX_PROG_GOB2([], [HAVE_GOB2=yes], [HAVE_GOB2=no]) -AC_SUBST([GOB2]) -AC_SUBST([HAVE_GOB2]) +TEST_CONFIGURE_AC([[DX_PROG_$2([], [HAVE_$2=yes], [HAVE_$2=no]) +AC_SUBST([$2]) +AC_SUBST([HAVE_$2]) set x conftest*; shift if test -f $[]1; then - AC_MSG_ERROR([conftest* left behind by [DX_PROG_GOB2]]) + AC_MSG_ERROR([$[]1 left behind by [DX_PROG_$2]]) fi AC_CONFIG_FILES([test]) @@ -33,58 +37,60 @@ TEST_AUTORECONF # Check the search via path lookup save_PATH=$PATH PATH=$PWD/bin${PATH:+":$PATH"} + +# Sanity test on PATH lookup +AT_CHECK([test x"`command -v $1`" = x"$PWD/bin/$1" || exit 99 #'']) + TEST_CONFIGURE AT_CHECK_UNQUOTED([cat test], [0], [yes -gob2 +$1 ]) PATH=$save_PATH # Check the search via user override -TEST_CONFIGURE([GOB2="$srcdir/t/gob2.sh"]) +TEST_CONFIGURE([$2="$srcdir/t/$1.sh"]) AT_CHECK_UNQUOTED([cat test], [0], [yes -$srcdir/t/gob2.sh +$srcdir/t/$1.sh ]) # Check that a bogus program doesn't come back as valid. -TEST_CONFIGURE([GOB2=true]) +TEST_CONFIGURE([$2=true]) AT_CHECK_UNQUOTED([cat test], [0], [no true ]) # min-version tests mv configure.ac configure.old -[sed 's/DX_PROG_GOB2(\[\]/DX_PROG_GOB2([2.1.3]/' configure.old >configure.ac] +sed ['s/\(DX_PROG_$2(\)\[\]/\1[2.1.3]/'] configure.old >configure.ac TEST_AUTORECONF -FAKE_GOB2_VERSION=2.0.0 -export FAKE_GOB2_VERSION -TEST_CONFIGURE([GOB2="$srcdir/t/gob2.sh"]) +TEST_CONFIGURE([FAKE_$2_VERSION=2.0.0 $2="$srcdir/t/$1.sh"]) AT_CHECK_UNQUOTED([cat test], [0], [no -$srcdir/t/gob2.sh +$srcdir/t/$1.sh ]) -FAKE_GOB2_VERSION=3.0.0 -TEST_CONFIGURE([GOB2="$srcdir/t/gob2.sh"]) +TEST_CONFIGURE([FAKE_$2_VERSION=3.0.0 $2="$srcdir/t/$1.sh"]) AT_CHECK_UNQUOTED([cat test], [0], [yes -$srcdir/t/gob2.sh +$srcdir/t/$1.sh ]) -FAKE_GOB2_VERSION=2.5.0 -TEST_CONFIGURE([GOB2="$srcdir/t/gob2.sh"]) +TEST_CONFIGURE([FAKE_$2_VERSION=2.5.0 $2="$srcdir/t/$1.sh"]) AT_CHECK_UNQUOTED([cat test], [0], [yes -$srcdir/t/gob2.sh +$srcdir/t/$1.sh ]) -FAKE_GOB2_VERSION=2.1.2 -TEST_CONFIGURE([GOB2="$srcdir/t/gob2.sh"]) +TEST_CONFIGURE([FAKE_$2_VERSION=2.1.2 $2="$srcdir/t/$1.sh"]) AT_CHECK_UNQUOTED([cat test], [0], [no -$srcdir/t/gob2.sh +$srcdir/t/$1.sh ]) -FAKE_GOB2_VERSION=2.1.3 -TEST_CONFIGURE([GOB2="$srcdir/t/gob2.sh"]) +TEST_CONFIGURE([FAKE_$2_VERSION=2.1.3 $2="$srcdir/t/$1.sh"]) AT_CHECK_UNQUOTED([cat test], [0], [yes -$srcdir/t/gob2.sh +$srcdir/t/$1.sh ]) AT_CLEANUP +]) + +TEST_SIMPLE_PROGRAM_PROBES([gob2]) +TEST_SIMPLE_PROGRAM_PROBES([flex]) -- 2.43.0