Changeset 2549 in kBuild
- Timestamp:
- Nov 9, 2011 1:22:04 AM (13 years ago)
- Location:
- trunk/src/kmk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kbuild-read.c
r2548 r2549 76 76 /** The kind of define. */ 77 77 enum kBuildDef enmKind; 78 /** Pointer to the element below us on the stack. */79 struct kbuild_eval_data *pDown;80 81 78 /** The bare name of the define. */ 82 79 char *pszName; 80 /** The file location where this define was declared. */ 81 struct floc FileLoc; 82 83 /** 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; 87 88 /** The variable set associated with this define. */ 89 struct variable_set_list *pVariables; 90 /** The saved current variable set, for restoring in kBuild-endef. */ 91 struct variable_set_list *pVariablesSaved; 83 92 84 93 /** The parent name, NULL if none. */ … … 86 95 /** The inheritance method. */ 87 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; 88 100 89 101 /** The template, NULL if none. Only applicable to targets. */ 90 102 char *pszTemplate; 91 92 /** The variable prefix*/ 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 108 char *pszVarPrefix; 94 109 /** The length of the variable prefix. */ 95 110 size_t cchVarPrefix; 96 111 }; 112 113 114 /******************************************************************************* 115 * Header Files * 116 *******************************************************************************/ 117 /** Linked list (LIFO) of kBuild defines. 118 * @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 } 97 150 98 151 … … 112 165 } 113 166 167 static char * 168 allocate_expanded_next_token(const char **ppszCursor, const char *pszEos, unsigned int *pcchToken, int fStrip) 169 { 170 unsigned int cchToken; 171 char *pszToken = find_next_token_eos(ppszCursor, pszEos, &cchToken); 172 if (pszToken) 173 { 174 pszToken = allocated_variable_expand_2(pszToken, cchToken, &cchToken); 175 if (pszToken) 176 { 177 if (fStrip) 178 { 179 unsigned int off = 0; 180 while (MY_IS_BLANK(pszToken[off])) 181 off++; 182 if (off) 183 { 184 cchToken -= off; 185 memmove(pszToken, &pszToken[off], cchToken + 1); 186 } 187 188 while (cchToken > 0 && MY_IS_BLANK(pszToken[cchToken - 1])) 189 pszToken[--cchToken] = '\0'; 190 } 191 192 assert(cchToken == strlen(pszToken)); 193 if (pcchToken) 194 *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; 207 while (pCur) 208 { 209 if ( pCur->enmKind == pData->enmKind 210 && !strcmp(pCur->pszName, pData->pszParent)) 211 { 212 if ( pCur->pszParent 213 && ( pCur->pParent == pData 214 || !strcmp(pCur->pszParent, pData->pszName)) ) 215 fatal(&pData->FileLoc, _("'%s' and '%s' are both trying to be each other children..."), 216 pData->pszName, pCur->pszName); 217 218 pData->pParent = pCur; 219 pData->pVariables->next = pData->pVariables; 220 break; 221 } 222 pCur = pCur->pGlobalNext; 223 } 224 } 225 return pData->pParent; 226 } 114 227 115 228 static int … … 117 230 const char *pszLine, const char *pszEos, int fIgnoring, enum kBuildDef enmKind) 118 231 { 119 unsigned int cch; 120 char *psz; 232 unsigned int cch; 233 unsigned int cchName; 234 char ch; 235 char *psz; 236 const char *pszPrefix; 121 237 struct kbuild_eval_data *pData; 122 238 123 /*124 * Create a new kBuild eval data item unless we're in ignore-mode.125 */126 239 if (fIgnoring) 127 240 return 0; 128 241 242 /* 243 * Create a new kBuild eval data item. 244 */ 129 245 pData = xmalloc(sizeof(*pData)); 130 pData->enmKind = enmKind; 131 pData->pszName = NULL; 132 pData->pszParent = NULL; 133 pData->enmExtendBy = kBuildExtendBy_NoParent; 134 pData->pszTemplate = NULL; 135 pData->pszVarPrefix = NULL; 136 pData->cchVarPrefix = 0; 137 pData->pDown = *ppData; 138 *ppData = 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; 139 267 140 268 /* 141 269 * The first word is the name. 142 270 */ 143 pData->pszName = find_next_token_eos(&pszLine, pszEos, &cch); 144 if (!pData->pszName) 145 { 146 error(pFileLoc, _("The kBuild define requires a name")); 147 return 0; 148 } 149 pData->pszName = allocated_variable_expand_2(pData->pszName, cch, &cch); 271 pData->pszName = allocate_expanded_next_token(&pszLine, pszEos, &cchName, 1 /*strip*/); 272 if (!pData->pszName || !*pData->pszName) 273 fatal(pFileLoc, _("The kBuild define requires a name")); 274 275 psz = pData->pszName; 276 while ((ch = *psz++) != '\0') 277 if (!isgraph(ch)) 278 { 279 error(pFileLoc, _("The 'kBuild-define-%s' name '%s' contains one or more invalid characters"), 280 eval_kbuild_kind_to_string(enmKind), pData->pszName); 281 break; 282 } 150 283 151 284 /* … … 160 293 if (pData->pszParent != NULL) 161 294 fatal(pFileLoc, _("'extending' can only occure once")); 162 pData->pszParent = find_next_token_eos(&pszLine, pszEos, &cch); 163 if (pData->pszParent) 164 pData->pszParent = allocated_variable_expand_2(pData->pszParent, cch, &cch); 295 pData->pszParent = allocate_expanded_next_token(&pszLine, pszEos, &cch, 1 /*strip*/); 165 296 if (!pData->pszParent || !*pData->pszParent) 166 297 fatal(pFileLoc, _("'extending' requires a parent name")); … … 187 318 } 188 319 } 189 else if ( WORD_IS(psz, cch, "using") 190 && enmKind == kBuildDef_Tool) 320 else if (WORD_IS(psz, cch, "using")) 191 321 { 192 322 /* Template directive. */ 193 if (pData->pszTemplate != NULL ) 323 if (enmKind != kBuildDef_Tool) 324 fatal(pFileLoc, _("'using <template>' can only be used with 'kBuild-define-target'")); 325 if (pData->pszTemplate != NULL) 194 326 fatal(pFileLoc, _("'using' can only occure once")); 195 pData->pszTemplate = find_next_token_eos(&pszLine, pszEos, &cch); 196 if (pData->pszTemplate) 197 pData->pszTemplate = allocated_variable_expand_2(pData->pszTemplate, cch, &cch); 327 328 pData->pszTemplate = allocate_expanded_next_token(&pszLine, pszEos, &cch, 1 /*fStrip*/); 198 329 if (!pData->pszTemplate || !*pData->pszTemplate) 199 330 fatal(pFileLoc, _("'using' requires a template name")); … … 209 340 * Calc the variable prefix. 210 341 */ 211 212 /** @todo continue here... */ 213 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; 214 365 215 366 return 0; … … 242 393 */ 243 394 if (pData->enmKind != enmKind) 244 {245 395 error(pFileLoc, _("'kBuild-endef-%s' does not match 'kBuild-define-%s %s'"), 246 396 eval_kbuild_kind_to_string(enmKind), eval_kbuild_kind_to_string(pData->enmKind), pData->pszName); 247 return 0;248 }249 397 250 398 /* … … 252 400 * It should match the name given to the kBuild-define. 253 401 */ 254 pszName = find_next_token_eos(&pszLine, pszEos, &cchName);402 pszName = allocate_expanded_next_token(&pszLine, pszEos, &cchName, 1 /*fStrip*/); 255 403 if (pszName) 256 404 { 257 pszName = allocated_variable_expand_2(pszName, cchName, &cchName);258 405 if (strcmp(pszName, pData->pszName)) 259 406 error(pFileLoc, _("'kBuild-endef-%s %s' does not match 'kBuild-define-%s %s'"), … … 266 413 * Pop a define off the stack. 267 414 */ 268 *ppData = pData->pDown; 269 free(pData->pszName); 270 free(pData->pszParent); 271 free(pData->pszTemplate); 272 free(pData->pszVarPrefix); 273 free(pData); 415 assert(pData == g_pTopKbDef); 416 *ppData = g_pTopKbDef = pData->pStackDown; 417 pData->pStackDown = NULL; 418 current_variable_set_list = pData->pVariablesSaved; 419 pData->pVariablesSaved = NULL; 274 420 275 421 return 0; … … 326 472 } 327 473 474 void print_kbuild_data_base(void) 475 { 476 struct kbuild_eval_data *pCur; 477 478 puts(_("\n# kBuild defines")); 479 480 for (pCur = g_pHeadKbDefs; pCur; pCur = pCur->pGlobalNext) 481 { 482 printf("\nkBuild-define-%s %s", 483 eval_kbuild_kind_to_string(pCur->enmKind), pCur->pszName); 484 if (pCur->pszParent) 485 { 486 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 if (pCur->pszTemplate) 496 printf(" using %s", pCur->pszTemplate); 497 putchar('\n'); 498 499 print_variable_set(pCur->pVariables->set, ""); 500 501 printf("kBuild-endef-%s %s\n", 502 eval_kbuild_kind_to_string(pCur->enmKind), pCur->pszName); 503 } 504 /** @todo hash stats. */ 505 } 506 507 void print_kbuild_define_stats(void) 508 { 509 /* later when hashing stuff */ 510 } 511 -
trunk/src/kmk/kbuild.h
r2548 r2549 40 40 41 41 struct kbuild_eval_data; 42 extern struct kbuild_eval_data *g_pTopKbDef; 43 struct variable_set *get_top_kbuild_variable_set(void); 44 char *kbuild_prefix_variable(const char *pszName, unsigned int *pcchName); 42 45 43 46 int eval_kbuild_define(struct kbuild_eval_data **kdata, const struct floc *flocp, … … 46 49 const char *word, unsigned int wlen, const char *line, const char *eos, int ignoring); 47 50 51 void print_kbuild_data_base(void); 52 void print_kbuild_define_stats(void); 53 48 54 #endif 49 55 -
trunk/src/kmk/main.c
r2546 r2549 3726 3726 print_file_data_base (); 3727 3727 print_vpath_data_base (); 3728 #ifdef KMK 3729 print_kbuild_data_base (); 3730 #endif 3728 3731 #ifndef CONFIG_WITH_STRCACHE2 3729 3732 strcache_print_stats ("#"); … … 3750 3753 print_variable_stats (); 3751 3754 print_file_stats (); 3755 # ifdef KMK 3756 print_kbuild_define_stats (); 3757 # endif 3752 3758 # ifndef CONFIG_WITH_STRCACHE2 3753 3759 strcache_print_stats ("#"); -
trunk/src/kmk/testcase-kBuild-define.kmk
r2548 r2549 29 29 kBuild-define-target MyTarget 30 30 31 TEMPLATE = MyTemplate32 SOURCES= MySourceFile.c31 _TEMPLATE = MyTemplate 32 _SOURCES = MySourceFile.c 33 33 34 34 kBuild-endef-target MyTarget 35 $(if "$(MyTarget_TEMPLATE)" == "MyTemplate",,$(error MyTarget's _TEMPLATE wasn't set correctly in the global space)) 36 $(if "$(MyTarget_SOURCES)" == "MySourceFile.c",,$(error MyTarget's _TEMPLATE wasn't set correctly in the global space)) 35 37 36 38 … … 38 40 kBuild-define-target $(call INDIRECT_NAME, 2) 39 41 40 TEMPLATE = MyTemplate241 SOURCES= MySourceFile2.c42 local _TEMPLATE = MyTemplate2 43 _SOURCES = MySourceFile2.c 42 44 43 45 kBuild-endef-target $(call INDIRECT_NAME, 2) 46 $(if "$(_TEMPLATE)" == "",,$(error _TEMPLATE has leaked out into the global space)) 44 47 45 48 … … 47 50 48 51 all_recursive: 49 $(ECHO) "kBuild-define-xxxx works fine"52 #$(ECHO) "kBuild-define-xxxx works fine" 50 53 51 54 -
trunk/src/kmk/variable.c
r2548 r2549 215 215 struct variable var_key; 216 216 217 #ifndef KMK 217 218 if (set == NULL) 218 219 set = &global_variable_set; 220 #else 221 if (set == NULL) 222 { 223 /* underscore prefixed variables are automatically local in 224 kBuild-define-* scopes. They also get a global definition with 225 the current scope prefix. */ 226 if (g_pTopKbDef && length > 0 && name[0] == '_') 227 { 228 char *prefixed_nm; 229 unsigned int prefixed_nm_len; 230 231 set = get_top_kbuild_variable_set(); 232 v = define_variable_in_set(name, length, value, value_len, 233 1 /* duplicate_value */, 234 origin, recursive, set, flocp); 235 236 prefixed_nm_len = length; 237 prefixed_nm = kbuild_prefix_variable(name, &prefixed_nm_len); 238 define_variable_in_set(prefixed_nm, prefixed_nm_len, 239 value, value_len, duplicate_value, 240 origin, recursive, &global_variable_set, 241 flocp); 242 free(prefixed_nm); 243 return v; 244 } 245 set = &global_variable_set; 246 } 247 #endif 219 248 220 249 #ifndef CONFIG_WITH_STRCACHE2
Note:
See TracChangeset
for help on using the changeset viewer.