Changeset 2717 for trunk/src/kmk/kbuild-read.c
- Timestamp:
- Dec 30, 2013, 1:58:43 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kbuild-read.c
r2549 r2717 5 5 6 6 /* 7 * Copyright (c) 2011 knut st. osmundsen <bird-kBuild-spamx@anduin.net>7 * Copyright (c) 2011-2013 knut st. osmundsen <bird-kBuild-spamx@anduin.net> 8 8 * 9 9 * This file is part of kBuild. … … 37 37 38 38 #include <assert.h> 39 #include <stdarg.h> 39 40 40 41 … … 49 50 * Structures and Typedefs * 50 51 *******************************************************************************/ 51 /** Indicate which kind of kBuild define we're working on. */52 enum kBuild Def53 { 54 kBuild Def_Invalid,55 kBuild Def_Target,56 kBuild Def_Template,57 kBuild Def_Tool,58 kBuild Def_Sdk,59 kBuild Def_Unit52 /** kBuild object type. */ 53 enum kBuildType 54 { 55 kBuildType_Invalid, 56 kBuildType_Target, 57 kBuildType_Template, 58 kBuildType_Tool, 59 kBuildType_Sdk, 60 kBuildType_Unit 60 61 }; 61 62 62 enum kBuildExtendBy 63 { 64 kBuildExtendBy_NoParent, 65 kBuildExtendBy_Overriding, 66 kBuildExtendBy_Appending, 67 kBuildExtendBy_Prepending 63 enum kBuildSeverity 64 { 65 kBuildSeverity_Warning, 66 kBuildSeverity_Error, 67 kBuildSeverity_Fatal 68 68 }; 69 69 70 70 71 71 /** 72 * The data we stack during eval. 73 */ 74 struct kbuild_eval_data 75 { 76 /** The kind of define. */ 77 enum kBuildDef enmKind; 72 * kBuild object data. 73 */ 74 struct kbuild_object 75 { 76 /** The object type. */ 77 enum kBuildType enmType; 78 /** Object name length. */ 79 size_t cchName; 78 80 /** The bare name of the define. */ 79 81 char *pszName; … … 82 84 83 85 /** Pointer to the next element in the global list. */ 84 struct kbuild_eval_data *pGlobalNext; 85 /** Pointer to the element below us on the stack. */ 86 struct kbuild_eval_data *pStackDown; 86 struct kbuild_object *pGlobalNext; 87 87 88 88 /** The variable set associated with this define. */ 89 89 struct variable_set_list *pVariables; 90 /** The saved current variable set, for restoring in kBuild-endef. */91 struct variable_set_list *pVariablesSaved;92 90 93 91 /** The parent name, NULL if none. */ 94 92 char *pszParent; 95 /** The inheritance method. */ 96 enum kBuildExtendBy enmExtendBy; 97 /** Pointer to the parent. Resolved lazily, so it can be NULL even if we have 98 * a parent. */ 99 struct kbuild_eval_data *pParent; 100 101 /** The template, NULL if none. Only applicable to targets. */ 102 char *pszTemplate; 103 /** Pointer to the template. Resolved lazily, so it can be NULL even if we have 104 * a parent. */ 105 struct kbuild_eval_data *pTemplate; 106 107 /** The variable prefix. */ 93 /** The length of the parent name. */ 94 size_t cchParent; 95 /** Pointer to the parent. Resolved lazily, so it can be NULL even if we 96 * have a parent. */ 97 struct kbuild_object *pParent; 98 99 /** The template, NULL if none. Only applicable to targets. Only covers the 100 * primary template, not target or type specific templates. 101 * @todo not sure if this is really necessary. */ 102 char const *pszTemplate; 103 104 /** The variable prefix. */ 108 105 char *pszVarPrefix; 109 106 /** The length of the variable prefix. */ 110 107 size_t cchVarPrefix; 111 108 }; 109 110 111 /** 112 * The data we stack during eval. 113 */ 114 struct kbuild_eval_data 115 { 116 /** Pointer to the element below us on the stack. */ 117 struct kbuild_eval_data *pStackDown; 118 /** Pointer to the object. */ 119 struct kbuild_object *pObj; 120 /** The saved current variable set, for restoring in kBuild-endef. */ 121 struct variable_set_list *pVariablesSaved; 122 }; 123 112 124 113 125 … … 117 129 /** Linked list (LIFO) of kBuild defines. 118 130 * @todo use a hash! */ 119 struct kbuild_eval_data *g_pHeadKbDefs = NULL; 120 /** Stack of kBuild defines. */ 121 struct kbuild_eval_data *g_pTopKbDef = NULL; 122 123 124 struct variable_set * 125 get_top_kbuild_variable_set(void) 126 { 127 struct kbuild_eval_data *pTop = g_pTopKbDef; 128 assert(pTop != NULL); 129 return pTop->pVariables->set; 130 } 131 132 133 char * 134 kbuild_prefix_variable(const char *pszName, unsigned int *pcchName) 135 { 136 struct kbuild_eval_data *pTop = g_pTopKbDef; 137 char *pszPrefixed; 138 unsigned int cchPrefixed; 139 140 assert(pTop != NULL); 141 142 cchPrefixed = pTop->cchVarPrefix + *pcchName; 143 pszPrefixed = xmalloc(cchPrefixed + 1); 144 memcpy(pszPrefixed, pTop->pszVarPrefix, pTop->cchVarPrefix); 145 memcpy(&pszPrefixed[pTop->cchVarPrefix], pszName, *pcchName); 146 pszPrefixed[cchPrefixed] = '\0'; 147 *pcchName = cchPrefixed; 148 return pszPrefixed; 149 } 150 151 131 static struct kbuild_object *g_pHeadKbObjs = NULL; 132 /** Stack of kBuild evalutation contexts. 133 * This is for dealing with potential recursive kBuild object definition, 134 * generally believed to only happen via $(eval ) or include similar. */ 135 struct kbuild_eval_data *g_pTopKbEvalData = NULL; 136 137 /** Cached variable name '_TEMPLATE'. */ 138 static const char *g_pszVarNmTemplate = NULL; 139 140 /** Zero if compatibility mode is disabled, non-zero if enabled. 141 * If explicitily enabled, the value will be greater than 1. */ 142 int g_fKbObjCompMode = 1; 143 144 145 /******************************************************************************* 146 * Internal Functions * 147 *******************************************************************************/ 148 static struct kbuild_object * 149 eval_kbuild_resolve_parent(struct kbuild_object *pObj, int fQuiet); 150 151 static struct kbuild_object * 152 parse_kbuild_object_variable_accessor(const char *pchExpr, size_t cchExpr, 153 enum kBuildSeverity enmSeverity, const struct floc *pFileLoc, 154 const char **ppchVarNm, size_t *pcchVarNm, enum kBuildType *penmType); 155 156 157 /** 158 * Initializes the kBuild object stuff. 159 * 160 * Requires the variable_cache to be initialized. 161 */ 162 void init_kbuild_object(void) 163 { 164 g_pszVarNmTemplate = strcache2_add(&variable_strcache, STRING_SIZE_TUPLE("_TEMPLATE")); 165 } 166 167 168 /** 169 * Reports a problem with dynamic severity level. 170 * 171 * @param enmSeverity The severity level. 172 * @param pFileLoc The file location. 173 * @param pszFormat The format string. 174 * @param ... Arguments for the format string. 175 */ 176 static void kbuild_report_problem(enum kBuildSeverity enmSeverity, const struct floc *pFileLoc, 177 const char *pszFormat, ...) 178 { 179 char szBuf[8192]; 180 va_list va; 181 182 va_start(va, pszFormat); 183 #ifdef _MSC_VER 184 _vsnprintf(szBuf, sizeof(szBuf), pszFormat, va); 185 #else 186 vsnprintf(szBuf, sizeof(szBuf), pszFormat, va); 187 #endif 188 va_end(va); 189 190 switch (enmSeverity) 191 { 192 case kBuildSeverity_Warning: 193 message(0, "%s", szBuf); 194 break; 195 case kBuildSeverity_Error: 196 error(pFileLoc, "%s", szBuf); 197 break; 198 default: 199 case kBuildSeverity_Fatal: 200 fatal(pFileLoc, "%s", szBuf); 201 break; 202 } 203 } 204 205 206 /** 207 * Helper function for caching variable name strings. 208 * 209 * @returns The string cache variable name. 210 * @param pszName The variable name. 211 * @param ppszCache Cache variable, static or global. Initialize to 212 * NULL. 213 */ 152 214 static const char * 153 eval_kbuild_kind_to_string(enum kBuildDef enmKind) 154 { 155 switch (enmKind) 156 { 157 case kBuildDef_Target: return "target"; 158 case kBuildDef_Template: return "template"; 159 case kBuildDef_Tool: return "tool"; 160 case kBuildDef_Sdk: return "sdk"; 161 case kBuildDef_Unit: return "unit"; 215 kbuild_variable_name(const char *pszName, const char **ppszCache) 216 { 217 const char *pszRet = *ppszCache; 218 if (!pszRet) 219 *ppszCache = pszRet = strcache2_add(&variable_strcache, pszName, strlen(pszName)); 220 return pszRet; 221 } 222 223 static struct kbuild_object * 224 lookup_kbuild_object(enum kBuildType enmType, const char *pchName, size_t cchName) 225 { 226 /* Linear lookup for now. */ 227 struct kbuild_object *pCur = g_pHeadKbObjs; 228 while (pCur) 229 { 230 if ( pCur->enmType == enmType 231 && pCur->cchName == cchName 232 && !memcmp(pCur->pszName, pchName, cchName)) 233 return pCur; 234 pCur = pCur->pGlobalNext; 235 } 236 return NULL; 237 } 238 239 240 /** @name Defining and modifying variables 241 * @{ 242 */ 243 244 /** 245 * Checks if the variable name is valid. 246 * 247 * @returns 1 if valid, 0 if not. 248 * @param pchName The variable name. 249 * @param cchName The length of the variable name. 250 */ 251 static int 252 is_valid_kbuild_object_variable_name(const char *pchName, size_t cchName) 253 { 254 if (cchName > 0) 255 { 256 if (!memchr(pchName, '[', cchName)) 257 { 258 /** @todo more? */ 259 return 1; 260 } 261 } 262 return 0; 263 } 264 265 static struct variable * 266 define_kbuild_object_variable_cached(struct kbuild_object *pObj, const char *pszName, 267 const char *pchValue, size_t cchValue, 268 int fDuplicateValue, enum variable_origin enmOrigin, 269 int fRecursive, const struct floc *pFileLoc) 270 { 271 struct variable *pVar; 272 size_t cchName = strcache2_get_len(&variable_strcache, pszName); 273 274 275 pVar = define_variable_in_set(pszName, cchName, 276 pchValue, cchValue, fDuplicateValue, 277 enmOrigin, fRecursive, 278 pObj->pVariables->set, 279 pFileLoc); 280 281 /* Single underscore prefixed variables gets a global alias. */ 282 if ( pszName[0] == '_' 283 && pszName[1] != '_' 284 && g_fKbObjCompMode) 285 { 286 size_t cchPrefixed = pObj->cchVarPrefix + cchName; 287 char *pszPrefixed = xmalloc(cchPrefixed + 1); 288 memcpy(pszPrefixed, pObj->pszVarPrefix, pObj->cchVarPrefix); 289 memcpy(&pszPrefixed[pObj->cchVarPrefix], pszName, cchName); 290 pszPrefixed[cchPrefixed] = '\0'; 291 292 /** @todo implement variable aliases or something. */ 293 define_variable_in_set(pszPrefixed, cchPrefixed, 294 pchValue, cchValue, 1 /*duplicate_value*/, 295 enmOrigin, fRecursive, 296 &global_variable_set, 297 pFileLoc); 298 } 299 300 return pVar; 301 } 302 303 #if 0 304 struct variable * 305 define_kbuild_object_variable(struct kbuild_object *pObj, const char *pchName, size_t cchName, 306 const char *pchValue, size_t cchValue, 307 int fDuplicateValue, enum variable_origin enmOrigin, 308 int fRecursive, const struct floc *pFileLoc) 309 { 310 return define_kbuild_object_variable_cached(pObj, strcache2_add(&variable_strcache, pchName, cchName), 311 pchValue, cchValue, 312 fDuplicateValue, enmOrigin, 313 fRecursive, pFileLoc); 314 } 315 #endif 316 317 /** 318 * Try define a kBuild object variable via a possible accessor 319 * ([type@object]var). 320 * 321 * @returns Pointer to the defined variable on success. 322 * @retval VAR_NOT_KBUILD_ACCESSOR if it isn't an accessor. 323 * 324 * @param pchName The variable name, not cached. 325 * @param cchName The variable name length. This will not be ~0U. 326 * @param pszValue The variable value. If @a fDuplicateValue is clear, 327 * this should be assigned as the actual variable 328 * value, otherwise it will be duplicated. In the 329 * latter case it might not be properly null 330 * terminated. 331 * @param cchValue The value length. 332 * @param fDuplicateValue Whether @a pszValue need to be duplicated on the 333 * heap or is already there. 334 * @param enmOrigin The variable origin. 335 * @param fRecursive Whether it's a recursive variable. 336 * @param pFileLoc The location of the variable definition. 337 */ 338 struct variable * 339 try_define_kbuild_object_variable_via_accessor(const char *pchName, size_t cchName, 340 const char *pszValue, size_t cchValue, int fDuplicateValue, 341 enum variable_origin enmOrigin, int fRecursive, 342 struct floc const *pFileLoc) 343 { 344 struct kbuild_object *pObj; 345 const char *pchVarNm; 346 size_t cchVarNm; 347 348 pObj = parse_kbuild_object_variable_accessor(pchName, cchName, kBuildSeverity_Fatal, pFileLoc, 349 &pchVarNm, &cchVarNm, NULL); 350 if (pObj != KOBJ_NOT_KBUILD_ACCESSOR) 351 { 352 assert(pObj != NULL); 353 if (!is_valid_kbuild_object_variable_name(pchVarNm, cchVarNm)) 354 fatal(pFileLoc, _("Invalid kBuild object variable name: '%.*s' ('%s')"), 355 (int)cchVarNm, pchVarNm, (int)cchName, pchName); 356 return define_kbuild_object_variable_cached(pObj, strcache2_add(&variable_strcache, pchVarNm, cchVarNm), 357 pszValue, cchValue, fDuplicateValue, enmOrigin, fRecursive, pFileLoc); 358 } 359 360 return VAR_NOT_KBUILD_ACCESSOR; 361 } 362 363 /** 364 * Define a kBuild object variable in the topmost kBuild object. 365 * 366 * This won't be an variable accessor. 367 * 368 * @returns Pointer to the defined variable on success. 369 * 370 * @param pchName The variable name, not cached. 371 * @param cchName The variable name length. This will not be ~0U. 372 * @param pszValue The variable value. If @a fDuplicateValue is clear, 373 * this should be assigned as the actual variable 374 * value, otherwise it will be duplicated. In the 375 * latter case it might not be properly null 376 * terminated. 377 * @param cchValue The value length. 378 * @param fDuplicateValue Whether @a pszValue need to be duplicated on the 379 * heap or is already there. 380 * @param enmOrigin The variable origin. 381 * @param fRecursive Whether it's a recursive variable. 382 * @param pFileLoc The location of the variable definition. 383 */ 384 struct variable * 385 define_kbuild_object_variable_in_top_obj(const char *pchName, size_t cchName, 386 const char *pszValue, size_t cchValue, int fDuplicateValue, 387 enum variable_origin enmOrigin, int fRecursive, 388 struct floc const *pFileLoc) 389 { 390 assert(g_pTopKbEvalData != NULL); 391 392 if (!is_valid_kbuild_object_variable_name(pchName, cchName)) 393 fatal(pFileLoc, _("Invalid kBuild object variable name: '%.*s'"), (int)cchName, pchName); 394 395 return define_kbuild_object_variable_cached(g_pTopKbEvalData->pObj, strcache2_add(&variable_strcache, pchName, cchName), 396 pszValue, cchValue, fDuplicateValue, enmOrigin, fRecursive, pFileLoc); 397 } 398 399 /** 400 * Implements appending and prepending to a kBuild object variable. 401 * 402 * The variable is either accessed thru an accessor or by the topmost kBuild 403 * object. 404 * 405 * @returns Pointer to the defined variable on success. 406 * 407 * @param pchName The variable name, not cached. 408 * @param cchName The variable name length. This will not be ~0U. 409 * @param pszValue The variable value. Must be duplicated. 410 * @param cchValue The value length. 411 * @param fSimpleValue Whether we've already figured that it's a simple 412 * value. This is for optimizing appending/prepending 413 * to an existing simple value variable. 414 * @param enmOrigin The variable origin. 415 * @param fAppend Append if set, prepend if clear. 416 * @param pFileLoc The location of the variable definition. 417 */ 418 struct variable * 419 kbuild_object_variable_pre_append(const char *pchName, size_t cchName, 420 const char *pchValue, size_t cchValue, int fSimpleValue, 421 enum variable_origin enmOrigin, int fAppend, 422 const struct floc *pFileLoc) 423 { 424 struct kbuild_object *pObj; 425 struct variable VarKey; 426 427 /* 428 * Resolve the relevant kBuild object first. 429 */ 430 if (cchName > 3 && pchName[0] == '[') 431 { 432 const char *pchVarNm; 433 size_t cchVarNm; 434 pObj = parse_kbuild_object_variable_accessor(pchName, cchName, kBuildSeverity_Fatal, pFileLoc, 435 &pchVarNm, &cchVarNm, NULL); 436 if (pObj != KOBJ_NOT_KBUILD_ACCESSOR) 437 { 438 pchName = pchVarNm; 439 cchName = cchVarNm; 440 } 441 else 442 pObj = g_pTopKbEvalData->pObj; 443 } 444 else 445 pObj = g_pTopKbEvalData->pObj; 446 447 /* 448 * Make sure the variable name is valid. Raise fatal error if not. 449 */ 450 if (!is_valid_kbuild_object_variable_name(pchName, cchName)) 451 fatal(pFileLoc, _("Invalid kBuild object variable name: '%.*s'"), (int)cchName, pchName); 452 453 /* 454 * Get the cached name and look it up in the object's variables. 455 */ 456 VarKey.name = strcache2_lookup(&variable_strcache, pchName, cchName); 457 if (VarKey.name) 458 { 459 struct variable *pVar; 460 461 VarKey.length = cchName; 462 pVar = (struct variable *)hash_find_item_strcached(&pObj->pVariables->set->table, &VarKey); 463 if (pVar) 464 { 465 /* Append/prepend to existing variable. */ 466 return do_variable_definition_append(pFileLoc, pVar, pchValue, cchValue, fSimpleValue, enmOrigin, fAppend); 467 } 468 469 /* 470 * Not found. Check ancestors if the 'override' directive isn't applied. 471 */ 472 if (pObj->pszParent && enmOrigin != o_override) 473 { 474 struct kbuild_object *pParent = pObj; 475 for (;;) 476 { 477 pParent = eval_kbuild_resolve_parent(pParent, 0 /*fQuiet*/); 478 if (!pParent) 479 break; 480 481 pVar = (struct variable *)hash_find_item_strcached(&pParent->pVariables->set->table, &VarKey); 482 if (pVar) 483 { 484 if (pVar->value_length != ~0U) 485 assert(pVar->value_length == strlen(pVar->value)); 486 else 487 pVar->value_length = strlen(pVar->value); 488 489 /* 490 * Combine the two values and define the variable in the 491 * specified child object. We must disregard 'origin' a 492 * little here, so we must do the gritty stuff our selves. 493 */ 494 if ( pVar->recursive 495 || fSimpleValue 496 || !cchValue 497 || memchr(pchValue, '$', cchValue) == NULL ) 498 { 499 size_t cchNewValue; 500 char *pszNewValue; 501 char *pszTmp; 502 503 /* Just join up the two values. */ 504 if (pVar->value_length == 0) 505 { 506 cchNewValue = cchValue; 507 pszNewValue = xstrndup(pchValue, cchValue); 508 } 509 else if (!cchValue) 510 { 511 cchNewValue = pVar->value_length; 512 pszNewValue = xmalloc(cchNewValue + 1); 513 memcpy(pszNewValue, pVar->value, cchNewValue + 1); 514 } 515 else 516 { 517 cchNewValue = pVar->value_length + 1 + cchValue; 518 pszNewValue = xmalloc(cchNewValue + 1); 519 if (fAppend) 520 { 521 memcpy(pszNewValue, pVar->value, pVar->value_length); 522 pszTmp = pszNewValue + pVar->value_length; 523 *pszTmp++ = ' '; 524 memcpy(pszTmp, pchValue, cchValue); 525 pszTmp[cchValue] = '\0'; 526 } 527 else 528 { 529 memcpy(pszNewValue, pchValue, cchValue); 530 pszTmp = pszNewValue + cchValue; 531 *pszTmp++ = ' '; 532 memcpy(pszNewValue, pVar->value, pVar->value_length); 533 pszTmp[pVar->value_length] = '\0'; 534 } 535 } 536 537 /* Define the new variable in the child. */ 538 return define_kbuild_object_variable_cached(pObj, VarKey.name, 539 pszNewValue, cchNewValue, 0 /*fDuplicateValue*/, 540 enmOrigin, pVar->recursive, pFileLoc); 541 542 } 543 else 544 { 545 /* Lazy bird: Copy the variable from the ancestor and 546 then do a normal append/prepend on it. */ 547 pVar = define_kbuild_object_variable_cached(pObj, VarKey.name, 548 pVar->value, pVar->value_length, 1 /*fDuplicateValue*/, 549 enmOrigin, pVar->recursive, pFileLoc); 550 append_expanded_string_to_variable(pVar, pchValue, cchValue, fAppend); 551 return pVar; 552 } 553 } 554 } 555 } 556 } 557 else 558 VarKey.name = strcache2_add(&variable_strcache, pchName, cchName); 559 560 /* Variable not found. */ 561 return define_kbuild_object_variable_cached(pObj, VarKey.name, 562 pchValue, cchValue, 1 /*fDuplicateValue*/, enmOrigin, 563 1 /*fRecursive */, pFileLoc); 564 } 565 566 /** @} */ 567 568 569 static const char * 570 eval_kbuild_type_to_string(enum kBuildType enmType) 571 { 572 switch (enmType) 573 { 574 case kBuildType_Target: return "target"; 575 case kBuildType_Template: return "template"; 576 case kBuildType_Tool: return "tool"; 577 case kBuildType_Sdk: return "sdk"; 578 case kBuildType_Unit: return "unit"; 162 579 default: 163 case kBuildDef_Invalid: return "invalid"; 164 } 165 } 580 case kBuildType_Invalid: return "invalid"; 581 } 582 } 583 584 /** 585 * Converts a string into an kBuild object type. 586 * 587 * @returns The type on success, kBuildType_Invalid on failure. 588 * @param pchWord The pchWord. Not necessarily zero terminated. 589 * @param cchWord The length of the word. 590 */ 591 static enum kBuildType 592 eval_kbuild_type_from_string(const char *pchWord, size_t cchWord) 593 { 594 if (cchWord >= 3) 595 { 596 if (*pchWord == 't') 597 { 598 if (WORD_IS(pchWord, cchWord, "target")) 599 return kBuildType_Target; 600 if (WORD_IS(pchWord, cchWord, "template")) 601 return kBuildType_Template; 602 if (WORD_IS(pchWord, cchWord, "tool")) 603 return kBuildType_Tool; 604 } 605 else 606 { 607 if (WORD_IS(pchWord, cchWord, "sdk")) 608 return kBuildType_Sdk; 609 if (WORD_IS(pchWord, cchWord, "unit")) 610 return kBuildType_Unit; 611 } 612 } 613 614 return kBuildType_Invalid; 615 } 616 166 617 167 618 static char * 168 allocate_expanded_next_token(const char **ppszCursor, const char *pszEos, unsigned int *pcchToken, int fStrip)619 allocate_expanded_next_token(const char **ppszCursor, const char *pszEos, size_t *pcchToken, int fStrip) 169 620 { 170 621 unsigned int cchToken; … … 193 644 if (pcchToken) 194 645 *pcchToken = cchToken; 195 } 196 } 197 return pszToken; 198 } 199 200 static struct kbuild_eval_data * 201 eval_kbuild_resolve_parent(struct kbuild_eval_data *pData) 202 { 203 if ( !pData->pParent 204 && pData->pszParent) 205 { 206 struct kbuild_eval_data *pCur = g_pHeadKbDefs; 646 return pszToken; 647 } 648 } 649 650 if (pcchToken) 651 *pcchToken = 0; 652 return NULL; 653 } 654 655 static struct kbuild_object * 656 eval_kbuild_resolve_parent(struct kbuild_object *pObj, int fQuiet) 657 { 658 if ( !pObj->pParent 659 && pObj->pszParent) 660 { 661 struct kbuild_object *pCur = g_pHeadKbObjs; 207 662 while (pCur) 208 663 { 209 if ( pCur->enm Kind == pData->enmKind210 && !strcmp(pCur->pszName, p Data->pszParent))664 if ( pCur->enmType == pObj->enmType 665 && !strcmp(pCur->pszName, pObj->pszParent)) 211 666 { 212 667 if ( pCur->pszParent 213 && ( pCur->pParent == p Data214 || !strcmp(pCur->pszParent, p Data->pszName)) )215 fatal(&p Data->FileLoc, _("'%s' and '%s' are both trying to be each other children..."),216 p Data->pszName, pCur->pszName);217 218 p Data->pParent = pCur;219 p Data->pVariables->next = pData->pVariables;220 break;668 && ( pCur->pParent == pObj 669 || !strcmp(pCur->pszParent, pObj->pszName)) ) 670 fatal(&pObj->FileLoc, _("'%s' and '%s' are both trying to be each other children..."), 671 pObj->pszName, pCur->pszName); 672 673 pObj->pParent = pCur; 674 pObj->pVariables->next = pObj->pVariables; 675 return pCur; 221 676 } 677 222 678 pCur = pCur->pGlobalNext; 223 679 } 224 } 225 return pData->pParent; 680 681 /* Not found. */ 682 if (!fQuiet) 683 error(&pObj->FileLoc, _("Could not locate parent '%s' of '%s'"), pObj->pszParent, pObj->pszName); 684 } 685 return pObj->pParent; 226 686 } 227 687 228 688 static int 229 689 eval_kbuild_define_xxxx(struct kbuild_eval_data **ppData, const struct floc *pFileLoc, 230 const char *pszLine, const char *pszEos, int fIgnoring, enum kBuild Def enmKind)690 const char *pszLine, const char *pszEos, int fIgnoring, enum kBuildType enmType) 231 691 { 232 692 unsigned int cch; 233 unsigned int cchName;234 693 char ch; 235 694 char *psz; 236 695 const char *pszPrefix; 696 struct kbuild_object *pObj; 237 697 struct kbuild_eval_data *pData; 238 698 … … 241 701 242 702 /* 243 * Create a new kBuild eval data item. 244 */ 245 pData = xmalloc(sizeof(*pData)); 246 pData->enmKind = enmKind; 247 pData->pszName = NULL; 248 pData->FileLoc = *pFileLoc; 249 250 pData->pGlobalNext = g_pHeadKbDefs; 251 g_pHeadKbDefs = pData; 252 253 pData->pStackDown = *ppData; 254 *ppData = g_pTopKbDef = pData; 255 pData->pVariables = create_new_variable_set(); 256 pData->pVariablesSaved = NULL; 257 258 pData->pszParent = NULL; 259 pData->enmExtendBy = kBuildExtendBy_NoParent; 260 pData->pParent = NULL; 261 262 pData->pszTemplate = NULL; 263 pData->pTemplate = NULL; 264 265 pData->pszVarPrefix = NULL; 266 pData->cchVarPrefix = 0; 703 * Create a new kBuild object. 704 */ 705 pObj = xmalloc(sizeof(*pObj)); 706 pObj->enmType = enmType; 707 pObj->pszName = NULL; 708 pObj->cchName = 0; 709 pObj->FileLoc = *pFileLoc; 710 711 pObj->pGlobalNext = g_pHeadKbObjs; 712 g_pHeadKbObjs = pObj; 713 714 pObj->pVariables = create_new_variable_set(); 715 716 pObj->pszParent = NULL; 717 pObj->cchParent = 0; 718 pObj->pParent = NULL; 719 720 pObj->pszTemplate = NULL; 721 722 pObj->pszVarPrefix = NULL; 723 pObj->cchVarPrefix = 0; 267 724 268 725 /* 269 726 * The first word is the name. 270 727 */ 271 p Data->pszName = allocate_expanded_next_token(&pszLine, pszEos, &cchName, 1 /*strip*/);272 if (!p Data->pszName || !*pData->pszName)728 pObj->pszName = allocate_expanded_next_token(&pszLine, pszEos, &pObj->cchName, 1 /*strip*/); 729 if (!pObj->pszName || !*pObj->pszName) 273 730 fatal(pFileLoc, _("The kBuild define requires a name")); 274 731 275 psz = p Data->pszName;732 psz = pObj->pszName; 276 733 while ((ch = *psz++) != '\0') 277 734 if (!isgraph(ch)) 278 735 { 279 736 error(pFileLoc, _("The 'kBuild-define-%s' name '%s' contains one or more invalid characters"), 280 eval_kbuild_ kind_to_string(enmKind), pData->pszName);737 eval_kbuild_type_to_string(enmType), pObj->pszName); 281 738 break; 282 739 } 740 741 /* 742 * Calc the variable prefix. 743 */ 744 switch (enmType) 745 { 746 case kBuildType_Target: pszPrefix = ""; break; 747 case kBuildType_Template: pszPrefix = "TEMPLATE_"; break; 748 case kBuildType_Tool: pszPrefix = "TOOL_"; break; 749 case kBuildType_Sdk: pszPrefix = "SDK_"; break; 750 case kBuildType_Unit: pszPrefix = "UNIT_"; break; 751 default: 752 fatal(pFileLoc, _("enmType=%d"), enmType); 753 return -1; 754 } 755 cch = strlen(pszPrefix); 756 pObj->cchVarPrefix = cch + pObj->cchName; 757 pObj->pszVarPrefix = xmalloc(pObj->cchVarPrefix + 1); 758 memcpy(pObj->pszVarPrefix, pszPrefix, cch); 759 memcpy(&pObj->pszVarPrefix[cch], pObj->pszName, pObj->cchName); 283 760 284 761 /* … … 291 768 { 292 769 /* Inheritance directive. */ 293 if (p Data->pszParent != NULL)770 if (pObj->pszParent != NULL) 294 771 fatal(pFileLoc, _("'extending' can only occure once")); 295 p Data->pszParent = allocate_expanded_next_token(&pszLine, pszEos, &cch, 1 /*strip*/);296 if (!p Data->pszParent || !*pData->pszParent)772 pObj->pszParent = allocate_expanded_next_token(&pszLine, pszEos, &pObj->cchParent, 1 /*strip*/); 773 if (!pObj->pszParent || !*pObj->pszParent) 297 774 fatal(pFileLoc, _("'extending' requires a parent name")); 298 299 pData->enmExtendBy = kBuildExtendBy_Overriding;300 301 /* optionally 'by overriding|prepending|appending' */302 psz = find_next_token_eos(&pszLine, pszEos, &cch);303 if (psz && WORD_IS(psz, cch, "by"))304 {305 cch = 0;306 psz = find_next_token_eos(&pszLine, pszEos, &cch);307 if (WORD_IS(psz, cch, "overriding"))308 pData->enmExtendBy = kBuildExtendBy_Overriding;309 else if (WORD_IS(psz, cch, "appending"))310 pData->enmExtendBy = kBuildExtendBy_Appending;311 else if (WORD_IS(psz, cch, "prepending"))312 pData->enmExtendBy = kBuildExtendBy_Prepending;313 else314 fatal(pFileLoc, _("Unknown 'extending by' method '%.*s'"), (int)cch, psz);315 316 /* next token */317 psz = find_next_token_eos(&pszLine, pszEos, &cch);318 }319 775 } 320 776 else if (WORD_IS(psz, cch, "using")) 321 777 { 778 char *pszTemplate; 779 size_t cchTemplate; 780 322 781 /* Template directive. */ 323 if (enm Kind != kBuildDef_Tool)782 if (enmType != kBuildType_Target) 324 783 fatal(pFileLoc, _("'using <template>' can only be used with 'kBuild-define-target'")); 325 if (p Data->pszTemplate != NULL)784 if (pObj->pszTemplate != NULL) 326 785 fatal(pFileLoc, _("'using' can only occure once")); 327 786 328 p Data->pszTemplate = allocate_expanded_next_token(&pszLine, pszEos, &cch, 1 /*fStrip*/);329 if (!p Data->pszTemplate || !*pData->pszTemplate)787 pszTemplate = allocate_expanded_next_token(&pszLine, pszEos, &cchTemplate, 1 /*fStrip*/); 788 if (!pszTemplate || !*pszTemplate) 330 789 fatal(pFileLoc, _("'using' requires a template name")); 790 791 define_kbuild_object_variable_cached(pObj, g_pszVarNmTemplate, pszTemplate, cchTemplate, 792 0 /*fDuplicateValue*/, o_default, 0 /*fRecursive*/, pFileLoc), 331 793 332 794 /* next token */ … … 338 800 339 801 /* 340 * Calc the variable prefix. 341 */ 342 switch (enmKind) 343 { 344 case kBuildDef_Target: pszPrefix = ""; break; 345 case kBuildDef_Template: pszPrefix = "TEMPLATE_"; break; 346 case kBuildDef_Tool: pszPrefix = "TOOL_"; break; 347 case kBuildDef_Sdk: pszPrefix = "SDK_"; break; 348 case kBuildDef_Unit: pszPrefix = "UNIT_"; break; 349 default: 350 fatal(pFileLoc, _("enmKind=%d"), enmKind); 351 return -1; 352 } 353 cch = strlen(pszPrefix); 354 pData->cchVarPrefix = cch + cchName; 355 pData->pszVarPrefix = xmalloc(pData->cchVarPrefix + 1); 356 memcpy(pData->pszVarPrefix, pszPrefix, cch); 357 memcpy(&pData->pszVarPrefix[cch], pData->pszName, cchName); 358 359 /* 360 * Try resolve the parent and change the current variable set. 361 */ 362 eval_kbuild_resolve_parent(pData); 363 pData->pVariablesSaved = current_variable_set_list; 364 current_variable_set_list = pData->pVariables; 802 * Try resolve the parent. 803 */ 804 eval_kbuild_resolve_parent(pObj, 1 /*fQuiet*/); 805 806 /* 807 * Create an eval stack entry and change the current variable set. 808 */ 809 pData = xmalloc(sizeof(*pData)); 810 pData->pObj = pObj; 811 pData->pVariablesSaved = current_variable_set_list; 812 current_variable_set_list = pObj->pVariables; 813 814 pData->pStackDown = *ppData; 815 *ppData = pData; 816 g_pTopKbEvalData = pData; 365 817 366 818 return 0; … … 369 821 static int 370 822 eval_kbuild_endef_xxxx(struct kbuild_eval_data **ppData, const struct floc *pFileLoc, 371 const char *pszLine, const char *pszEos, int fIgnoring, enum kBuild Def enmKind)823 const char *pszLine, const char *pszEos, int fIgnoring, enum kBuildType enmType) 372 824 { 373 825 struct kbuild_eval_data *pData; 374 unsigned int cchName; 826 struct kbuild_object *pObj; 827 size_t cchName; 375 828 char *pszName; 376 829 … … 385 838 { 386 839 error(pFileLoc, _("kBuild-endef-%s is missing kBuild-define-%s"), 387 eval_kbuild_ kind_to_string(enmKind), eval_kbuild_kind_to_string(enmKind));840 eval_kbuild_type_to_string(enmType), eval_kbuild_type_to_string(enmType)); 388 841 return 0; 389 842 } … … 392 845 * ... and does it have a matching kind? 393 846 */ 394 if (pData->enmKind != enmKind) 847 pObj = pData->pObj; 848 if (pObj->enmType != enmType) 395 849 error(pFileLoc, _("'kBuild-endef-%s' does not match 'kBuild-define-%s %s'"), 396 eval_kbuild_ kind_to_string(enmKind), eval_kbuild_kind_to_string(pData->enmKind), pData->pszName);850 eval_kbuild_type_to_string(enmType), eval_kbuild_type_to_string(pObj->enmType), pObj->pszName); 397 851 398 852 /* … … 403 857 if (pszName) 404 858 { 405 if (strcmp(pszName, pData->pszName)) 859 if ( cchName != pObj->cchName 860 || strcmp(pszName, pObj->pszName)) 406 861 error(pFileLoc, _("'kBuild-endef-%s %s' does not match 'kBuild-define-%s %s'"), 407 eval_kbuild_ kind_to_string(enmKind), pszName,408 eval_kbuild_ kind_to_string(pData->enmKind), pData->pszName);862 eval_kbuild_type_to_string(enmType), pszName, 863 eval_kbuild_type_to_string(pObj->enmType), pObj->pszName); 409 864 free(pszName); 410 865 } … … 413 868 * Pop a define off the stack. 414 869 */ 415 assert(pData == g_pTopKb Def);416 *ppData = g_pTopKb Def= pData->pStackDown;870 assert(pData == g_pTopKbEvalData); 871 *ppData = g_pTopKbEvalData = pData->pStackDown; 417 872 pData->pStackDown = NULL; 418 873 current_variable_set_list = pData->pVariablesSaved; 419 874 pData->pVariablesSaved = NULL; 875 free(pData); 420 876 421 877 return 0; 422 878 } 423 879 424 int eval_kbuild_define(struct kbuild_eval_data **kdata, const struct floc *flocp, 425 const char *word, unsigned int wlen, const char *line, const char *eos, int ignoring) 426 { 427 assert(memcmp(word, "kBuild-define", sizeof("kBuild-define") - 1) == 0); 428 word += sizeof("kBuild-define") - 1; 429 wlen -= sizeof("kBuild-define") - 1; 430 if ( wlen > 1 431 && word[0] == '-') 432 { 433 if (WORD_IS(word, wlen, "-target")) 434 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Target); 435 if (WORD_IS(word, wlen, "-template")) 436 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Template); 437 if (WORD_IS(word, wlen, "-tool")) 438 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Tool); 439 if (WORD_IS(word, wlen, "-sdk")) 440 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Sdk); 441 if (WORD_IS(word, wlen, "-unit")) 442 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Unit); 443 } 444 445 error(flocp, _("Unknown syntax 'kBuild-define%.*s'"), (int)wlen, word); 880 int eval_kbuild_read_hook(struct kbuild_eval_data **kdata, const struct floc *flocp, 881 const char *pchWord, size_t cchWord, const char *line, const char *eos, int ignoring) 882 { 883 enum kBuildType enmType; 884 885 /* 886 * Skip the 'kBuild-' prefix that the caller already matched. 887 */ 888 assert(memcmp(pchWord, "kBuild-", sizeof("kBuild-") - 1) == 0); 889 pchWord += sizeof("kBuild-") - 1; 890 cchWord -= sizeof("kBuild-") - 1; 891 892 /* 893 * String switch. 894 */ 895 if ( cchWord >= sizeof("define-") - 1 896 && strneq(pchWord, "define-", sizeof("define-") - 1)) 897 { 898 enmType = eval_kbuild_type_from_string(pchWord + sizeof("define-") - 1, cchWord - sizeof("define-") + 1); 899 if (enmType != kBuildType_Invalid) 900 return eval_kbuild_define_xxxx(kdata, flocp, line, eos, ignoring, enmType); 901 } 902 else if ( cchWord >= sizeof("endef-") - 1 903 && strneq(pchWord, "endef-", sizeof("endef-") - 1)) 904 { 905 enmType = eval_kbuild_type_from_string(pchWord + sizeof("endif-") - 1, cchWord - sizeof("endif-") + 1); 906 if (enmType != kBuildType_Invalid) 907 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, enmType); 908 } 909 else if (WORD_IS(pchWord, cchWord, "endef")) 910 { 911 /* Terminate whatever definition is on top. */ 912 913 } 914 915 /* 916 * Everything that is prefixed with 'kBuild-' is reserved for language 917 * extensions, at least until legacy assignments/whatever turns up. 918 */ 919 error(flocp, _("Unknown syntax 'kBuild-%.*s'"), (int)cchWord, pchWord); 446 920 return 0; 447 921 } 448 922 449 int eval_kbuild_endef(struct kbuild_eval_data **kdata, const struct floc *flocp, 450 const char *word, unsigned int wlen, const char *line, const char *eos, int ignoring) 451 { 452 assert(memcmp(word, "kBuild-endef", sizeof("kBuild-endef") - 1) == 0); 453 word += sizeof("kBuild-endef") - 1; 454 wlen -= sizeof("kBuild-endef") - 1; 455 if ( wlen > 1 456 && word[0] == '-') 457 { 458 if (WORD_IS(word, wlen, "-target")) 459 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Target); 460 if (WORD_IS(word, wlen, "-template")) 461 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Template); 462 if (WORD_IS(word, wlen, "-tool")) 463 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Tool); 464 if (WORD_IS(word, wlen, "-sdk")) 465 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Sdk); 466 if (WORD_IS(word, wlen, "-unit")) 467 return eval_kbuild_endef_xxxx(kdata, flocp, line, eos, ignoring, kBuildDef_Unit); 468 } 469 470 error(flocp, _("Unknown syntax 'kBuild-endef%.*s'"), (int)wlen, word); 923 924 /** @name kBuild object variable accessor related functions 925 * @{ 926 */ 927 928 /** 929 * Checks if the given name is an object variable accessor. 930 * 931 * @returns 1 if it is, 0 if it isn't. 932 * @param pchName The potential kBuild variable accessor 933 * expression. 934 * @param cchName Length of the expression. 935 */ 936 int is_kbuild_object_variable_accessor(const char *pchName, size_t cchName) 937 { 938 char const *pchTmp; 939 940 /* See lookup_kbuild_object_variable for the rules. */ 941 if (cchName >= 1+1+1+1 && *pchName == '[') 942 { 943 pchName++; 944 cchName--; 945 946 pchTmp = memchr(pchName, '@', cchName); 947 if (pchTmp) 948 { 949 cchName -= pchTmp + 1 - pchName; 950 pchName = pchTmp + 1; 951 pchTmp = memchr(pchName, ']', cchName); 952 if (pchTmp) 953 { 954 cchName -= pchTmp + 1 - pchName; 955 if (cchName > 0) 956 return 1; 957 } 958 } 959 } 471 960 return 0; 472 961 } 473 962 963 /** 964 * Parses a kBuild object variable accessor, resolving the object. 965 * 966 * @returns Pointer to the variable if found. 967 * @retval NULL if the object (or type) couldn't be resolved. 968 * @retval KOBJ_NOT_KBUILD_ACCESSOR if no a kBuild variable accessor. 969 * 970 * @param pchExpr The kBuild variable accessor expression. 971 * @param cchExpr Length of the expression. 972 * @param enmSeverity The minimum severity level for errors. 973 * @param pFileLoc The file location any errors should be reported 974 * at. Optional. 975 * @param ppchVarNm Where to return the pointer to the start of the 976 * variable name within the string @a pchExpr 977 * points to. Mandatory. 978 * @param pcchVarNm Where to return the length of the variable name. 979 * Mandatory. 980 * @param penmType Where to return the object type. Optional. 981 */ 982 static struct kbuild_object * 983 parse_kbuild_object_variable_accessor(const char *pchExpr, size_t cchExpr, 984 enum kBuildSeverity enmSeverity, const struct floc *pFileLoc, 985 const char **ppchVarNm, size_t *pcchVarNm, enum kBuildType *penmType) 986 { 987 const char * const pchOrgExpr = pchExpr; 988 size_t const cchOrgExpr = cchExpr; 989 char const *pchTmp; 990 991 /* 992 * To accept this as an kBuild accessor, we require: 993 * 1. Open bracket. 994 * 2. At sign separating the type from the name. 995 * 3. Closing bracket. 996 * 4. At least one character following it. 997 */ 998 if (cchExpr >= 1+1+1+1 && *pchExpr == '[') 999 { 1000 pchExpr++; 1001 cchExpr--; 1002 1003 pchTmp = memchr(pchExpr, '@', cchExpr); 1004 if (pchTmp) 1005 { 1006 const char * const pchType = pchExpr; 1007 size_t const cchType = pchTmp - pchExpr; 1008 1009 cchExpr -= cchType + 1; 1010 pchExpr = pchTmp + 1; 1011 pchTmp = memchr(pchExpr, ']', cchExpr); 1012 if (pchTmp) 1013 { 1014 const char * const pchObjName = pchExpr; 1015 size_t const cchObjName = pchTmp - pchExpr; 1016 1017 cchExpr -= cchObjName + 1; 1018 pchExpr = pchTmp + 1; 1019 if (cchExpr > 0) 1020 { 1021 enum kBuildType enmType; 1022 1023 *pcchVarNm = cchExpr; 1024 *ppchVarNm = pchExpr; 1025 1026 /* 1027 * It's an kBuild define variable accessor, alright. 1028 */ 1029 enmType = eval_kbuild_type_from_string(pchType, cchType); 1030 if (penmType) 1031 *penmType = enmType; 1032 if (enmType != kBuildType_Invalid) 1033 { 1034 struct kbuild_object *pObj = lookup_kbuild_object(enmType, pchObjName, cchObjName); 1035 if (pObj) 1036 return pObj; 1037 1038 /* failed. */ 1039 kbuild_report_problem(enmSeverity, pFileLoc, 1040 _("kBuild object '%s' not found in kBuild variable accessor '%.*s'"), 1041 (int)cchObjName, pchObjName, (int)cchOrgExpr, pchOrgExpr); 1042 } 1043 else 1044 kbuild_report_problem(MAX(enmSeverity, kBuildSeverity_Error), pFileLoc, 1045 _("Invalid type '%.*s' specified in kBuild variable accessor '%.*s'"), 1046 (int)cchType, pchType, (int)cchOrgExpr, pchOrgExpr); 1047 return NULL; 1048 } 1049 } 1050 } 1051 } 1052 1053 *ppchVarNm = NULL; 1054 *pcchVarNm = 0; 1055 if (penmType) 1056 *penmType = kBuildType_Invalid; 1057 return KOBJ_NOT_KBUILD_ACCESSOR; 1058 } 1059 1060 /** 1061 * Looks up a variable in a kBuild object. 1062 * 1063 * The caller has done minimal matching, i.e. starting square brackets and 1064 * minimum length. We do the rest here. 1065 * 1066 * @returns Pointer to the variable if found. 1067 * @retval NULL if not found. 1068 * @retval VAR_NOT_KBUILD_ACCESSOR if no a kBuild variable accessor. 1069 * 1070 * @param pchName The kBuild variable accessor expression. 1071 * @param cchName Length of the expression. 1072 */ 1073 struct variable * 1074 lookup_kbuild_object_variable_accessor(const char *pchName, size_t cchName) 1075 { 1076 const char * const pchOrgName = pchName; 1077 size_t const cchOrgName = cchName; 1078 const char * pchVarNm; 1079 size_t cchVarNm; 1080 struct kbuild_object *pObj; 1081 1082 pObj = parse_kbuild_object_variable_accessor(pchName, cchName, kBuildSeverity_Warning, NULL, &pchVarNm, &cchVarNm, NULL); 1083 if (pObj != KOBJ_NOT_KBUILD_ACCESSOR) 1084 { 1085 if (pObj) 1086 { 1087 /* 1088 * Do the variable lookup. 1089 */ 1090 const char *pszCachedName = strcache2_lookup(&variable_strcache, pchVarNm, cchVarNm); 1091 if (pszCachedName) 1092 { 1093 struct variable VarKey; 1094 struct variable *pVar; 1095 VarKey.name = pszCachedName; 1096 VarKey.length = cchName; 1097 1098 pVar = (struct variable *)hash_find_item_strcached(&pObj->pVariables->set->table, &VarKey); 1099 if (pVar) 1100 return pVar; 1101 1102 /* 1103 * Not found, check ancestors if any. 1104 */ 1105 if (pObj->pszParent || pObj->pszTemplate) 1106 { 1107 struct kbuild_object *pParent = pObj; 1108 for (;;) 1109 { 1110 pParent = eval_kbuild_resolve_parent(pParent, 0 /*fQuiet*/); 1111 if (!pParent) 1112 break; 1113 pVar = (struct variable *)hash_find_item_strcached(&pParent->pVariables->set->table, &VarKey); 1114 if (pVar) 1115 return pVar; 1116 } 1117 } 1118 } 1119 } 1120 1121 /* Not found one way or the other. */ 1122 return NULL; 1123 } 1124 1125 /* Not a kBuild object variable accessor. */ 1126 return VAR_NOT_KBUILD_ACCESSOR; 1127 } 1128 1129 /** @} */ 1130 474 1131 void print_kbuild_data_base(void) 475 1132 { 476 struct kbuild_ eval_data*pCur;1133 struct kbuild_object *pCur; 477 1134 478 1135 puts(_("\n# kBuild defines")); 479 1136 480 for (pCur = g_pHeadKb Defs; pCur; pCur = pCur->pGlobalNext)1137 for (pCur = g_pHeadKbObjs; pCur; pCur = pCur->pGlobalNext) 481 1138 { 482 1139 printf("\nkBuild-define-%s %s", 483 eval_kbuild_ kind_to_string(pCur->enmKind), pCur->pszName);1140 eval_kbuild_type_to_string(pCur->enmType), pCur->pszName); 484 1141 if (pCur->pszParent) 485 {486 1142 printf(" extending %s", pCur->pszParent); 487 switch (pCur->enmExtendBy)488 {489 case kBuildExtendBy_Overriding: break;490 case kBuildExtendBy_Appending: printf(" by appending"); break;491 case kBuildExtendBy_Prepending: printf(" by prepending"); break;492 default: printf(" by ?!?");493 }494 }495 1143 if (pCur->pszTemplate) 496 1144 printf(" using %s", pCur->pszTemplate); … … 500 1148 501 1149 printf("kBuild-endef-%s %s\n", 502 eval_kbuild_ kind_to_string(pCur->enmKind), pCur->pszName);1150 eval_kbuild_type_to_string(pCur->enmType), pCur->pszName); 503 1151 } 504 1152 /** @todo hash stats. */
Note:
See TracChangeset
for help on using the changeset viewer.