bool Run::ParseArgument()

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;
}