Changeset 17512
- Timestamp:
- May 4, 2008, 2:00:42 PM (18 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/config/pmConfigRecipes.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/config/pmConfigRecipes.c
r16611 r17512 13 13 static bool loadRecipeSystem(bool *status, pmConfig *config, psMetadata *source); 14 14 static bool loadRecipeCamera(bool *status, pmConfig *config, psMetadata *source); 15 static bool loadRecipeSymbols(bool *status, pmConfig *config, pmRecipeSource source); 15 16 static bool loadRecipeFromArguments(bool *status, pmConfig *config); 16 static bool loadRecipeSymbols(bool *status, pmConfig *config);17 17 static bool loadRecipeOptions(bool *status, pmConfig *config); 18 static bool mergeRecipeCamera(bool *status, pmConfig *config); 18 19 19 20 // use this function to select the options structure for the specified recipe … … 45 46 } 46 47 47 // this function may be called several times. it attempts to load the recipe data from one of 48 // three locations: config->complete, config->camera, and argv. We cannot read the recipes49 // from config->camera until a camera has been read BUT, the argv recipes must override the50 // camera and system recipes.48 // this function may be called several times. it attempts to load the recipe data from one of three 49 // locations: config->complete, config->camera, and argv. We cannot read the recipes from 50 // config->camera until a camera has been read BUT, the argv recipes must override the camera and 51 // system recipes. This command strips the argv elements it uses from the argv list. 51 52 bool pmConfigReadRecipes(pmConfig *config, pmRecipeSource source) 52 53 { … … 61 62 // It is an error for config->complete:recipes not to exist. all programs install their 62 63 // master recipe files in the system:recipe location when they are built. 63 if (config->complete && (source & PM_RECIPE_SOURCE_SYSTEM)) { 64 psAssert (config->complete, "base config data defined"); 65 if (source & PM_RECIPE_SOURCE_SYSTEM) { 64 66 if (!loadRecipeSystem(&status, config, config->complete)) { 65 67 psError(PS_ERR_IO, false, "Failed to read recipes from system config"); … … 85 87 } 86 88 87 // apply recipes loaded into config->arguments based on command-line arguments89 // merge camera and sytem recipes, apply recipes loaded into config->arguments based on command-line arguments 88 90 if (config->arguments && (source & PM_RECIPE_SOURCE_CL)) { 91 92 // update the system-level recipes with the symbolically-defined recipes 93 if (!loadRecipeSymbols(&status, config, PM_RECIPE_SOURCE_SYSTEM)) { 94 psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references"); 95 return false; 96 } 97 if (status) { 98 psTrace ("psModules.config", 3, "read recipes from symbolic references"); 99 } else { 100 psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by symbolic reference"); 101 } 102 103 // merge the SYSTEM and CAMERA recipes 104 if (!mergeRecipeCamera(&status, config)) { 105 psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references"); 106 return false; 107 } 108 psLogMsg ("psModules.config", PS_LOG_DETAIL, "merged camera recipes with system recipes"); 109 110 // load recipe-files specified on the command line 89 111 if (!loadRecipeFromArguments(&status, config)) { 90 112 psError(PS_ERR_IO, false, "Failed to read recipes from command-line arguments"); … … 96 118 psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments"); 97 119 } 98 if (!loadRecipeSymbols(&status, config)) { 120 121 // update the system-level recipes with the symbolically-defined recipes 122 if (!loadRecipeSymbols(&status, config, PM_RECIPE_SOURCE_CAMERA)) { 99 123 psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references"); 100 124 return false; … … 105 129 psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by symbolic reference"); 106 130 } 131 132 // override any specific values with values from the command line 107 133 if (!loadRecipeOptions(&status, config)) { 108 134 psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references"); … … 124 150 int argNum; 125 151 126 // save the recipe s onto config->arguments:RECIPES152 // save the recipe options onto config->arguments:OPTIONS 127 153 // increment so we can free below (is a NOP if 'options' is NULL) 128 154 psMetadata *options = psMetadataLookupMetadata(&success, config->arguments, "OPTIONS"); … … 205 231 } 206 232 207 // examine command-line arguments for -recipe KEY VALUE208 // i f VALUE is an existing file, read as metadata and save on config->arguments with name = KEY209 // if VALUE is not an exiting file, it is a symbolic lookup: it is saved on config->recipeSymbols210 // for later interpolation (pmConfigReadRecipes with option CL)233 // examine command-line arguments for -recipe RECIPE SYMBOLIC-NAME or -recipe-file RECIPE FILENAME 234 // in the first case, the symbolic lookup is saved on config->recipeSymbols 235 // for later interpolation (pmConfigReadRecipes with option CL) 236 // in the second case, read as metadata and save on config->arguments with name = KEY 211 237 bool pmConfigLoadRecipeArguments (int *argc, char **argv, pmConfig *config) 212 238 { … … 272 298 // Assume it's a symbolic reference to something that's not yet read in. 273 299 // it will be loaded later by pmConfigReadRecipes with option CL 274 psMetadataAddStr(config->recipeSymbols, PS_LIST_TAIL, recipeName, PS_META_REPLACE, NULL, 275 recipeSource); 300 psMetadataAddStr(config->recipeSymbols, PS_LIST_TAIL, recipeName, PS_META_REPLACE, NULL, recipeSource); 276 301 277 302 psTrace ("psModules.config", 3, "read recipe %s from %s", recipeName, recipeSource); … … 303 328 psError(PS_ERR_IO, false, "RECIPES not found in the system configuration\n"); 304 329 return false; 305 }306 307 // Copy contents of the filenames to config->recipes from the "RECIPES" metadata in the source.308 // We could use psMetadataCopy for this, but it's better to check that everything's of the correct type.309 // If it's not of the correct type, we can tell the user which file it's in, so they can find it easier.310 psMetadataIterator *recipesIter = psMetadataIteratorAlloc(recipes, PS_LIST_HEAD, NULL); // Iterator311 psMetadataItem *fileItem = NULL; // MD item containing the filename, from recipe iteration312 while ((fileItem = psMetadataGetAndIncrement(recipesIter))) {313 // type mismatch is a serious error314 if (fileItem->type != PS_DATA_STRING) {315 psError(PS_ERR_IO, true, "%s in system configuration RECIPES is not of type STR", fileItem->name);316 return false;317 }318 319 // Read the recipe file. if we fail on a file, give a warning, but continue320 psMetadata *recipe = NULL;321 if (!pmConfigFileRead(&recipe, fileItem->data.str, "recipe")) {322 psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in system configuration\n",323 fileItem->data.str);324 return false;325 }326 327 // if this named recipe exists, supplement it328 psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE,329 fileItem->comment, recipe);330 psFree(recipe); // Drop reference331 }332 psFree(recipesIter);333 config->recipesRead |= PM_RECIPE_SOURCE_SYSTEM;334 335 *status = true;336 return true;337 }338 339 // Load the recipe files (valid for SYSTEM | CAMERA)340 // each time we load a specific recipe, it overrides the existing metadata for that recipe341 // for sourceType == SYSTEM | CAMERA, RECIPES contains a list of files to be read (pmConfigFileRead)342 static bool loadRecipeCamera(bool *status, // status variable343 pmConfig *config, // The configuration into which to read the recipes344 psMetadata *source // The source configuration, from which to read the filenames345 )346 {347 bool success;348 349 assert(status);350 assert(config);351 *status = false;352 353 if (!source) {354 psError(PS_ERR_IO, true, "The camera configuration has not been read --- cannot read recipes from this location.\n");355 config->recipesRead &= ~PM_RECIPE_SOURCE_CAMERA;356 return false;357 }358 359 // it is not necessary to define any local recipes in the camera config360 psMetadata *recipes = psMetadataLookupMetadata(&success, source, "RECIPES"); // The list of recipes361 if (!recipes) {362 psTrace ("psModules.config", 3, "RECIPES not found in the camera configuration\n");363 return true;364 330 } 365 331 … … 373 339 char *recipeFile = fileItem->data.str; 374 340 375 psTrace("psModules.config", 3, "Supplementing %s from %s within camera configuration.\n", recipeName, recipeFile); 341 // type mismatch is a serious error 342 if (fileItem->type != PS_DATA_STRING) { 343 psAbort("%s in system configuration RECIPES is not of type STR", recipeName); 344 } 345 346 // Read the recipe file. if we fail on a file, give a warning, but continue 347 psMetadata *recipe = NULL; 348 if (!pmConfigFileRead(&recipe, recipeFile, "recipe")) { 349 psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in system configuration\n", recipeFile); 350 return false; 351 } 352 353 // and the contents of this recipe file to config->recipes 354 psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE, fileItem->comment, recipe); 355 psFree(recipe); // Drop reference 356 } 357 psFree(recipesIter); 358 config->recipesRead |= PM_RECIPE_SOURCE_SYSTEM; 359 360 *status = true; 361 return true; 362 } 363 364 // Load the recipe files for a specific CAMERA. these are saved on recipesCamera 365 static bool loadRecipeCamera(bool *status, // status variable 366 pmConfig *config, // The configuration into which to read the recipes 367 psMetadata *source // The source configuration, from which to read the filenames 368 ) 369 { 370 bool success; 371 372 assert(status); 373 assert(config); 374 *status = false; 375 376 if (!source) { 377 psError(PS_ERR_IO, true, "The camera configuration has not been read --- cannot read recipes from this location.\n"); 378 config->recipesRead &= ~PM_RECIPE_SOURCE_CAMERA; 379 return false; 380 } 381 382 // it is not necessary to define any local recipes in the camera config; it this entry is missing, 383 // just return true 384 psMetadata *recipes = psMetadataLookupMetadata(&success, source, "RECIPES"); // The list of recipes 385 if (!recipes) { 386 psTrace ("psModules.config", 3, "RECIPES not found in the camera configuration\n"); 387 return true; 388 } 389 390 // Copy contents of the filenames to config->recipes from the "RECIPES" metadata in the source. 391 // We could use psMetadataCopy for this, but it's better to check that everything's of the correct type. 392 // If it's not of the correct type, we can tell the user which file it's in, so they can find it easier. 393 psMetadataIterator *recipesIter = psMetadataIteratorAlloc(recipes, PS_LIST_HEAD, NULL); // Iterator 394 psMetadataItem *fileItem = NULL; // MD item containing the filename, from recipe iteration 395 while ((fileItem = psMetadataGetAndIncrement(recipesIter))) { 396 char *recipeName = fileItem->name; 397 char *recipeFile = fileItem->data.str; 398 399 psTrace("psModules.config", 3, "loading %s from %s within camera configuration.\n", recipeName, recipeFile); 376 400 377 401 // type mismatch is a serious error … … 383 407 psMetadata *recipe = NULL; 384 408 if (!pmConfigFileRead(&recipe, recipeFile, "recipe")) { 385 psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in camera configuration\n", 386 recipeFile); 387 return false; 388 } 389 390 // the named recipe must exist; supplement it 409 psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in camera configuration\n", recipeFile); 410 return false; 411 } 412 413 // the named recipe must exist at the system level 391 414 psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName); 392 415 if (!current) { … … 396 419 } 397 420 398 if (!psMetadataUpdate(current, recipe)) { 399 psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName); 400 psFree(recipe); // Drop reference 401 return false; 402 } 421 // add the contents of this recipe file to config->recipesCamera 422 psMetadataAdd(config->recipesCamera, PS_LIST_TAIL, recipeName, PS_DATA_METADATA | PS_META_REPLACE, fileItem->comment, recipe); 403 423 psFree(recipe); // Drop reference 404 424 } 405 425 psFree(recipesIter); 406 426 config->recipesRead |= PM_RECIPE_SOURCE_CAMERA; 427 *status = true; 428 return true; 429 } 430 431 // Merge the CAMERA recipes into the SYSTEM recipes 432 static bool mergeRecipeCamera(bool *status, // status variable 433 pmConfig *config // The configuration into which to read the recipes 434 ) 435 { 436 assert(status); 437 assert(config); 438 *status = false; 439 440 // Copy contents of config->recipesCamera to config->recipes 441 // We could use psMetadataCopy for this, but it's better to check that everything's of the correct type. 442 // If it's not of the correct type, we can tell the user which file it's in, so they can find it easier. 443 psMetadataIterator *recipesIter = psMetadataIteratorAlloc(config->recipesCamera, PS_LIST_HEAD, NULL); // Iterator 444 psMetadataItem *folderItem = NULL; // MD item containing the filename, from recipe iteration 445 while ((folderItem = psMetadataGetAndIncrement(recipesIter))) { 446 char *recipeName = folderItem->name; 447 psMetadata *recipe = folderItem->data.md; 448 449 psTrace("psModules.config", 3, "merging %s from camera with system recipes.\n", recipeName); 450 451 // type mismatch is a serious error 452 if (folderItem->type != PS_DATA_METADATA) { 453 psAbort("%s not of type METADATA", recipeName); 454 } 455 456 // the select the named recipe from the system level 457 psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName); 458 psAssert (current, "Failed to find recipe for %s in system recipe list", recipeName); 459 460 // update the contents of this recipe from the one on config->recipesCamera 461 if (!psMetadataUpdate(current, recipe)) { 462 psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName); 463 return false; 464 } 465 } 466 psFree(recipesIter); 407 467 *status = true; 408 468 return true; … … 464 524 // Load the recipes: each time we load a specific recipe, it overrides the metadata 465 525 // entries for an existing recipe metadata 466 static bool loadRecipeSymbols(bool *status, 467 pmConfig *config // The configuration into which to read the recipes 468 ) 469 { 526 // The configuration into which to read the recipes 527 static bool loadRecipeSymbols(bool *status, pmConfig *config, pmRecipeSource source) { 528 470 529 bool found = false; 471 530 … … 492 551 } 493 552 494 // search for sourceName : it may be in config->recipes or target MD 495 psMetadata *sourceMD = NULL; 496 sourceMD = psMetadataLookupMetadata(&found, config->recipes, sourceName); 497 if (!sourceMD) { 498 sourceMD = psMetadataLookupMetadata(&found, targetMD, sourceName); 499 if (!sourceMD) { 500 psError(PS_ERR_IO, false, "Selected symbolic name %s does not exist in recipes", sourceName); 501 return false; 502 } 503 } 504 505 if (!psMetadataUpdate(targetMD, sourceMD)) { 553 // search for sourceName in config->recipes (folder name is targetName) 554 psMetadata *folder = psMetadataLookupMetadata(&found, config->recipes, targetName); 555 psMetadata *sourceMD = psMetadataLookupMetadata(&found, folder, sourceName); 556 557 // if we find the desired symbolic name at this level, set the item comment to say "FOUND" 558 if (sourceMD) { 559 if (!psMetadataUpdate(targetMD, sourceMD)) { 506 560 psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", targetName); 507 561 return false; 508 } 562 } 563 psStringAppend (&item->comment, "(FOUND)"); 564 } 565 566 // if we have not found it by the camera level, we have a problem 567 if (source == PM_RECIPE_SOURCE_CAMERA) { 568 if (strstr (item->comment, "(FOUND)") == NULL) { 569 psError(PS_ERR_IO, false, "Selected symbolic name %s does not exist in recipes", sourceName); 570 return false; 571 } 572 } 509 573 } 510 574 psFree(iter);
Note:
See TracChangeset
for help on using the changeset viewer.
