# Generate export header from input script
#   Input variables:
#     EXPORTS_FILE - filepath to input script
#     OUTPUT_FILE - filepath of header that will be created

# Declare content blocks
set(CONTENT_HEADER)
set(CONTENT_PRE_ABI)
set(CONTENT_PRE_EXPORTS)
set(CONTENT_POST_EXPORTS)

# Write content line
macro(write)
  set(CONTENT "${CONTENT}${ARGN}\n")
endmacro()

# Write content block, if non-empty
function(write_content NAME)
  if(NOT "x_${${NAME}}" STREQUAL "x_")
    string(REPLACE ";" "\n" content "${${NAME}}")
    write("${content}\n")
    set(CONTENT "${CONTENT}" PARENT_SCOPE)
  endif()
endfunction()

# Write export block
function(write_export ITEM)
  string(REGEX REPLACE "=.*$"   "" target "${ITEM}")
  string(REGEX REPLACE "^[^=]*=" "" symbol "${ITEM}")
  write("#ifdef ${target}_EXPORTS")
  write("#  define ${symbol}_EXPORT ${PROJECT}_ABI_EXPORT")
  write("#  define ${symbol}_EXPORT_TEMPLATE ${PROJECT}_EXPORT_TEMPLATE")
  write("#else")
  write("#  define ${symbol}_EXPORT ${PROJECT}_ABI_IMPORT")
  write("#  define ${symbol}_EXPORT_TEMPLATE ${PROJECT}_IMPORT_TEMPLATE")
  write("#endif")
  write()
  set(CONTENT "${CONTENT}" PARENT_SCOPE)
endfunction()

# Add export
macro(add_export TARGET SYMBOL)
  list(APPEND EXPORTS "${TARGET}=${SYMBOL}")
endmacro()

# Include exports file
set(EXPORTS)
include("${EXPORTS_FILE}" RESULT_VARIABLE EXPORTS_FILE)

# Generate output file
set(CONTENT)
write_content(CONTENT_HEADER)
write("/* This file was generated by ${CMAKE_CURRENT_LIST_FILE}")
write(" * from ${EXPORTS_FILE}.")
write(" * Do not edit this file directly.")
write(" */")
write()
write("#ifndef ${INCLUDE_GUARD}")
write("#define ${INCLUDE_GUARD}")
write()
write_content(CONTENT_PRE_ABI)
write("#ifndef ${PROJECT}_STATIC")
write("#  if defined(_WIN32)")
write("#    define ${PROJECT}_ABI_IMPORT __declspec(dllimport)")
write("#    define ${PROJECT}_ABI_EXPORT __declspec(dllexport)")
write("#    define ${PROJECT}_IMPORT_TEMPLATE extern")
write("#    define ${PROJECT}_EXPORT_TEMPLATE")
write("#  elif __GNUC__ >= 4")
write("#    define ${PROJECT}_ABI_IMPORT __attribute__ ((visibility(\"default\")))")
write("#    define ${PROJECT}_ABI_EXPORT __attribute__ ((visibility(\"default\")))")
write("#    define ${PROJECT}_IMPORT_TEMPLATE extern")
write("#    define ${PROJECT}_EXPORT_TEMPLATE extern")
write("#  else")
write("#    define ${PROJECT}_ABI_IMPORT")
write("#    define ${PROJECT}_ABI_EXPORT")
write("#    define ${PROJECT}_IMPORT_TEMPLATE extern")
write("#    define ${PROJECT}_EXPORT_TEMPLATE extern")
write("#  endif")
write("#else")
write("#  define ${PROJECT}_ABI_IMPORT")
write("#  define ${PROJECT}_ABI_EXPORT")
write("#  define ${PROJECT}_IMPORT_TEMPLATE extern")
write("#  define ${PROJECT}_EXPORT_TEMPLATE extern")
write("#endif")
write()
write_content(CONTENT_PRE_EXPORTS)
foreach(export ${EXPORTS})
  write_export(${export})
endforeach()
write("#endif")

# Write output file
file(WRITE "${OUTPUT_FILE}" "${CONTENT}")
