VirtualBox

Changeset 98380 in vbox


Ignore:
Timestamp:
Feb 1, 2023 12:40:48 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
155624
Message:

scm: More on the kmk makefile cleanup. bugref:10348

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/bldprogs/scmrw-kmk.cpp

    r98374 r98380  
    5252*   Structures and Typedefs                                                                                                      *
    5353*********************************************************************************************************************************/
     54typedef enum KMKASSIGNTYPE
     55{
     56    kKmkAssignType_Recursive,
     57    kKmkAssignType_Conditional,
     58    kKmkAssignType_Appending,
     59    kKmkAssignType_Prepending,
     60    kKmkAssignType_Simple,
     61    kKmkAssignType_Immediate
     62} KMKASSIGNTYPE;
     63
     64/** Context for scmKmkWordLength. */
     65typedef enum
     66{
     67    /** Target file or assignment.
     68     *  Separators: space, '=', ':' */
     69    kKmkWordCtx_TargetFileOrAssignment,
     70    /** Target file.
     71     *  Separators: space, ':' */
     72    kKmkWordCtx_TargetFile,
     73    /** Dependency file or (target variable) assignment.
     74     *  Separators: space, '=', ':', '|' */
     75    kKmkWordCtx_DepFileOrAssignment,
     76    /** Dependency file.
     77     *  Separators: space, '|' */
     78    kKmkWordCtx_DepFile
     79} KMKWORDCTX;
     80
     81typedef struct KMKWORDSTATE
     82{
     83    uint16_t uDepth;
     84    char     chOpen;
     85} KMKWORDSTATE;
     86
    5487typedef enum KMKTOKEN
    5588{
     
    91124    {
    92125        KMKTOKEN        enmToken;
    93         uint32_t        iLine;
    94126        bool            fIgnoreNesting;
     127        size_t          iLine;
    95128    } aDepth[64];
    96129    unsigned            iDepth;
     
    98131    bool                fInRecipe;
    99132
    100     /** The current line number (for error messages and peeking).   */
    101     uint32_t            iLine;
    102133    /** The EOL type of the current line. */
    103134    SCMEOL              enmEol;
     
    185216
    186217/**
     218 * Modifies the fInRecipe state variable, logging changes in verbose mode.
     219 */
     220static void scmKmkSetInRecipe(KMKPARSER *pParser, bool fInRecipe)
     221{
     222    if (pParser->fInRecipe != fInRecipe)
     223        ScmVerbose(pParser->pState, 4, "%u: debug: %s\n",
     224                   ScmStreamTellLine(pParser->pIn), fInRecipe ? "in-recipe" : "not-in-recipe");
     225    pParser->fInRecipe = fInRecipe;
     226}
     227
     228
     229/**
    187230 * Gives up on the current line, copying it as it and requesting manual repair.
    188231 */
     
    191234    va_list va;
    192235    va_start(va, pszFormat);
    193     ScmFixManually(pParser->pState, "%u: %N\n", pParser->iLine, pszFormat, &va);
     236    ScmFixManually(pParser->pState, "%u: %N\n", ScmStreamTellLine(pParser->pIn), pszFormat, &va);
    194237    va_end(va);
    195238
     
    277320    if (iDepth + 1 >= RT_ELEMENTS(pParser->aDepth))
    278321    {
    279         ScmError(pParser->pState, VERR_ASN1_TOO_DEEPLY_NESTED /*?*/, "%u: Too deep if/define nesting!\n", pParser->iLine);
     322        ScmError(pParser->pState, VERR_ASN1_TOO_DEEPLY_NESTED /*?*/,
     323                 "%u: Too deep if/define nesting!\n", ScmStreamTellLine(pParser->pIn));
    280324        return false;
    281325    }
    282326
    283327    pParser->aDepth[iDepth].enmToken       = enmToken;
    284     pParser->aDepth[iDepth].iLine          = pParser->iLine;
     328    pParser->aDepth[iDepth].iLine          = ScmStreamTellLine(pParser->pIn);
    285329    pParser->aDepth[iDepth].fIgnoreNesting = false;
    286330    pParser->iDepth        = iDepth + 1;
    287331    pParser->iActualDepth += 1;
     332    ScmVerbose(pParser->pState, 5, "%u: debug: nesting %u (token %u)\n", pParser->aDepth[iDepth].iLine, iDepth + 1, enmToken);
    288333    return true;
    289334}
     
    320365
    321366
    322 /** Context for scmKmkWordLength. */
    323 typedef enum
    324 {
    325     /** Target file or assignment.
    326      *  Separators: space, '=', ':' */
    327     kKmkWordCtx_TargetFileOrAssignment,
    328     /** Target file.
    329      *  Separators: space, ':' */
    330     kKmkWordCtx_TargetFile,
    331     /** Dependency file or (target variable) assignment.
    332      *  Separators: space, '=', ':', '|' */
    333     kKmkWordCtx_DepFileOrAssignment,
    334     /** Dependency file.
    335      *  Separators: space, '|' */
    336     kKmkWordCtx_DepFile
    337 } KMKWORDCTX;
    338 
    339367/**
    340368 * Finds the length of the word (file) @a offStart.
     369 *
     370 * This only takes one line into account, so variable expansions (function
     371 * calls) spanning multiple lines will be handled as one word per line with help
     372 * from @a pState.  This allows the caller to properly continutation intend the
     373 * additional lines.
    341374 *
    342375 * @returns Length of word starting at @a offStart. Zero if there is whitespace
     
    346379 * @param   cchLine             The line length.
    347380 * @param   offStart            Offset to the start of the word.
     381 * @param   pState              Where multiline variable expansion is tracked.
    348382 */
    349 static size_t scmKmkWordLength(const char *pchLine, size_t cchLine, size_t offStart, KMKWORDCTX enmCtx)
     383static size_t scmKmkWordLength(const char *pchLine, size_t cchLine, size_t offStart, KMKWORDCTX enmCtx, KMKWORDSTATE *pState)
    350384{
    351385    AssertReturn(offStart < cchLine && !RT_C_IS_BLANK(pchLine[offStart]), 0);
     386
     387    /*
     388     * Drop any line continuation slash from the line length, so we don't count
     389     * it into the word length. Also, any spaces preceeding it (for multiline
     390     * variable function expansion).  ASSUMES no trailing slash escaping.
     391     */
     392    if (cchLine > 0 && pchLine[cchLine - 1] == '\\')
     393        do
     394            cchLine--;
     395        while (cchLine > offStart && RT_C_IS_SPACE(pchLine[cchLine - 1]));
     396
     397    /*
     398     * If we were inside a variable function expansion, continue till we reach the end.
     399     * This kind of duplicates the code below.
     400     */
    352401    size_t off = offStart;
     402    if (pState->uDepth > 0)
     403    {
     404        Assert(pState->chOpen == '(' || pState->chOpen == '{');
     405        char const chOpen  = pState->chOpen;
     406        char const chClose = chOpen == '(' ? ')' : '}';
     407        unsigned   uDepth  = pState->uDepth;
     408        for (;;)
     409        {
     410            char ch;
     411            if (off < cchLine)
     412                ch = pchLine[off++];
     413            else /* Reached the end while still inside the expansion. */
     414            {
     415                pState->chOpen = chOpen;
     416                pState->uDepth = (uint16_t)uDepth;
     417                return cchLine - offStart;
     418            }
     419            if (ch == chOpen)
     420                uDepth++;
     421            else if (ch == chClose && --uDepth == 0)
     422                break;
     423        }
     424        pState->uDepth = 0;
     425        pState->chOpen = 0;
     426    }
     427
     428    /*
     429     * Process till we find blank or end of the line.
     430     */
    353431    while (off < cchLine)
    354432    {
     
    357435            break;
    358436
    359         if (ch == ':')
     437        if (ch == '$')
     438        {
     439            /*
     440             * Skip variable expansion.
     441             */
     442            if (off + 2 >= cchLine)
     443                return cchLine - offStart;
     444            char const chOpen = pchLine[++off];
     445            if (chOpen == '(' || chOpen == '{')
     446            {
     447                char const chClose = chOpen == '(' ? ')' : '}';
     448                unsigned   uDepth  = 1;
     449                off++;
     450                for (;;)
     451                {
     452                    if (off < cchLine)
     453                        ch = pchLine[off++];
     454                    else /* Reached the end while inside the expansion. */
     455                    {
     456                        pState->chOpen = chOpen;
     457                        pState->uDepth = (uint16_t)uDepth;
     458                        return cchLine - offStart;
     459                    }
     460                    if (ch == chOpen)
     461                        uDepth++;
     462                    else if (ch == chClose && --uDepth == 0)
     463                        break;
     464                }
     465                continue;
     466            }
     467            /* else: $X */
     468        }
     469        else if (ch == ':')
    360470        {
    361471            /*
     
    474584    /* Complain and copy out the text unmodified. */
    475585    ScmError(pParser->pState, VERR_PARSE_ERROR, "%u:%u: Expected comment, found: %.*s",
    476              pParser->iLine, offSrc, cchLine - offSrc, &pchLine[offSrc]);
     586             ScmStreamTellLine(pParser->pIn), offSrc, cchLine - offSrc, &pchLine[offSrc]);
    477587    *ppszDst = (char *)mempcpy(pszDst, &pchLine[offSrcStart], cchLine - offSrcStart);
    478588    return false; /*dummy*/
     
    495605     * Push it onto the stack.  All these nestings are relevant.
    496606     */
    497     if (!scmKmkPushNesting(pParser, enmToken))
    498         return false;
     607    if (!fElse)
     608    {
     609        if (!scmKmkPushNesting(pParser, enmToken))
     610            return false;
     611    }
     612    else
     613    {
     614        pParser->aDepth[pParser->iDepth - 1].enmToken = enmToken;
     615        pParser->aDepth[pParser->iDepth - 1].iLine    = ScmStreamTellLine(pParser->pIn);
     616    }
    499617
    500618    /*
     
    637755     * the define matches the typical pattern for a file blocker.
    638756     */
     757    bool fIgnoredNesting = false;
    639758    if (!fElse)
    640759    {
    641760        if (!scmKmkPushNesting(pParser, enmToken))
    642761            return false;
     762        if (enmToken == kKmkToken_ifndef)
     763        {
     764            /** @todo */
     765        }
    643766    }
    644767    else
    645768    {
    646769        pParser->aDepth[pParser->iDepth - 1].enmToken = enmToken;
    647         pParser->aDepth[pParser->iDepth - 1].iLine    = pParser->iLine;
    648     }
    649     bool fIgnoredNesting = false;
    650     if (enmToken == kKmkToken_ifndef)
    651     {
    652         /** @todo */
     770        pParser->aDepth[pParser->iDepth - 1].iLine    = ScmStreamTellLine(pParser->pIn);
    653771    }
    654772
     
    809927            }
    810928            cchLine = pParser->cchLine;
    811             pParser->iLine++;
    812929
    813930            /* Skip leading whitespace and adjust the source continuation indent: */
     
    852969        *pszDst = '\0';
    853970
    854         /* Check for special comment making us ignore the nesting. We do this in the
    855 
    856            */
     971        /* Check for special comment making us ignore the nesting.  We do this
     972           on the destination buffer since it's zero terminated allowing normal
     973           strstr use. */
    857974        if (!fIgnoredNesting && strstr(pszDstSrc, "scm:ignore-nesting") != NULL)
    858975        {
    859976            pParser->aDepth[pParser->iDepth - 1].fIgnoreNesting = true;
    860977            pParser->iActualDepth--;
     978            ScmVerbose(pParser->pState, 5, "%u: debug: ignoring nesting - actual depth: %u\n",
     979                       pParser->aDepth[pParser->iDepth - 1].iLine, pParser->iActualDepth);
    861980        }
    862981    }
     
    9771096    }
    9781097    uint32_t const cchIndent = pParser->iActualDepth;
     1098    ScmVerbose(pParser->pState, 5, "%u: debug: unnesting %u/%u (endif)\n",
     1099               ScmStreamTellLine(pParser->pIn), iDepth, pParser->iActualDepth);
    9791100
    9801101    /*
     
    10591180static bool scmKmkHandleDefine(KMKPARSER *pParser, size_t offToken)
    10601181{
    1061     /* Assignments takes us out of recipe mode. */
    1062     pParser->fInRecipe = false;
     1182    /* Hack Alert! Start out parsing the define in recipe mode.
     1183
     1184       Technically, we shouldn't evaluate the content of a define till it's
     1185       used. However, we ASSUME they are either makefile code snippets or
     1186       recipe templates.  */
     1187    scmKmkSetInRecipe(pParser, true);
    10631188
    10641189    return scmKmkHandleSimple(pParser, offToken);
     
    10691194{
    10701195    /* Leaving a define resets the recipt mode. */
    1071     pParser->fInRecipe = false;
     1196    scmKmkSetInRecipe(pParser, false);
    10721197
    10731198    return scmKmkHandleSimple(pParser, offToken);
     
    10751200
    10761201
    1077 typedef enum KMKASSIGNTYPE
    1078 {
    1079     kKmkAssignType_Recursive,
    1080     kKmkAssignType_Conditional,
    1081     kKmkAssignType_Appending,
    1082     kKmkAssignType_Prepending,
    1083     kKmkAssignType_Simple,
    1084     kKmkAssignType_Immediate
    1085 } KMKASSIGNTYPE;
    1086 
     1202/**
     1203 * Checks for escaped trailing slashes on a line, giving up and asking the
     1204 * developer to fix those manually.
     1205 *
     1206 * @returns true if we gave up. false if no escaped slashed and we didn't.
     1207 */
     1208static bool scmKmkGiveUpIfTrailingEscapedSlashed(KMKPARSER *pParser, const char *pchLine, size_t cchLine)
     1209{
     1210    if (cchLine > 2 && pchLine[cchLine - 2] == '\\' && pchLine[cchLine - 1] == '\\')
     1211    {
     1212        scmKmkGiveUp(pParser, "Escaped slashes at end of line not allowed. Insert space before line continuation slash!");
     1213        return true;
     1214    }
     1215    return false;
     1216}
    10871217
    10881218/**
     
    11061236
    11071237    /* Assignments takes us out of recipe mode. */
    1108     pParser->fInRecipe = false;
     1238    ScmVerbose(pParser->pState, 6, "%u: debug: assignment\n", ScmStreamTellLine(pParser->pIn));
     1239    scmKmkSetInRecipe(pParser, false);
    11091240
    11101241    /* This is too much hazzle to deal with. */
    1111     if (cLines > 0 && pchLine[cchLine - 2] == '\\')
    1112         return scmKmkGiveUp(pParser, "Escaped slashes at end of line not allowed. Insert space before line continuation slash!");
     1242    if (cLines > 1 && scmKmkGiveUpIfTrailingEscapedSlashed(pParser, pchLine, cchLine))
     1243        return false;
    11131244    if (cchLine + 64 > sizeof(pParser->szBuf))
    11141245        return scmKmkGiveUp(pParser, "Line too long!");
     
    11531284            cchLine = pParser->cchLine;
    11541285            iSubLine++;
    1155             if (iSubLine + 1 < cLines && pchLine[cchLine - 2] == '\\')
    1156                 return scmKmkGiveUp(pParser, "Escaped slashes at end of line not allowed. Insert space before line continuation slash!");
     1286            if (iSubLine + 1 < cLines && scmKmkGiveUpIfTrailingEscapedSlashed(pParser, pchLine, cchLine))
     1287                return false;
    11571288
    11581289            /* Adjust offAssignOp: */
     
    11921323            break;
    11931324        case kKmkAssignType_Prepending:
    1194             *pszDst++ = '>';
     1325            *pszDst++ = '<';
    11951326            *pszDst++ = '=';
    1196             Assert(pchLine[offLine] == '>'); Assert(pchLine[offLine + 1] == '=');
     1327            Assert(pchLine[offLine] == '<'); Assert(pchLine[offLine + 1] == '=');
    11971328            offLine += 2;
    11981329            break;
     
    13711502
    13721503    /* Following this, we'll be in recipe-mode. */
    1373     pParser->fInRecipe = true;
     1504    ScmVerbose(pParser->pState, 4, "%u: debug: start rule\n", ScmStreamTellLine(pParser->pIn));
     1505    scmKmkSetInRecipe(pParser, true);
    13741506
    13751507    /* This is too much hazzle to deal with. */
    1376     if (cLines > 0 && pchLine[cchLine - 2] == '\\')
    1377         return scmKmkGiveUp(pParser, "Escaped slashes at end of line not allowed. Insert space before line continuation slash!");
     1508    if (cLines > 0 && scmKmkGiveUpIfTrailingEscapedSlashed(pParser, pchLine, cchLine))
     1509        return false;
    13781510
    13791511    /* Too special case. */
     
    13891521    /*
    13901522     * Process word by word past the colon, taking new lines into account.
    1391      *
    1392      */
    1393     KMKWORDCTX enmCtx      = kKmkWordCtx_TargetFileOrAssignment;
    1394     bool       fPendingEol = false;
     1523     */
     1524    KMKWORDSTATE WordState   = { 0, 0 };
     1525    KMKWORDCTX   enmCtx      = kKmkWordCtx_TargetFileOrAssignment;
     1526    bool         fPendingEol = false;
    13951527    for (;;)
    13961528    {
     
    13981530         * Output the next word.
    13991531         */
    1400         size_t cchWord = scmKmkWordLength(pchLine, cchLine, offLine, enmCtx);
     1532        size_t cchWord = scmKmkWordLength(pchLine, cchLine, offLine, enmCtx, &WordState);
    14011533        Assert(offLine + cchWord <= offColon);
    14021534        ScmStreamWrite(pOut, &pchLine[offLine], cchWord);
     
    14321564                cchLine = pParser->cchLine;
    14331565                iSubLine++;
    1434                 if (iSubLine + 1 < cLines && pchLine[cchLine - 2] == '\\')
    1435                     return scmKmkGiveUp(pParser, "Escaped slashes at end of line not allowed. Insert space before line continuation slash!");
     1566                if (iSubLine + 1 < cLines && scmKmkGiveUpIfTrailingEscapedSlashed(pParser, pchLine, cchLine))
     1567                    return false;
    14361568
    14371569                /* Adjust offColon: */
     
    14601592
    14611593                    fPendingEol = true;
    1462                     break;
    14631594                }
    1464                 ScmStreamWrite(pOut, RT_STR_TUPLE(" \\"));
    1465                 ScmStreamPutEol(pOut, pParser->enmEol);
    1466                 ScmStreamWrite(pOut, g_szSpaces, cchIndent);
     1595                else
     1596                {
     1597                    ScmStreamWrite(pOut, RT_STR_TUPLE(" \\"));
     1598                    ScmStreamPutEol(pOut, pParser->enmEol);
     1599                    ScmStreamWrite(pOut, g_szSpaces, cchIndent);
     1600                }
     1601                break;
    14671602            }
    14681603            if (offLine >= offColon)
     
    14761611    /*
    14771612     * We're immediately past the colon now, so eat whitespace and newlines and
    1478      * whatever till we get to a solid word.
     1613     * whatever till we get to a solid word or the end of the line.
    14791614     */
    14801615    /* Skip spaces - there should be exactly one. */
     
    14921627        cchLine = pParser->cchLine;
    14931628        iSubLine++;
    1494         if (iSubLine + 1 < cLines && pchLine[cchLine - 2] == '\\')
    1495             return scmKmkGiveUp(pParser, "Escaped slashes at end of line not allowed. Insert space before line continuation slash!");
     1629        if (iSubLine + 1 < cLines && scmKmkGiveUpIfTrailingEscapedSlashed(pParser, pchLine, cchLine))
     1630            return false;
    14961631
    14971632         /* Skip leading spaces. */
     
    15081643     * Special case: No dependencies.
    15091644     */
    1510     if (offLine == cchLine && iSubLine >= cLines)
     1645    if (offLine == cchLine && iSubLine + 1 >= cLines)
    15111646    {
    15121647        ScmStreamPutEol(pOut, pParser->enmEol);
     
    15341669
    15351670        /* Get the next word and output it. */
    1536         size_t cchWord = scmKmkWordLength(pchLine, cchLine, offLine, enmCtx);
     1671        size_t cchWord = scmKmkWordLength(pchLine, cchLine, offLine, enmCtx, &WordState);
    15371672        Assert(offLine + cchWord <= cchLine);
    15381673
     
    15601695                cchLine = pParser->cchLine;
    15611696                iSubLine++;
    1562                 if (iSubLine + 1 < cLines && pchLine[cchLine - 2] == '\\')
    1563                     return scmKmkGiveUp(pParser, "Escaped slashes at end of line not allowed. Insert space before line continuation slash!");
     1697                if (iSubLine + 1 < cLines && scmKmkGiveUpIfTrailingEscapedSlashed(pParser, pchLine, cchLine))
     1698                    return false;
    15641699
    15651700                /* Skip leading spaces. */
     
    16821817                    if (ch == '+')
    16831818                        return scmKmkHandleAssignment2(pParser, offWord, offEndPrev, kKmkAssignType_Appending,   offLine, 0);
    1684                     if (ch == '>')
     1819                    if (ch == '<')
    16851820                        return scmKmkHandleAssignment2(pParser, offWord, offEndPrev, kKmkAssignType_Prepending,  offLine, 0);
    16861821                    if (ch == '?')
     
    17101845                else if (ch == '?')
    17111846                    enmType = kKmkAssignType_Conditional;
    1712                 else if (ch == '>')
     1847                else if (ch == '<')
    17131848                    enmType = kKmkAssignType_Prepending;
    17141849                else
     
    17451880
    17461881    /*
     1882     * Check if this is a $(error ) or similar function call line.
     1883     */
     1884    if (   pchLine[offWord]     == '$'
     1885        && pchLine[offWord + 1] == '(')
     1886    {
     1887        size_t const cchLine = pParser->cchLine;
     1888        size_t       offEnd  = offWord + 2;
     1889        char         ch      = '\0';
     1890        while (offEnd < cchLine && (RT_C_IS_LOWER(ch = pchLine[offEnd]) || RT_C_IS_DIGIT(ch) || ch == '-'))
     1891            offEnd++;
     1892        if (offEnd >= cchLine || RT_C_IS_SPACE(ch) || (offEnd == cchLine - 1 && ch == '\\'))
     1893        {
     1894            static const RTSTRTUPLE s_aAllowedFunctions[] =
     1895            {
     1896                { RT_STR_TUPLE("info") },
     1897                { RT_STR_TUPLE("error") },
     1898                { RT_STR_TUPLE("warning") },
     1899                { RT_STR_TUPLE("eval") },
     1900                { RT_STR_TUPLE("set-umask") },
     1901            };
     1902            size_t cchFunc = offEnd - offWord - 2;
     1903            for (size_t i = 0; i < RT_ELEMENTS(s_aAllowedFunctions); i++)
     1904                if (   cchFunc == s_aAllowedFunctions[i].cch
     1905                    && memcmp(&pchLine[offWord + 2], s_aAllowedFunctions[i].psz, cchFunc) == 0)
     1906                    return scmKmkHandleSimple(pParser, offWord);
     1907        }
     1908    }
     1909
     1910    /*
    17471911     * If we didn't find anything, output it as-as.
    17481912     * We use scmKmkHandleSimple in a special way to do this.
    17491913     */
    1750     ScmVerbose(pParser->pState, 1, "debug: %u: Unable to make sense of this line!", pParser->iLine);
     1914    ScmVerbose(pParser->pState, 1, "%u: debug: Unable to make sense of this line!\n", ScmStreamTellLine(pParser->pIn));
    17511915    return scmKmkHandleSimple(pParser, 0 /*offToken*/, false /*fIndentIt*/);
    17521916}
     
    17571921{
    17581922    /* Assignments takes us out of recipe mode. */
    1759     pParser->fInRecipe = false;
     1923    scmKmkSetInRecipe(pParser, false);
    17601924
    17611925    RT_NOREF(pParser, offToken, enmToken, cchWord, fMustBeAssignment);
     
    17901954    Parser.iActualDepth = 0;
    17911955    Parser.fInRecipe    = false;
    1792     Parser.iLine        = 0;
    17931956    Parser.pState       = pState;
    17941957    Parser.pIn          = pIn;
     
    18031966    {
    18041967        size_t cchLine = Parser.cchLine;
    1805         Parser.iLine++;
    18061968
    18071969        /*
     
    18261988                offLine++;
    18271989
    1828             /* Find end of word (if any): */
     1990            /* Find end of word (if any) - only looking for keywords here: */
    18291991            size_t cchWord = 0;
    18301992            while (   offLine + cchWord < cchLine
     
    19152077                }
    19162078            }
     2079            /*
     2080             * Not keyword, check for assignment, rule or comment:
     2081             */
     2082            else if (offLine < cchLine)
     2083            {
     2084                if (pchLine[offLine] != '#')
     2085                {
     2086                    Parser.cLines       = 1;
     2087                    Parser.cchTotalLine = cchLine;
     2088                    if (scmKmkIsLineWithContinuation(pchLine, cchLine))
     2089                        Parser.cchTotalLine = scmKmkLineContinuationPeek(&Parser, &Parser.cLines, NULL);
     2090                    scmKmkHandleAssignmentOrRule(&Parser, offLine);
     2091                    continue;
     2092                }
     2093                /** @todo process comments. */
     2094            }
    19172095        }
    19182096
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette