|
|
|
|
|
|
#include "stdafx.h" |
#include "startdll.h" |
#include "cmdline.h" |
#include "roxen.h" |
#include "enumproc.h" |
|
#ifdef _DEBUG |
#undef THIS_FILE |
static char THIS_FILE[]=__FILE__; |
|
#endif |
|
static char *defPikeArgs[] = { |
|
|
NULL |
}; |
|
static char *defPikeDefines[] = { |
"-DRAM_CACHE", |
"-DENABLE_THREADS", |
|
|
NULL |
}; |
|
static char *defRoxenArgs[] = { |
|
|
NULL |
}; |
|
|
|
|
|
|
#define ARG_ALLOC 1 |
#define ARG_THRESH 1 |
|
|
|
|
|
CArgList::CArgList() |
{ |
m_Count = 0; |
m_Size = 0; |
m_pData = NULL; |
|
|
ReSize(1); |
} |
|
CArgList::~CArgList() |
{ |
if (m_pData == NULL) |
return; |
|
for (int i=0; i<m_Count; i++) |
{ |
delete (m_pData)[i]; |
} |
|
delete [] m_pData; |
} |
|
BOOL CArgList::CopyData(tData *p, int size) |
{ |
int i; |
int copySize = min(m_Size, size); |
|
|
for (i=0; i<copySize; i++) |
p[i] = m_pData[i]; |
|
|
if (copySize < size) |
for (i=copySize; i<size; i++) |
p[i] = 0; |
|
return TRUE; |
} |
|
BOOL CArgList::ReSize(int diff) |
{ |
if (diff > 0) |
{ |
int need = m_Count + diff; |
|
if (need > m_Size) |
{ |
|
tData *p = new tData[need + ARG_ALLOC + 1]; |
CopyData(p, need+ARG_ALLOC+1); |
if (m_pData) |
delete m_pData; |
m_pData = p; |
m_Size = need + ARG_ALLOC; |
} |
} |
else |
{ |
|
|
|
|
int thresh = ARG_THRESH; |
if (diff < 0) |
thresh = -diff; |
if (m_Count + thresh < m_Size) |
{ |
|
tData *p = new tData[m_Count + thresh + 1]; |
CopyData(p, m_Count + thresh + 1); |
if (m_pData) |
delete m_pData; |
m_pData = p; |
m_Size = m_Count + thresh; |
} |
} |
|
return TRUE; |
} |
|
|
BOOL CArgList::Exists(const char *item) |
{ |
int ret = FALSE; |
int i; |
|
for (i=0; i<m_Count; i++) |
{ |
if (strcmp(m_pData[i], item) == 0) |
{ |
ret = TRUE; |
break; |
} |
} |
|
return ret; |
} |
|
|
BOOL CArgList::Add(const char *item) |
{ |
ReSize(1); |
|
int len = strlen(item); |
char *p = new char[len+1]; |
|
strcpy(p, item); |
m_pData[m_Count++] = p; |
|
return TRUE; |
} |
|
|
BOOL CArgList::AddIfNew(const char *item) |
{ |
if (Exists(item)) |
return TRUE; |
|
return Add(item); |
} |
|
|
BOOL CArgList::Remove(const char *item) |
{ |
int ret = FALSE; |
int i; |
|
for (i=0; i<m_Count; i++) |
{ |
if (strcmp(m_pData[i], item) == 0) |
{ |
delete m_pData[i]; |
|
|
for (int j=i+1; j<=m_Count; j++) |
m_pData[j-1] = m_pData[j]; |
|
m_Count--; |
|
ret = TRUE; |
break; |
} |
} |
|
ReSize(0); |
|
return ret; |
} |
|
|
|
|
|
|
|
|
|
|
|
CCmdLine::CCmdLine() |
: m_SelfTestDir("data\\test"), m_LogDir("..\\logs"), |
m_ConfigDir("..\\configurations") |
{ |
m_bPreloaded = FALSE; |
m_bParseFinished = FALSE; |
|
m_bInstall = FALSE; |
m_bRemove = FALSE; |
m_bOnce = FALSE; |
m_bHelp = FALSE; |
m_bVersion = FALSE; |
m_bPassHelp = FALSE; |
m_bKeepMysql = FALSE; |
m_bMsdev = FALSE; |
m_bCheckVersion = TRUE; |
|
m_iVerbose = 1; |
|
m_iDebug = -1; |
|
} |
|
CCmdLine::~CCmdLine() |
{ |
} |
|
|
|
static BOOL does_match(char *s, char *p) |
{ |
for (; *p; p++) |
{ |
switch (*p) |
{ |
case '?': |
if(!*s++) return 0; |
break; |
|
case '*': |
p++; |
if (!*p) return 1; |
|
for (; *s; s++) |
if (does_match(s, p)) |
return 1; |
|
return 0; |
|
default: |
if(!*s || |
*p != *s) return 0; |
s++; |
} |
} |
|
return *s==0; |
} |
|
|
|
|
|
|
|
|
|
|
|
BOOL CCmdLine::Match(char *s, char *pattern, char *delim, char **value) |
{ |
BOOL ret = FALSE; |
if (does_match(s, pattern)) |
{ |
if (delim && value) |
{ |
*value = strpbrk(s, delim); |
if (*value != NULL) |
{ |
(*value)++; |
ret = TRUE; |
} |
} |
else |
ret = TRUE; |
} |
|
return ret; |
} |
|
|
void CCmdLine::OutputLineFmt(HANDLE out, char *pFormat, ...) |
{ |
TCHAR chMsg[1024]; |
va_list pArg; |
|
va_start(pArg, pFormat); |
_vstprintf(chMsg, pFormat, pArg); |
va_end(pArg); |
|
OutputLine(out, chMsg); |
} |
|
|
void CCmdLine::OutputLine(HANDLE out, char *line) |
{ |
CONSOLE_SCREEN_BUFFER_INFO csbiInfo; |
WORD wOldColorAttrs; |
DWORD cWritten; |
|
if (GetConsoleScreenBufferInfo(out, &csbiInfo)) |
wOldColorAttrs = csbiInfo.wAttributes; |
else |
wOldColorAttrs = 0; |
|
while (line && *line) |
{ |
if (*line == '.' && line[1] && line[1] == 'B') |
{ |
SetConsoleTextAttribute(out, wOldColorAttrs | FOREGROUND_INTENSITY); |
|
line += 2; |
continue; |
} |
if (*line == 'B' && line[1] && line[1] == '.') |
{ |
SetConsoleTextAttribute(out, wOldColorAttrs); |
line += 2; |
continue; |
} |
|
WriteFile(out, line, 1, &cWritten, NULL); |
line++; |
} |
|
SetConsoleTextAttribute(out, wOldColorAttrs); |
WriteFile(out, "\r\n", 2, &cWritten, NULL); |
} |
|
|
void CCmdLine::PrintHelp() |
{ |
char * helptext[] = |
{ |
"", |
"", |
".BThis command will start Roxen CMSB..", |
"", |
"The environment variable .BROXEN_ARGSB. can be used to specify", |
"the default arguments.", |
"", |
" .BArguments:B.", |
"", |
" .B--versionB.: Output version information.", |
"", |
" .B--help -?B.: This information.", |
"", |
" .B--installB.: Register application and install as", |
" an NT service.", |
"", |
" .B--registerB.: Register application.", |
"", |
" .B--removeB.: Remove all registry setting and uninstall", |
" the NT service.", |
"", |
" .B--offlineB.: Indicate that there is no network", |
" connection available. Disables DNS and some", |
" other similar things.", |
"", |
" .B--remove-dumpedB.: Remove all dumped code, thus forcing", |
" a recompile.", |
"", |
" .B--verbose -vB.: Enable more verbose messages.", |
"", |
" .B--quiet -qB.: Disable most of the messages.", |
"", |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"", |
" .B--without-ram-cacheB.: Do not use an in-RAM cache to speed", |
" things up. Saves RAM at the cost of speed.", |
"", |
" .B--without-ram-cache-statB.: Disable the stat that is usually done", |
" for files in the ram cache to ensure that", |
" they are not changed before they are sent.", |
" Improves performance at the cost of constant", |
" aggravation if the site is edited. Useful for", |
" truly static sites.", |
"", |
" .B--with-threadsB.: If threads are available, use them.", |
"", |
" .B--without-threadsB.: Even if threads are enabled by default,", |
" disable them.", |
"", |
" .B--with-profileB.: Store runtime profiling information on", |
" a directory basis. This information is", |
" not saved on permanent storage, it is only", |
" available until the next server restart", |
" This will enable a new 'action' in the", |
" administration interface", |
"", |
" .B--with-file-profileB.: Like .B--with-profileB., but save information", |
" for each and every file.", |
"", |
" .B--self-testB.: Runs a testsuite.", |
" .B--self-test-verboseB.: Runs a testsuite, report all tests.", |
|
" .B--self-test-dir=DIRB.: Use this self test directory instead of", |
" the default .Bdata/testB. directory.", |
"", |
" .B--onceB.: Run the server only once, in the foreground.", |
" This is very useful when debugging.", |
" Implies --module-debug.", |
"", |
" .B--keep-mysqlB.: Don't shut down MySQL process when exiting", |
" the start script. Useful during development", |
" or any other scenario where the start script", |
" is frequently terminated.", |
"", |
|
|
|
|
|
|
|
|
"", |
" .B--programB.: Start a different program with the roxen", |
" Pike.", |
"", |
" .B--with-debugB.: Enable debug", |
"", |
" .B--without-debugB.: Disable all debug. This is the default.", |
"", |
" .B--module-debugB.: Enable more internal debug checks to", |
" simplify debugging of Roxen modules.", |
"", |
" .B--fd-debugB.: Enable FD debug.", |
"", |
" .B--dump-debugB.: Enable dump debug.", |
"", |
|
|
|
|
|
|
|
|
|
|
|
|
" .B--with-snmp-agentB.: Enable internal SNMP agent code.", |
"", |
" .BArguments passed to pike:B.", |
"", |
" .B-DDEFINEB.: Define the symbol .BDEFINEB..", |
"", |
" .B-d<level>B.: Set the runtime Pike debug to level.", |
" This only works if Pike is compiled", |
" with debug (i.e. with --rtl-debug to", |
" configure).", |
"", |
" .B-rtB.: Enable runtime typechecking.", |
" Things will run more slowly, but it is very", |
" useful while developing code.", |
"", |
" Enabled when starting roxen with --debug", |
"", |
" .B-rTB.: Enable strict types.", |
" Same as adding #pragma strict-types", |
" to all files.", |
"", |
" This enables more strict", |
" type-checking, things that are", |
" normally permitted (such as calling", |
" a mixed value, or assigning a typed", |
" object variable with an untyped", |
" object) will generate warnings.", |
"", |
" Useful for module and roxen core", |
" developers, but not so useful for", |
" the occasional pike-script-writer.", |
"", |
" Enabled when starting roxen with --debug", |
"", |
" .B-s<size>B.: Set the stack size.", |
"", |
" .B-M<path>B.: Add the path to the Pike module path.", |
"", |
" .B-I<path>B.: Add the path to the Pike include path.", |
"", |
" .B-P<path>B.: Add the path to the Pike program path.", |
"", |
" .B-dtB.: Turn off tail recursion optimization.", |
"", |
" .B-tB.: Turn on Pike level tracing.", |
"", |
" .B-t<level>B.: Turn on more Pike tracing. This only", |
" works if Pike is compiled with debug", |
" (i.e. with --rtl-debug to configure).", |
"", |
" .B-a<level>B.: Turn on Pike assembler debug. This only", |
" works if Pike is compiled with debug", |
" (i.e. with --rtl-debug to configure).", |
"", |
" .B-wB.: Turn on Pike warnings.", |
"", |
" .BEnvironment variables:B.", |
"", |
" .BLANGB.: Used to determine the default locale", |
" in the administration interface and logs.", |
|
|
|
|
" .BROXEN_LANGB.: The default language for all language", |
" related tags. Defaults to 'en' for english.", |
|
|
NULL |
}; |
|
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); |
int i = 0; |
while (helptext[i] != NULL) |
{ |
OutputLine(hOut, helptext[i]); |
i++; |
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define NULCHAR _T('\0') |
#define SPACECHAR _T(' ') |
#define TABCHAR _T('\t') |
#define DQUOTECHAR _T('\"') |
#define SLASHCHAR _T('\\') |
|
void CCmdLine::SplitCmdline( |
_TSCHAR *cmdstart, |
_TSCHAR **argv, |
_TSCHAR *args, |
int *numargs, |
int *numchars |
) |
{ |
_TSCHAR *p; |
_TUCHAR c; |
int inquote; |
int copychar; |
unsigned numslash; |
|
*numchars = 0; |
*numargs = 1; |
|
|
p = cmdstart; |
if (argv) |
*argv++ = args; |
|
#ifdef WILDCARD |
|
it's first character before quote handling. This is done |
so _[w]cwild() knows whether to expand an entry or not. */ |
if (args) |
*args++ = *p; |
++*numchars; |
|
#endif /* WILDCARD */ |
|
|
|
|
|
|
|
|
if ( *p == DQUOTECHAR ) { |
|
|
while ( (*(++p) != DQUOTECHAR) && (*p != NULCHAR) ) { |
|
#ifdef _MBCS |
if (_ismbblead(*p)) { |
++*numchars; |
if ( args ) |
*args++ = *p++; |
} |
#endif /* _MBCS */ |
++*numchars; |
if ( args ) |
*args++ = *p; |
} |
|
++*numchars; |
if ( args ) |
*args++ = NULCHAR; |
|
|
if ( *p == DQUOTECHAR ) |
p++; |
} |
else { |
|
do { |
++*numchars; |
if (args) |
*args++ = *p; |
|
c = (_TUCHAR) *p++; |
#ifdef _MBCS |
if (_ismbblead(c)) { |
++*numchars; |
if (args) |
*args++ = *p; |
p++; |
} |
#endif /* _MBCS */ |
|
} while ( c != SPACECHAR && c != NULCHAR && c != TABCHAR ); |
|
if ( c == NULCHAR ) { |
p--; |
} else { |
if (args) |
*(args-1) = NULCHAR; |
} |
} |
|
inquote = 0; |
|
|
for(;;) { |
|
if ( *p ) { |
while (*p == SPACECHAR || *p == TABCHAR) |
++p; |
} |
|
if (*p == NULCHAR) |
break; |
|
|
if (argv) |
*argv++ = args; |
++*numargs; |
|
#ifdef WILDCARD |
|
it's first character before quote handling. This is done |
so _[w]cwild() knows whether to expand an entry or not. */ |
if (args) |
*args++ = *p; |
++*numchars; |
|
#endif /* WILDCARD */ |
|
|
for (;;) { |
copychar = 1; |
|
|
|
numslash = 0; |
while (*p == SLASHCHAR) { |
|
++p; |
++numslash; |
} |
if (*p == DQUOTECHAR) { |
|
|
if (numslash % 2 == 0) { |
if (inquote) { |
if (p[1] == DQUOTECHAR) |
p++; |
else |
copychar = 0; |
} else |
copychar = 0; |
|
inquote = !inquote; |
} |
numslash /= 2; |
} |
|
|
while (numslash--) { |
if (args) |
*args++ = SLASHCHAR; |
++*numchars; |
} |
|
|
if (*p == NULCHAR || (!inquote && (*p == SPACECHAR || *p == TABCHAR))) |
break; |
|
|
#ifdef _MBCS |
if (copychar) { |
if (args) { |
if (_ismbblead(*p)) { |
*args++ = *p++; |
++*numchars; |
} |
*args++ = *p; |
} else { |
if (_ismbblead(*p)) { |
++p; |
++*numchars; |
} |
} |
++*numchars; |
} |
++p; |
#else /* _MBCS */ |
if (copychar) { |
if (args) |
*args++ = *p; |
++*numchars; |
} |
++p; |
#endif /* _MBCS */ |
} |
|
|
|
if (args) |
*args++ = NULCHAR; |
++*numchars; |
} |
|
|
if (argv) |
*argv++ = NULL; |
++*numargs; |
} |
|
|
|
|
|
|
|
int CCmdLine::ParseArg(int argc, char *argv[], CCmdLine::tArgType & type) |
{ |
char *value; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Match(*argv, "-install", NULL, NULL) || |
Match(*argv, "--install", NULL, NULL) ) |
{ |
m_bInstall = TRUE; |
m_bCheckVersion = FALSE; |
type = eArgStart; |
return 1; |
} |
|
|
|
if (Match(*argv, "-register", NULL, NULL) || |
Match(*argv, "--register", NULL, NULL) ) |
{ |
m_bRegister = TRUE; |
m_bCheckVersion = FALSE; |
type = eArgStart; |
return 1; |
} |
|
|
|
if (Match(*argv, "-remove", NULL, NULL) || |
Match(*argv, "--remove", NULL, NULL) ) |
{ |
m_bRemove = TRUE; |
m_bCheckVersion = FALSE; |
type = eArgStart; |
return 1; |
} |
|
|
|
if (Match(*argv, "-D*", NULL, NULL)) |
{ |
m_saPikeDefines.Add(*argv); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "-l*", NULL, NULL)) |
{ |
m_saPikeArgs.Add(*argv); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--log-dir=*", "=", &value)) |
{ |
|
type = eArgUnsupported; |
return 1; |
} |
|
|
|
if (Match(*argv, "--debug-log=*", "=", &value)) |
{ |
|
type = eArgUnsupported; |
return 1; |
} |
|
|
|
|
if (Match(*argv, "--config-dir=*", "=", &value)) |
{ |
|
type = eArgUnsupported; |
return 1; |
} |
|
|
|
|
|
|
|
if (Match(*argv, "--with-security", NULL, NULL) || |
Match(*argv, "--enable-security", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DSECURITY"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--with-snmp-agent", NULL, NULL) || |
Match(*argv, "--enable-snmp-agent", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DSNMP_AGENT"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--debug", NULL, NULL) || |
Match(*argv, "--with-debug", NULL, NULL) || |
Match(*argv, "--enable-debug", NULL, NULL) ) |
{ |
m_iDebug = 1; |
type = eArgDebug; |
return 1; |
} |
|
|
|
if (Match(*argv, "--without-debug", NULL, NULL)) |
{ |
m_iDebug = -1; |
type = eArgNoDebug; |
return 1; |
} |
|
|
|
if (Match(*argv, "--module-debug", NULL, NULL) || |
Match(*argv, "--with-module-debug", NULL, NULL) || |
Match(*argv, "--enable-module-debug", NULL, NULL) ) |
{ |
m_iDebug = 0; |
type = eArgDebug; |
return 1; |
} |
|
|
|
if (Match(*argv, "--fd-debug", NULL, NULL) || |
Match(*argv, "--with-fd-debug", NULL, NULL) || |
Match(*argv, "--enable-fd-debug", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DFD_DEBUG"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--offline", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DNO_DNS"); |
m_saPikeDefines.Add("-DOFFLINE"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--without-ram-cache", NULL, NULL) || |
Match(*argv, "--disable-ram-cache", NULL, NULL) ) |
{ |
m_saPikeDefines.Remove("-DRAM_CACHE"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--without-ram-cache-stat", NULL, NULL) || |
Match(*argv, "--disable-ram-cache-stat", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DRAM_CACHE_ASUME_STATIC_CONTENT"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--dump-debug", NULL, NULL) || |
Match(*argv, "--with-dump-debug", NULL, NULL) || |
Match(*argv, "--enable-dump-debug", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DDUMP_DEBUG"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--threads", NULL, NULL) || |
Match(*argv, "--with-threads", NULL, NULL) || |
Match(*argv, "--enable-threads", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DENABLE_THREADS"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--no-threads", NULL, NULL) || |
Match(*argv, "--without-threads", NULL, NULL) || |
Match(*argv, "--disable-threads", NULL, NULL) ) |
{ |
m_saPikeDefines.Remove("-DENABLE_THREADS"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--profile", NULL, NULL) || |
Match(*argv, "--with-profile", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DPROFILE"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "--file-profile", NULL, NULL) || |
Match(*argv, "--with-file-profile", NULL, NULL) ) |
{ |
m_saPikeDefines.Add("-DFILE_PROFILE"); |
type = eArgPike; |
return 1; |
} |
|
|
|
if (Match(*argv, "-q", NULL, NULL) || |
Match(*argv, "--quiet", NULL, NULL) ) |
{ |
m_iVerbose = 0; |
m_saRoxenArgs.Add("--quiet"); |
type = eArgStart; |
return 1; |
} |
|
|
|
|
if (Match(*argv, "-v", NULL, NULL) || |
Match(*argv, "--verbose", NULL, NULL) ) |
{ |
m_iVerbose = 2; |
m_iDebug = 1; |
type = eArgStart; |
return 1; |
} |
|
|
|
if (Match(*argv, "--remove-dumped", NULL, NULL) ) |
{ |
m_saRoxenArgs.Add(*argv); |
type = eArgRoxen; |
return 1; |
} |
|
|
|
if (Match(*argv, "--once", NULL, NULL) ) |
{ |
m_bOnce = TRUE; |
m_iDebug = max(m_iDebug, 0); |
type = eArgStart; |
return 1; |
} |
|
|
|
|
|
if (Match(*argv, "--onve", NULL, NULL) || |
Match(*argv, "--onec", NULL, NULL) || |
Match(*argv, "--onev", NULL, NULL) ) |
{ |
m_bOnce = TRUE; |
m_iDebug = max(m_iDebug, 0); |
type = eArgStart; |
return 1; |
} |
|
|
|
if (Match(*argv, "--keep-mysql", NULL, NULL) ) |
{ |
m_bKeepMysql = TRUE; |
type = eArgStart; |
return 1; |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Match(*argv, "--program", NULL, NULL) ) |
{ |
if (argc > 1) |
{ |
int count; |
for (count=0; count<argc; count++) |
m_saRoxenArgs.Add(argv[count]); |
m_bOnce = TRUE; |
m_bPassHelp = TRUE; |
m_bKeepMysql = TRUE; |
m_bCheckVersion = FALSE; |
type = eArgNtLoader; |
return count; |
} |
else |
{ |
type = eArgMoreData; |
return 1; |
} |
} |
|
|
|
|
|
|
|
if (Match(*argv, "--cd", NULL, NULL) ) |
{ |
if (argc > 1) |
{ |
m_saRoxenArgs.Add(*argv); |
m_saRoxenArgs.Add(argv[1]); |
m_bOnce = TRUE; |
type = eArgNtLoader; |
return 2; |
} |
else |
{ |
type = eArgMoreData; |
return 1; |
} |
} |
|
|
|
|
if (Match(*argv, "--debug-without=*", NULL, NULL) || |
Match(*argv, "-r*", NULL, NULL) || |
Match(*argv, "-d*", NULL, NULL) || |
Match(*argv, "-t*", NULL, NULL) || |
Match(*argv, "-l*", NULL, NULL) || |
Match(*argv, "-w*", NULL, NULL) || |
Match(*argv, "-p*", NULL, NULL) || |
Match(*argv, "-a*", NULL, NULL) || |
Match(*argv, "--*-debug*", NULL, NULL) ) |
{ |
m_saPikeArgs.Add(*argv); |
type = eArgPike; |
return 1; |
} |
|
|
|
|
if (Match(*argv, "-D*", NULL, NULL) || |
Match(*argv, "-M*", NULL, NULL) || |
Match(*argv, "-I*", NULL, NULL) || |
Match(*argv, "-P*", NULL, NULL) ) |
{ |
m_saPikeDefines.Add(*argv); |
type = eArgPike; |
return 1; |
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
if (Match(*argv, "--version", NULL, NULL)) |
{ |
if (m_bPassHelp) |
{ |
m_saRoxenArgs.Add(*argv); |
type = eArgRoxen; |
} |
else |
{ |
m_bCheckVersion = FALSE; |
m_bVersion = TRUE; |
type = eArgVersion; |
} |
return 1; |
} |
|
|
|
if (Match(*argv, "--self-test", NULL, NULL)) |
{ |
type = eArgSelfTest; |
return 1; |
} |
|
|
|
|
|
|
if (Match(*argv, "--self-test-quiet", NULL, NULL)) |
{ |
|
|
type = eArgUnsupported; |
return 1; |
} |
|
|
|
|
if (Match(*argv, "--self-test-verbose", NULL, NULL)) |
{ |
m_saRoxenArgs.Add("--tests-verbose=1"); |
type = eArgSelfTest; |
return 1; |
} |
|
|
|
if (Match(*argv, "--self-test-dir=*", "=", &value)) |
{ |
m_SelfTestDir.resize(strlen(value)); |
for (int i=0; i<strlen(value); i++) |
{ |
if (value[i] == '/') |
m_SelfTestDir[i] = '\\'; |
else |
m_SelfTestDir[i] = value[i]; |
} |
type = eArgStart; |
return 1; |
} |
|
|
if (Match(*argv, "--help", NULL, NULL) || |
Match(*argv, "-?", NULL, NULL) ) |
{ |
if (m_bPassHelp) |
{ |
m_saRoxenArgs.Add(*argv); |
type = eArgRoxen; |
} |
else |
{ |
m_bCheckVersion = FALSE; |
m_bHelp = TRUE; |
type = eArgHelp; |
} |
return 1; |
} |
|
|
|
m_saRoxenArgs.Add(*argv); |
type = eArgRoxen; |
return 1; |
} |
|
|
|
void CCmdLine::ParseFinish() |
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (m_bParseFinished) |
return; |
|
|
m_bParseFinished = TRUE; |
|
if (m_iDebug == 0) |
{ |
m_saPikeDefines.AddIfNew("-DMODULE_DEBUG"); |
m_saPikeArgs.AddIfNew("-w"); |
} |
else if (m_iDebug == -1) |
{ |
} |
else if (m_iDebug == 1) |
{ |
m_saPikeDefines.AddIfNew("-DDEBUG"); |
m_saPikeDefines.AddIfNew("-DMODULE_DEBUG"); |
m_saPikeArgs.AddIfNew("-w"); |
} |
|
|
if (m_bCheckVersion) |
{ |
if (CRoxen::CheckVersionChange()) |
{ |
m_saRoxenArgs.AddIfNew("--remove-dumped"); |
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); |
if (m_iVerbose >= 1) |
OutputLine(hOut, " : Removing old precompiled files (defines or pike version changed)"); |
} |
} |
} |
|
|
BOOL CCmdLine::Parse(char * cmdline) |
{ |
int numargs; |
int numchars; |
|
SplitCmdline((_TSCHAR *)cmdline, NULL, NULL, &numargs, &numchars); |
|
_TSCHAR *p = new _TSCHAR[numargs * sizeof(_TSCHAR *) + numchars * sizeof(_TSCHAR)]; |
|
SplitCmdline((_TSCHAR *)cmdline, (_TSCHAR **)p, p + numargs * sizeof(char *), &numargs, &numchars); |
|
int ret = Parse(numargs-1, (char **)p); |
|
delete p; |
|
return ret; |
} |
|
|
BOOL CCmdLine::Parse(int argc, char *argv[]) |
{ |
BOOL ret = TRUE; |
tArgType type; |
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); |
int i; |
|
if (!m_bPreloaded) |
{ |
|
i = 0; |
while (defPikeArgs[i] != NULL) |
{ |
m_saPikeArgs.Add(defPikeArgs[i]); |
i++; |
} |
|
i = 0; |
while (defPikeDefines[i] != NULL) |
{ |
m_saPikeDefines.Add(defPikeDefines[i]); |
i++; |
} |
|
i = 0; |
while (defRoxenArgs[i] != NULL) |
{ |
m_saRoxenArgs.Add(defRoxenArgs[i]); |
i++; |
} |
m_bPreloaded = TRUE; |
} |
|
|
i = 1; |
while (i < argc && ret) |
{ |
int numParsed = ParseArg(argc-i, &argv[i], type); |
|
switch (type) |
{ |
case eArgStart: |
|
|
break; |
|
case eArgNtLoader: |
|
|
break; |
|
case eArgPike: |
|
|
break; |
|
case eArgRoxen: |
|
|
break; |
|
case eArgDebug: |
|
|
break; |
|
case eArgNoDebug: |
|
|
break; |
|
case eArgVersion: |
|
|
break; |
|
case eArgSelfTest: |
{ |
|
CreateDirectory("..\\var", NULL); |
|
std::string selfTestDirUnx; |
selfTestDirUnx.resize(m_SelfTestDir.length()); |
for (int i=0; i<m_SelfTestDir.length(); i++) |
{ |
if (m_SelfTestDir[i] == '\\') |
selfTestDirUnx[i] = '/'; |
else |
selfTestDirUnx[i] = m_SelfTestDir[i]; |
} |
|
|
|
|
|
|
|
|
m_saPikeArgs.Add("-DRUN_SELF_TEST"); |
m_saPikeArgs.Add(("-DSELF_TEST_DIR=\\\"" + selfTestDirUnx + "\\\"").c_str()); |
|
m_bOnce = TRUE; |
m_iDebug = max(m_iDebug, 1); |
m_ConfigDir = "../var/test_config"; |
m_saRoxenArgs.Add(("--config-dir=" + m_ConfigDir).c_str()); |
m_saRoxenArgs.Add("--remove-dumped"); |
|
|
KillMySql(m_ConfigDir.c_str()); |
|
SetEnvironmentVariable("COPYCMD", "/Y"); |
system("rmdir /Q /S ..\\var\\test_config >NUL:"); |
|
std::string setupCmd = m_SelfTestDir + "\\scripts\\setup.pike"; |
DWORD attr = GetFileAttributes(setupCmd.c_str()); |
if (attr != -1 && !(attr & FILE_ATTRIBUTE_DIRECTORY)) |
{ |
setupCmd += " " + selfTestDirUnx + " ../var"; |
CRoxen::RunPike(setupCmd.c_str()); |
} |
|
} |
|
break; |
|
case eArgHelp: |
|
|
break; |
|
|
case eArgMoreData: |
ret = FALSE; |
OutputLineFmt(hOut, ".BArgument requires more data: %sB.", argv[i]); |
break; |
|
|
case eArgUnsupported: |
OutputLineFmt(hOut, ".BArgument not supported: %sB.", argv[i]); |
break; |
|
|
default: |
OutputLineFmt(hOut, ".BInternal Error: default case hit with: %sB.", argv[i]); |
break; |
|
} |
|
i += numParsed; |
} |
|
|
return ret; |
} |
|
|
|