Changeset 2011 in kBuild for trunk/src/kmk/kbuild.c
- Timestamp:
- Nov 1, 2008 2:15:50 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kbuild.c
r1999 r2011 458 458 kbuild_get_variable_n(const char *pszName, size_t cchName) 459 459 { 460 #ifndef NDEBUG461 int i;462 #endif463 460 struct variable *pVar = lookup_variable(pszName, cchName); 464 461 if (!pVar) … … 466 463 if (pVar->recursive) 467 464 fatal(NILF, _("variable `%.*s' is defined as `recursive' instead of `simple'!"), (int)cchName, pszName); 468 #ifndef NDEBUG 469 i = strlen(pVar->value); 470 if (i != pVar->value_length) 471 { 472 printf("%d != %d %s\n", pVar->value_length, i, pVar->name); 473 # ifdef _MSC_VER 474 __debugbreak(); 475 # endif 476 assert(0); 477 } 478 #endif 465 466 MY_ASSERT_MSG(strlen(pVar->value) == pVar->value_length, 467 ("%u != %u %.*s\n", pVar->value_length, strlen(pVar->value), (int)cchName, pVar->name)); 479 468 return pVar; 480 469 } 481 482 483 #if 0 /* unused */484 /**485 * Gets a variable that must exist.486 * Will cause a fatal failure if the variable doesn't exist.487 *488 * @returns Pointer to the variable.489 * @param pszName The variable name.490 */491 static struct variable *492 kbuild_get_variable(const char *pszName)493 {494 return kbuild_get_variable_n(pszName, strlen(pszName));495 }496 #endif497 470 498 471 … … 507 480 kbuild_get_recursive_variable(const char *pszName) 508 481 { 509 #ifndef NDEBUG510 int i;511 #endif512 482 struct variable *pVar = lookup_variable(pszName, strlen(pszName)); 513 483 if (!pVar) 514 484 fatal(NILF, _("variable `%s' isn't defined!"), pszName); 515 #ifndef NDEBUG 516 i = strlen(pVar->value); 517 if (i != pVar->value_length) 518 { 519 printf("%d != %d %s\n", pVar->value_length, i, pVar->name); 520 # ifdef _MSC_VER 521 __debugbreak(); 522 # endif 523 assert(0); 524 } 525 #endif 485 486 MY_ASSERT_MSG(strlen(pVar->value) == pVar->value_length, 487 ("%u != %u %s\n", pVar->value_length, strlen(pVar->value), pVar->name)); 488 return pVar; 489 } 490 491 492 /** 493 * Gets a variable that doesn't have to exit, but if it does can be recursive. 494 * 495 * @returns Pointer to the variable. 496 * NULL if not found. 497 * @param pszName The variable name. Doesn't need to be terminated. 498 * @param cchName The name length. 499 */ 500 static struct variable * 501 kbuild_query_recursive_variable_n(const char *pszName, size_t cchName) 502 { 503 struct variable *pVar = lookup_variable(pszName, cchName); 504 MY_ASSERT_MSG(!pVar || strlen(pVar->value) == pVar->value_length, 505 ("%u != %u %.*s\n", pVar->value_length, strlen(pVar->value), (int)cchName, pVar->name)); 526 506 return pVar; 527 507 } … … 538 518 kbuild_query_recursive_variable(const char *pszName) 539 519 { 540 #ifndef NDEBUG 541 int i; 542 #endif 543 struct variable *pVar = lookup_variable(pszName, strlen(pszName)); 544 if (pVar) 545 { 546 #ifndef NDEBUG 547 i = strlen(pVar->value); 548 if (i != pVar->value_length) 549 { 550 printf("%d != %d %s\n", pVar->value_length, i, pVar->name); 551 # ifdef _MSC_VER 552 __debugbreak(); 553 # endif 554 assert(0); 555 } 556 #endif 557 } 558 return pVar; 520 return kbuild_query_recursive_variable_n(pszName, strlen(pszName)); 559 521 } 560 522 … … 602 564 if (pVar) 603 565 { 604 #ifndef NDEBUG 605 int i = strlen(pVar->value); 606 if (i != pVar->value_length) 607 { 608 printf("%d != %d %s\n", pVar->value_length, i, pVar->name); 609 # ifdef _MSC_VER 610 __debugbreak(); 611 # endif 612 assert(0); 613 } 614 #endif 566 MY_ASSERT_MSG(strlen(pVar->value) == pVar->value_length, 567 ("%u != %u %.*s\n", pVar->value_length, strlen(pVar->value), (int)cchName, pVar->name)); 568 615 569 /* Make sure the variable is simple, convert it if necessary. */ 616 570 if (pVar->recursive) … … 2199 2153 } 2200 2154 2155 /* 2156 2157 ## Inherit one template property in a non-accumulative manner. 2158 # @param $(prop) Property name 2159 # @param $(target) Target name 2160 # @todo fix the precedence order for some properties. 2161 define def_inherit_template_one 2162 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop) 2163 ifndef $(target)_$(prop) 2164 $(target)_$(prop) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop)) 2165 endif 2166 endif 2167 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg) 2168 ifndef $(target)_$(prop).$(bld_trg) 2169 $(target)_$(prop).$(bld_trg) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)) 2170 endif 2171 endif 2172 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch) 2173 ifndef $(target)_$(prop).$(bld_trg).$(bld_trg_arch) 2174 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)) 2175 endif 2176 endif 2177 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch) 2178 ifndef $(target)_$(prop).$(bld_trg_arch) 2179 $(target)_$(prop).$(bld_trg_arch) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)) 2180 endif 2181 endif 2182 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu) 2183 ifndef $(target)_$(prop).$(bld_trg_cpu) 2184 $(target)_$(prop).$(bld_trg_cpu) := $(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)) 2185 endif 2186 endif 2187 endef 2188 2189 ## Inherit one template property in a non-accumulative manner, deferred expansion. 2190 # @param 1: $(prop) Property name 2191 # @param 2: $(target) Target name 2192 # @todo fix the precedence order for some properties. 2193 # @remark this define relies on double evaluation 2194 define def_inherit_template_one_deferred 2195 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop) 2196 ifndef $(target)_$(prop) 2197 $(target)_$(prop) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop)) 2198 endif 2199 endif 2200 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg) 2201 ifndef $(target)_$(prop).$(bld_trg) 2202 $(target)_$(prop).$(bld_trg) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)) 2203 endif 2204 endif 2205 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch) 2206 ifndef $(target)_$(prop).$(bld_trg).$(bld_trg_arch) 2207 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)) 2208 endif 2209 endif 2210 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch) 2211 ifndef $(target)_$(prop).$(bld_trg_arch) 2212 $(target)_$(prop).$(bld_trg_arch) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)) 2213 endif 2214 endif 2215 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu) 2216 ifndef $(target)_$(prop).$(bld_trg_cpu) 2217 $(target)_$(prop).$(bld_trg_cpu) = $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)) 2218 endif 2219 endif 2220 endef 2221 2222 ## Inherit one acculumlative template property where the 'most significant' items are at the left end. 2223 # @param $(prop) Property name 2224 # @param $(target) Target name 2225 define def_inherit_template_one_accumulate_l 2226 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop) 2227 ifeq ($$(flavor $(target)_$(prop)),simple) 2228 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop)) 2229 endif 2230 $(target)_$(prop) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop)) 2231 endif 2232 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE) 2233 ifeq ($$(flavor $(target)_$(prop).$(KBUILD_TYPE)),simple) 2234 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(KBUILD_TYPE)) 2235 endif 2236 $(target)_$(prop).$(KBUILD_TYPE) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE)) 2237 endif 2238 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg) 2239 ifeq ($$(flavor $(target)_$(prop).$(bld_trg)),simple) 2240 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg)) 2241 endif 2242 $(target)_$(prop).$(bld_trg) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)) 2243 endif 2244 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch) 2245 ifeq ($$(flavor $(target)_$(prop).$(bld_trg).$(bld_trg_arch)),simple) 2246 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg).$(bld_trg_arch)) 2247 endif 2248 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)) 2249 endif 2250 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu) 2251 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_cpu)),simple) 2252 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_cpu)) 2253 endif 2254 $(target)_$(prop).$(bld_trg_cpu) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)) 2255 endif 2256 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch) 2257 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_arch)),simple) 2258 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_arch)) 2259 endif 2260 $(target)_$(prop).$(bld_trg_arch) += $$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)) 2261 endif 2262 endef 2263 2264 ## Inherit one acculumlative template property where the 'most significant' items are at the right end. 2265 # @param $(prop) Property name 2266 # @param $(target) Target name 2267 define def_inherit_template_one_accumulate_r 2268 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop) 2269 ifeq ($$(flavor $(target)_$(prop)),simple) 2270 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop)) 2271 endif 2272 $(target)_$(prop) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop)) 2273 endif 2274 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE) 2275 ifeq ($$(flavor $(target)_$(prop).$(KBUILD_TYPE)),simple) 2276 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(KBUILD_TYPE)) 2277 endif 2278 $(target)_$(prop).$(KBUILD_TYPE) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(KBUILD_TYPE)) 2279 endif 2280 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg) 2281 ifeq ($$(flavor $(target)_$(prop).$(bld_trg)),simple) 2282 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg)) 2283 endif 2284 $(target)_$(prop).$(bld_trg) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg)) 2285 endif 2286 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch) 2287 ifeq ($$(flavor $(target)_$(prop).$(bld_trg).$(bld_trg_arch)),simple) 2288 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg).$(bld_trg_arch)) 2289 endif 2290 $(target)_$(prop).$(bld_trg).$(bld_trg_arch) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg).$(bld_trg_arch)) 2291 endif 2292 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu) 2293 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_cpu)),simple) 2294 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_cpu)) 2295 endif 2296 $(target)_$(prop).$(bld_trg_cpu) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_cpu)) 2297 endif 2298 ifdef TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch) 2299 ifeq ($$(flavor $(target)_$(prop).$(bld_trg_arch)),simple) 2300 $$(evalcall2 def_simple_2_recursive,$(target)_$(prop).$(bld_trg_arch)) 2301 endif 2302 $(target)_$(prop).$(bld_trg_arch) <=$$(TEMPLATE_$($(target)_TEMPLATE)_$(prop).$(bld_trg_arch)) 2303 endif 2304 endef 2305 2306 2307 ## Inherit template properties for on target. 2308 # @param $(target) Target name. 2309 define def_inherit_template 2310 # sanity check. 2311 ifdef _$(target)_ALREADY_PROCESSED 2312 $(error kBuild: The target $(target) appears more than once in the target lists! Please correct the makefile(s)) 2313 endif 2314 _$(target)_ALREADY_PROCESSED := 1 2315 2316 # Inherit any default template. 2317 ifdef TEMPLATE 2318 ifeq ($($(target)_TEMPLATE),) 2319 $(eval $(target)_TEMPLATE:=$(TEMPLATE)) 2320 endif 2321 endif 2322 # Expand the template if specified. 2323 ifneq ($($(target)_TEMPLATE),) 2324 $(foreach prop,$(PROPS_SINGLE),$(evalval def_inherit_template_one)) 2325 $(foreach prop,$(PROPS_DEFERRED),$(eval $(def_inherit_template_one_deferred))) # exploits the 2 evaluation, so no value! 2326 $(foreach prop,$(PROPS_ACCUMULATE_L),$(eval $(def_inherit_template_one_accumulate_l))) # += works fine without value 2327 $(foreach prop,$(PROPS_ACCUMULATE_R),$(eval $(def_inherit_template_one_accumulate_r))) # use <= (kmk addition) 2328 endif 2329 endef 2330 2331 2332 Invoked like this: 2333 $(kb-exp-tmpl 1,$(_ALL_TARGET_TARGETS),$(KBUILD_TARGET),$(KBUILD_TARGET_ARCH),$(KBUILD_TARGET_CPU),$(KBUILD_TYPE)) 2334 */ 2335 char * 2336 func_kbuild_expand_template(char *o, char **argv, const char *pszFuncName) 2337 { 2338 const char *pszVersion = argv[0]; 2339 const char *pszBldTrg = argv[2]; 2340 const char *pszBldTrgArch = argv[3]; 2341 const char *pszBldTrgCpu = argv[4]; 2342 const char *pszBldType = argv[5]; 2343 size_t cchBldTrg = strlen(pszBldTrg); 2344 size_t cchBldTrgArch = strlen(pszBldTrgArch); 2345 size_t cchBldTrgCpu = strlen(pszBldTrgCpu); 2346 size_t cchBldType = strlen(pszBldType); 2347 size_t cchMaxBld = cchBldTrg + cchBldTrgArch + cchBldTrgCpu + cchBldType; /* too big, but so what. */ 2348 struct kbet_key 2349 { 2350 unsigned int cch; 2351 char *psz; 2352 } aKeys[6]; 2353 unsigned int const cKeys = 6; 2354 unsigned int iKey; 2355 struct variable *pDefTemplate; 2356 struct variable *pProps; 2357 struct kbet_prop 2358 { 2359 unsigned int cch; 2360 const char *pch; 2361 } *paProps; 2362 unsigned int cProps; 2363 unsigned int iProp; 2364 unsigned int iPropsSingle; 2365 unsigned int iPropsSingleEnd; 2366 unsigned int iPropsDeferred; 2367 unsigned int iPropsDeferredEnd; 2368 unsigned int iPropsAccumulateL; 2369 unsigned int iPropsAccumulateLEnd; 2370 unsigned int iPropsAccumulateR; 2371 unsigned int iPropsAccumulateREnd; 2372 size_t cchMaxProp; 2373 struct variable *pVarTrg; 2374 struct variable *pVarSrc; 2375 const char *pszIter; 2376 const char *pszTarget; 2377 unsigned int cchTarget; 2378 char *pszSrc = 0; 2379 char *pszSrcRef = 0; 2380 char *pszSrcBuf = 0; 2381 size_t cchSrcBuf = 0; 2382 char *pszTrg = 0; 2383 size_t cchTrg = 0; 2384 2385 /* 2386 * Validate input. 2387 */ 2388 if (pszVersion[0] != '1' || pszVersion[1]) 2389 fatal(NULL, "%s: Unsupported version `%s'", pszFuncName, pszVersion); 2390 2391 if (!cchBldTrg) 2392 fatal(NULL, "%s: missing bldtrg", pszFuncName); 2393 2394 if (!cchBldTrgArch) 2395 fatal(NULL, "%s: missing bld_trg_arch", pszFuncName); 2396 2397 if (!cchBldTrgCpu) 2398 fatal(NULL, "%s: missing bld_trg_cpu", pszFuncName); 2399 2400 if (!cchBldType) 2401 fatal(NULL, "%s: missing bld_type", pszFuncName); 2402 2403 /* 2404 * Prepare the keywords, prepending dots for quicker copying. 2405 * This allows for an inner loop when processing properties, saving code 2406 * at the expense of a few xmallocs. 2407 */ 2408 /* the first entry is empty. */ 2409 aKeys[0].cch = 0; 2410 aKeys[0].psz = NULL; 2411 2412 aKeys[1].cch = cchBldType + 1; 2413 aKeys[1].psz = xmalloc (aKeys[1].cch + 1); 2414 aKeys[1].psz[0] = '.'; 2415 memcpy(aKeys[1].psz + 1, pszBldType, cchBldType + 1); 2416 2417 aKeys[2].cch = cchBldTrg + 1; 2418 aKeys[2].psz = xmalloc (aKeys[2].cch + 1); 2419 aKeys[2].psz[0] = '.'; 2420 memcpy(aKeys[2].psz + 1, pszBldTrg, cchBldTrg + 1); 2421 2422 aKeys[3].cch = cchBldTrg + 1 + cchBldTrgArch + 1; 2423 aKeys[3].psz = xmalloc (aKeys[3].cch + 1); 2424 aKeys[3].psz[0] = '.'; 2425 memcpy(aKeys[3].psz + 1, pszBldTrg, cchBldTrg); 2426 aKeys[3].psz[1 + cchBldTrg] = '.'; 2427 memcpy(aKeys[3].psz + 1 + cchBldTrg + 1, pszBldTrgArch, cchBldTrgArch + 1); 2428 2429 aKeys[4].cch = cchBldTrgCpu + 1; 2430 aKeys[4].psz = xmalloc (aKeys[4].cch + 1); 2431 aKeys[4].psz[0] = '.'; 2432 memcpy(aKeys[4].psz + 1, pszBldTrgCpu, cchBldTrgCpu + 1); 2433 2434 aKeys[5].cch = cchBldTrgArch + 1; 2435 aKeys[5].psz = xmalloc (aKeys[5].cch + 1); 2436 aKeys[5].psz[0] = '.'; 2437 memcpy(aKeys[5].psz + 1, pszBldTrgArch, cchBldTrgArch + 1); 2438 2439 2440 /* 2441 * Prepare the properties, folding them into an array. 2442 * This way we won't have to reparse them for each an every target, though 2443 * it comes at the expense of one or more heap calls. 2444 */ 2445 #define PROP_ALLOC_INC 128 2446 iProp = 0; 2447 cProps = PROP_ALLOC_INC; 2448 paProps = xmalloc(sizeof(*pProps) * cProps); 2449 2450 pProps = kbuild_get_variable_n(ST("PROPS_SINGLE")); 2451 iPropsSingle = iProp; 2452 pszIter = pProps->value; 2453 while ((paProps[iProp].pch = find_next_token(&pszIter, &paProps[iProp].cch))) 2454 if (++iProp >= cProps) 2455 { 2456 cProps += PROP_ALLOC_INC; 2457 paProps = xrealloc(paProps, sizeof(*paProps) * cProps); 2458 } 2459 iPropsSingleEnd = iProp; 2460 2461 pProps = kbuild_get_variable_n(ST("PROPS_DEFERRED")); 2462 iPropsDeferred = iProp; 2463 pszIter = pProps->value; 2464 while ((paProps[iProp].pch = find_next_token(&pszIter, &paProps[iProp].cch))) 2465 if (++iProp >= cProps) 2466 { 2467 cProps += PROP_ALLOC_INC; 2468 paProps = xrealloc(paProps, sizeof(*paProps) * cProps); 2469 } 2470 iPropsDeferredEnd = iProp; 2471 2472 pProps = kbuild_get_variable_n(ST("PROPS_ACCUMULATE_L")); 2473 iPropsAccumulateL = iProp; 2474 pszIter = pProps->value; 2475 while ((paProps[iProp].pch = find_next_token(&pszIter, &paProps[iProp].cch))) 2476 if (++iProp >= cProps) 2477 { 2478 cProps += PROP_ALLOC_INC; 2479 paProps = xrealloc(paProps, sizeof(*paProps) * cProps); 2480 } 2481 iPropsAccumulateLEnd = iProp; 2482 2483 pProps = kbuild_get_variable_n(ST("PROPS_ACCUMULATE_R")); 2484 iPropsAccumulateR = iProp; 2485 pszIter = pProps->value; 2486 while ((paProps[iProp].pch = find_next_token(&pszIter, &paProps[iProp].cch))) 2487 if (++iProp >= cProps) 2488 { 2489 cProps += PROP_ALLOC_INC; 2490 paProps = xrealloc(paProps, sizeof(*paProps) * cProps); 2491 } 2492 iPropsAccumulateREnd = iProp; 2493 #undef PROP_ALLOC_INC 2494 cProps = iProp; 2495 2496 /* find the max prop length. */ 2497 cchMaxProp = paProps[0].cch; 2498 while (--iProp > 0) 2499 if (paProps[iProp].cch > cchMaxProp) 2500 cchMaxProp = paProps[iProp].cch; 2501 2502 /* 2503 * Query and prepare (strip) the default template 2504 * (given by the TEMPLATE variable). 2505 */ 2506 pDefTemplate = kbuild_lookup_variable_n(ST("TEMPLATE")); 2507 if (pDefTemplate) 2508 { 2509 if ( pDefTemplate->value_length 2510 && ( isspace(pDefTemplate->value[0]) 2511 || isspace(pDefTemplate->value[pDefTemplate->value_length - 1]))) 2512 { 2513 unsigned int off; 2514 if (pDefTemplate->rdonly_val) 2515 fatal(NULL, "%s: TEMPLATE is read-only", pszFuncName); 2516 2517 /* head */ 2518 for (off = 0; isspace(pDefTemplate->value[off]); off++) 2519 /* nothing */; 2520 if (off) 2521 { 2522 pDefTemplate->value_length -= off; 2523 memmove(pDefTemplate->value, pDefTemplate->value + off, pDefTemplate->value_length + 1); 2524 } 2525 2526 /* tail */ 2527 off = pDefTemplate->value_length; 2528 while (off > 0 && isspace(pDefTemplate->value[off - 1])) 2529 off--; 2530 pDefTemplate->value_length = off; 2531 pDefTemplate->value[off] = '\0'; 2532 } 2533 2534 if (!pDefTemplate->value_length) 2535 pDefTemplate = NULL; 2536 } 2537 2538 /* 2539 * Iterate the target list. 2540 */ 2541 pszIter = argv[1]; 2542 while ((pszTarget = find_next_token(&pszIter, &cchTarget))) 2543 { 2544 char *pszTrgProp, *pszSrcProp; 2545 char *pszTrgKey, *pszSrcKey; 2546 struct variable *pTmpl; 2547 const char *pszTmpl; 2548 size_t cchTmpl, cchMax; 2549 2550 /* resize the target buffer. */ 2551 cchMax = cchTarget + cchMaxProp + cchMaxBld + 10; 2552 if (cchTrg < cchMax) 2553 { 2554 cchTrg = (cchMax + 31U) & ~(size_t)31; 2555 pszTrg = xrealloc(pszTrg, cchTrg); 2556 } 2557 2558 /* 2559 * Query the TEMPLATE property, if not found or zero-length fall back on the default. 2560 */ 2561 memcpy(pszTrg, pszTarget, cchTarget); 2562 pszTrgProp = pszTrg + cchTarget; 2563 memcpy(pszTrgProp, "_TEMPLATE", sizeof("_TEMPLATE")); 2564 pszTrgProp++; /* after '_'. */ 2565 2566 /** @todo Change this to a recursive lookup with simplification below. That 2567 * will allow target_TEMPLATE = $(NO_SUCH_TEMPLATE) instead of having 2568 * to use target_TEMPLATE = DUMMY */ 2569 pTmpl = kbuild_lookup_variable_n(pszTrg, cchTarget + sizeof("_TEMPLATE") - 1); 2570 if (!pTmpl || !pTmpl->value_length) 2571 { 2572 if (!pDefTemplate) 2573 continue; /* no template */ 2574 pszTmpl = pDefTemplate->value; 2575 cchTmpl = pDefTemplate->value_length; 2576 } 2577 else 2578 { 2579 pszTmpl = pTmpl->value; 2580 cchTmpl = pTmpl->value_length; 2581 while (isspace(*pszTmpl)) 2582 cchTmpl--, pszTmpl++; 2583 if (!cchTmpl) 2584 continue; /* no template */ 2585 } 2586 2587 /* resize the source buffer. */ 2588 cchMax = sizeof("TEMPLATE_") + cchTmpl + cchMaxProp + cchMaxBld + 10 + sizeof(void *); 2589 if (cchSrcBuf < cchMax) 2590 { 2591 cchSrcBuf = (cchMax + 31U) & ~(size_t)31; 2592 pszSrcBuf = xrealloc(pszSrcBuf, cchSrcBuf); 2593 pszSrc = pszSrcBuf + sizeof(void *); assert(sizeof(void *) >= 2); 2594 pszSrcRef = pszSrc - 2; 2595 pszSrcRef[0] = '$'; 2596 pszSrcRef[1] = '('; 2597 } 2598 2599 /* prepare the source buffer */ 2600 memcpy(pszSrc, "TEMPLATE_", sizeof("TEMPLATE_") - 1); 2601 pszSrcProp = pszSrc + sizeof("TEMPLATE_") - 1; 2602 memcpy(pszSrcProp, pszTmpl, cchTmpl); 2603 pszSrcProp += cchTmpl; 2604 *pszSrcProp++ = '_'; 2605 2606 /* 2607 * Process properties. 2608 * Note! The single and deferred are handled in the same way now. 2609 */ 2610 #define BY_REF_LIMIT 64 /*(cchSrcVar * 4 > 64 ? cchSrcVar * 4 : 64)*/ 2611 2612 /* single: copy template prop if target doesn't define it. */ 2613 for (iProp = iPropsSingle; iProp < iPropsSingleEnd; iProp++) 2614 { 2615 memcpy(pszTrgProp, paProps[iProp].pch, paProps[iProp].cch); 2616 pszTrgKey = pszTrgProp + paProps[iProp].cch; 2617 2618 memcpy(pszSrcProp, paProps[iProp].pch, paProps[iProp].cch); 2619 pszSrcKey = pszSrcProp + paProps[iProp].cch; 2620 2621 for (iKey = 0; iKey < cKeys; iKey++) 2622 { 2623 char *pszTrgEnd; 2624 size_t cchSrcVar; 2625 2626 /* lookup source, skip ahead if it doesn't exist. */ 2627 memcpy(pszSrcKey, aKeys[iKey].psz, aKeys[iKey].cch); 2628 cchSrcVar = pszSrcKey - pszSrc + aKeys[iKey].cch; 2629 pszSrc[cchSrcVar] = '\0'; 2630 pVarSrc = kbuild_query_recursive_variable_n(pszSrc, cchSrcVar); 2631 if (!pVarSrc) 2632 continue; 2633 2634 /* lookup target, skip ahead if it exists. */ 2635 memcpy(pszTrgKey, aKeys[iKey].psz, aKeys[iKey].cch); 2636 pszTrgEnd = pszTrgKey + aKeys[iKey].cch; 2637 *pszTrgEnd = '\0'; 2638 pVarTrg = kbuild_query_recursive_variable_n(pszTrg, pszTrgEnd - pszTrg); 2639 if (pVarTrg) 2640 continue; 2641 2642 /* copy the variable if its short, otherwise reference it. */ 2643 if (pVarSrc->value_length < BY_REF_LIMIT) 2644 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2645 pVarSrc->value, pVarSrc->value_length, 2646 1 /* duplicate_value */, 2647 o_file, 2648 pVarSrc->recursive, 2649 NULL /* flocp */); 2650 else 2651 { 2652 pszSrc[cchSrcVar] = ')'; 2653 pszSrc[cchSrcVar + 1] = '\0'; 2654 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2655 pszSrcRef, 2 + cchSrcVar + 1, 2656 1 /* duplicate_value */, 2657 o_file, 2658 1 /* recursive */, 2659 NULL /* flocp */); 2660 } 2661 } /* foreach key */ 2662 } /* foreach single prop */ 2663 2664 /* deferred: copy template prop if target doesn't define it. */ 2665 for (iProp = iPropsDeferred; iProp < iPropsDeferredEnd; iProp++) 2666 { 2667 memcpy(pszTrgProp, paProps[iProp].pch, paProps[iProp].cch); 2668 pszTrgKey = pszTrgProp + paProps[iProp].cch; 2669 2670 memcpy(pszSrcProp, paProps[iProp].pch, paProps[iProp].cch); 2671 pszSrcKey = pszSrcProp + paProps[iProp].cch; 2672 2673 for (iKey = 0; iKey < cKeys; iKey++) 2674 { 2675 char *pszTrgEnd; 2676 size_t cchSrcVar; 2677 2678 /* lookup source, skip ahead if it doesn't exist. */ 2679 memcpy(pszSrcKey, aKeys[iKey].psz, aKeys[iKey].cch); 2680 cchSrcVar = pszSrcKey - pszSrc + aKeys[iKey].cch; 2681 pszSrc[cchSrcVar] = '\0'; 2682 pVarSrc = kbuild_query_recursive_variable_n(pszSrc, cchSrcVar); 2683 if (!pVarSrc) 2684 continue; 2685 2686 /* lookup target, skip ahead if it exists. */ 2687 memcpy(pszTrgKey, aKeys[iKey].psz, aKeys[iKey].cch); 2688 pszTrgEnd = pszTrgKey + aKeys[iKey].cch; 2689 *pszTrgEnd = '\0'; 2690 pVarTrg = kbuild_query_recursive_variable_n(pszTrg, pszTrgEnd - pszTrg); 2691 if (pVarTrg) 2692 continue; 2693 2694 /* copy the variable if its short, otherwise reference it. */ 2695 if (pVarSrc->value_length < BY_REF_LIMIT) 2696 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2697 pVarSrc->value, pVarSrc->value_length, 2698 1 /* duplicate_value */, 2699 o_file, 2700 pVarSrc->recursive, 2701 NULL /* flocp */); 2702 else 2703 { 2704 pszSrc[cchSrcVar] = ')'; 2705 pszSrc[cchSrcVar + 1] = '\0'; 2706 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2707 pszSrcRef, 2 + cchSrcVar + 1, 2708 1 /* duplicate_value */, 2709 o_file, 2710 1 /* recursive */, 2711 NULL /* flocp */); 2712 } 2713 } /* foreach key */ 2714 } /* foreach deferred prop */ 2715 2716 /* accumulate_l: append the unexpanded template variable to the . */ 2717 for (iProp = iPropsAccumulateL; iProp < iPropsAccumulateLEnd; iProp++) 2718 { 2719 memcpy(pszTrgProp, paProps[iProp].pch, paProps[iProp].cch); 2720 pszTrgKey = pszTrgProp + paProps[iProp].cch; 2721 2722 memcpy(pszSrcProp, paProps[iProp].pch, paProps[iProp].cch); 2723 pszSrcKey = pszSrcProp + paProps[iProp].cch; 2724 2725 for (iKey = 0; iKey < cKeys; iKey++) 2726 { 2727 char *pszTrgEnd; 2728 size_t cchSrcVar; 2729 2730 /* lookup source, skip ahead if it doesn't exist. */ 2731 memcpy(pszSrcKey, aKeys[iKey].psz, aKeys[iKey].cch); 2732 cchSrcVar = pszSrcKey - pszSrc + aKeys[iKey].cch; 2733 pszSrc[cchSrcVar] = '\0'; 2734 pVarSrc = kbuild_query_recursive_variable_n(pszSrc, cchSrcVar); 2735 if (!pVarSrc) 2736 continue; 2737 2738 /* lookup target, skip ahead if it exists. */ 2739 memcpy(pszTrgKey, aKeys[iKey].psz, aKeys[iKey].cch); 2740 pszTrgEnd = pszTrgKey + aKeys[iKey].cch; 2741 *pszTrgEnd = '\0'; 2742 pVarTrg = kbuild_query_recursive_variable_n(pszTrg, pszTrgEnd - pszTrg); 2743 if (!pVarTrg) 2744 { 2745 /* The target doesn't exist, copy the source if it's short, 2746 otherwise just reference it. */ 2747 if (pVarSrc->value_length < BY_REF_LIMIT) 2748 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2749 pVarSrc->value, pVarSrc->value_length, 2750 1 /* duplicate_value */, 2751 o_file, 2752 pVarSrc->recursive, 2753 NULL /* flocp */); 2754 else 2755 { 2756 pszSrc[cchSrcVar] = ')'; 2757 pszSrc[cchSrcVar + 1] = '\0'; 2758 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2759 pszSrcRef, 2 + cchSrcVar + 1, 2760 1 /* duplicate_value */, 2761 o_file, 2762 1 /* recursive */, 2763 NULL /* flocp */); 2764 } 2765 } 2766 else 2767 { 2768 /* Append to existing variable. If the source is recursive, 2769 or we append by reference, we'll have to make sure the 2770 target is recusive as well. */ 2771 if ( !pVarTrg->recursive 2772 && ( pVarSrc->value_length >= BY_REF_LIMIT 2773 || pVarSrc->recursive)) 2774 pVarTrg->recursive = 1; 2775 2776 if (pVarSrc->value_length < BY_REF_LIMIT) 2777 append_string_to_variable(pVarTrg, pVarSrc->value, pVarSrc->value_length, 1 /* append */); 2778 else 2779 { 2780 pszSrc[cchSrcVar] = ')'; 2781 pszSrc[cchSrcVar + 1] = '\0'; 2782 append_string_to_variable(pVarTrg, pszSrcRef, 2 + cchSrcVar + 1, 1 /* append */); 2783 } 2784 } 2785 } /* foreach key */ 2786 } /* foreach accumulate_l prop */ 2787 2788 /* accumulate_r: prepend the unexpanded template variable to the . */ 2789 for (iProp = iPropsAccumulateR; iProp < iPropsAccumulateREnd; iProp++) 2790 { 2791 memcpy(pszTrgProp, paProps[iProp].pch, paProps[iProp].cch); 2792 pszTrgKey = pszTrgProp + paProps[iProp].cch; 2793 2794 memcpy(pszSrcProp, paProps[iProp].pch, paProps[iProp].cch); 2795 pszSrcKey = pszSrcProp + paProps[iProp].cch; 2796 2797 for (iKey = 0; iKey < cKeys; iKey++) 2798 { 2799 char *pszTrgEnd; 2800 size_t cchSrcVar; 2801 2802 /* lookup source, skip ahead if it doesn't exist. */ 2803 memcpy(pszSrcKey, aKeys[iKey].psz, aKeys[iKey].cch); 2804 cchSrcVar = pszSrcKey - pszSrc + aKeys[iKey].cch; 2805 pszSrc[cchSrcVar] = '\0'; 2806 pVarSrc = kbuild_query_recursive_variable_n(pszSrc, cchSrcVar); 2807 if (!pVarSrc) 2808 continue; 2809 2810 /* lookup target, skip ahead if it exists. */ 2811 memcpy(pszTrgKey, aKeys[iKey].psz, aKeys[iKey].cch); 2812 pszTrgEnd = pszTrgKey + aKeys[iKey].cch; 2813 *pszTrgEnd = '\0'; 2814 pVarTrg = kbuild_query_recursive_variable_n(pszTrg, pszTrgEnd - pszTrg); 2815 if (!pVarTrg) 2816 { 2817 /* The target doesn't exist, copy the source if it's short, 2818 otherwise just reference it. */ 2819 if (pVarSrc->value_length < BY_REF_LIMIT) 2820 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2821 pVarSrc->value, pVarSrc->value_length, 2822 1 /* duplicate_value */, 2823 o_file, 2824 pVarSrc->recursive, 2825 NULL /* flocp */); 2826 else 2827 { 2828 pszSrc[cchSrcVar] = ')'; 2829 pszSrc[cchSrcVar + 1] = '\0'; 2830 define_variable_vl_global(pszTrg, pszTrgEnd - pszTrg, 2831 pszSrcRef, 2 + cchSrcVar + 1, 2832 1 /* duplicate_value */, 2833 o_file, 2834 1 /* recursive */, 2835 NULL /* flocp */); 2836 } 2837 } 2838 else 2839 { 2840 /* Append to existing variable. If the source is recursive, 2841 or we append by reference, we'll have to make sure the 2842 target is recusive as well. */ 2843 if ( !pVarTrg->recursive 2844 && ( pVarSrc->value_length >= BY_REF_LIMIT 2845 || pVarSrc->recursive)) 2846 pVarTrg->recursive = 1; 2847 2848 if (pVarSrc->value_length < BY_REF_LIMIT) 2849 append_string_to_variable(pVarTrg, pVarSrc->value, pVarSrc->value_length, 0 /* prepend */); 2850 else 2851 { 2852 pszSrc[cchSrcVar] = ')'; 2853 pszSrc[cchSrcVar + 1] = '\0'; 2854 append_string_to_variable(pVarTrg, pszSrcRef, 2 + cchSrcVar + 1, 0 /* append */); 2855 } 2856 } 2857 } /* foreach key */ 2858 } /* foreach accumulate_r prop */ 2859 2860 #undef BY_REF_LIMIT 2861 } /* foreach target */ 2862 2863 /* 2864 * Cleanup. 2865 */ 2866 free(pszSrcBuf); 2867 free(pszTrg); 2868 free(paProps); 2869 for (iKey = 1; iKey < cKeys; iKey++) 2870 free(aKeys[iKey].psz); 2871 2872 return o; 2873 } 2201 2874 2202 2875 #endif /* KMK_HELPERS */
Note:
See TracChangeset
for help on using the changeset viewer.