Example #1
0
STDMETHODIMP CTextLexer::SetInput (PCWSTR pszInput, long iLen)
{
    HRESULT     hr;

    // Release anything we already have
    if (m_pszInput != NULL)
        VSFree (m_pszInput);
    for (long i=0; i<m_arrayTokens.Count(); i++)
    {
        if (m_arrayTokens[i].HasOverhead()) {
            VSFree (m_arrayTokens[i].Overhead());
        }
    }
    m_arrayTokens.ClearAll();
    m_arrayLines.ClearAll();
    m_fTokenized = FALSE;
    m_hr = S_OK;

    // If iLen is -1, use the null-terminated length
    if (iLen == -1)
        iLen = (long)wcslen (pszInput);

    // Copy the text, ensuring that it's null-terminated
    m_pszInput = (PWSTR)VSAlloc ((iLen + 1) * sizeof (WCHAR));
    if (m_pszInput == NULL)
        return E_OUTOFMEMORY;

    memcpy (m_pszInput, pszInput, iLen * sizeof (WCHAR));
    m_pszInput[iLen] = 0;

    long    *piLine;

    // Establish the first entry in the line table
    if (FAILED (hr = m_arrayLines.Add (NULL, &piLine)))
        return hr;

    *piLine = 0;

    // Start the input stream for tokenization
    m_pszCurrent = m_pszCurLine = m_pszInput;
    m_iCurLine = 0;

    TOKENID     tok = TID_INVALID;
    CSTOKEN     *pToken;

    // Scan the text
    while (tok != TID_ENDFILE && !FAILED (m_hr))
    {
        if (FAILED (hr = m_arrayTokens.Add (NULL, &pToken)))
            return hr;

        tok = ScanToken (pToken);
    }

    // That's it!  If we didn't fail, signal ourselves as being tokenized
    if (!FAILED (m_hr))
        m_fTokenized = TRUE;

    return m_hr;
}
Example #2
0
void *CTextLexer::TokenMemAlloc (CSTOKEN *pToken, size_t iSize)
{
    // Each token for which extra space is allocated must be (is) placed in our
    // array of tokens, which we are responsible for cleaning up during our
    // destruction.
    return VSAlloc (iSize);
}
//
// Search the binary tree and add the given string
// return true if it was added or false if it already
// exists
//
HRESULT ConsoleArgs::TreeAdd(b_tree **root, LPCWSTR add)
{
    // Special case - init the tree if it
    // doesn't already exist
    if (*root == NULL) {
        *root = MakeLeaf(add);
        return *root == NULL ? E_OUTOFMEMORY : S_OK;
    }

    size_t name_len = wcslen(add)+1;
    LPWSTR szCopy = (LPWSTR)VSAlloc(name_len * sizeof(WCHAR));

    if (!szCopy) {
        m_output->ShowErrorId (FTL_NoMemory, ERROR_FATAL);
        return NULL;
    }

    HRESULT hr = StringCchCopyW (szCopy, name_len, add);
    ASSERT (SUCCEEDED (hr));

    // otherwise, just let the template do the work
    hr = (*root)->Add(szCopy, _wcsicmp);

    if (hr != S_OK) // S_FALSE means it already existed
        VSFree(szCopy);

    return hr;
}
// Copy an argument list into an argv array. The argv array is allocated, the
// arguments themselves are not allocated -- just pointer copied.
bool ConsoleArgs::GetArgs( int * pargc, WCBuffer ** pargv)
{
    LPWSTR cmdLine = GetCommandLineW();
    *pargc = 0;
    *pargv = NULL;
    
    TextToArgs(cmdLine, &m_listArgs);
    if (m_output->HadFatalError())
        return false;

    if (m_listArgs) { // make prefix happy...
        // Strip the process name
        VSFree(m_listArgs->arg);
        WStrList * listProc = m_listArgs;
        m_listArgs = m_listArgs->next;
        delete listProc;
    }

#ifdef CLIENT_IS_CSC
    // Process '/noconfig', and CSC.CFG, modifying the argument list
    ProcessAutoConfig();
#endif

    // Process Response Files
    ProcessResponseArgs();
    if (m_output->HadError())
        return false;

    // Now convert to an argc/argv form for remaining processing.
    int argc = 0;
    for (WStrList * listCurArg = m_listArgs; listCurArg != NULL; listCurArg = listCurArg->next) {
        if (listCurArg->arg)
            ++argc;
    }

    m_rgArgs = (WCBuffer *)VSAlloc(sizeof(WCBuffer) * (argc));
    if (!m_rgArgs) {
        m_output->ShowErrorId (FTL_NoMemory, ERROR_FATAL);
        return false;       
    }
    int i = 0;
    for (WStrList * listCurArg = m_listArgs; listCurArg != NULL; listCurArg = listCurArg->next) {
        if (listCurArg->arg)
            m_rgArgs[i++] = WCBuffer::CreateFrom(listCurArg->arg);
    }

    *pargc = argc;
    *pargv = m_rgArgs;
    return !m_output->HadError();
}
Example #5
0
void *CScanLexer::TokenMemAlloc (CSTOKEN *pToken, size_t iSize)
{
    if (SizeAdd(iSize, m_iMemUsed) > (size_t)m_iMemSize)
    {
        size_t  iRoundSize = SizeAdd(m_iMemUsed + iSize, 0x100) & ~(size_t)0xff; // Hard-coded growth by 256 byte blocks
        void    *pMem = (m_pTokenMem == NULL) ? VSAlloc (iRoundSize) : VSRealloc (m_pTokenMem, iRoundSize);

        if (pMem == NULL)
            return NULL;

        m_pTokenMem = pMem;
        m_iMemSize = iRoundSize;
    }

    ASSERT (SizeAdd(m_iMemUsed, iSize) <= (size_t)m_iMemSize);
    void    *pRet = ((BYTE *)m_pTokenMem + m_iMemUsed);
    m_iMemUsed += iSize;
    return pRet;
}
//
// Create a simple leaf tree node with the given text
//
b_tree * ConsoleArgs::MakeLeaf(LPCWSTR text)
{
    b_tree * t = NULL;
    size_t name_len = wcslen(text)+1;
    LPWSTR szCopy = (LPWSTR)VSAlloc(name_len * sizeof(WCHAR));

    if (!szCopy) {
        m_output->ShowErrorId (FTL_NoMemory, ERROR_FATAL);
        return NULL;
    }

    HRESULT hr; hr = StringCchCopyW (szCopy, name_len, text);
    ASSERT (SUCCEEDED (hr));

    t = new b_tree(szCopy);
    if (!t) {
        VSFree(szCopy);
        m_output->ShowErrorId (FTL_NoMemory, ERROR_FATAL);
        return NULL;
    }
    return t;
}
Example #7
0
void CStringBuilder::Append (PCWSTR pszText, size_t iLen)
{
    // Do nothing if we've already failed
    if (FAILED (m_hr))
        return;

    // If -1, use nul to determine length
    if (iLen == (size_t)-1)
        iLen = wcslen (pszText);

    // Determine new size and reallocate if necessary
    size_t      iReqSize = (m_iLen + iLen + m_iAllocSize) & (~(m_iAllocSize -1));

    if (m_pszText == m_szBuf)
    {
        if (iReqSize > (sizeof (m_szBuf) / sizeof (m_szBuf[0])))
        {
            // The size needed is bigger than our static buffer.  Time to allocate
            // the dynamic buffer for the first time
            m_pszText = (PWSTR)VSAlloc (iReqSize * sizeof (WCHAR));
            if (m_pszText == NULL)
            {
                m_hr = E_OUTOFMEMORY;
                m_pszText = m_szBuf;
                return;
            }

            // Copy the current text
            wcscpy (m_pszText, m_szBuf);

            // Keep our current pointer current...
            m_pszCur = m_pszText + m_iLen;
            ASSERT (m_pszCur[0] == 0);
        }
        else
        {
            // Do nothing -- the text will fit in our static buffer.
        }
    }
    else if (iReqSize != ((m_iLen + m_iAllocSize) & (~(m_iAllocSize - 1))))
    {
        // See if we need to increase our allocation size
        if (iReqSize >= 0x10000 && m_iAllocSize < 0x10000)
        {
            m_iAllocSize = 0x10000;
            iReqSize = ((m_iLen + iLen + m_iAllocSize) & (~(m_iAllocSize - 1)));
        }
        else if (iReqSize >= 0x1000 && m_iAllocSize < 0x1000)
        {
            m_iAllocSize = 0x1000;
            iReqSize = ((m_iLen + iLen + m_iAllocSize) & (~(m_iAllocSize - 1)));
        }

        // Need to grow
        PWSTR   pszNewText = (PWSTR)VSRealloc (m_pszText, iReqSize * sizeof (WCHAR));
        if (pszNewText == NULL)
        {
            m_hr = E_OUTOFMEMORY;
            return;
        }
        m_pszText = pszNewText;

        // Keep our current pointer current...
        m_pszCur = m_pszText + m_iLen;
        ASSERT (m_pszCur[0] == 0);
    }

    ASSERT (iReqSize > m_iLen + iLen);

    // Copy incoming text to end of buffer.
    wcsncpy (m_pszCur, pszText, iLen);
    m_iLen += iLen;
    m_pszCur += iLen;
    m_pszCur[0] = 0;
}
//
// Process Auto Config options:
// #1 search for '/noconfig'
// if not present and csc.cfg exists in EXE dir, inject after env var stuff
//
void ConsoleArgs::ProcessAutoConfig()
{
    bool fFoundNoConfig = false;

    // Scan the argument list for the "/noconfig" options. If present, just kill it and bail.
    for (WStrList * listArgCur = m_listArgs; listArgCur; listArgCur = listArgCur->next)
    {
        // Skip everything except options
        WCHAR * szArg = listArgCur->arg;
        if (szArg == NULL || (szArg[0] != '/' && szArg[0] != '-'))
            continue;

        if (_wcsicmp(szArg + 1, L"noconfig") == 0) {
            listArgCur->arg = NULL;
            VSFree(szArg);
            // We found it, empty it but keep checking in case they specified it twice
            fFoundNoConfig = true;
        }
    }

    if (fFoundNoConfig)
        return;

    // If we got here it means there was no '/noconfig'
    WCHAR szPath[MAX_PATH];
    if (W_IsUnicodeSystem()) {
        if(!GetModuleFileNameW(NULL, szPath, lengthof(szPath)))
            szPath[0] = 0;
    } else {
        CHAR szTemp[MAX_PATH];
        if (!GetModuleFileNameA(NULL, szTemp, lengthof(szTemp)) ||
            !MultiByteToWideChar( AreFileApisANSI() ? CP_ACP : CP_OEMCP,
                0, szTemp, -1, szPath, lengthof(szPath)))
            szPath[0] = 0;
    }
    if (*szPath && PathRemoveFileSpecW(szPath) &&
        PathAppendW(szPath, L"csc.rsp")) {

        if (W_Access( szPath, 4) == 0) { 
            // We know the file exists and that we have read access
            // so add into the list
            size_t cchLen = wcslen(szPath) + 2; // +2 for @ and terminator
            WCHAR * szPathCopy = (WCHAR*)VSAlloc( sizeof(WCHAR) * cchLen);
            if (!szPathCopy || FAILED(StringCchCopyW(szPathCopy + 1, cchLen, szPath))) {
                VSFAIL("The string changed size, or our pointers got messed up");
                m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
                return;
            }
            szPathCopy[0] = L'@';

            WStrList * listArgNew = new WStrList( szPathCopy, m_listArgs);
            if (!listArgNew) {
                VSFree(szPathCopy);
                m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
                return;
            }

            m_listArgs = listArgNew;
        }
    }
}
//
// Parse the text into a list of argument
// return the total count 
// and set 'args' to point to the last list element's 'next'
// This function assumes the text is NULL terminated
//
void ConsoleArgs::TextToArgs(LPCWSTR szText, WStrList ** listReplace)
{
    WStrList **argLast;
    const WCHAR *pCur;
    size_t iSlash;
    int iCount;

    argLast = listReplace;
    pCur = szText;
    iCount = 0;

    // Guaranteed that all tokens are no bigger than the entire file.
    LPWSTR szTemp = (LPWSTR)VSAlloc(sizeof(WCHAR) * (wcslen(szText) + 1));
    if (!szTemp) {
        m_output->ShowErrorId (FTL_NoMemory, ERROR_FATAL);
        return;
    }
    while (*pCur != '\0')
    {
        WCHAR *pPut, *pFirst, *pLast;
        WCHAR chIllegal;

LEADINGWHITE:
        while (IsWhitespace( *pCur) && *pCur != '\0')
            pCur++;

        if (*pCur == '\0')
            break;
        else if (*pCur == L'#')
        {
            while ( *pCur != '\0' && *pCur != '\n')
                pCur++; // Skip to end of line
            goto LEADINGWHITE;
        }

        int cQuotes = 0;
        pPut = pFirst = szTemp;
        chIllegal = 0;
        while ((!IsWhitespace( *pCur) || !!(cQuotes & 1)) && *pCur != '\0')
        {
            switch (*pCur)
            {
                // All this weird slash stuff follows the standard argument processing routines
            case L'\\':
                iSlash = 0;
                // Copy and advance while counting slashes
                while (*pCur == L'\\') {
                    *pPut++ = *pCur++;
                    iSlash++;
                }

                // Slashes not followed by a quote character don't matter now
                if (*pCur != L'\"')
                    break;

                // If there's an odd count of slashes, it's escaping the quote
                // Otherwise the quote is a quote
                if ((iSlash & 1) == 0) {
                    ++cQuotes;
                }
                *pPut++ = *pCur++;
                break;

            case L'\"':
                ++cQuotes;
                *pPut++ = *pCur++;
                break;

            case L'\x01': case L'\x02': case L'\x03': case L'\x04': case L'\x05': case L'\x06': case L'\x07': case L'\x08':
            case L'\x09': case L'\x0A': case L'\x0B': case L'\x0C': case L'\x0D': case L'\x0E': case L'\x0F': case L'\x10':
            case L'\x11': case L'\x12': case L'\x13': case L'\x14': case L'\x15': case L'\x16': case L'\x17': case L'\x18':
            case L'\x19': case L'\x1A': case L'\x1B': case L'\x1C': case L'\x1D': case L'\x1E': case L'\x1F':
            case L'|':
                // Save the first legal character and skip over them
                if (chIllegal == 0)
                    chIllegal = *pCur;
                pCur++;
                break;

            default:
                *pPut++ = *pCur++;  // Copy the char and advance
                break;
            }
        }

        pLast = pPut;
        *pPut++ = '\0';

        // If the string is surrounded by quotes, with no interior quotes, remove them.
        if (cQuotes == 2 && *pFirst == L'\"' && *(pLast - 1) == L'\"') {
            ++pFirst;
            --pLast;
            *pLast = L'\0';
        }

        if (chIllegal != 0) {
            m_output->ShowErrorIdString( ERR_IllegalOptionChar, ERROR_ERROR, chIllegal, pFirst);
        }

        size_t cchLen = pLast - pFirst + 1;
        WCHAR * szArgCopy = (WCHAR*)VSAlloc( sizeof(WCHAR) * cchLen);
        if (!szArgCopy || FAILED(StringCchCopyW(szArgCopy, cchLen, pFirst))) {
            VSFAIL("The string changed size, or our pointers got messed up");
            m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
            break;
        }

        WStrList * listArgNew = new WStrList( szArgCopy, (*argLast));
        if (!listArgNew) {
            m_output->ShowErrorId(FTL_NoMemory, ERROR_FATAL);
            break;
        }

        *argLast = listArgNew;
        argLast = &listArgNew->next;
    }

    VSFree(szTemp);

}