--		Copyright 2010 by Daniel R. Grayson 

use M2;
use hashtables;

declarations "
   #ifdef WITH_MYSQL
     #include <mysql/mysql.h>
   #endif
   #ifdef WITH_PYTHON
     #include <Python.h>
   #endif
   ";

header "
   #include <M2/config.h>
   #include <M2/gc-include.h>
   #include <M2/math-include.h>
   #include \"distributed-packages.h\"

   #define stringize0(a) #a
   #define stringize(a) stringize0(a)

   const char * M2_version () { return PACKAGE_VERSION; }

   extern char timestamp[];
   static int32_t endianness_string[2] = {0x61626364,0};

   #include <boost/version.hpp>

//   #include <mpfr.h>
//   #include <mpfi.h>

   #include <memtailor.h>
   #include <mathic.h>
   #include <mathicgb.h>

   #include <frobby.h>
   #ifdef HAVE_FROBBY_VERSION
     extern const char* const frobby_version;
   #else
     namespace constants { extern const char* const version; }
     const char* const frobby_version = constants::version;
   #endif

   #include <mps/version.h>
   #ifndef MPS_MAJOR_VERSION
     #error \"MPS_MAJOR_VERSION undefined\"
   #endif

   #undef ASSERT
   #ifdef HAVE_SCSCP
     #include <scscp.h>
     void scscp_dummy() { SCSCP_sc_init(NULL,NULL); /* just to force linking with the library */ }
   #endif

   #include <NTL/version.h>

   #undef ASSERT

   #ifdef WITH_TBB
   #include <tbb/tbb.h>
   #endif

   #include <Eigen/Core>
   ";

