# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
FindFLEX
--------

Find flex executable and provides a macro to generate custom build rules



The module defines the following variables:

::

  FLEX_FOUND - true is flex executable is found
  FLEX_EXECUTABLE - the path to the flex executable
  FLEX_VERSION - the version of flex
  FLEX_LIBRARIES - The flex libraries
  FLEX_INCLUDE_DIRS - The path to the flex headers



The minimum required version of flex can be specified using the
standard syntax, e.g.  find_package(FLEX 2.5.13)



If flex is found on the system, the module provides the macro:

::

  FLEX_TARGET(Name FlexInput FlexOutput
              [COMPILE_FLAGS <string>]
              [DEFINES_FILE <string>]
              )

which creates a custom command to generate the <FlexOutput> file from
the <FlexInput> file.  If COMPILE_FLAGS option is specified, the next
parameter is added to the flex command line. If flex is configured to
output a header file, the DEFINES_FILE option may be used to specify its
name. Name is an alias used to get details of this custom command.
Indeed the macro defines the following variables:

::

  FLEX_${Name}_DEFINED - true is the macro ran successfully
  FLEX_${Name}_OUTPUTS - the source file generated by the custom rule, an
  alias for FlexOutput
  FLEX_${Name}_INPUT - the flex source file, an alias for ${FlexInput}
  FLEX_${Name}_OUTPUT_HEADER - the header flex output, if any.



Flex scanners often use tokens defined by Bison: the code generated
by Flex depends of the header generated by Bison.  This module also
defines a macro:

::

  ADD_FLEX_BISON_DEPENDENCY(FlexTarget BisonTarget)

which adds the required dependency between a scanner and a parser
where <FlexTarget> and <BisonTarget> are the first parameters of
respectively FLEX_TARGET and BISON_TARGET macros.

::

  ====================================================================
  Example:



::

   find_package(BISON)
   find_package(FLEX)



::

   BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
   FLEX_TARGET(MyScanner lexer.l  ${CMAKE_CURRENT_BINARY_DIR}/lexer.cpp)
   ADD_FLEX_BISON_DEPENDENCY(MyScanner MyParser)



::

   include_directories(${CMAKE_CURRENT_BINARY_DIR})
   add_executable(Foo
      Foo.cc
      ${BISON_MyParser_OUTPUTS}
      ${FLEX_MyScanner_OUTPUTS}
   )
  ====================================================================
#]=======================================================================]

find_program(FLEX_EXECUTABLE NAMES flex win_flex DOC "path to the flex executable")
mark_as_advanced(FLEX_EXECUTABLE)

find_library(FL_LIBRARY NAMES fl
  DOC "Path to the fl library")

find_path(FLEX_INCLUDE_DIR FlexLexer.h
  DOC "Path to the flex headers")

mark_as_advanced(FL_LIBRARY FLEX_INCLUDE_DIR)

set(FLEX_INCLUDE_DIRS ${FLEX_INCLUDE_DIR})
set(FLEX_LIBRARIES ${FL_LIBRARY})

if(FLEX_EXECUTABLE)

  execute_process(COMMAND ${FLEX_EXECUTABLE} --version
    OUTPUT_VARIABLE FLEX_version_output
    ERROR_VARIABLE FLEX_version_error
    RESULT_VARIABLE FLEX_version_result
    OUTPUT_STRIP_TRAILING_WHITESPACE)
  if(NOT ${FLEX_version_result} EQUAL 0)
    if(FLEX_FIND_REQUIRED)
      message(SEND_ERROR "Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}")
    else()
      message("Command \"${FLEX_EXECUTABLE} --version\" failed with output:\n${FLEX_version_output}\n${FLEX_version_error}\nFLEX_VERSION will not be available")
    endif()
  else()
    # older versions of flex printed "/full/path/to/executable version X.Y"
    # newer versions use "basename(executable) X.Y"
    get_filename_component(FLEX_EXE_NAME_WE "${FLEX_EXECUTABLE}" NAME_WE)
    get_filename_component(FLEX_EXE_EXT "${FLEX_EXECUTABLE}" EXT)
    string(REGEX REPLACE "^.*${FLEX_EXE_NAME_WE}(${FLEX_EXE_EXT})?\"? (version )?([0-9]+[^ ]*)( .*)?$" "\\3"
      FLEX_VERSION "${FLEX_version_output}")
    unset(FLEX_EXE_EXT)
    unset(FLEX_EXE_NAME_WE)
  endif()

  #============================================================
  # FLEX_TARGET (public macro)
  #============================================================
  #
  macro(FLEX_TARGET Name Input Output)
    set(FLEX_TARGET_outputs "${Output}")
    set(FLEX_EXECUTABLE_opts "")

    set(FLEX_TARGET_PARAM_OPTIONS)
    set(FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS
      COMPILE_FLAGS
      DEFINES_FILE
      )
    set(FLEX_TARGET_PARAM_MULTI_VALUE_KEYWORDS)

    cmake_parse_arguments(
      FLEX_TARGET_ARG
      "${FLEX_TARGET_PARAM_OPTIONS}"
      "${FLEX_TARGET_PARAM_ONE_VALUE_KEYWORDS}"
      "${FLEX_TARGET_MULTI_VALUE_KEYWORDS}"
      ${ARGN}
      )

    set(FLEX_TARGET_usage "FLEX_TARGET(<Name> <Input> <Output> [COMPILE_FLAGS <string>] [DEFINES_FILE <string>]")

    if(NOT "${FLEX_TARGET_ARG_UNPARSED_ARGUMENTS}" STREQUAL "")
      message(SEND_ERROR ${FLEX_TARGET_usage})
    else()
      if(NOT "${FLEX_TARGET_ARG_COMPILE_FLAGS}" STREQUAL "")
        set(FLEX_EXECUTABLE_opts "${FLEX_TARGET_ARG_COMPILE_FLAGS}")
        separate_arguments(FLEX_EXECUTABLE_opts)
      endif()
      if(NOT "${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
        list(APPEND FLEX_TARGET_outputs "${FLEX_TARGET_ARG_DEFINES_FILE}")
        list(APPEND FLEX_EXECUTABLE_opts --header-file=${FLEX_TARGET_ARG_DEFINES_FILE})
      endif()

      add_custom_command(OUTPUT ${FLEX_TARGET_outputs}
        COMMAND ${FLEX_EXECUTABLE} ${FLEX_EXECUTABLE_opts} -o${Output} ${Input}
        VERBATIM
        DEPENDS ${Input}
        COMMENT "[FLEX][${Name}] Building scanner with flex ${FLEX_VERSION}"
        WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})

      set(FLEX_${Name}_DEFINED TRUE)
      set(FLEX_${Name}_OUTPUTS ${Output})
      set(FLEX_${Name}_INPUT ${Input})
      set(FLEX_${Name}_COMPILE_FLAGS ${FLEX_EXECUTABLE_opts})
      if("${FLEX_TARGET_ARG_DEFINES_FILE}" STREQUAL "")
        set(FLEX_${Name}_OUTPUT_HEADER "")
      else()
        set(FLEX_${Name}_OUTPUT_HEADER ${FLEX_TARGET_ARG_DEFINES_FILE})
      endif()
    endif()
  endmacro()
  #============================================================


  #============================================================
  # ADD_FLEX_BISON_DEPENDENCY (public macro)
  #============================================================
  #
  macro(ADD_FLEX_BISON_DEPENDENCY FlexTarget BisonTarget)

    if(NOT FLEX_${FlexTarget}_OUTPUTS)
      message(SEND_ERROR "Flex target `${FlexTarget}' does not exist.")
    endif()

    if(NOT BISON_${BisonTarget}_OUTPUT_HEADER)
      message(SEND_ERROR "Bison target `${BisonTarget}' does not exist.")
    endif()

    set_source_files_properties(${FLEX_${FlexTarget}_OUTPUTS}
      PROPERTIES OBJECT_DEPENDS ${BISON_${BisonTarget}_OUTPUT_HEADER})
  endmacro()
  #============================================================

endif()

include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(FLEX REQUIRED_VARS FLEX_EXECUTABLE
                                       VERSION_VAR FLEX_VERSION)
