// ***************************************************************** -*- C++ -*- /* * Copyright (C) 2004-2013 Andreas Huggel * * This program is part of the Exiv2 distribution. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA. */ /* File: version.cpp Version: $Rev$ Author(s): Andreas Huggel (ahu) History: 06-Mar-07, ahu: created */ // ***************************************************************************** #include "rcsid_int.hpp" EXIV2_RCSID("@(#) $Id$") // ***************************************************************************** // included header files #ifdef _MSC_VER # include "exv_msvc.h" #else # include "exv_conf.h" #endif #if defined(__MINGW32__) || defined(__MINGW64__) # ifndef __MINGW__ # define __MINGW__ # endif #endif #if defined(__CYGWIN__) || defined(__MINGW__) #include #endif #include "version.hpp" // + standard includes #include #include namespace Exiv2 { int versionNumber() { return EXIV2_MAKE_VERSION(EXIV2_MAJOR_VERSION, EXIV2_MINOR_VERSION, EXIV2_PATCH_VERSION); } std::string versionString() { std::ostringstream os; os << EXIV2_MAJOR_VERSION << '.' << EXIV2_MINOR_VERSION << '.' << EXIV2_PATCH_VERSION; return os.str(); } std::string versionNumberHexString() { std::ostringstream os; os << std::hex << std::setw(6) << std::setfill('0') << Exiv2::versionNumber(); return os.str(); } const char* version() { return EXV_PACKAGE_VERSION; } bool testVersion(int major, int minor, int patch) { return versionNumber() >= EXIV2_MAKE_VERSION(major,minor,patch); } } // namespace Exiv2 #include #include #include using namespace std; typedef vector string_v; typedef string_v::iterator string_i; #ifndef lengthof #define lengthof(x) sizeof(x)/sizeof(x[0]) #endif #ifndef _MAX_PATH #define _MAX_PATH 512 #endif // platform specific support for dumpLibraryInfo #if defined(WIN32) # include # include // tell MSVC to link psapi. #ifdef _MSC_VER #pragma comment( lib, "psapi" ) #endif #elif defined(__APPLE__) # include #elif defined(__linux__) # include // http://syprog.blogspot.com/2011/12/listing-loaded-shared-objects-in-linux.html # include "link.h" # include struct something { void* pointers[3]; struct something* ptr; }; struct lmap { void* base_address; /* Base address of the shared object */ char* path; /* Absolute file name (path) of the shared object */ void* not_needed1; /* Pointer to the dynamic section of the shared object */ struct lmap *next, *prev;/* chain of loaded objects */ }; #elif defined(__MINGW32__) || defined(__MINGW64__) #ifndef __MINGW__ #define __MINGW__ #endif #endif EXIV2API void dumpLibraryInfo(std::ostream& os) { string_v libs; // libs[0] == executable int bits = 8*sizeof(void*); #if defined(_DEBUG) || defined(DEBUG) int debug=1; #else int debug=0; #endif #if defined(DLL_EXPORT) || defined(EXV_HAVE_DLL) int dll=1; #else int dll=0; #endif const char* compiler = #if defined(_MSC_VER) "MSVC" ; #ifndef __VERSION__ char version[20]; sprintf(version,"%d.%02d",(_MSC_VER-600)/100,_MSC_VER%100); #define __VERSION__ version #endif #elif defined(__clang__) "Clang" ; #elif defined(__GNUG__) "G++" ; #elif defined(__GNUC__) "GCC" ; #elif defined(__SUNPRO_CC) "CC (oracle)"; #elif defined (__SUNPRO_C) "cc (oracle)"; #else "unknown" ; #endif #if defined(__SUNPRO_CC) || defined (__SUNPRO_C) #define __oracle__ #endif #ifndef __VERSION__ #ifdef __clang__version__ #define __VERSION__ __clang__version__ #else #define __VERSION__ "unknown" #endif #endif const char* platform = #if defined(__CYGWIN__) "cygwin"; #elif defined(_MSC_VER) "windows"; #elif defined(__APPLE__) "apple"; #elif defined(__MINGW__) "mingw"; #elif defined(__linux__) "linux"; #else "unknown"; #endif #if defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW__) // enumerate loaded libraries and determine path to executable HMODULE handles[200]; DWORD cbNeeded; if ( EnumProcessModules(GetCurrentProcess(),handles,lengthof(handles),&cbNeeded)) { char szFilename[_MAX_PATH]; for ( DWORD h = 0 ; h < cbNeeded/sizeof(handles[0]) ; h++ ) { GetModuleFileNameA(handles[h],szFilename,lengthof(szFilename)) ; libs.push_back(szFilename); } } #elif defined(__APPLE__) // man 3 dyld uint32_t count = _dyld_image_count(); for (uint32_t image = 0 ; image < count ; image++ ) { const char* image_path = _dyld_get_image_name(image); libs.push_back(image_path); } #elif defined(__linux__) // http://stackoverflow.com/questions/606041/how-do-i-get-the-path-of-a-process-in-unix-linux char proc[100]; char path[500]; sprintf(proc,"/proc/%d/exe", getpid()); int l = readlink (proc, path,sizeof(path)-1); if (l>0) { path[l]=0; libs.push_back(path); } else { libs.push_back("unknown"); } // http://syprog.blogspot.com/2011/12/listing-loaded-shared-objects-in-linux.html struct lmap* pl; void* ph = dlopen(NULL, RTLD_NOW); struct something* p = (struct something*)ph; p = p->ptr; pl = (struct lmap*)p->ptr; while ( pl ) { libs.push_back(pl->path); pl = pl->next; } #endif os << "exiv2=" << Exiv2::versionString() << endl; os << "platform=" << platform << endl; os << "compiler=" << compiler << endl; os << "bits=" << bits << endl; os << "dll=" << dll << endl; os << "debug=" << debug << endl; os << "version=" << __VERSION__ << endl; os << "date=" << __DATE__ << endl; os << "time=" << __TIME__ << endl; if ( libs.begin() != libs.end() ) { os << "executable=" << *libs.begin() << endl; for ( string_i lib = libs.begin()+1 ; lib != libs.end() ; lib++ ) os << "library=" << *lib << endl; } }