1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-04 18:06:22 +03:00
occt/src/OSD/OSD_Process.cxx
abv 1bd04b5a02 0031060: Configuration - Support building with CLang compiler under VS 2019
Build tools are updated to support building with Visual Studion 2019 toolset ClangCL (LLVM clang-cl):
- In CMake builds, use of unsupported option "-std=c++0x" is avoided
- Tool genconf recognizes availability of ClangCL toolset and proposes it in the list
- Tool genproj recognizes new compiler specification VCVER=vclang and generates VS 2019 projects for it

Note that vclang configuration puts binaries to folder "vc14" as it is compatible with vc14 CRT.

Code is updated to build with Clang for Windows without errors and warnings:
- In BVH classes, pure virtual destructors are replaced by empty ones, to avoid bogus compiler warning
- In .lex files, pragmas are added to disable warnings in parser code
- In OSD, signature of function _osd_wnt_set_error() is corrected to avoid warning on incorrect use of va_args (undefined behavior)
- In OSD_Host, OSD_Parallel_TBB, warnings on usage of deprecated function are disabled
- In Quantity_ColorRGBA and ViewerTest_CmdParser, incorrect use of predefined macro __FUNCTION__ assuming it was a string literal is avoided
- In Standard_Macro.hxx, code is reordered to handle Clang for Windows appropriately
- In AdvApp2Var_SysBase.hxx, inclusion of obsolete (MSVC-specific) header file is replaced by Standard_TypeDef.hxx
- In Standard_ErrorHandler.hxx, empty statements added to avoid warning on unused class fields
- In IVtkDraw and ViewerTest, interface is corrected to use actual type avoiding unnecessary type casts

Off-topic: corrections of some errors (uninitialized class fields) reported by VS Code Analysis in TKernel
2019-11-03 21:47:59 +03:00

469 lines
12 KiB
C++

