Logo Search packages:      
Sourcecode: kbuild version File versions  Download package

static int kOCEntryCompareFast ( PCKOCENTRY  pEntry  )  [static]

Worker for kOCEntryCompareOldAndNewOutput() that compares the precompiled output using a fast but not very good method.

Returns:
1 if matching, 0 if not matching.
Parameters:
pEntry The entry containing the names of the files to compare. The entry is not updated in any way.

Definition at line 2379 of file kObjCache.c.

References KOCENTRY::KOCENTRYDATA::cbCpp, kOCEntryFindFileStatement(), kOCEntryIsLineStatement(), KOCENTRY::New, NULL, KOCENTRY::Old, and KOCENTRY::KOCENTRYDATA::pszCppMapping.

Referenced by kOCEntryCompareOldAndNewOutput().

{
    const char *        psz1 = pEntry->New.pszCppMapping;
    const char * const  pszEnd1 = psz1 + pEntry->New.cbCpp;
    const char *        psz2 = pEntry->Old.pszCppMapping;
    const char * const  pszEnd2 = psz2 + pEntry->Old.cbCpp;

    assert(*pszEnd1 == '\0');
    assert(*pszEnd2 == '\0');

    /*
     * Iterate block by block and backtrack when we find a difference.
     */
    for (;;)
    {
        size_t cch = pszEnd1 - psz1;
        if (cch > (size_t)(pszEnd2 - psz2))
            cch = pszEnd2 - psz2;
        if (cch > 4096)
            cch = 4096;
        if (    cch
            &&  !memcmp(psz1, psz2, cch))
        {
            /* no differences */
            psz1 += cch;
            psz2 += cch;
        }
        else
        {
            /*
             * Pinpoint the difference exactly and the try find the start
             * of that line. Then skip forward until we find something to
             * work on that isn't spaces, #line statements or closing curly
             * braces.
             *
             * The closing curly braces are ignored because they are frequently
             * found at the end of header files (__END_DECLS) and the worst
             * thing that may happen if it isn't one of these braces we're
             * ignoring is that the final line in a function block is a little
             * bit off in the debug info.
             *
             * Since we might be skipping a few new empty headers, it is
             * possible that we will omit this header from the dependencies
             * when using VCC. This might not be a problem, since it seems
             * we'll have to use the precompiler output to generate the deps
             * anyway.
             */
            const char *psz;
            const char *pszMismatch1;
            const char *pszFile1 = NULL;
            unsigned    iLine1 = 0;
            unsigned    cCurlyBraces1 = 0;
            const char *pszMismatch2;
            const char *pszFile2 = NULL;
            unsigned    iLine2 = 0;
            unsigned    cCurlyBraces2 = 0;

            /* locate the difference. */
            while (cch >= 512 && !memcmp(psz1, psz2, 512))
                psz1 += 512, psz2 += 512, cch -= 512;
            while (cch >= 64 && !memcmp(psz1, psz2, 64))
                psz1 += 64, psz2 += 64, cch -= 64;
            while (*psz1 == *psz2 && cch > 0)
                psz1++, psz2++, cch--;

            /* locate the start of that line. */
            psz = psz1;
            while (     psz > pEntry->New.pszCppMapping
                   &&   psz[-1] != '\n')
                psz--;
            psz2 -= (psz1 - psz);
            pszMismatch2 = psz2;
            pszMismatch1 = psz1 = psz;

            /* Parse the 1st file line by line. */
            while (psz1 < pszEnd1)
            {
                if (*psz1 == '\n')
                {
                    psz1++;
                    iLine1++;
                }
                else
                {
                    psz = psz1;
                    while (isspace(*psz) && *psz != '\n')
                        psz++;
                    if (*psz == '\n')
                    {
                        psz1 = psz + 1;
                        iLine1++;
                    }
                    else if (*psz == '#' && kOCEntryIsLineStatement(psz, &iLine1, &pszFile1))
                    {
                        psz1 = memchr(psz, '\n', pszEnd1 - psz);
                        if (!psz1++)
                            psz1 = pszEnd1;
                    }
                    else if (*psz == '}')
                    {
                        do psz++;
                        while (isspace(*psz) && *psz != '\n');
                        if (*psz == '\n')
                            iLine1++;
                        else if (psz != pszEnd1)
                            break;
                        cCurlyBraces1++;
                        psz1 = psz;
                    }
                    else if (psz == pszEnd1)
                        psz1 = psz;
                    else /* found something that can be compared. */
                        break;
                }
            }

            /* Ditto for the 2nd file. */
            while (psz2 < pszEnd2)
            {
                if (*psz2 == '\n')
                {
                    psz2++;
                    iLine2++;
                }
                else
                {
                    psz = psz2;
                    while (isspace(*psz) && *psz != '\n')
                        psz++;
                    if (*psz == '\n')
                    {
                        psz2 = psz + 1;
                        iLine2++;
                    }
                    else if (*psz == '#' && kOCEntryIsLineStatement(psz, &iLine2, &pszFile2))
                    {
                        psz2 = memchr(psz, '\n', pszEnd2 - psz);
                        if (!psz2++)
                            psz2 = pszEnd2;
                    }
                    else if (*psz == '}')
                    {
                        do psz++;
                        while (isspace(*psz) && *psz != '\n');
                        if (*psz == '\n')
                            iLine2++;
                        else if (psz != pszEnd2)
                            break;
                        cCurlyBraces2++;
                        psz2 = psz;
                    }
                    else if (psz == pszEnd2)
                        psz2 = psz;
                    else /* found something that can be compared. */
                        break;
                }
            }

            /* Match the number of ignored closing curly braces. */
            if (cCurlyBraces1 != cCurlyBraces2)
                return 0;

            /* Reaching the end of any of them means the return statement can decide. */
            if (   psz1 == pszEnd1
                || psz2 == pszEnd2)
                break;

            /* Match the current line. */
            psz = memchr(psz1, '\n', pszEnd1 - psz1);
            if (!psz++)
                psz = pszEnd1;
            cch = psz - psz1;
            if (psz2 + cch > pszEnd2)
                break;
            if (memcmp(psz1, psz2, cch))
                break;

            /* Check that we're at the same location now. */
            if (!pszFile1)
                pszFile1 = kOCEntryFindFileStatement(pszMismatch1, pEntry->New.pszCppMapping, &iLine1);
            if (!pszFile2)
                pszFile2 = kOCEntryFindFileStatement(pszMismatch2, pEntry->Old.pszCppMapping, &iLine2);
            if (pszFile1 && pszFile2)
            {
                if (iLine1 != iLine2)
                    break;
                while (*pszFile1 == *pszFile2 && *pszFile1 != '\n' && *pszFile1)
                    pszFile1++, pszFile2++;
                if (*pszFile1 != *pszFile2)
                    break;
            }
            else if (pszFile1 || pszFile2)
            {
                assert(0); /* this shouldn't happen. */
                break;
            }

            /* Advance. We might now have a misaligned buffer, but that's memcmps problem... */
            psz1 += cch;
            psz2 += cch;
        }
    }

    return psz1 == pszEnd1
        && psz2 == pszEnd2;
}


Generated by  Doxygen 1.6.0   Back to index