IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 17512


Ignore:
Timestamp:
May 4, 2008, 2:00:42 PM (18 years ago)
Author:
eugene
Message:

modify recipe hierarchy rules: system->system symbols->camera->camera symbols->cmdline options

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/config/pmConfigRecipes.c

    r16611 r17512  
    1313static bool loadRecipeSystem(bool *status, pmConfig *config, psMetadata *source);
    1414static bool loadRecipeCamera(bool *status, pmConfig *config, psMetadata *source);
     15static bool loadRecipeSymbols(bool *status, pmConfig *config, pmRecipeSource source);
    1516static bool loadRecipeFromArguments(bool *status, pmConfig *config);
    16 static bool loadRecipeSymbols(bool *status, pmConfig *config);
    1717static bool loadRecipeOptions(bool *status, pmConfig *config);
     18static bool mergeRecipeCamera(bool *status, pmConfig *config);
    1819
    1920// use this function to select the options structure for the specified recipe
     
    4546}
    4647
    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 recipes
    49 // from config->camera until a camera has been read BUT, the argv recipes must override the
    50 // 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.
    5152bool pmConfigReadRecipes(pmConfig *config, pmRecipeSource source)
    5253{
     
    6162    // It is an error for config->complete:recipes not to exist.  all programs install their
    6263    // 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) {
    6466        if (!loadRecipeSystem(&status, config, config->complete)) {
    6567            psError(PS_ERR_IO, false, "Failed to read recipes from system config");
     
    8587    }
    8688
    87     // apply recipes loaded into config->arguments based on command-line arguments
     89    // merge camera and sytem recipes, apply recipes loaded into config->arguments based on command-line arguments
    8890    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
    89111        if (!loadRecipeFromArguments(&status, config)) {
    90112            psError(PS_ERR_IO, false, "Failed to read recipes from command-line arguments");
     
    96118            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
    97119        }
    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)) {
    99123            psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references");
    100124            return false;
     
    105129            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by symbolic reference");
    106130        }
     131
     132        // override any specific values with values from the command line
    107133        if (!loadRecipeOptions(&status, config)) {
    108134            psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references");
     
    124150    int argNum;
    125151
    126     // save the recipes onto config->arguments:RECIPES
     152    // save the recipe options onto config->arguments:OPTIONS
    127153    // increment so we can free below (is a NOP if 'options' is NULL)
    128154    psMetadata *options = psMetadataLookupMetadata(&success, config->arguments, "OPTIONS");
     
    205231}
    206232
    207 // examine command-line arguments for -recipe KEY VALUE
    208 // if VALUE is an existing file, read as metadata and save on config->arguments with name = KEY
    209 // if VALUE is not an exiting file, it is a symbolic lookup: it is saved on config->recipeSymbols
    210 // 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
    211237bool pmConfigLoadRecipeArguments (int *argc, char **argv, pmConfig *config)
    212238{
     
    272298        // Assume it's a symbolic reference to something that's not yet read in.
    273299        // 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);
    276301
    277302        psTrace ("psModules.config", 3, "read recipe %s from %s", recipeName, recipeSource);
     
    303328        psError(PS_ERR_IO, false, "RECIPES not found in the system configuration\n");
    304329        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); // Iterator
    311     psMetadataItem *fileItem = NULL;    // MD item containing the filename, from recipe iteration
    312     while ((fileItem = psMetadataGetAndIncrement(recipesIter))) {
    313         // type mismatch is a serious error
    314         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 continue
    320         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 it
    328         psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE,
    329                       fileItem->comment, recipe);
    330         psFree(recipe);  // Drop reference
    331     }
    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 recipe
    341 // for sourceType == SYSTEM | CAMERA, RECIPES contains a list of files to be read (pmConfigFileRead)
    342 static bool loadRecipeCamera(bool *status, // status variable
    343                              pmConfig *config, // The configuration into which to read the recipes
    344                              psMetadata *source // The source configuration, from which to read the filenames
    345     )
    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 config
    360     psMetadata *recipes = psMetadataLookupMetadata(&success, source, "RECIPES"); // The list of recipes
    361     if (!recipes) {
    362         psTrace ("psModules.config", 3, "RECIPES not found in the camera configuration\n");
    363         return true;
    364330    }
    365331
     
    373339        char *recipeFile = fileItem->data.str;
    374340
    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
     365static 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);
    376400
    377401        // type mismatch is a serious error
     
    383407        psMetadata *recipe = NULL;
    384408        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
    391414        psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName);
    392415        if (!current) {
     
    396419        }
    397420
    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);
    403423        psFree(recipe);  // Drop reference
    404424    }
    405425    psFree(recipesIter);
    406426    config->recipesRead |= PM_RECIPE_SOURCE_CAMERA;
     427    *status = true;
     428    return true;
     429}
     430
     431// Merge the CAMERA recipes into the SYSTEM recipes
     432static 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);
    407467    *status = true;
    408468    return true;
     
    464524// Load the recipes: each time we load a specific recipe, it overrides the metadata
    465525// 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
     527static bool loadRecipeSymbols(bool *status, pmConfig *config, pmRecipeSource source) {
     528
    470529    bool found = false;
    471530
     
    492551        }
    493552
    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)) {
    506560            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", targetName);
    507561            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        }
    509573    }
    510574    psFree(iter);
Note: See TracChangeset for help on using the changeset viewer.