header "
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored \"-Wconversion\"
#include <flint/flint.h>
#pragma GCC diagnostic pop";
gcversion():constcharstar := Ccode(returns,"
     static char buf[40];
     unsigned x = GC_get_version();
     unsigned major = x >> 16;
     unsigned minor = (x >> 8) & 0xff;
     unsigned micro = x & 0xff;
     if (micro == 0xff) snprintf(buf,40,\"%d.%d\", major, minor);
     else snprintf(buf,40,\"%d.%d.%d\", major, minor, micro);
     return buf");

header "#include <fflas-ffpack/config.h>";
ffpackVersion():constcharstar := Ccode(constcharstar,"__FFLASFFPACK_PACKAGE_VERSION");

header"
#pragma push_macro(\"PACKAGE_VERSION\")
#undef PACKAGE_VERSION
#include <factory/factoryconf.h>
const char * factory_version () { return PACKAGE_VERSION; }
extern const char factoryVersion[]; /* extracted from factory's factory.h */
#pragma pop_macro(\"PACKAGE_VERSION\")";
factoryversion():constcharstar := Ccode(returns,"
     return factory_version();
     // the following way used to work, but now it gives 4.0.1 instead of 4.1.0:
     //   char const * p = strrchr(factoryVersion,' ');
     //   return p ? p+1 : factoryVersion;
     ");

header "#include <readline/readline.h>";
readlineversion():constcharstar := Ccode(returns,"
     static char buf[8];
     snprintf(buf, 8, \"%d.%d\", (rl_readline_version>>8)&0xff, rl_readline_version&0xff );
     return buf");

header "#include <gdbm.h>";
gdbmversion():constcharstar := Ccode(returns, "return gdbm_version");

header "extern \"C\" void ilaver_(int *major, int *minor, int *patch);";
lapackversion():constcharstar := Ccode(returns, "
    int major, minor, patch;
    static char buf[40];
    ilaver_(&major, &minor, &patch);
    snprintf(buf, 40, \"%d.%d.%d\", major, minor, patch);
    return buf");

ic := Ccode(int, "
     #if defined(__INTEL_COMPILER)
     	  __INTEL_COMPILER
     #else
     	  0
     #endif
     ");
compiler := (
     if ic != 0
     then "icc " + (
	  if ic % 10 == 0
	  then tostring(ic/100) + "." + tostring((ic/10)%10)
	  else tostring(ic/100) + "." + tostring(ic%100)
	  )
     else tostring(Ccode(constcharstar,"
	    #ifdef __clang__
	        \"clang \" __clang_version__
	    #else
	    #if defined(__GNUC__)
	    #ifdef __GNUC_PATCHLEVEL__
		 \"gcc \" stringize(__GNUC__) \".\" stringize(__GNUC_MINOR__) \".\" stringize(__GNUC_PATCHLEVEL__)
	    #else
		 \"gcc \" stringize(__GNUC__) \".\" stringize(__GNUC_MINOR__)
	    #endif
	    #else
	    \"unknown\"
	    #endif
	    #endif
	    ")));

setupconst("version", Expr(toHashTable(Sequence(
   "VERSION" => Ccode(constcharstar,"M2_version()"),
   "architecture" => Ccode(constcharstar,"ARCH"),
   "issue" => Ccode(constcharstar,"ISSUE"),
   "machine" => Ccode(constcharstar,"MACHINE"),
   "operating system" => Ccode(constcharstar,"OS"),
   "operating system release" => Ccode(constcharstar,"REL"),
   "compiler" => compiler,
   "configure arguments" => Ccode(constcharstar,"CONFIG_ARGS"),
   "compile time" => Ccode(constcharstar,"timestamp"),
   "compile node name" => Ccode(constcharstar,"NODENAME"),
   "gc version" => gcversion(),
   "mysql version" => Ccode(constcharstar,"
	  #if WITH_MYSQL
		   mysql_get_client_info()
	  #else
		   \"not present\"
	  #endif
	  "),
   "fflas_ffpack version" => ffpackVersion(),
   "mpsolve version" => Ccode(constcharstar, "stringize(MPS_MAJOR_VERSION) \".\" stringize(MPS_MINOR_VERSION) \".\" stringize(MPS_PATCH_VERSION)" ),
   "python version" => Ccode(constcharstar,"
	#ifdef WITH_PYTHON
		 PY_VERSION
	#else
		 \"not present\"
	#endif
	"),
   "gdbm version" => gdbmversion(),
   "gmp version" => Ccode(constcharstar,"
	  #if USING_MPIR
	       \"not present\"
	  #else
	       __gmp_version
	  #endif
	  "),
   "mpir version" => Ccode(constcharstar,"
	#if USING_MPIR
	     __mpir_version
	#else
	     \"not present\"
	#endif
	"),
   "ntl version" => Ccode(constcharstar,"NTL_VERSION"),
   "frobby version" => Ccode(constcharstar,"frobby_version"),
   "flint version" => Ccode(constcharstar,"FLINT_VERSION"),
   "scscp version" => Ccode(constcharstar,"
	 #ifdef HAVE_SCSCP
	   stringize(SCSCP_VERSION_MAJOR) \".\" stringize(SCSCP_VERSION_MINOR) \".\" stringize(SCSCP_VERSION_PATCH)
	 #else
	   \"not present\"
	 #endif
	 "),
   "boost version" => Ccode(constcharstar,"BOOST_LIB_VERSION"),
   "memtailor version" => Ccode(constcharstar,"MEMTAILOR_VERSION_STRING"),
   "mathic version" => Ccode(constcharstar,"MATHIC_VERSION_STRING"),
   "mathicgb version" => Ccode(constcharstar,"MATHICGB_VERSION_STRING"),
   "factory version" => factoryversion(),
   "readline version" => readlineversion(),
   "mpfr version" => Ccode(constcharstar,"MPFR_VERSION_STRING"),
   "mpfi version" => Ccode(constcharstar,"MPFI_VERSION_STRING"),
   "tbb version" => Ccode(constcharstar,"
	 #ifdef WITH_TBB
	   stringize(TBB_VERSION_MAJOR) \".\" stringize(TBB_VERSION_MINOR)
	 #else
	   \"not present\"
	 #endif
	 "),
   "lapack version" => lapackversion(),
   "eigen version" => Ccode(constcharstar, "
       stringize(EIGEN_WORLD_VERSION) \".\"
       stringize(EIGEN_MAJOR_VERSION) \".\"
       stringize(EIGEN_MINOR_VERSION)"),
   "libffi version" => Ccode(constcharstar, "FFI_VERSION"),
   "M2 suffix" => Ccode(constcharstar,"M2SUFFIX"),
   "executable extension" => Ccode(constcharstar,"EXEEXT"),
   "M2 name" => Ccode(constcharstar," \"M2\" M2SUFFIX EXEEXT "),
   "endianness" => Ccode(constcharstar,"(char *)endianness_string"),
   "pointer size" => Ccode(int,"sizeof(void *)"),
   "packages" => Ccode(constcharstar,"DISTRIBUTED_PACKAGES"),
   "build" => Ccode(constcharstar,"buildsystemtype"),
   "host" => Ccode(constcharstar,"hostsystemtype"),
   "git description" => Ccode(constcharstar,"GIT_DESCRIPTION")
   ))));

-- Local Variables:
-- compile-command: "echo \"make: Entering directory \\`$M2BUILDDIR/Macaulay2/d'\" && echo \"make: Entering directory \\`$M2BUILDDIR/Macaulay2/d'\" && make -C $M2BUILDDIR/Macaulay2/d version.o "
-- End:
