Merge pull request #1062 from openscad/sysinfo

Report system information in the 'Library Info' dialog
master
Marius Kintel 2014-12-10 22:45:15 -05:00
commit df53d05bba
7 changed files with 289 additions and 6 deletions

View File

@ -116,7 +116,6 @@ macx {
win* {
RC_FILE = openscad_win32.rc
QTPLUGIN += qtaccessiblewidgets
}
CONFIG += qt
@ -130,8 +129,6 @@ unix:!macx {
QMAKE_LIBS_OPENGL *= -lX11
}
#QTPLUGIN += qtaccessiblewidgets
netbsd* {
QMAKE_LFLAGS += -L/usr/X11R7/lib
QMAKE_LFLAGS += -Wl,-R/usr/X11R7/lib

View File

@ -29,12 +29,20 @@ std::string LibraryInfo::info()
{
std::stringstream s;
#if defined(__x86_64__) || defined(_M_X64)
std::string bits(" 64bit");
#elif defined(__i386) || defined(_M_IX86)
std::string bits(" 32bit");
#else
std::string bits("");
#endif
#if defined(__GNUG__) && !defined(__clang__)
std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) );
std::string compiler_info( "GCC " + std::string(TOSTRING(__VERSION__)) + bits);
#elif defined(_MSC_VER)
std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) );
std::string compiler_info( "MSVC " + std::string(TOSTRING(_MSC_FULL_VER)) + bits);
#elif defined(__clang__)
std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) );
std::string compiler_info( "Clang " + std::string(TOSTRING(__clang_version__)) + bits);
#else
std::string compiler_info( "unknown compiler" );
#endif
@ -80,6 +88,7 @@ std::string LibraryInfo::info()
const char *env_font_path = getenv("OPENSCAD_FONT_PATH");
s << "OpenSCAD Version: " << TOSTRING(OPENSCAD_VERSION)
<< "\nSystem information: " << PlatformUtils::sysinfo()
<< "\nCompiler, build date: " << compiler_info << ", " << __DATE__
<< "\nBoost version: " << BOOST_LIB_VERSION
<< "\nEigen version: " << EIGEN_WORLD_VERSION << "." << EIGEN_MAJOR_VERSION << "." << EIGEN_MINOR_VERSION

View File

@ -1,5 +1,8 @@
#include "PlatformUtils.h"
#import <Foundation/Foundation.h>
#include <boost/lexical_cast.hpp>
#include <sys/types.h>
#include <sys/sysctl.h>
std::string PlatformUtils::pathSeparatorChar()
{
@ -35,5 +38,33 @@ unsigned long PlatformUtils::stackLimit()
return STACK_LIMIT_DEFAULT;
}
std::string PlatformUtils::sysinfo()
{
std::string result;
result += "Mac OS X ";
result += [[[NSProcessInfo processInfo] operatingSystemVersionString] UTF8String];
int mib[2];
int64_t physical_memory;
int32_t numcpu;
size_t length64 = sizeof(int64_t);
size_t length32 = sizeof(int32_t);;
sysctlbyname("hw.memsize", &physical_memory, &length64, NULL, 0);
sysctlbyname("hw.physicalcpu", &numcpu, &length32, NULL, 0);
result += " ";
result += boost::lexical_cast<std::string>(numcpu);
result += " CPU";
if (numcpu > 1) result += "s";
result += " ";
result += PlatformUtils::toMemorySizeString(physical_memory, 2);
result += " RAM";
return result;
}
void PlatformUtils::ensureStdIO(void) {}

View File

@ -1,4 +1,13 @@
#include <string>
#include <fstream>
#include <streambuf>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/utsname.h>
#include <boost/regex.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string.hpp>
#include "PlatformUtils.h"
#include "boosty.h"
@ -60,5 +69,109 @@ unsigned long PlatformUtils::stackLimit()
return STACK_LIMIT_DEFAULT;
}
static std::string readText(const std::string &path)
{
std::ifstream s(path.c_str());
s.seekg(0, std::ios::end);
if (s.fail() || s.tellg() > 4096) {
return "";
}
s.seekg(0, std::ios::beg);
std::string text((std::istreambuf_iterator<char>(s)), std::istreambuf_iterator<char>());
return text;
}
/**
* Check /etc/os-release as defined by systemd.
* @see http://0pointer.de/blog/projects/os-release.html
* @see http://www.freedesktop.org/software/systemd/man/os-release.html
* @return the PRETTY_NAME from the os-release file or an empty string.
*/
static std::string checkOsRelease()
{
std::string os_release(readText("/etc/os-release"));
boost::smatch results;
boost::regex pretty_name("^PRETTY_NAME=\"([^\"]+)\"");
if (boost::regex_search(os_release, results, pretty_name)) {
return results[1];
}
return "";
}
static std::string checkEtcIssue()
{
std::string issue(readText("/etc/issue"));
boost::regex nl("\n.*$");
issue = boost::regex_replace(issue, nl, "");
boost::regex esc("\\\\.");
issue = boost::regex_replace(issue, esc, "");
boost::algorithm::trim(issue);
return issue;
}
static std::string detectDistribution()
{
std::string osrelease = checkOsRelease();
if (!osrelease.empty()) {
return osrelease;
}
std::string etcissue = checkEtcIssue();
if (!etcissue.empty()) {
return etcissue;
}
return "";
}
std::string PlatformUtils::sysinfo()
{
std::string result;
struct utsname osinfo;
if (uname(&osinfo) == 0) {
result += osinfo.sysname;
result += " ";
result += osinfo.release;
result += " ";
result += osinfo.version;
result += " ";
result += osinfo.machine;
} else {
result += "Unknown Linux";
}
long numcpu = sysconf(_SC_NPROCESSORS_ONLN);
if (numcpu > 0) {
result += " ";
result += boost::lexical_cast<std::string>(numcpu);
result += " CPU";
if (numcpu > 1) {
result += "s";
}
}
long pages = sysconf(_SC_PHYS_PAGES);
long pagesize = sysconf(_SC_PAGE_SIZE);
if ((pages > 0) && (pagesize > 0)) {
result += " ";
result += PlatformUtils::toMemorySizeString(pages * pagesize, 2);
result += " RAM";
}
std::string distribution = detectDistribution();
if (!distribution.empty()) {
result += " ";
result += distribution;
}
return result;
}
void PlatformUtils::ensureStdIO(void) {}

View File

@ -98,6 +98,96 @@ unsigned long PlatformUtils::stackLimit()
return STACK_LIMIT_DEFAULT;
}
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
// see http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx
static BOOL IsWow64()
{
BOOL bIsWow64 = FALSE;
//IsWow64Process is not available on all supported versions of Windows.
//Use GetModuleHandle to get a handle to the DLL that contains the function
//and GetProcAddress to get a pointer to the function if available.
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
if (NULL != fnIsWow64Process) {
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
{
return false;
}
}
return bIsWow64;
}
std::string PlatformUtils::sysinfo()
{
std::string result;
OSVERSIONINFOEX osinfo;
osinfo.dwOSVersionInfoSize = sizeof(osinfo);
if (GetVersionEx((OSVERSIONINFO*)&osinfo) == 0) {
result += "Unknown Windows";
} else {
unsigned int version = osinfo.dwMajorVersion * 1000 + osinfo.dwMinorVersion;
if (osinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
switch (version) {
case 5000:
result += "Windows 2000";
break;
case 5001:
result += "Windows XP";
break;
case 5002:
result += "Windows Server 2003";
break;
case 6000:
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows Vista" : "Windows Server 2008");
break;
case 6001:
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 7" : "Windows Server 2008 R2");
break;
case 6002:
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8" : "Windows Server 2012");
break;
case 6003:
// For applications that have been manifested for Windows 8.1.
result += (osinfo.wProductType == VER_NT_WORKSTATION ? "Windows 8.1" : "Windows Server 2012 R2");
break;
}
boost::format fmt(" (v%d.%d)");
fmt % osinfo.dwMajorVersion % osinfo.dwMinorVersion;
result += fmt.str();
} else {
boost::format fmt("Unknown Windows (dwPlatformId = %d, dwMajorVersion = %d, dwMinorVersion = %d");
fmt % osinfo.dwPlatformId % osinfo.dwMajorVersion % osinfo.dwMinorVersion;
result += fmt.str();
}
}
SYSTEM_INFO systeminfo;
bool isWow64 = IsWow64();
if (isWow64) {
GetNativeSystemInfo(&systeminfo);
} else {
GetSystemInfo(&systeminfo);
}
int numcpu = systeminfo.dwNumberOfProcessors;
boost::format fmt(" %d CPU%s%s");
fmt % numcpu % (numcpu > 1 ? "s" : "") % (isWow64 ? " WOW64" : "");
result += fmt.str();
MEMORYSTATUSEX memoryinfo;
memoryinfo.dwLength = sizeof(memoryinfo);
if (GlobalMemoryStatusEx(&memoryinfo) != 0) {
result += " ";
result += PlatformUtils::toMemorySizeString(memoryinfo.ullTotalPhys, 2);
result += " RAM";
}
return result;
}
#include <io.h>
#include <stdio.h>
#include <fstream>

View File

@ -1,4 +1,5 @@
#include <stdlib.h>
#include <iomanip>
#include "PlatformUtils.h"
@ -190,3 +191,25 @@ int PlatformUtils::setenv(const char *name, const char *value, int overwrite)
return ::setenv(name, value, overwrite);
#endif
}
std::string PlatformUtils::toMemorySizeString(unsigned long bytes, int digits)
{
static const char *units[] = { "B", "kB", "MB", "GB", "TB", NULL };
int idx = 0;
double val = bytes;
while (true) {
if (val < 1024.0) {
break;
}
if (units[idx + 1] == NULL) {
break;
}
idx++;
val /= 1024.0;
}
boost::format fmt("%f %s");
fmt % boost::io::group(std::setprecision(digits), val) % units[idx];
return fmt.str();
}

View File

@ -34,6 +34,20 @@ namespace PlatformUtils {
std::string backupPath();
bool createBackupPath();
/**
* Return a human readable text describing the operating system
* the application is currently running on. This is mainly intended
* to provide information for bug reports (e.g. to be included in
* the LibraryInfoDialog).
*
* If there is some error to retrieve the details, at least the
* OS type is reported based on what platform the application was
* built for.
*
* @return system information.
*/
std::string sysinfo();
/**
* Platform abstraction to set environment variables. Windows/MinGW
* does not support setenv(), but needs _putenv().
@ -65,4 +79,10 @@ namespace PlatformUtils {
* Currently limited to MS Windows GUI application console only.
*/
void ensureStdIO(void);
/**
* Convert the number of bytes to a human readable string with
* a given number of digits.
*/
std::string toMemorySizeString(unsigned long bytes, int digits);
}