in Unix/nits/base/Run.cpp [982:1248]
bool Run::ParseArgument(_In_ char *arg)
{
char *temp = strchr(arg, ':');
char *second = NULL;
if (arg[0] != '-' && arg[0] != '+')
{
/* This is not an option. Must be a test path. */
/* Ignore the colon in drive-letter paths. */
if (temp && (temp[1] == '\\' || temp[1] == '/'))
temp = strchr(temp + 1, ':');
/* New test path format matches WinDBG symbol. */
if (temp == NULL)
temp = strchr(arg, '!');
}
if (temp)
{
*temp = '\0';
second = temp + 1;
}
if (!Strcasecmp(arg, "-localinjection"))
{
if (!ConfigureLocalInjection())
return false;
}
else if (!Strcasecmp(arg, "-bpassert"))
{
m_config.breakAssert = true;
}
else if (!Strcasecmp(arg, "-skipflaky"))
{
m_config.skipFlakyTests = true;
}
else if (!Strcasecmp(arg, "-bpfault"))
{
m_config.breakFault = true;
if (second == NULL)
{
Tprintf(PAL_T("ERROR: 'bpfault' option requires an iteration number!\n"));
return false;
}
m_bpFault->push_back(Strtoul(second, 0, 10));
}
else if (!Strcasecmp(arg, "-file"))
{
//Open file, tokenize, and parse contents.
if (second == NULL)
{
Tprintf(PAL_T("ERROR: 'file' option requires a filename!\n"));
return false;
}
char buf[MAX_PATH];
Strlcpy(buf, second, MAX_PATH);
ifstream file(buf);
if (!file.good())
{
Tprintf(PAL_T("%T%T%T"), PAL_T("ERROR: file '"), second, PAL_T("' could not be loaded!\n"));
return false;
}
while (file.good())
{
char widebuf[MAX_PATH];
memset(buf, 0, sizeof(buf));
file >> buf;
// allow empty lines or commented lines with #
if (buf[0] == '\0' || buf[0] == '#')
continue;
int size = Strlcpy(widebuf, buf, MAX_PATH);
if (size == 0)
{
throw Exception();
}
if (!ParseArgument(widebuf))
return false;
}
}
else if (!Strcasecmp(arg, "-filter"))
{
if (m_binaryFilter)
delete [] m_binaryFilter;
m_binaryFilter = ConvertStringAToPalChar(second);
}
else if (!Strcasecmp(arg, "-match"))
{
if (m_testFilter)
delete [] m_testFilter;
if (!second || (second[0] == '\0'))
{
Tprintf(PAL_T("ERROR: '-match' option requires at least one string to match with!\n"));
return false;
}
m_testFilter = ConvertStringAToPalChar(second);
}
else if (!Strcasecmp(arg, "-install"))
{
if (!InstallInjector())
return false;
}
else if (!Strcasecmp(arg, "-mode"))
{
if (!second)
{
Tprintf(PAL_T("ERROR: 'mode' option requires a mode to be selected!\n"));
return false;
}
else if (!Strcasecmp(second, "Skip"))
{
m_config.mode = NitsTestSkip;
}
else if (!Strcasecmp(second, "Enable"))
{
m_config.mode = NitsTestEnable;
}
else if (!Strcasecmp(second, "IterativeFault"))
{
m_config.mode = NitsTestIterativeFault;
}
else if (!Strcasecmp(second, "StackFault"))
{
m_config.mode = NitsTestStackFault;
}
else if (!Strcasecmp(second, "CompoundFault"))
{
m_config.mode = NitsTestCompoundFault;
}
else
{
Tprintf(PAL_T("ERROR: Invalid value for 'mode' option!\n"));
return false;
}
}
else if (!Strcasecmp(arg, "-pause"))
{
m_pause = true;
}
else if (!Strcasecmp(arg, "-reset"))
{
m_reset = true;
}
else if (!Strcasecmp(arg, "-target"))
{
if (m_binaryTarget)
delete [] m_binaryTarget;
m_binaryTarget = ConvertStringAToPalChar(second);
}
else if (!Strcasecmp(arg, "-trace"))
{
if (!second || !Strcasecmp(second, "Verbose"))
{
m_config.traces = NitsTraceVerbose;
}
else if (!Strcasecmp(second, "FailedTests"))
{
m_config.traces = NitsTraceFailedTests;
}
else if (!Strcasecmp(second, "WarnedTests"))
{
m_config.traces = NitsTraceWarnedTests;
}
else if (!Strcasecmp(second, "AllTests"))
{
m_config.traces = NitsTraceAllTests;
}
else if (!Strcasecmp(second, "Asserts"))
{
m_config.traces = NitsTraceAsserts;
}
else if (!Strcasecmp(second, "Warnings"))
{
m_config.traces = NitsTraceWarnings;
}
else if (!Strcasecmp(second, "Iterations"))
{
m_config.traces = NitsTraceIterations;
}
else
{
Tprintf(PAL_T("ERROR: Invalid value for 'trace' option!\n"));
return false;
}
}
else if (!Strcasecmp(arg, "-uninstall"))
{
RemoveInjector();
}
//V1 compatibility options.
else if (!Strcasecmp(arg, "-assert"))
{
}
else if (!Strcasecmp(arg, "-noassert"))
{
m_config.traces = NitsTraceAllTests;
}
else if (!Strcasecmp(arg, "-child"))
{
m_child = true;
}
else if (!Strcasecmp(arg, "-fault"))
{
m_fault = true;
if (second)
{
m_config.breakFault = true;
m_bpFault->push_back(Strtoul(second, 0, 10));
}
}
else if (!Strcasecmp(arg, "-output"))
{
Tprintf(PAL_T("ERROR: 'output' option is not implemented!\n"));
return false;
}
else if (!Strcasecmp(arg, "-skip"))
{
m_config.mode = NitsTestSkip;
}
else if (!Strcasecmp(arg, "-verbose"))
{
m_config.traces = NitsTraceVerbose;
}
else if (!Strcasecmp(arg, "-noverbose"))
{
}
else if (!Strncmp(arg, "+", Strlen("+")))
{
//Spurious prefast warning.
if (strlen(arg) < 1)
throw Exception();
if ((second == NULL) || (second[0] == '\0'))
{
Tprintf(PAL_T("%T%T%T"), PAL_T("ERROR: Custom argument "), arg, PAL_T(" should be of the form +name:value!\n"));
return false;
}
AddParam(ConvertStringAToPalChar(arg+1), ConvertStringAToPalChar(second));
}
else
{
PAL_Char *palCharArg = ConvertStringAToPalChar(arg);
PAL_Char *palCharSecond = ConvertStringAToPalChar(second);
bool addRunSuccess = AddRun(palCharArg, palCharSecond);
delete [] palCharArg;
delete [] palCharSecond;
//Error message already printed.
if(!addRunSuccess)
return false;
}
return true;
}