VirtualBox

Changeset 99028 in vbox


Ignore:
Timestamp:
Mar 17, 2023 8:49:31 PM (2 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
156393
Message:

scm: Insist on recipe command line starting with only a single tab. bugref:10348

File:
1 edited

Legend:

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

    r98440 r99028  
    20452045
    20462046/**
     2047 * Handles a line with a recipe command.
     2048 */
     2049static void scmKmkHandleRecipeCommand(KMKPARSER *pParser, const char *pchLine, size_t cchLine)
     2050{
     2051    /*
     2052     * Make sure there is only a single tab and no spaces following it.
     2053     * This helps tell prerequisites from the commands in the recipe.
     2054     * 
     2055     * Iff the line starts with a '#' it is probably a Makefile comment line,
     2056     * but it will be executed by the shell (kmk_ash) and waste time. So, we
     2057     * expand the initial tab into spaces when seeing that.
     2058     */
     2059    Assert(*pchLine == '\t');
     2060    size_t offLine = 1;
     2061    while (offLine < cchLine && RT_C_IS_BLANK(pchLine[offLine]))
     2062        offLine++;
     2063
     2064    if (offLine < cchLine && pchLine[offLine] == '#')
     2065        ScmStreamWrite(pParser->pOut, g_szSpaces, pParser->pSettings->cchTab);
     2066    else
     2067        ScmStreamPutCh(pParser->pOut, '\t');
     2068
     2069    ScmStreamWrite(pParser->pOut, &pchLine[offLine], cchLine - offLine);
     2070    ScmStreamPutEol(pParser->pOut, pParser->enmEol);
     2071
     2072    /*
     2073     * Any continuation lines are currently just passed thru as-is.
     2074     * We could insist on these also starting with tabs, but later.
     2075     */
     2076    scmKmkPassThruLineContinuationLines(pParser);
     2077}
     2078
     2079
     2080/**
    20472081 * Rewrite a kBuild makefile.
    20482082 *
     
    20892123        if (Parser.fInRecipe && *pchLine == '\t')
    20902124        {
    2091             /* Do we do anything here? */
    2092         }
    2093         else
    2094         {
    2095             /*
    2096              * Skip leading whitespace and check for directives (simplified).
    2097              *
    2098              * This is simplified in the sense that GNU make first checks for variable
    2099              * assignments, so that directive can be used as variable names.  We don't
    2100              * want that, so we do the variable assignment check later.
    2101              */
    2102             size_t offLine = 0;
    2103             while (offLine < cchLine && RT_C_IS_BLANK(pchLine[offLine]))
    2104                 offLine++;
    2105 
    2106             /* Find end of word (if any) - only looking for keywords here: */
    2107             size_t cchWord = 0;
    2108             while (   offLine + cchWord < cchLine
    2109                    && (   RT_C_IS_ALNUM(pchLine[offLine + cchWord])
    2110                        || pchLine[offLine + cchWord] == '-'))
    2111                 cchWord++;
    2112             if (cchWord > 0)
     2125            scmKmkHandleRecipeCommand(&Parser, pchLine, cchLine);
     2126            continue;
     2127        }
     2128
     2129        /*
     2130         * Skip leading whitespace and check for directives (simplified).
     2131         *
     2132         * This is simplified in the sense that GNU make first checks for variable
     2133         * assignments, so that directive can be used as variable names.  We don't
     2134         * want that, so we do the variable assignment check later.
     2135         */
     2136        size_t offLine = 0;
     2137        while (offLine < cchLine && RT_C_IS_BLANK(pchLine[offLine]))
     2138            offLine++;
     2139
     2140        /* Find end of word (if any) - only looking for keywords here: */
     2141        size_t cchWord = 0;
     2142        while (   offLine + cchWord < cchLine
     2143               && (   RT_C_IS_ALNUM(pchLine[offLine + cchWord])
     2144                   || pchLine[offLine + cchWord] == '-'))
     2145            cchWord++;
     2146        if (cchWord > 0)
     2147        {
     2148            /* If the line is just a line continuation slash, simply remove it
     2149               (this also makes the parsing a lot easier). */
     2150            if (cchWord == 1 && offLine == cchLine - 1 && pchLine[cchLine] == '\\')
     2151                continue;
     2152
     2153            /* Unlike the GNU make parser, we won't recognize 'if' or any other
     2154               directives as variable names, so we can  */
     2155            KMKTOKEN enmToken = scmKmkIdentifyToken(&pchLine[offLine], cchWord);
     2156            switch (enmToken)
    21132157            {
    2114                 /* If the line is just a line continuation slash, simply remove it
    2115                    (this also makes the parsing a lot easier). */
    2116                 if (cchWord == 1 && offLine == cchLine - 1 && pchLine[cchLine] == '\\')
     2158                case kKmkToken_ifeq:
     2159                case kKmkToken_ifneq:
     2160                case kKmkToken_if1of:
     2161                case kKmkToken_ifn1of:
     2162                    scmKmkHandleIfParentheses(&Parser, offLine, enmToken, cchWord, false /*fElse*/);
    21172163                    continue;
    21182164
    2119                 /* Unlike the GNU make parser, we won't recognize 'if' or any other
    2120                    directives as variable names, so we can  */
    2121                 KMKTOKEN enmToken = scmKmkIdentifyToken(&pchLine[offLine], cchWord);
    2122                 switch (enmToken)
    2123                 {
    2124                     case kKmkToken_ifeq:
    2125                     case kKmkToken_ifneq:
    2126                     case kKmkToken_if1of:
    2127                     case kKmkToken_ifn1of:
    2128                         scmKmkHandleIfParentheses(&Parser, offLine, enmToken, cchWord, false /*fElse*/);
    2129                         continue;
    2130 
    2131                     case kKmkToken_ifdef:
    2132                     case kKmkToken_ifndef:
    2133                     case kKmkToken_if:
    2134                         scmKmkHandleIfSpace(&Parser, offLine, enmToken, cchWord, false /*fElse*/);
    2135                         continue;
    2136 
    2137                     case kKmkToken_else:
    2138                         scmKmkHandleElse(&Parser, offLine);
    2139                         continue;
    2140 
    2141                     case kKmkToken_endif:
    2142                         scmKmkHandleEndif(&Parser, offLine);
    2143                         continue;
    2144 
    2145                     /* Includes: */
    2146                     case kKmkToken_include:
    2147                     case kKmkToken_sinclude:
    2148                     case kKmkToken_dash_include:
    2149                     case kKmkToken_includedep:
    2150                     case kKmkToken_includedep_queue:
    2151                     case kKmkToken_includedep_flush:
    2152                         scmKmkHandleSimple(&Parser, offLine);
    2153                         continue;
    2154 
    2155                     /* Others: */
    2156                     case kKmkToken_define:
    2157                         scmKmkHandleDefine(&Parser, offLine);
    2158                         continue;
    2159                     case kKmkToken_endef:
    2160                         scmKmkHandleEndef(&Parser, offLine);
    2161                         continue;
    2162 
    2163                     case kKmkToken_override:
    2164                     case kKmkToken_local:
    2165                         scmKmkHandleAssignKeyword(&Parser, offLine, enmToken, cchWord, true /*fMustBeAssignment*/);
    2166                         continue;
    2167 
    2168                     case kKmkToken_export:
    2169                         scmKmkHandleAssignKeyword(&Parser, offLine, enmToken, cchWord, false /*fMustBeAssignment*/);
    2170                         continue;
    2171 
    2172                     case kKmkToken_unexport:
    2173                     case kKmkToken_undefine:
    2174                         scmKmkHandleSimple(&Parser, offLine);
    2175                         continue;
    2176 
    2177                     case kKmkToken_Comment:
    2178                         AssertFailed(); /* not possible */
    2179                         break;
    2180 
    2181                     /*
    2182                      * Check if it's perhaps an variable assignment or start of a rule.
    2183                      * We'll do this in a very simple fashion.
    2184                      */
    2185                     case kKmkToken_Word:
    2186                     {
    2187                         Parser.cLines       = 1;
    2188                         Parser.cchTotalLine = cchLine;
    2189                         if (scmKmkIsLineWithContinuation(pchLine, cchLine))
    2190                             Parser.cchTotalLine = scmKmkLineContinuationPeek(&Parser, &Parser.cLines, NULL);
    2191                         scmKmkHandleAssignmentOrRule(&Parser, offLine);
    2192                         continue;
    2193                     }
    2194                 }
    2195             }
    2196             /*
    2197              * Not keyword, check for assignment, rule or comment:
    2198              */
    2199             else if (offLine < cchLine)
    2200             {
    2201                 if (pchLine[offLine] != '#')
     2165                case kKmkToken_ifdef:
     2166                case kKmkToken_ifndef:
     2167                case kKmkToken_if:
     2168                    scmKmkHandleIfSpace(&Parser, offLine, enmToken, cchWord, false /*fElse*/);
     2169                    continue;
     2170
     2171                case kKmkToken_else:
     2172                    scmKmkHandleElse(&Parser, offLine);
     2173                    continue;
     2174
     2175                case kKmkToken_endif:
     2176                    scmKmkHandleEndif(&Parser, offLine);
     2177                    continue;
     2178
     2179                /* Includes: */
     2180                case kKmkToken_include:
     2181                case kKmkToken_sinclude:
     2182                case kKmkToken_dash_include:
     2183                case kKmkToken_includedep:
     2184                case kKmkToken_includedep_queue:
     2185                case kKmkToken_includedep_flush:
     2186                    scmKmkHandleSimple(&Parser, offLine);
     2187                    continue;
     2188
     2189                /* Others: */
     2190                case kKmkToken_define:
     2191                    scmKmkHandleDefine(&Parser, offLine);
     2192                    continue;
     2193                case kKmkToken_endef:
     2194                    scmKmkHandleEndef(&Parser, offLine);
     2195                    continue;
     2196
     2197                case kKmkToken_override:
     2198                case kKmkToken_local:
     2199                    scmKmkHandleAssignKeyword(&Parser, offLine, enmToken, cchWord, true /*fMustBeAssignment*/);
     2200                    continue;
     2201
     2202                case kKmkToken_export:
     2203                    scmKmkHandleAssignKeyword(&Parser, offLine, enmToken, cchWord, false /*fMustBeAssignment*/);
     2204                    continue;
     2205
     2206                case kKmkToken_unexport:
     2207                case kKmkToken_undefine:
     2208                    scmKmkHandleSimple(&Parser, offLine);
     2209                    continue;
     2210
     2211                case kKmkToken_Comment:
     2212                    AssertFailed(); /* not possible */
     2213                    break;
     2214
     2215                /*
     2216                 * Check if it's perhaps an variable assignment or start of a rule.
     2217                 * We'll do this in a very simple fashion.
     2218                 */
     2219                case kKmkToken_Word:
    22022220                {
    22032221                    Parser.cLines       = 1;
     
    22082226                    continue;
    22092227                }
    2210 
    2211                 /*
    2212                  * Indent comment lines, unless the comment is too far too the right.
    2213                  */
    2214                 size_t const offEffLine = ScmCalcSpacesForSrcSpan(pchLine, 0, offLine, pSettings);
    2215                 if (offEffLine <= Parser.iActualDepth + 7)
     2228            }
     2229        }
     2230        /*
     2231         * Not keyword, check for assignment, rule or comment:
     2232         */
     2233        else if (offLine < cchLine)
     2234        {
     2235            if (pchLine[offLine] != '#')
     2236            {
     2237                Parser.cLines       = 1;
     2238                Parser.cchTotalLine = cchLine;
     2239                if (scmKmkIsLineWithContinuation(pchLine, cchLine))
     2240                    Parser.cchTotalLine = scmKmkLineContinuationPeek(&Parser, &Parser.cLines, NULL);
     2241                scmKmkHandleAssignmentOrRule(&Parser, offLine);
     2242                continue;
     2243            }
     2244
     2245            /*
     2246             * Indent comment lines, unless the comment is too far too the right.
     2247             */
     2248            size_t const offEffLine = ScmCalcSpacesForSrcSpan(pchLine, 0, offLine, pSettings);
     2249            if (offEffLine <= Parser.iActualDepth + 7)
     2250            {
     2251                ScmStreamWrite(pOut, g_szSpaces, Parser.iActualDepth);
     2252                ScmStreamWrite(pOut, &pchLine[offLine], cchLine - offLine);
     2253                ScmStreamPutEol(pOut, Parser.enmEol);
     2254
     2255                /* If line continuation is used, it's typically to disable
     2256                   a property variable, so we just pass it thru as-is */
     2257                while (scmKmkIsLineWithContinuation(pchLine, cchLine))
    22162258                {
    2217                     ScmStreamWrite(pOut, g_szSpaces, Parser.iActualDepth);
    2218                     ScmStreamWrite(pOut, &pchLine[offLine], cchLine - offLine);
    2219                     ScmStreamPutEol(pOut, Parser.enmEol);
    2220 
    2221                     /* If line continuation is used, it's typically to disable
    2222                        a property variable, so we just pass it thru as-is */
    2223                     while (scmKmkIsLineWithContinuation(pchLine, cchLine))
    2224                     {
    2225                         Parser.pchLine = pchLine = ScmStreamGetLine(pIn, &Parser.cchLine, &Parser.enmEol);
    2226                         if (!pchLine)
    2227                             break;
    2228                         cchLine = Parser.cchLine;
    2229                         ScmStreamPutLine(pOut, pchLine, cchLine, Parser.enmEol);
    2230                     }
    2231                     continue;
     2259                    Parser.pchLine = pchLine = ScmStreamGetLine(pIn, &Parser.cchLine, &Parser.enmEol);
     2260                    if (!pchLine)
     2261                        break;
     2262                    cchLine = Parser.cchLine;
     2263                    ScmStreamPutLine(pOut, pchLine, cchLine, Parser.enmEol);
    22322264                }
     2265                continue;
    22332266            }
    22342267        }
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