#
# cmake package for autotools support
#
# @Author Ralf Habacker
# 

#
# load autotools configure file into an internal list named _configure_ac
#
macro(autoinit config)
    set(_configure_ac_name ${config})
    file(READ ${config} _configure_ac_raw)
    # Convert file contents into a CMake list (where each element in the list
    # is one line of the file)
    STRING(REGEX REPLACE ";" "\\\\;" _configure_ac "${_configure_ac_raw}")
    STRING(REGEX REPLACE "\n" ";" _configure_ac "${_configure_ac}")
endmacro()

# extracts version information from autoconf config file
# and set related cmake variables
# 
# returns  
#   ${prefix}_VERSION
#   ${prefix}_VERSION_STRING
#   ${prefix}_MAJOR_VERSION
#   ${prefix}_MINOR_VERSION
#   ${prefix}_MICRO_VERSION
#   ${prefix}_LIBRARY_AGE
#   ${prefix}_LIBRARY_REVISION
#   ${prefix}_LIBRARY_CURRENT
# 
macro(autoversion prefix)
    string(TOUPPER ${prefix} prefix_upper)
    string (REGEX REPLACE ".*${prefix}_major_version], .([0-9]+).*" "\\1" ${prefix_upper}_MAJOR_VERSION ${_configure_ac_raw})
    string (REGEX REPLACE ".*${prefix}_minor_version], .([0-9]+).*" "\\1" ${prefix_upper}_MINOR_VERSION ${_configure_ac_raw})
    string (REGEX REPLACE ".*${prefix}_micro_version], .([0-9]+).*" "\\1" ${prefix_upper}_MICRO_VERSION ${_configure_ac_raw})
    set (${prefix_upper}_VERSION ${${prefix_upper}_MAJOR_VERSION}.${${prefix_upper}_MINOR_VERSION}.${${prefix_upper}_MICRO_VERSION})
    set (${prefix_upper}_VERSION_STRING "${${prefix_upper}_VERSION}")
    string (REGEX REPLACE ".*LT_AGE=([0-9]+).*" "\\1" ${prefix_upper}_LIBRARY_AGE ${_configure_ac_raw})
    string (REGEX REPLACE ".*LT_CURRENT=([0-9]+).*" "\\1" ${prefix_upper}_LIBRARY_CURRENT ${_configure_ac_raw})
    string (REGEX REPLACE ".*LT_REVISION=([0-9]+).*" "\\1" ${prefix_upper}_LIBRARY_REVISION ${_configure_ac_raw})
endmacro()

#
# Defines package related variables (PACKAGE_..., PACKAGE and VERSION)
# as done by autotools.
#
# Additional it defines a cmake variable named PACKAGE_CONFIG_H_TEMPLATE
# which could be placed in config.h templates to have those variables
# defined at code level like shown below:
#
# config.h.template
#   ...
#   @AUTOPACKAGE_CONFIG_H_TEMPLATE@
#   ...
#
macro(autopackage name version url support_url)
    # Define to the full name of this package.
    set(PACKAGE_NAME ${name})

    # Define to the version of this package.
    set(PACKAGE_VERSION ${version})

    # Define to the home page for this package.
    set(PACKAGE_URL ${url})

    # Define to the address where bug reports for this package should be sent.
    set(PACKAGE_BUGREPORT ${support_url})

    # Define to the full name and version of this package.
    set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}")

    # Define to the one symbol short name of this package.
    set(PACKAGE_TARNAME ${PACKAGE_NAME})

    set(PACKAGE ${name})
    set(VERSION ${DBUS_VERSION_STRING})

    string(CONFIGURE "/* generated by cmake macro autopackage */\n
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT \"@PACKAGE_BUGREPORT@\"

/* Define to the full name of this package. */
#define PACKAGE_NAME \"@PACKAGE_NAME@\"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING \"@PACKAGE_STRING@\"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME \"@PACKAGE_TARNAME@\"

/* Define to the home page for this package. */
#define PACKAGE_URL \"@PACKAGE_URL@\"

/* Define to the version of this package. */
#define PACKAGE_VERSION \"@PACKAGE_VERSION@\"

/* defined by autotools package */
#define PACKAGE \"@PACKAGE@\"
#define VERSION \"@VERSION@\"
" AUTOPACKAGE_CONFIG_H_TEMPLATE)
endmacro(autopackage)

#
# define a cmake variable from autotools AC_DEFINE statement
#
macro(autodefine name)
    foreach(line ${_configure_ac})
        if(line MATCHES ".*AC_DEFINE(.*${name}.*).*")
            string (REGEX REPLACE ".*AC_DEFINE(.*).*" "\\1" value ${line})
            string (REGEX REPLACE "[^[]*\\[[^]]*\\], *\\[([^]]*)\\],.*" "\\1" value2 ${value})
            string (REPLACE "[" "" value3 ${value2})
            string (REPLACE "]" "" value4 ${value3})
            set(${name} ${value4})
        endif()
    endforeach()
endmacro()

macro(autoheaderchecks config_h_in configure_checks_file config_h_cmake)
    file(READ ${configure_checks_file} configure_checks_file_raw)
    file(READ ${config_h_in} _config_h_in_raw)
    file(READ ${config_h_cmake} _config_h_cmake_raw)
    STRING(REGEX REPLACE ";" "\\\\;" _config_h_in "${_config_h_in_raw}")
    STRING(REGEX REPLACE "\n" ";" _config_h_in "${_config_h_in}")
    foreach(line ${_config_h_in})
        #message(STATUS ${line})
        if(line MATCHES ".*HAVE_.*_H.*")
            string (REGEX REPLACE ".*HAVE_(.*)_H.*" "\\1" key ${line})
            set(full_key "HAVE_${key}_H")
            if(key MATCHES ".*_.*")
                string(REGEX MATCH "^[A-Z0-9]+" dir ${key})
                string(REGEX MATCH "[A-Z0-9]+$" file ${key})
                string(TOLOWER ${dir} dirname)
                string(TOLOWER ${file} filename)
                set(check "check_include_file(${dirname}/${filename}.h     ${full_key})")
                set(config_define "#cmakedefine ${full_key}")
            else()
                set(file ${key})
                string(TOLOWER ${file} filename)
                set(check "check_include_file(${filename}.h     ${full_key})")
                set(config_define "#cmakedefine ${full_key}")
            endif()
            if(NOT configure_checks_file_raw MATCHES ".*${full_key}.*")
                message("${check}")
            endif()
            if(NOT _config_h_cmake_raw MATCHES "${full_key}")
                message("${config_define}")
            endif()
        endif()
    endforeach()
endmacro(autoheaderchecks)

#
# parses config.h template and create cmake equivalent 
# not implemented yet
# 
macro(autoconfig template output)
	file(READ ${template} contents)
	# Convert file contents into a CMake list (where each element in the list
	# is one line of the file)
	STRING(REGEX REPLACE ";" "\\\\;" contents "${contents}")
	STRING(REGEX REPLACE "\n" ";" contents "${contents}")
	foreach(line contents)
		message(STATUS ${line})
		# find #undef lines
		# append to config.h #define <variable-name> <variable-content>
	endforeach()
endmacro()
