Changeset 99028 in vbox
- Timestamp:
- Mar 17, 2023 8:49:31 PM (2 years ago)
- svn:sync-xref-src-repo-rev:
- 156393
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/bldprogs/scmrw-kmk.cpp
r98440 r99028 2045 2045 2046 2046 /** 2047 * Handles a line with a recipe command. 2048 */ 2049 static 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 /** 2047 2081 * Rewrite a kBuild makefile. 2048 2082 * … … 2089 2123 if (Parser.fInRecipe && *pchLine == '\t') 2090 2124 { 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) 2113 2157 { 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*/); 2117 2163 continue; 2118 2164 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: 2202 2220 { 2203 2221 Parser.cLines = 1; … … 2208 2226 continue; 2209 2227 } 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)) 2216 2258 { 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); 2232 2264 } 2265 continue; 2233 2266 } 2234 2267 }
Note:
See TracChangeset
for help on using the changeset viewer.