// Copyright (c) 1998-1999 Matra Datavision
// Copyright (c) 1999-2014 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifdef _WIN32
//it is important to undefine NOUSER and enforce including <windows.h> before
//Standard_Macro.hxx defines it and includes <windows.h> causing compilation errors
#ifdef NOUSER
#undef NOUSER // we need SW_HIDE from windows.h
#endif
#include <windows.h>
#endif
#include <OSD_Process.hxx>
#include <NCollection_Array1.hxx>
#include <OSD_Environment.hxx>
#include <OSD_OSDError.hxx>
#include <OSD_Path.hxx>
#include <OSD_WhoAmI.hxx>
#include <Standard_PExtCharacter.hxx>
#include <TCollection_ExtendedString.hxx>
#include <Quantity_Date.hxx>
#ifdef _WIN32
#include <OSD_WNT.hxx>
#include <lmcons.h> // for UNLEN - maximum user name length GetUserName()
#else
const OSD_WhoAmI Iam = OSD_WProcess;
#include <errno.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/time.h>
#include <pwd.h> // For command getpwuid
#include <unistd.h>
#endif
#if defined(__APPLE__)
#include <mach-o/dyld.h>
#endif
#ifndef _WIN32
OSD_Process::OSD_Process(){
}
void OSD_Process::TerminalType(TCollection_AsciiString& Name){
TCollection_AsciiString which="TERM";
OSD_Environment term (which,"");
term.Value();
which = term.Value();
Name = term.Name();
}
// Get date of system date
Quantity_Date OSD_Process::SystemDate(){
Quantity_Date result;
Standard_Integer month=0,day=0,year=0,hh=0,mn=0,ss=0;
struct tm transfert;
struct timeval tval;
struct timezone tzone;
int status;
status = gettimeofday( &tval, &tzone );
if (status == -1) myError.SetValue (errno, Iam, "GetSystem");
else {
memcpy(&transfert, localtime((time_t *)&tval.tv_sec), sizeof(struct
tm));
month = transfert.tm_mon + 1; // Add to January (month #1)
day = transfert.tm_mday;
year = transfert.tm_year;
hh = transfert.tm_hour;
mn = transfert.tm_min ;
ss = transfert.tm_sec ;
}
result.SetValues ( month, day, year+1900, hh, mn, ss);
return (result);
}
Standard_Integer OSD_Process::ProcessId(){
return (getpid());
}
TCollection_AsciiString OSD_Process::UserName()
{
struct passwd *anInfos = getpwuid (getuid());
return TCollection_AsciiString (anInfos ? anInfos->pw_name : "");
}
Standard_Boolean OSD_Process::IsSuperUser (){
if (getuid()) {
return Standard_False;
}
else {
return Standard_True;
}
}
OSD_Path OSD_Process::CurrentDirectory(){
char cwd[MAXPATHLEN+1] ;
OSD_Path result;
TCollection_AsciiString Name;
if (!getcwd(cwd,MAXPATHLEN+1))
myError.SetValue (errno, Iam, "Where");
else {
Name = cwd;
// JPT : August,20 1993. This code has been replaced by #ifdef ... #endif
// position = Name.SearchFromEnd(".");
// if (position != -1){
// Ext = Name;
// Ext.Remove(1,position);
// Name.Remove( position,Ext.Length()+1);
// }
// result.SetValues("","","","","",Name,Ext);
// End
#if defined(vax) || defined(__vms)
Standard_Integer iDisk = Name.Search(":");
if (iDisk){
TCollection_AsciiString Disk;
TCollection_AsciiString Directory;
Disk = Name.SubString(1,iDisk-1);
Directory = Name.SubString(iDisk+1,Name.Length());
result.SetValues("","","",Disk,Directory,"","");
}
#else
Name += TCollection_AsciiString("/");
result = OSD_Path(Name);
// result.SetValues("","","","",Name,"","");
#endif
}
return (result);
}
void OSD_Process::SetCurrentDirectory(const OSD_Path& where){
TCollection_AsciiString Name;
int status;
where.SystemName(Name);
status = chdir (Name.ToCString());
if (status == -1) myError.SetValue(errno, Iam, "Move to directory");
}
void OSD_Process::Reset(){
myError.Reset();
}
Standard_Boolean OSD_Process::Failed()const{
return( myError.Failed());
}
void OSD_Process::Perror() {
myError.Perror();
}
Standard_Integer OSD_Process::Error()const{
return( myError.Error());
}
#else
//------------------------------------------------------------------------
//------------------- WNT Sources of OSD_Path ---------------------------
//------------------------------------------------------------------------
void _osd_wnt_set_error ( OSD_Error&, Standard_Integer, ... );
// =======================================================================
// function : OSD_Process
// purpose :
// =======================================================================
OSD_Process::OSD_Process()
{
//
}
void OSD_Process :: TerminalType ( TCollection_AsciiString& Name ) {
Name = "WIN32 console";
} // end OSD_Process :: TerminalType
Quantity_Date OSD_Process :: SystemDate () {
Quantity_Date retVal;
SYSTEMTIME st;
GetLocalTime ( &st );
retVal.SetValues (
st.wMonth, st.wDay, st.wYear, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds
);
return retVal;
} // end OSD_Process :: SystemDate
// =======================================================================
// function : UserName
// purpose :
// =======================================================================
TCollection_AsciiString OSD_Process::UserName()
{
#ifndef OCCT_UWP
wchar_t aUserName[UNLEN + 1];
DWORD aNameSize = UNLEN + 1;
TCollection_AsciiString retVal;
if (!GetUserNameW (aUserName, &aNameSize))
{
_osd_wnt_set_error(myError, OSD_WProcess);
return TCollection_AsciiString();
}
return TCollection_AsciiString (aUserName);
#else
return TCollection_AsciiString();
#endif
}
Standard_Boolean OSD_Process :: IsSuperUser () {
#ifndef OCCT_UWP
Standard_Boolean retVal = FALSE;
PSID pSIDadmin;
HANDLE hProcessToken = INVALID_HANDLE_VALUE;
PTOKEN_GROUPS pTKgroups = NULL;
if ( !OpenProcessToken (
GetCurrentProcess (),
TOKEN_QUERY, &hProcessToken
) ||
( pTKgroups = ( PTOKEN_GROUPS )GetTokenInformationEx (
hProcessToken, TokenGroups
)
) == NULL
)
_osd_wnt_set_error ( myError, OSD_WProcess );
else {
pSIDadmin = AdminSid ();
for ( int i = 0; i < ( int )pTKgroups -> GroupCount; ++i )
if ( EqualSid ( pTKgroups -> Groups[ i ].Sid, pSIDadmin ) ) {
retVal = TRUE;
break;
} // end if
} // end else
if ( hProcessToken != INVALID_HANDLE_VALUE ) CloseHandle ( hProcessToken );
if ( pTKgroups != NULL ) FreeTokenInformation ( pTKgroups );
return retVal;
#else
return FALSE;
#endif
} // end OSD_Process :: IsSuperUser
// =======================================================================
// function : ProcessId
// purpose :
// =======================================================================
Standard_Integer OSD_Process::ProcessId()
{
return (Standard_Integer )GetCurrentProcessId();
}
// =======================================================================
// function : CurrentDirectory
// purpose :
// =======================================================================
OSD_Path OSD_Process::CurrentDirectory()
{
OSD_Path anCurrentDirectory;
#ifndef OCCT_UWP
const DWORD aBuffLen = GetCurrentDirectoryW (0, NULL);
if (aBuffLen > 0)
{
wchar_t* aBuff = new wchar_t[aBuffLen + 1];
GetCurrentDirectoryW (aBuffLen, aBuff);
aBuff[aBuffLen] = L'\0';
const TCollection_AsciiString aPath (aBuff);
delete[] aBuff;
anCurrentDirectory = OSD_Path (aPath);
}
else
{
_osd_wnt_set_error (myError, OSD_WProcess);
}
#endif
return anCurrentDirectory;
}
void OSD_Process :: SetCurrentDirectory ( const OSD_Path& where ) {
TCollection_AsciiString path;
where.SystemName ( path );
TCollection_ExtendedString pathW(path);
if (!::SetCurrentDirectoryW (pathW.ToWideString()))
_osd_wnt_set_error ( myError, OSD_WProcess );
} // end OSD_Process :: SetCurrentDirectory
Standard_Boolean OSD_Process :: Failed () const {
return myError.Failed ();
} // end OSD_Process :: Failed
void OSD_Process :: Reset () {
myError.Reset ();
} // end OSD_Process :: Reset
void OSD_Process :: Perror () {
myError.Perror ();
} // end OSD_Process :: Perror
Standard_Integer OSD_Process :: Error () const {
return myError.Error ();
} // end OSD_Process :: Error
#endif
// =======================================================================
// function : ExecutablePath
// purpose :
// =======================================================================
TCollection_AsciiString OSD_Process::ExecutablePath()
{
#ifdef _WIN32
wchar_t aBuff[MAX_PATH + 2];
DWORD aLenFilled = GetModuleFileNameW (0, aBuff, MAX_PATH + 1);
aBuff[MAX_PATH + 1] = 0;
if (aLenFilled == 0)
{
return TCollection_AsciiString();
}
else if (aLenFilled <= MAX_PATH)
{
return TCollection_AsciiString (aBuff);
}
// buffer is not large enough (e.g. path uses \\?\ prefix)
wchar_t* aBuffDyn = NULL;
for (int anIter = 2;; ++anIter)
{
size_t aBuffLen = MAX_PATH * anIter;
aBuffDyn = reinterpret_cast<wchar_t*> (realloc (aBuffDyn, sizeof(wchar_t) * (aBuffLen + 1)));
if (aBuffDyn == NULL)
{
return TCollection_AsciiString();
}
aLenFilled = GetModuleFileNameW (NULL, aBuffDyn, DWORD(aBuffLen));
if (aLenFilled != aBuffLen)
{
aBuffDyn[aBuffLen] = L'\0';
TCollection_AsciiString aRes (aBuffDyn);
free (aBuffDyn);
return aRes;
}
}
#elif defined(__APPLE__)
// determine buffer size
uint32_t aNbBytes = 0;
_NSGetExecutablePath (NULL, &aNbBytes);
if (aNbBytes == 0)
{
return TCollection_AsciiString();
}
// retrieve path to executable (probably link)
NCollection_Array1<char> aBuff (0, aNbBytes);
_NSGetExecutablePath (&aBuff.ChangeFirst(), &aNbBytes);
aBuff[aNbBytes] = '\0';
// retrieve real path to executable (resolve links and normalize)
char* aResultBuf = realpath (&aBuff.First(), NULL);
if (aResultBuf == NULL)
{
return TCollection_AsciiString();
}
TCollection_AsciiString aProcessPath (aResultBuf);
free (aResultBuf); // according to man for realpath()
return aProcessPath;
#elif defined(__linux__)
// get info from /proc/PID/exe
TCollection_AsciiString aSimLink = TCollection_AsciiString("/proc/") + TCollection_AsciiString(getpid()) + "/exe";
char aBuff[4096];
ssize_t aBytes = readlink (aSimLink.ToCString(), aBuff, 4096);
if (aBytes > 0)
{
aBuff[aBytes] = '\0';
return TCollection_AsciiString(aBuff);
}
return TCollection_AsciiString();
#else
// not implemented
return TCollection_AsciiString();
#endif
}
// =======================================================================
// function : ExecutableFolder
// purpose :
// =======================================================================
TCollection_AsciiString OSD_Process::ExecutableFolder()
{
TCollection_AsciiString aFullPath = ExecutablePath();
Standard_Integer aLastSplit = -1;
#ifdef _WIN32
const char THE_FILE_SEPARATOR = '\\';
#else
const char THE_FILE_SEPARATOR = '/';
#endif
for (Standard_Integer anIter = 1; anIter <= aFullPath.Length(); ++anIter)
{
if (aFullPath.Value (anIter) == THE_FILE_SEPARATOR)
{
aLastSplit = anIter;
}
}
if (aLastSplit != -1)
{
return aFullPath.SubString (1, aLastSplit);
}
return TCollection_AsciiString();
}