include(CheckFunctionExists)
include(CheckIncludeFile)
include(CheckLibraryExists)
include(CheckSymbolExists)

if(MSVC)
  find_package(LibXml2 CONFIG QUIET)
  if(LibXml2_FOUND)
    foreach(_XML2_VAR LIBXML2_LIBRARY LIBXML2_INCLUDE_DIR LIBXML2_XMLLINT_EXECUTABLE)
      if(DEFINED ${_XML2_VAR} AND NOT ${${_XML2_VAR}})
        unset(${_XML2_VAR} CACHE)
      endif()
    endforeach()
  else()
    find_package(LibXml2 REQUIRED)
    if(LibXml2_FOUND)
      unset(LibXml2_DIR CACHE)
    endif()
  endif()
else()
  find_package(LibXml2 REQUIRED)
endif()
find_package(GCrypt)

check_include_file("errno.h" HAVE_ERRNO_H)
check_include_file("ctype.h" HAVE_CTYPE_H)
check_include_file("fcntl.h" HAVE_FCNTL_H)
check_include_file("float.h" HAVE_FLOAT_H)
check_include_file("ieeefp.h" HAVE_IEEEFP_H)
check_include_file("locale.h" HAVE_LOCALE_H)
check_include_file("malloc.h" HAVE_MALLOC_H)
check_include_file("math.h" HAVE_MATH_H)
check_include_file("nan.h" HAVE_NAN_H)
check_include_file("stdarg.h" HAVE_STDARG_H)
check_include_file("stdint.h" HAVE_STDINT_H)
check_include_file("stdlib.h" HAVE_STDLIB_H)
check_include_file("string.h" HAVE_STRING_H)
check_include_file("sys/select.h" HAVE_SYS_SELECT_H)
check_include_file("sys/stat.h" HAVE_SYS_STAT_H)
check_include_file("sys/timeb.h" HAVE_SYS_TIMEB_H)
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
check_include_file("sys/types.h" HAVE_SYS_TYPES_H)
check_include_file("time.h" HAVE_TIME_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
check_include_file("xlocale.h" HAVE_XLOCALE_H)

if (CMAKE_HAVE_PTHREAD_H)
  set(HAVE_PTHREAD_H 1)
endif (CMAKE_HAVE_PTHREAD_H)

check_library_exists(rt clock_gettime "" HAVE_CLOCK_GETTIME)
if (NOT HAVE_CLOCK_GETTIME)
   set(CMAKE_EXTRA_INCLUDE_FILES time.h)
   check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
   SET(CMAKE_EXTRA_INCLUDE_FILES)
endif()

check_function_exists(printf HAVE_PRINTF)
check_function_exists(fprintf HAVE_FPRINTF)
check_function_exists(scanf HAVE_SCANF)
check_function_exists(fscanf HAVE_FSCANF)
check_function_exists(ftime HAVE_FTIME)
check_function_exists(gettimeofday HAVE_GETTIMEOFDAY)
check_function_exists(gmtime HAVE_GMTIME)
check_function_exists(gmtime_r HAVE_GMTIME_R)
check_function_exists(localtime HAVE_LOCALTIME)
check_function_exists(localtime_r HAVE_LOCALTIME_R)
if(WIN32 AND MSVC)
  check_function_exists(_stat HAVE__STAT)
  check_function_exists(_snprintf HAVE__SNPRINTF)
  check_function_exists(_vsnprintf HAVE__VSNPRINTF)
else()
  check_function_exists(stat HAVE_STAT)
  check_function_exists(snprintf HAVE_SNPRINTF)
  check_function_exists(vsnprintf HAVE_VSNPRINTF)
endif()
check_function_exists(sprintf HAVE_SPRINTF)
check_function_exists(sscanf HAVE_SSCANF)
check_function_exists(strxfrm_l HAVE_STRXFRM_L)
check_function_exists(time HAVE_TIME)

check_symbol_exists(isinf "math.h" HAVE_ISINF)
check_symbol_exists(isnan "math.h" HAVE_ISNAN)

if (GCRYPT_FOUND)
  set(HAVE_GCRYPT 1)
endif()

check_function_exists(vfprintf HAVE_VFPRINTF)
check_function_exists(vfscanf HAVE_VFSCANF)
check_function_exists(vprintf HAVE_VPRINTF)
check_function_exists(vscanf HAVE_VSCANF)
check_function_exists(vsprintf HAVE_VSPRINTF)
check_function_exists(vsscanf HAVE_VSSCANF)

if(WIN32)
  find_program(MAKENSIS_EXE NAMES ${PREFERRED_NSIS_NAMES} makensis
    HINTS "C:/Program\ Files/NSIS/" "C:/Program\ Files\ (x86)/NSIS/")
  mark_as_advanced(MAKENSIS_EXE)
  if(MAKENSIS_EXE)
    set(NSIS_FOUND TRUE)
  else()
    set(NSIS_FOUND FALSE)
  endif()
endif()
