mirror of
https://github.com/rehlds/rechecker.git
synced 2024-12-30 22:25:28 +03:00
355 lines
6.7 KiB
C++
355 lines
6.7 KiB
C++
|
#include "precompiled.h"
|
||
|
|
||
|
class CCommandLine: public ICommandLine {
|
||
|
public:
|
||
|
CCommandLine();
|
||
|
virtual ~CCommandLine();
|
||
|
|
||
|
void CreateCmdLine(const char *commandline);
|
||
|
void CreateCmdLine(int argc, const char *argv[]);
|
||
|
const char *GetCmdLine() const;
|
||
|
|
||
|
// Check whether a particular parameter exists
|
||
|
const char *CheckParm(const char *psz, char **ppszValue = nullptr) const;
|
||
|
void RemoveParm(const char *pszParm);
|
||
|
void AppendParm(const char *pszParm, const char *pszValues);
|
||
|
|
||
|
void SetParm(const char *pszParm, const char *pszValues);
|
||
|
void SetParm(const char *pszParm, int iValue);
|
||
|
|
||
|
// When the commandline contains @name, it reads the parameters from that file
|
||
|
void LoadParametersFromFile(const char *&pSrc, char *&pDst, int maxDestLen);
|
||
|
|
||
|
private:
|
||
|
// Copy of actual command line
|
||
|
char *m_pszCmdLine;
|
||
|
};
|
||
|
|
||
|
CCommandLine g_CmdLine;
|
||
|
ICommandLine *cmdline = &g_CmdLine;
|
||
|
|
||
|
ICommandLine *CommandLine()
|
||
|
{
|
||
|
return &g_CmdLine;
|
||
|
}
|
||
|
|
||
|
CCommandLine::CCommandLine()
|
||
|
{
|
||
|
m_pszCmdLine = nullptr;
|
||
|
}
|
||
|
|
||
|
CCommandLine::~CCommandLine()
|
||
|
{
|
||
|
if (m_pszCmdLine)
|
||
|
{
|
||
|
delete [] m_pszCmdLine;
|
||
|
m_pszCmdLine = nullptr;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
char *CopyString(const char *src)
|
||
|
{
|
||
|
if (!src)
|
||
|
return nullptr;
|
||
|
|
||
|
char *out = (char *)new char[strlen(src) + 1];
|
||
|
strcpy(out, src);
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
// Creates a command line from the arguments passed in
|
||
|
void CCommandLine::CreateCmdLine(int argc, const char *argv[])
|
||
|
{
|
||
|
char cmdline[4096] = "";
|
||
|
const int MAX_CHARS = sizeof(cmdline) - 1;
|
||
|
|
||
|
for (int i = 0; i < argc; ++i)
|
||
|
{
|
||
|
if (strchr(argv[i], ' '))
|
||
|
{
|
||
|
strncat(cmdline, "\"", MAX_CHARS);
|
||
|
strncat(cmdline, argv[i], MAX_CHARS);
|
||
|
strncat(cmdline, "\"", MAX_CHARS);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
strncat(cmdline, argv[i], MAX_CHARS);
|
||
|
}
|
||
|
|
||
|
strncat(cmdline, " ", MAX_CHARS);
|
||
|
}
|
||
|
|
||
|
cmdline[strlen(cmdline)] = '\0';
|
||
|
CreateCmdLine(cmdline);
|
||
|
}
|
||
|
|
||
|
void CCommandLine::LoadParametersFromFile(const char *&pSrc, char *&pDst, int maxDestLen)
|
||
|
{
|
||
|
// Suck out the file name
|
||
|
char szFileName[ MAX_PATH ];
|
||
|
char *pOut;
|
||
|
char *pDestStart = pDst;
|
||
|
|
||
|
// Skip the @ sign
|
||
|
pSrc++;
|
||
|
pOut = szFileName;
|
||
|
|
||
|
while (*pSrc && *pSrc != ' ')
|
||
|
{
|
||
|
*pOut++ = *pSrc++;
|
||
|
#if 0
|
||
|
if ((pOut - szFileName) >= (MAX_PATH - 1))
|
||
|
break;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
*pOut = '\0';
|
||
|
|
||
|
// Skip the space after the file name
|
||
|
if (*pSrc)
|
||
|
pSrc++;
|
||
|
|
||
|
// Now read in parameters from file
|
||
|
FILE *fp = fopen(szFileName, "r");
|
||
|
if (fp)
|
||
|
{
|
||
|
char c;
|
||
|
c = (char)fgetc(fp);
|
||
|
while (c != EOF)
|
||
|
{
|
||
|
// Turn return characters into spaces
|
||
|
if (c == '\n')
|
||
|
c = ' ';
|
||
|
|
||
|
*pDst++ = c;
|
||
|
|
||
|
#if 0
|
||
|
// Don't go past the end, and allow for our terminating space character AND a terminating null character.
|
||
|
if ((pDst - pDestStart) >= (maxDestLen - 2))
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
// Get the next character, if there are more
|
||
|
c = (char)fgetc(fp);
|
||
|
}
|
||
|
|
||
|
// Add a terminating space character
|
||
|
*pDst++ = ' ';
|
||
|
|
||
|
fclose(fp);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
printf("Parameter file '%s' not found, skipping...", szFileName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Purpose: Create a command line from the passed in string
|
||
|
// Note that if you pass in a @filename, then the routine will read settings from a file instead of the command line
|
||
|
void CCommandLine::CreateCmdLine(const char *commandline)
|
||
|
{
|
||
|
if (m_pszCmdLine)
|
||
|
{
|
||
|
delete[] m_pszCmdLine;
|
||
|
m_pszCmdLine = nullptr;
|
||
|
}
|
||
|
|
||
|
char szFull[4096];
|
||
|
|
||
|
char *pDst = szFull;
|
||
|
const char *pSrc = commandline;
|
||
|
|
||
|
bool allowAtSign = true;
|
||
|
|
||
|
while (*pSrc)
|
||
|
{
|
||
|
if (*pSrc == '@')
|
||
|
{
|
||
|
if (allowAtSign)
|
||
|
{
|
||
|
LoadParametersFromFile(pSrc, pDst, sizeof(szFull) - (pDst - szFull));
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
allowAtSign = isspace(*pSrc) != 0;
|
||
|
|
||
|
#if 0
|
||
|
// Don't go past the end.
|
||
|
if ((pDst - szFull) >= (sizeof(szFull) - 1))
|
||
|
break;
|
||
|
#endif
|
||
|
*pDst++ = *pSrc++;
|
||
|
}
|
||
|
|
||
|
*pDst = '\0';
|
||
|
|
||
|
int len = strlen(szFull) + 1;
|
||
|
m_pszCmdLine = new char[len];
|
||
|
memcpy(m_pszCmdLine, szFull, len);
|
||
|
}
|
||
|
|
||
|
// Purpose: Remove specified string ( and any args attached to it ) from command line
|
||
|
void CCommandLine::RemoveParm(const char *pszParm)
|
||
|
{
|
||
|
if (!m_pszCmdLine)
|
||
|
return;
|
||
|
|
||
|
if (!pszParm || *pszParm == '\0')
|
||
|
return;
|
||
|
|
||
|
// Search for first occurrence of pszParm
|
||
|
char *p, *found;
|
||
|
char *pnextparam;
|
||
|
int n;
|
||
|
int curlen;
|
||
|
|
||
|
p = m_pszCmdLine;
|
||
|
while (*p)
|
||
|
{
|
||
|
curlen = strlen(p);
|
||
|
found = strstr(p, pszParm);
|
||
|
|
||
|
if (!found)
|
||
|
break;
|
||
|
|
||
|
pnextparam = found + 1;
|
||
|
while (pnextparam && *pnextparam && (*pnextparam != '-') && (*pnextparam != '+'))
|
||
|
pnextparam++;
|
||
|
|
||
|
if (pnextparam && *pnextparam)
|
||
|
{
|
||
|
// We are either at the end of the string, or at the next param. Just chop out the current param.
|
||
|
// # of characters after this param.
|
||
|
n = curlen - (pnextparam - p);
|
||
|
|
||
|
memcpy(found, pnextparam, n);
|
||
|
found[n] = '\0';
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// Clear out rest of string.
|
||
|
n = pnextparam - found;
|
||
|
memset(found, 0, n);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Strip and trailing ' ' characters left over.
|
||
|
while (1)
|
||
|
{
|
||
|
int curpos = strlen(m_pszCmdLine);
|
||
|
if (curpos == 0 || m_pszCmdLine[ curpos - 1 ] != ' ')
|
||
|
break;
|
||
|
|
||
|
m_pszCmdLine[curpos - 1] = '\0';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Purpose: Append parameter and argument values to command line
|
||
|
void CCommandLine::AppendParm(const char *pszParm, const char *pszValues)
|
||
|
{
|
||
|
int nNewLength = 0;
|
||
|
char *pCmdString;
|
||
|
|
||
|
// Parameter.
|
||
|
nNewLength = strlen(pszParm);
|
||
|
|
||
|
// Values + leading space character.
|
||
|
if (pszValues)
|
||
|
nNewLength += strlen(pszValues) + 1;
|
||
|
|
||
|
// Terminal 0;
|
||
|
nNewLength++;
|
||
|
|
||
|
if (!m_pszCmdLine)
|
||
|
{
|
||
|
m_pszCmdLine = new char[ nNewLength ];
|
||
|
strcpy(m_pszCmdLine, pszParm);
|
||
|
if (pszValues)
|
||
|
{
|
||
|
strcat(m_pszCmdLine, " ");
|
||
|
strcat(m_pszCmdLine, pszValues);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Remove any remnants from the current Cmd Line.
|
||
|
RemoveParm(pszParm);
|
||
|
|
||
|
nNewLength += strlen(m_pszCmdLine) + 1 + 1;
|
||
|
|
||
|
pCmdString = new char[ nNewLength ];
|
||
|
memset(pCmdString, 0, nNewLength);
|
||
|
|
||
|
strcpy(pCmdString, m_pszCmdLine); // Copy old command line.
|
||
|
strcat(pCmdString, " "); // Put in a space
|
||
|
strcat(pCmdString, pszParm);
|
||
|
|
||
|
if (pszValues)
|
||
|
{
|
||
|
strcat(pCmdString, " ");
|
||
|
strcat(pCmdString, pszValues);
|
||
|
}
|
||
|
|
||
|
// Kill off the old one
|
||
|
delete[] m_pszCmdLine;
|
||
|
|
||
|
// Point at the new command line.
|
||
|
m_pszCmdLine = pCmdString;
|
||
|
}
|
||
|
|
||
|
void CCommandLine::SetParm(const char *pszParm, const char *pszValues)
|
||
|
{
|
||
|
RemoveParm(pszParm);
|
||
|
AppendParm(pszParm, pszValues);
|
||
|
}
|
||
|
|
||
|
void CCommandLine::SetParm(const char *pszParm, int iValue)
|
||
|
{
|
||
|
char buf[64];
|
||
|
_snprintf(buf, sizeof(buf), "%d", iValue);
|
||
|
SetParm(pszParm, buf);
|
||
|
}
|
||
|
|
||
|
// Purpose: Search for the parameter in the current commandline
|
||
|
const char *CCommandLine::CheckParm(const char *psz, char **ppszValue) const
|
||
|
{
|
||
|
static char sz[128] = "";
|
||
|
|
||
|
if (!m_pszCmdLine)
|
||
|
return nullptr;
|
||
|
|
||
|
char *pret = strstr(m_pszCmdLine, psz);
|
||
|
if (!pret || !ppszValue)
|
||
|
return pret;
|
||
|
|
||
|
*ppszValue = nullptr;
|
||
|
|
||
|
// find the next whitespace
|
||
|
char *p1 = pret;
|
||
|
do {
|
||
|
++p1;
|
||
|
} while (*p1 != ' ' && *p1);
|
||
|
|
||
|
int i = 0;
|
||
|
char *p2 = p1 + 1;
|
||
|
|
||
|
do {
|
||
|
if (p2[i] == '\0' || p2[i] == ' ')
|
||
|
break;
|
||
|
|
||
|
sz[i++] = p2[i];
|
||
|
} while (i < sizeof(sz));
|
||
|
|
||
|
sz[i] = '\0';
|
||
|
*ppszValue = sz;
|
||
|
|
||
|
return pret;
|
||
|
}
|
||
|
|
||
|
const char *CCommandLine::GetCmdLine() const
|
||
|
{
|
||
|
return m_pszCmdLine;
|
||
|
}
|