IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 22, 2007, 8:07:18 AM (19 years ago)
Author:
magnier
Message:

changed config recipes rules: master recipe file must exist

File:
1 edited

Legend:

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

    r11687 r12544  
    1515#include "pmConfigRecipes.h"
    1616
    17 static bool loadRecipeFiles(pmConfig *config, psMetadata *source, pmRecipeSource type, const char *name);
    18 static bool loadRecipeFromArguments(pmConfig *config);
    19 static bool loadRecipeSymbols(pmConfig *config);
    20 static bool loadRecipeOptions(pmConfig *config);
     17static bool loadRecipeSite(bool *status, pmConfig *config, psMetadata *source);
     18static bool loadRecipeCamera(bool *status, pmConfig *config, psMetadata *source);
     19static bool loadRecipeFromArguments(bool *status, pmConfig *config);
     20static bool loadRecipeSymbols(bool *status, pmConfig *config);
     21static bool loadRecipeOptions(bool *status, pmConfig *config);
    2122
    2223// use this function to select the options structure for the specified recipe
     
    2425psMetadata *pmConfigRecipeOptions (pmConfig *config, char *recipeName)
    2526{
    26 
    27     // if the recipe is already defined in config->arguments, supplement
     27    bool success;
     28
     29    // select or create the OPTIONS folder
     30    psMetadata *options = psMetadataLookupMetadata(&success, config->arguments, "OPTIONS");
     31    if (!options) {
     32        options = psMetadataAlloc ();
     33        success = psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "OPTIONS",  PS_DATA_METADATA, "", options);
     34        assert (success); // type mismatch : OPTIONS already defined but wrong type
     35        psFree (options); // drop extra reference
     36    }
     37
     38    // look for the recipe defined in recipes
     39    // if the recipe is already defined in config->arguments:OPTIONS, supplement
    2840    // save the recipe options onto config->arguments:RECIPES
    29     psMetadata *options;
    30     psMetadataItem *optionsItem = psMetadataLookup(config->arguments, "OPTIONS");
    31     if (optionsItem) {
    32         assert(optionsItem->type == PS_DATA_METADATA);
    33         options = psMemIncrRefCounter(optionsItem->data.V);
    34     } else {
    35         options = psMetadataAlloc ();
    36         psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "OPTIONS",  PS_DATA_METADATA, "", options);
    37     }
    38 
    39     // look for the recipe defined in recipes
    40     psMetadata *recipe;
    41     psMetadataItem *recipeItem = psMetadataLookup(options, recipeName);
    42     psFree(options);                   // Drop reference
    43     if (recipeItem) {
    44         assert(recipeItem->type == PS_DATA_METADATA);
    45         recipe = psMemIncrRefCounter(recipeItem->data.V);
    46     } else {
     41    psMetadata *recipe = psMetadataLookupMetadata(&success, options, recipeName);
     42    if (!recipe) {
    4743        recipe = psMetadataAlloc();
    48         psMetadataAddPtr(options, PS_LIST_TAIL, recipeName,  PS_DATA_METADATA, "", recipe);
    49     }
    50 
     44        success = psMetadataAddPtr(options, PS_LIST_TAIL, recipeName,  PS_DATA_METADATA, "", recipe);
     45        assert (success); // type mismatch : OPTIONS already defined but wrong type
     46        psFree (recipe);  // drop extra reference
     47    }
    5148    return recipe;
    5249}
    5350
    5451// this function may be called several times.  it attempts to load the recipe data from one of
    55 // three locations: config->site, config->camera, and config->argv we cannot read the recipes
     52// three locations: config->site, config->camera, and config->argv.  We cannot read the recipes
    5653// from config->camera until a camera has been read BUT, the argv recipes must override the
    5754// camera and site recipes.
    5855bool pmConfigReadRecipes(pmConfig *config, pmRecipeSource source)
    5956{
     57    bool status;
    6058    PS_ASSERT_PTR_NON_NULL(config, false);
    6159
     
    6563
    6664    // Read the recipe file names from the site configuration and camera configuration
    67     // XXX EAM : I think it should be an error for config->site:recipes not to exist
    68     // for now, keep this as a warning
     65    // It is an error for config->site:recipes not to exist.  all programs install their
     66    // master recipe files in the site:recipe location when they are built.
    6967    if (config->site && (source & PM_RECIPE_SOURCE_SITE)) {
    70         if (!loadRecipeFiles(config, config->site, PM_RECIPE_SOURCE_SITE, "site configuration")) {
    71             psLogMsg ("psModules.config", PS_LOG_WARN, "Failed to read recipes from site config");
    72         } else {
    73             psTrace ("psModules.config", 3, "read recipes from site config");
    74         }
     68        if (!loadRecipeSite(&status, config, config->site)) {
     69            psError(PS_ERR_IO, false, "Failed to read recipes from site config");
     70            return false;
     71        }
     72        psTrace ("psModules.config", 3, "read recipes from site config");
    7573    }
    7674
     
    8078    // set should not override the first set
    8179    if (config->camera && (source & PM_RECIPE_SOURCE_CAMERA) && !(config->recipesRead & PM_RECIPE_SOURCE_CAMERA)) {
    82         if (!loadRecipeFiles(config, config->camera, PM_RECIPE_SOURCE_CAMERA, "camera configuration")) {
    83             psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by camera config");
    84         } else {
    85             psTrace ("psModules.config", 3, "read recipes from camera config");
    86         }
     80        if (!loadRecipeCamera(&status, config, config->camera)) {
     81            psError(PS_ERR_IO, false, "Failed to read recipes from camera config");
     82            return false;
     83        }
     84        if (status) {
     85            psTrace ("psModules.config", 3, "read recipes from camera config");
     86        } else {
     87            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by camera config");
     88        }
    8789    }
    8890
    8991    // apply recipes loaded into config->arguments based on command-line arguments
    9092    if (config->arguments && (source & PM_RECIPE_SOURCE_CL)) {
    91         if (!loadRecipeFromArguments(config)) {
     93        if (!loadRecipeFromArguments(&status, config)) {
     94            psError(PS_ERR_IO, false, "Failed to read recipes from command-line arguments");
     95            return false;
     96        }
     97        if (status) {
     98            psTrace ("psModules.config", 3, "read recipes from command-line arguments");
     99        } else {
     100            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
     101        }
     102        if (!loadRecipeSymbols(&status, config)) {
     103            psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references");
     104            return false;
     105        }
     106        if (status) {
     107            psTrace ("psModules.config", 3, "read recipes from symbolic references");
     108        } else {
     109            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied by symbolic reference");
     110        }
     111        if (!loadRecipeOptions(&status, config)) {
     112            psError(PS_ERR_IO, false, "Failed to read recipes from symbolic references");
     113            return false;
     114        }
     115        if (status) {
     116            psTrace ("psModules.config", 3, "read recipes from command-line arguments");
     117        } else {
    92118            psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
    93         } else {
    94             psTrace ("psModules.config", 3, "read recipes from command-line arguments");
    95         }
    96         if (!loadRecipeSymbols(config)) {
    97             psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
    98         } else {
    99             psTrace ("psModules.config", 3, "read recipes from command-line arguments");
    100         }
    101         if (!loadRecipeOptions(config)) {
    102             psLogMsg ("psModules.config", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
    103         } else {
    104             psTrace ("psModules.config", 3, "read recipes from command-line arguments");
    105         }
    106     }
    107     /*
    108      * We may have seen real errors, but we also get false status returned by valid conditions (e.g. asking a
    109      * file for a recipe when none was provided).  For now we'll never signal an error, but this should
    110      * be reconsidered ASAP.
    111      */
    112     psErrorClear();
     119        }
     120    }
    113121    return true;
    114122}
     
    117125bool pmConfigLoadRecipeOptions (pmConfig *config, char *flag)
    118126{
    119 
     127    bool success;
    120128    int argNum;
    121129
    122130    // save the recipes onto config->arguments:RECIPES
    123     // increment so we can free below (is a NOP is options is NULL)
    124     psMetadata *options;                // OPTIONS on the arguments
    125     psMetadataItem *optionsItem = psMetadataLookup(config->arguments, "OPTIONS");
    126     if (optionsItem) {
    127         if (optionsItem->type != PS_DATA_METADATA) {
    128             psAbort("OPTIONS is not of type METADATA.");
    129         }
    130         options = psMemIncrRefCounter(optionsItem->data.V);
    131     } else {
     131    // increment so we can free below (is a NOP if 'options' is NULL)
     132    psMetadata *options = psMetadataLookupMetadata(&success, config->arguments, "OPTIONS");
     133    if (!options) {
    132134        options = psMetadataAlloc();
    133         psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "OPTIONS",  PS_DATA_METADATA,
    134                          "Command-line options specified with -D", options);
     135        success = psMetadataAddPtr(config->arguments, PS_LIST_TAIL, "OPTIONS",  PS_DATA_METADATA, "Command-line options specified with -D", options);
     136        assert (success); // type mismatch : OPTIONS already defined but wrong type
     137        psFree (options); // drop extra reference
    135138    }
    136139
     
    168171
    169172        // if this recipe is already defined in options, supplement
    170         psMetadata *recipe;
    171         psMetadataItem *recipeItem = psMetadataLookup(options, recipeName);
    172         if (recipeItem) {
    173             assert(recipeItem->type == PS_DATA_METADATA);
    174             recipe = psMemIncrRefCounter(recipeItem->data.V);
    175         } else {
     173        psMetadata *recipe = psMetadataLookupMetadata(&success, options, recipeName);
     174        if (!recipe) {
    176175            recipe = psMetadataAlloc();
    177             psMetadataAddPtr(options, PS_LIST_TAIL, recipeName,  PS_DATA_METADATA, "", recipe);
     176            success = psMetadataAddPtr(options, PS_LIST_TAIL, recipeName,  PS_DATA_METADATA, "", recipe);
     177            assert (success); // type mismatch : recipe already defined but wrong type
     178            psFree (recipe); // drop extra reference
    178179        }
    179180
     
    200201        }
    201202        psFree (words);
    202         psFree (recipe);
    203203        assert (valid);  // flag may be: -D, -Df, -Di, -Db
    204204
     
    206206        psArgumentRemove (argNum, config->argc, config->argv);
    207207    }
    208     psFree (options);
    209208    return true;
    210209}
     
    216215bool pmConfigLoadRecipeArguments (pmConfig *config)
    217216{
    218     psMetadata *recipes;                // Recipes in the arguments list
    219     psMetadataItem *recipesItem = psMetadataLookup(config->arguments, "RECIPES");
    220     if (recipesItem) {
    221         if (recipesItem->type != PS_DATA_METADATA) {
    222             psAbort("RECIPES is not of type METADATA.");
    223         }
    224         recipes = psMemIncrRefCounter(recipesItem->data.V);
    225     } else {
     217    bool success;
     218
     219    psMetadata *recipes = psMetadataLookupMetadata(&success, config->arguments, "RECIPES");
     220    if (!recipes) {
    226221        recipes = psMetadataAlloc();
    227         psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "RECIPES",  PS_DATA_METADATA, "", recipes);
    228     }
    229 
     222        success = psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "RECIPES",  PS_DATA_METADATA, "", recipes);
     223        assert (success);
     224        psFree (recipes);
     225    }
    230226
    231227    // Go through the command-line arguments
     
    238234        }
    239235
    240         const char *recipeName = psStringCopy(config->argv[argNum]); // Name of the recipe
     236        char *recipeName = psStringCopy(config->argv[argNum]); // Name of the recipe
    241237        psArgumentRemove(argNum, config->argc, config->argv);
    242         const char *recipeSource = psStringCopy(config->argv[argNum]); // Source of the recipe
     238        char *recipeSource = psStringCopy(config->argv[argNum]); // Source of the recipe
    243239        psArgumentRemove(argNum, config->argc, config->argv);
    244240
     
    265261        }
    266262        psTrace ("psModules.config", 3, "read recipe %s from %s", recipeName, recipeSource);
    267         psFree((void *)recipeName);
    268         psFree((void *)recipeSource);
     263        psFree(recipeName);
     264        psFree(recipeSource);
    269265    } // Iterating through the command-line arguments
    270266
    271     psFree(recipes);                    // Drop reference
    272     return true;
    273 }
    274 
    275 // Load the recipe files (valid for SITE | CAMERA)
    276 // each time we load a specific recipe, it overrides the existing metadata for that recipe
    277 // for sourceType == SITE | CAMERA, RECIPES contains a list of files to be read (pmConfigFileRead)
    278 static bool loadRecipeFiles(pmConfig *config, // The configuration into which to read the recipes
    279                             psMetadata *source, // The source configuration, from which to read the filenames
    280                             pmRecipeSource sourceType, // The source type
    281                             const char *sourceName // The name of the source, for error messages
    282                            )
    283 {
     267    return true;
     268}
     269
     270// Load the recipe files for SITE : REQUIRED
     271static bool loadRecipeSite(bool *status,
     272                           pmConfig *config, // The configuration into which to read the recipes
     273                           psMetadata *source // The source configuration, from which to read the filenames
     274    )
     275{
     276    assert(status);
    284277    assert(config);
    285     if ((sourceType != PM_RECIPE_SOURCE_SITE) && (sourceType != PM_RECIPE_SOURCE_CAMERA)) {
    286         psAbort("invalid source for loadRecipes");
    287     }
     278    *status = false;
     279
    288280    if (!source) {
    289         psTrace("psModules.config", 4, "The %s has not been read --- cannot read recipes from this "
    290                 "location.\n", sourceName);
    291         config->recipesRead &= ~sourceType;
     281        psError(PS_ERR_IO, true, "The site configuration has not been read --- cannot read recipes from this location.\n");
     282        config->recipesRead &= ~PM_RECIPE_SOURCE_SITE;
    292283        return false;
    293284    }
     
    295286    psMetadata *recipes = psMetadataLookupMetadata(NULL, source, "RECIPES"); // The list of recipes
    296287    if (!recipes) {
    297         psLogMsg("psModules.config", PS_LOG_WARN, "RECIPES not found in the %s\n", sourceName);
    298         config->recipesRead &= ~sourceType;
     288        psError(PS_ERR_IO, false, "RECIPES not found in the site configuration\n");
    299289        return false;
    300290    }
     
    308298        // type mismatch is a serious error
    309299        if (fileItem->type != PS_DATA_STRING) {
    310             psAbort("%s in %s RECIPES is not of type STR", fileItem->name, sourceName);
     300            psError(PS_ERR_IO, true, "%s in site configuration RECIPES is not of type STR", fileItem->name);
     301            return false;
    311302        }
    312303
     
    314305        psMetadata *recipe = NULL;
    315306        if (!pmConfigFileRead(&recipe, fileItem->data.V, "recipe")) {
    316             psWarning("Failed to read recipe file %s listed in %s\n", (char *)fileItem->data.V, sourceName);
    317             continue;
     307            psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in site configuration\n", (char *)fileItem->data.V);
     308            return false;
    318309        }
    319310
    320311        // if this named recipe exists, supplement it
    321         psMetadata *current = NULL;     // Current, extant recipe of the same name, to be supplemented
    322         psMetadataItem *currentItem = psMetadataLookup(config->recipes, fileItem->name);
    323         if (currentItem) {
    324             if (currentItem->type != PS_DATA_METADATA) {
    325                 psAbort("Item from recipes is not of type METADATA.");
    326             }
    327             current = psMemIncrRefCounter(currentItem->data.V);
    328             psTrace("psModules.config", 3, "Supplementing %s from %s within %s.\n", currentItem->name,
    329                     fileItem->name, sourceName);
    330         }
    331         current = psMetadataCopy(current, recipe);
     312        psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE,
     313                      fileItem->comment, recipe);
    332314        psFree(recipe);  // Drop reference
    333         psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE,
    334                       fileItem->comment, current);
    335         psFree(current);  // Drop reference
    336315    }
    337316    psFree(recipesIter);
    338     config->recipesRead |= sourceType;
     317    config->recipesRead |= PM_RECIPE_SOURCE_SITE;
     318
     319    *status = true;
     320    return true;
     321}
     322
     323// Load the recipe files (valid for SITE | CAMERA)
     324// each time we load a specific recipe, it overrides the existing metadata for that recipe
     325// for sourceType == SITE | CAMERA, RECIPES contains a list of files to be read (pmConfigFileRead)
     326static bool loadRecipeCamera(bool *status, // status variable
     327                             pmConfig *config, // The configuration into which to read the recipes
     328                             psMetadata *source // The source configuration, from which to read the filenames
     329    )
     330{
     331    bool success;
     332
     333    assert(status);
     334    assert(config);
     335    *status = false;
     336
     337    if (!source) {
     338        psError(PS_ERR_IO, true, "The camera configuration has not been read --- cannot read recipes from this location.\n");
     339        config->recipesRead &= ~PM_RECIPE_SOURCE_CAMERA;
     340        return false;
     341    }
     342
     343    // it is not necessary to define any local recipes in the camera config
     344    psMetadata *recipes = psMetadataLookupMetadata(&success, source, "RECIPES"); // The list of recipes
     345    if (!recipes) {
     346        psTrace ("psModules.config", 3, "RECIPES not found in the camera configuration\n");
     347        return true;
     348    }
     349
     350    // Copy contents of the filenames to config->recipes from the "RECIPES" metadata in the source.
     351    // We could use psMetadataCopy for this, but it's better to check that everything's of the correct type.
     352    // If it's not of the correct type, we can tell the user which file it's in, so they can find it easier.
     353    psMetadataIterator *recipesIter = psMetadataIteratorAlloc(recipes, PS_LIST_HEAD, NULL); // Iterator
     354    psMetadataItem *fileItem = NULL;    // MD item containing the filename, from recipe iteration
     355    while ((fileItem = psMetadataGetAndIncrement(recipesIter))) {
     356        char *recipeName = fileItem->name;
     357        char *recipeFile = fileItem->data.V;
     358
     359        psTrace("psModules.config", 3, "Supplementing %s from %s within camera configuration.\n", recipeName, recipeFile);
     360
     361        // type mismatch is a serious error
     362        if (fileItem->type != PS_DATA_STRING) {
     363            psAbort("%s in camera configuration RECIPES is not of type STR", recipeName);
     364        }
     365
     366        // Read the recipe file. if we fail on a file, give a warning, but continue
     367        psMetadata *recipe = NULL;
     368        if (!pmConfigFileRead(&recipe, recipeFile, "recipe")) {
     369            psError(PS_ERR_IO, false, "Failed to read recipe file %s listed in camera configuration\n", recipeFile);
     370            return false;
     371        }
     372
     373        // the named recipe must exist; supplement it
     374        psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName);
     375        if (!current) {
     376            psError(PS_ERR_IO, false, "Failed to find recipe for %s in master recipe list", recipeName);
     377            psFree(recipe);  // Drop reference
     378            return false;
     379        }
     380
     381        if (!psMetadataUpdate(current, recipe)) {
     382            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName);
     383            psFree(recipe);  // Drop reference
     384            return false;
     385        }
     386        psFree(recipe);  // Drop reference
     387    }
     388    psFree(recipesIter);
     389    config->recipesRead |= PM_RECIPE_SOURCE_CAMERA;
     390    *status = true;
    339391    return true;
    340392}
     
    343395// Load the recipes: each time we load a specific recipe, it overrides the metadata
    344396// entries for an existing recipe metadata
    345 static bool loadRecipeFromArguments(pmConfig *config // The configuration into which to read the recipes
    346                                    )
    347 {
     397static bool loadRecipeFromArguments(bool *status,
     398                                    pmConfig *config // The configuration into which to read the recipes
     399    )
     400{
     401    assert(status);
    348402    assert(config);
     403    *status = false;
     404
    349405    if (!config->arguments) {
    350406        psTrace("psModules.config", 4, "no config->arguments metadata, nothing to read here");
    351         return false;
     407        return true;
    352408    }
    353409
     
    355411    if (!recipes) {
    356412        psTrace("psModules.config", 4, "no RECIPES in config->arguments, nothing to read here");
    357         return false;
     413        return true;
    358414    }
    359415
     
    371427
    372428        // if this named recipe exists, supplement it
    373         psMetadata *current = NULL;
    374         psMetadataItem *currentItem = psMetadataLookup(config->recipes, item->name);
    375         if (currentItem) {
    376             assert(currentItem->type == PS_DATA_METADATA);
    377             current = psMemIncrRefCounter(currentItem->data.V);
    378         }
    379         current = psMetadataCopy (current, recipe);
    380         psMetadataAdd(config->recipes, PS_LIST_TAIL, item->name, PS_DATA_METADATA | PS_META_REPLACE,
    381                       "added from command-line recipe", current);
    382         psFree(current);  // Drop reference
     429        psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, item->name);
     430        if (!current) {
     431            psError(PS_ERR_IO, false, "Failed to find recipe for %s in master recipe list", item->name);
     432            psFree(recipe);  // Drop reference
     433            return false;
     434        }
     435        psTrace("psModules.config", 3, "Supplementing %s from arguments.\n", item->name);
     436
     437        if (!psMetadataUpdate (current, recipe)) {
     438            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", item->name);
     439            return false;
     440        }
    383441    }
    384442    psFree(recipesIter);
     443    *status = true;
    385444    return true;
    386445}
     
    388447// Load the recipes: each time we load a specific recipe, it overrides the metadata
    389448// entries for an existing recipe metadata
    390 static bool loadRecipeSymbols(pmConfig *config // The configuration into which to read the recipes
    391                              )
    392 {
     449static bool loadRecipeSymbols(bool *status,
     450                              pmConfig *config // The configuration into which to read the recipes
     451    )
     452{
     453    bool found = false;
     454
     455    assert(status);
    393456    assert(config);
     457    *status = false;
    394458
    395459    // check to see if any symbolic names need to be resolved
    396     // each entry in recipeSymbols are of the form NAME=REF where NAME is an existing
     460    // each entry in recipeSymbols are of the form TARGET=SOURCE where TARGET is an existing
    397461    // recipe MD and REF is a MD to load over that recipe
    398     psMetadataIterator *recipesIter = psMetadataIteratorAlloc(config->recipeSymbols, PS_LIST_HEAD, NULL);
     462    psMetadataIterator *iter = psMetadataIteratorAlloc(config->recipeSymbols, PS_LIST_HEAD, NULL);
    399463    psMetadataItem *item = NULL;  // Item containing source, from iteration
    400     while ((item = psMetadataGetAndIncrement(recipesIter))) {
     464    while ((item = psMetadataGetAndIncrement(iter))) {
    401465        assert(item->type == PS_DATA_STRING); // It should be this type: we put it in ourselves
    402         const char *symbolRef = item->data.V; // The name of the symbolic reference
    403         const char *symbolName = item->name;
    404 
    405         // search for linkName in config->recipes
    406         psMetadataItem *recipeItem = psMetadataLookup(config->recipes, symbolRef);
    407         if (recipeItem) {
    408             // if this named recipe exists, supplement it
    409             assert(recipeItem->type == PS_DATA_METADATA);
    410             psMetadata *recipe = recipeItem->data.V;
    411             psTrace("psModules.config", 3, "Supplementing %s from %s.\n", symbolName, symbolRef);
    412 
    413             psMetadata *current = NULL;
    414             psMetadataItem *currentItem = psMetadataLookup(config->recipes, symbolName);
    415             if (currentItem) {
    416                 assert(currentItem->type == PS_DATA_METADATA);
    417                 current = psMemIncrRefCounter(currentItem->data.V);
    418             }
    419 
    420             current = psMetadataCopy(current, recipe);
    421             psMetadataAdd(config->recipes, PS_LIST_TAIL, symbolName, PS_DATA_METADATA | PS_META_REPLACE,
    422                           symbolRef, current);
    423             psFree(current);  // Drop reference
    424             continue;
    425         }
    426 
    427         // search for linkName in config->recipes:NAME
    428         psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, symbolName); // The source
    429         if (current) {
    430             psMetadataItem *recipeItem = psMetadataLookup(current, symbolRef);
    431             if (recipeItem) {
    432                 assert(recipeItem->type == PS_DATA_METADATA);
    433                 psMetadata *recipe = recipeItem->data.V;
    434                 psTrace("psModules.config", 3, "Supplementing %s from %s metadata within %s.\n",
    435                         symbolName, symbolRef, symbolRef);
    436                 psMetadataCopy (current, recipe);
    437                 psMetadataAdd(config->recipes, PS_LIST_TAIL, symbolName, PS_DATA_METADATA | PS_META_REPLACE,
    438                               symbolRef, current);
    439                 continue;
    440             }
    441         }
    442         // symbol is not found: ERROR
    443     }
    444     psFree(recipesIter);
     466        const char *sourceName = item->data.V; // The name of the symbolic reference
     467        const char *targetName = item->name;
     468        psTrace("psModules.config", 3, "Supplementing %s from %s.\n", targetName, sourceName);
     469
     470        // the target recipe must exist; select it
     471        psMetadata *targetMD = psMetadataLookupMetadata(&found, config->recipes, targetName);
     472        if (!targetMD) {
     473            psError(PS_ERR_IO, true, "Failed to find recipe for %s in master recipe list", targetName);
     474            return false;
     475        }
     476
     477        // search for sourceName : it may be in config->recipes or target MD
     478        psMetadata *sourceMD = NULL;
     479        sourceMD = psMetadataLookupMetadata(&found, config->recipes, sourceName);
     480        if (!sourceMD) {
     481            sourceMD = psMetadataLookupMetadata(&found, targetMD, sourceName);
     482            if (!sourceMD) {
     483                psError(PS_ERR_IO, false, "Selected symbolic name %s does not exist in recipes", sourceName);
     484                return false;
     485            }
     486        }
     487
     488        if (!psMetadataUpdate(targetMD, sourceMD)) {
     489            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", targetName);
     490            return false;
     491        }
     492    }
     493    psFree(iter);
     494    *status = true;
    445495    return true;
    446496}
     
    449499// Load the recipes: each time we load a specific recipe, it overrides the metadata
    450500// entries for an existing recipe metadata
    451 static bool loadRecipeOptions(pmConfig *config // The configuration into which to read the recipes
    452                              )
    453 {
     501static bool loadRecipeOptions(bool *status,
     502                              pmConfig *config // The configuration into which to read the recipes
     503    )
     504{
     505    bool found;
     506    assert(status);
    454507    assert(config);
     508    *status = false;
     509
    455510    if (!config->arguments) {
    456511        psTrace("psModules.config", 4, "no config->arguments metadata, nothing to read here");
    457         return false;
    458     }
    459 
    460     psMetadata *recipes = psMetadataLookupMetadata(NULL, config->arguments, "OPTIONS"); // The list of recipes
     512        return true;
     513    }
     514
     515    psMetadata *recipes = psMetadataLookupMetadata(&found, config->arguments, "OPTIONS"); // The list of recipes
    461516    if (!recipes) {
    462517        psTrace("psModules.config", 4, "no OPTIONS in config->arguments, nothing to read here");
    463         return false;
     518        return true;
    464519    }
    465520
     
    468523    psMetadataItem *item = NULL;    // MD item containing the filename, from recipe iteration
    469524    while ((item = psMetadataGetAndIncrement(recipesIter))) {
     525        char *recipeName = item->name;
     526        psMetadata *recipe = item->data.V;
     527
    470528        // type mismatch is a serious error
    471529        if (item->type != PS_DATA_METADATA) {
    472             psAbort("%s in config arguments OPTIONS is not of type METADATA", item->name);
    473         }
    474         // increment the ref counter to protect the data
    475         psMetadata *recipe = psMemIncrRefCounter (item->data.V);
     530            psAbort("%s in config arguments OPTIONS is not of type METADATA", recipeName);
     531        }
    476532
    477533        // if this named recipe exists, supplement it
    478         psMetadata *current = NULL;
    479         psMetadataItem *currentItem = psMetadataLookup(config->recipes, item->name);
    480         if (currentItem) {
    481             assert(currentItem->type == PS_DATA_METADATA);
    482             current = psMemIncrRefCounter(currentItem->data.V);
    483         }
    484         current = psMetadataCopy (current, recipe);
    485         psMetadataAdd(config->recipes, PS_LIST_TAIL, item->name, PS_DATA_METADATA | PS_META_REPLACE,
    486                       "supplement command-line arguments", current);
    487         psFree(recipe);  // Drop reference
    488         psFree(current);  // Drop reference
     534        psMetadata *current = psMetadataLookupMetadata(NULL, config->recipes, recipeName);
     535        if (!current) {
     536            psError(PS_ERR_IO, false, "Selected recipe %s is not found in camera recipe", recipeName);
     537            return false;
     538        }
     539        if (!psMetadataUpdate (current, recipe)) {
     540            psError(PS_ERR_IO, false, "Failed to update recipe for %s from camera recipe", recipeName);
     541            return false;
     542        }
    489543    }
    490544    psFree(recipesIter);
    491     return true;
    492 }
    493 
    494 
     545    *status = true;
     546    return true;
     547}
Note: See TracChangeset for help on using the changeset viewer.