legatt 32f4597c4d Base frontend module
- Naming style migrated to camel-case
- P7lib logger sources added
- Vcpkg manifest, CMake presets and build moved to root
- SDL2, Vulkan and RmlUi dependencies added
- Logger LOG macro added
- Logger  configuration
- SDL2 window configuration
- Vulkan configuration
- RmlUi configuration
- SDL event loop
2025-08-08 00:07:32 +03:00

576 lines
15 KiB
C++

////////////////////////////////////////////////////////////////////////////////
// /
// 2012-2020 (c) Baical /
// /
// This library is free software; you can redistribute it and/or /
// modify it under the terms of the GNU Lesser General Public /
// License as published by the Free Software Foundation; either /
// version 3.0 of the License, or (at your option) any later version. /
// /
// This library 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 /
// Lesser General Public License for more details. /
// /
// You should have received a copy of the GNU Lesser General Public /
// License along with this library. /
// /
////////////////////////////////////////////////////////////////////////////////
#ifndef PPROCESS_H
#define PPROCESS_H
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>
#include <fcntl.h>
#include <asm/param.h> //HZ macro !
#include <sched.h>
class CProc
{
public:
///////////////////////////////////////////////////////////////////////////////
//Get_ArgV
static tXCHAR **Get_ArgV(tINT32 *o_pCount)
{
const tUINT16 l_wLen = 4096;
tXCHAR *l_pBuffer = new tXCHAR[l_wLen];
tXCHAR **l_pReturn = NULL;
int l_pFile = -1;
tINT32 l_iRead = -1;
tBOOL l_bNew = TRUE;
tINT32 l_iIDX = 0;
if ( (NULL == l_pBuffer)
|| (NULL == o_pCount)
)
{
goto l_lblExit;
}
l_pFile = open("/proc/self/cmdline", O_RDONLY);
if (-1 == l_pFile)
{
goto l_lblExit;
}
l_iRead = read(l_pFile, l_pBuffer, l_wLen * sizeof(tXCHAR));
if (0 >= l_iRead)
{
goto l_lblExit;
}
//calculate count of items//////////////////////////////////////////////////
*o_pCount = 0;
for (tINT32 l_iI = 0; l_iI < l_iRead; l_iI++)
{
if ( (0 == l_pBuffer[l_iI])
|| ((l_iI + 1) == l_iRead)
)
{
(*o_pCount) ++;
}
}
if (0 >= *o_pCount)
{
goto l_lblExit;
}
//allocate result///////////////////////////////////////////////////////////
l_pReturn = new tXCHAR*[*o_pCount];
if (NULL == l_pReturn)
{
goto l_lblExit;
}
//fill result///////////////////////////////////////////////////////////////
l_bNew = TRUE;
for (tINT32 l_iI = 0; l_iI < l_iRead; l_iI++)
{
if (l_bNew)
{
l_pReturn[l_iIDX++] = &l_pBuffer[l_iI];
l_bNew = FALSE;
}
if (0 == l_pBuffer[l_iI])
{
l_bNew = TRUE;
}
}
l_lblExit:
if (-1 != l_pFile)
{
close(l_pFile);
}
if (NULL == l_pReturn)
{
if (l_pBuffer)
{
delete [] l_pBuffer;
l_pBuffer = NULL;
}
}
return l_pReturn;
// return = CommandLineToArgvW(GetCommandLineW(), o_pCount);
}//Get_ArgV
///////////////////////////////////////////////////////////////////////////////
//Get_ArgV
static tXCHAR **Get_ArgV(const tXCHAR *i_pCmdLine, tINT32 *o_pCount)
{
tINT32 l_iLen = 0;//strlen(i_pCmdLine);
tXCHAR *l_pBuffer = NULL;//new tXCHAR[l_iLen];
tXCHAR **l_pReturn = NULL;
tBOOL l_bNew = TRUE;
tBOOL l_bStr = FALSE;
tINT32 l_iIDX = 0;
if ( (NULL == i_pCmdLine)
|| (NULL == o_pCount)
)
{
goto l_lblExit;
}
l_iLen = (tINT32)strlen(i_pCmdLine) + 1;
l_pBuffer = new tXCHAR[l_iLen];
if (NULL == l_pBuffer)
{
goto l_lblExit;
}
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
{
if (TM('\"') == i_pCmdLine[l_iI])
{
l_bStr = ! l_bStr;
}
else
{
if ( (TM(' ') == i_pCmdLine[l_iI])
&& (!l_bStr)
)
{
l_pBuffer[l_iIDX++] = 0;
}
else
{
l_pBuffer[l_iIDX++] = i_pCmdLine[l_iI];
}
}
}
l_iLen = l_iIDX;
//calculate count of items//////////////////////////////////////////////////
*o_pCount = 0;
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
{
if ( (0 == l_pBuffer[l_iI])
|| ((l_iI + 1) == l_iLen)
)
{
(*o_pCount) ++;
}
}
if (0 >= *o_pCount)
{
goto l_lblExit;
}
//allocate result///////////////////////////////////////////////////////////
l_pReturn = new tXCHAR*[*o_pCount];
if (NULL == l_pReturn)
{
goto l_lblExit;
}
//fill result///////////////////////////////////////////////////////////////
l_bNew = TRUE;
l_iIDX = 0;
for (tINT32 l_iI = 0; l_iI < l_iLen; l_iI++)
{
if (l_bNew)
{
l_pReturn[l_iIDX++] = &l_pBuffer[l_iI];
l_bNew = FALSE;
}
if (0 == l_pBuffer[l_iI])
{
l_bNew = TRUE;
}
}
l_lblExit:
return l_pReturn;
}//Get_ArgV
///////////////////////////////////////////////////////////////////////////////
//Free_ArgV
static void Free_ArgV(tXCHAR **i_pArgV)
{
if (NULL == i_pArgV)
{
return;
}
if (i_pArgV[0])
{
delete [] i_pArgV[0];
}
delete [] i_pArgV;
//LocalFree(i_pArgV);
}//Free_ArgV
////////////////////////////////////////////////////////////////////////////////
//Get_Process_Time()
//return a 64-bit value divided into 2 parts representing the number of
//100-nanosecond intervals since January 1, 1601 (UTC).
static tBOOL Get_Process_Time(tUINT32 *o_pHTime, tUINT32 *o_pLTime)
{
const int l_iLen = 8192;
char *l_pBuffer = new char[l_iLen];
int l_iRead = 0;
int l_pFile = -1;
char *l_pIter = NULL;
long long l_llBtime = 0;
long long l_llStime = 0;
int l_iSscanf = 0;
tBOOL l_bResult = FALSE;
if ( (NULL == l_pBuffer)
|| (NULL == o_pHTime)
|| (NULL == o_pLTime)
)
{
goto l_lblExit;
}
*o_pHTime = 0;
*o_pLTime = 0;
//read global stat//////////////////////////////////////////////////////////
l_pFile = open("/proc/stat", O_RDONLY);
if (-1 == l_pFile)
{
goto l_lblExit;
}
l_iRead = read(l_pFile, l_pBuffer, l_iLen);
close(l_pFile);
if (0 >= l_iRead)
{
goto l_lblExit;
}
if (l_iRead < l_iLen)
{
l_pBuffer[l_iRead -1] = 0;
}
else
{
l_pBuffer[l_iLen -1] = 0;
}
//printf((char*)l_pBuffer, 0);
//printf("\nLen = %d\n", l_iRead);
//get "btime" value/////////////////////////////////////////////////////////
{
const char l_pBtime[] = "btime ";
int l_iBLen = strlen(l_pBtime);
l_pIter = l_pBuffer;
for (int l_iI = 0; l_iI < l_iRead; l_iI++)
{
if (0 == strncmp(l_pBtime, l_pIter, l_iBLen))
{
l_iSscanf = sscanf(l_pIter + l_iBLen, "%lld", &l_llBtime);
break;
}
else
{
l_pIter++;
}
}
}
if (0 >= l_iSscanf)
{
goto l_lblExit;
}
//read process statistics///////////////////////////////////////////////////
l_pFile = open("/proc/self/stat", O_RDONLY);
if (-1 == l_pFile)
{
goto l_lblExit;
}
l_iRead = read(l_pFile, l_pBuffer, l_iLen);
close(l_pFile);
if (0 >= l_iRead)
{
goto l_lblExit;
}
if (l_iRead < l_iLen)
{
l_pBuffer[l_iRead -1] = 0;
}
else
{
l_pBuffer[l_iLen -1] = 0;
}
//get process start time////////////////////////////////////////////////////
{
int l_iItem = 1;
l_pIter = l_pBuffer;
for (int l_iI = 0; l_iI < l_iRead; l_iI++)
{
if (' ' == *l_pIter)
{
if (21 == l_iItem)
{
l_iSscanf = sscanf(l_pIter, " %lld", &l_llStime);
break;
}
else
{
l_iItem ++;
}
}
l_pIter++;
}
}
if (0 >= l_iSscanf)
{
goto l_lblExit;
}
//HZ defined in #include <asm/param.h>
l_llStime = l_llBtime * 10000000ull + (l_llStime * 10000000ull / HZ);
l_llStime += TIME_OFFSET_1601_1970; //defined in "PTime.h"
*o_pHTime = (l_llStime >> 32);
*o_pLTime = (l_llStime & 0xFFFFFFFF);
l_bResult = TRUE;
l_lblExit:
if (l_pBuffer)
{
delete [] l_pBuffer;
l_pBuffer = NULL;
}
return l_bResult;
}//Get_Process_Time()
////////////////////////////////////////////////////////////////////////////////
//Get_Process_Name
static tBOOL Get_Process_Name(tACHAR *o_pName, tINT32 i_iMax_Len)
{
int l_iRead = 0;
char *l_pName = NULL;
char *l_pDst = o_pName;
tBOOL l_bReturn = FALSE;
if ( (NULL == o_pName)
|| (32 >= i_iMax_Len)
|| (NULL == o_pName)
)
{
goto l_lblExit;
}
l_iRead = readlink("/proc/self/exe", o_pName, i_iMax_Len - 1);
if (0 >= l_iRead)
{
// I guess we're not running on the right version of unix
goto l_lblExit;
}
if (l_iRead >= i_iMax_Len)
{
l_iRead = i_iMax_Len - 1;
}
o_pName[l_iRead] = '\0';
l_pName = o_pName + l_iRead;
while (l_pName != o_pName)
{
if ( ('/' == *l_pName)
|| ('\\' == *l_pName)
)
{
l_pName ++;
break;
}
else
{
l_pName --;
}
}
while (*l_pName)
{
*l_pDst++=*l_pName++;
}
*l_pDst = 0;
l_bReturn = TRUE;
l_lblExit:
return l_bReturn;
}//Get_Process_Name
////////////////////////////////////////////////////////////////////////////////
//Get_Process_Name
static tBOOL Get_Process_Name(tWCHAR *o_pName, tINT32 i_iMax_Len)
{
int l_iLen = 4096;
char *l_pBuffer = new char[l_iLen];
tBOOL l_bReturn = FALSE;
if ( (l_pBuffer)
&& (Get_Process_Name(l_pBuffer, l_iLen))
)
{
l_bReturn = TRUE;
Convert_UTF8_To_UTF16(l_pBuffer, o_pName, i_iMax_Len);
}
else
{
Convert_UTF8_To_UTF16("Unknown", o_pName, i_iMax_Len);
}
if (l_pBuffer)
{
delete [] l_pBuffer;
l_pBuffer = NULL;
}
return l_bReturn;
}//Get_Process_Name
////////////////////////////////////////////////////////////////////////////////
//Get_Process_Path
static tBOOL Get_Process_Path(tXCHAR *o_pPath, tINT32 i_iMax_Len)
{
int l_iRead = 0;
tBOOL l_bReturn = FALSE;
if ( (NULL == o_pPath)
|| (32 >= i_iMax_Len)
)
{
goto l_lblExit;
}
l_iRead = readlink("/proc/self/exe", o_pPath, i_iMax_Len - 4);
if (0 >= l_iRead)
{
// I guess we're not running on the right version of unix
goto l_lblExit;
}
if (l_iRead >= i_iMax_Len)
{
// buffer is too small
goto l_lblExit;
}
o_pPath[l_iRead] = '\0';
while (l_iRead)
{
if ( ('/' == o_pPath[l_iRead])
|| ('\\' == o_pPath[l_iRead])
)
{
break;
}
else
{
o_pPath[l_iRead--] = 0;
}
}
l_bReturn = TRUE;
l_lblExit:
if (TRUE != l_bReturn)
{
strcpy(o_pPath, "./");
}
return l_bReturn;
}//Get_Process_Path
////////////////////////////////////////////////////////////////////////////////
//Get_Process_ID
static tUINT32 Get_Process_ID()
{
return getpid();
//return GetCurrentProcessId();
}//Get_Process_ID
////////////////////////////////////////////////////////////////////////////////
//Get_Thread_Id
static tUINT32 Get_Thread_Id()
{
return (int32_t)syscall(SYS_gettid);
//return pthread_self();
//return gettid();
}//Get_Thread_Id
////////////////////////////////////////////////////////////////////////////////
//Get_Processor
static __forceinline tUINT32 Get_Processor()
{
#ifdef __ARM_ARCH_5TEJ__
return 0;
#else
return sched_getcpu();
#endif
}//Get_Processor
};
#endif //PPROCESS_H