IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 4, 2006, 10:41:51 AM (20 years ago)
Author:
magnier
Message:

pulled recipe functions from pmConfig to pmConfigRecipes, fixed up hierarchy for symbols

File:
1 edited

Legend:

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

    r10422 r10428  
    44 *  @author EAM (IfA)
    55 *
    6  *  @version $Revision: 1.56 $ $Name: not supported by cvs2svn $
    7  *  @date $Date: 2006-12-04 02:14:09 $
     6 *  @version $Revision: 1.57 $ $Name: not supported by cvs2svn $
     7 *  @date $Date: 2006-12-04 20:41:51 $
    88 *
    99 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2525#include <pslib.h>
    2626#include "pmConfig.h"
     27#include "pmConfigRecipes.h"
    2728
    2829#define PS_SITE "PS_SITE"         // Name of the environment variable containing the site config file
     
    3839    psFree(config->cameraName);
    3940    psFree(config->recipes);
    40     psFree(config->recipesSource);
     41    psFree(config->recipeSymbols);
    4142    psFree(config->arguments);
    4243    psFree(config->database);
     
    5556    config->recipes = psMetadataAlloc();
    5657    config->recipesRead = PM_RECIPE_SOURCE_NONE;
    57     config->recipesSource = psMetadataAlloc();
     58    config->recipeSymbols = psMetadataAlloc();
    5859    config->arguments = psMetadataAlloc();
    5960    config->database = NULL;
     
    660661}
    661662
    662 
    663 // Load the recipes: each time we load a specific recipe, it overrides the metadata
    664 // entries for an existing recipe metadata
    665 static bool loadRecipes(pmConfig *config, // The configuration into which to read the recipes
    666                         psMetadata *source, // The source configuration, from which to read the filenames
    667                         pmRecipeSource sourceType, // The source type
    668                         const char *sourceName // The name of the source, for error messages
    669                        )
    670 {
    671     assert(config);
    672 
    673     if (!source) {
    674         psTrace("psModules.pmConfig", 4, "The %s has not been read --- cannot read recipes from this "
    675                 "location.\n", sourceName);
    676         config->recipesRead &= ~sourceType;
    677         return false;
    678     }
    679 
    680     bool mdok = true;                   // Status of MD lookup
    681     psMetadata *recipes = psMetadataLookupMetadata(&mdok, source, "RECIPES"); // The list of recipes
    682     if (!mdok || !recipes) {
    683         psLogMsg("psModules.pmConfig", PS_LOG_WARN, "RECIPES in the %s is not of type METADATA --- ignored\n",
    684                  sourceName);
    685         config->recipesRead &= ~sourceType;
    686         return false;
    687     }
    688 
    689     // for sourceType == SITE | CAMERA, RECIPES contains a list of files to be read (pmConfigFileRead)
    690     // for sourceType == CL, RECIPES contains a list of metadata already loaded
    691 
    692     // Copy the filenames to the target from the "RECIPES" in the source.
    693     // We could use psMetadataCopy for this, but it's better to check that everything's of the correct type.
    694     // If it's not of the correct type, we can tell the user which file it's in, so they can find it easier.
    695     {
    696         psMetadataIterator *recipesIter = psMetadataIteratorAlloc(recipes, PS_LIST_HEAD, NULL); // Iterator
    697         psMetadataItem *fileItem = NULL;    // MD item containing the filename, from recipe iteration
    698         while ((fileItem = psMetadataGetAndIncrement(recipesIter)))
    699         {
    700             psMetadata *recipe = NULL;
    701             psMetadata *current = NULL;
    702 
    703             switch (sourceType) {
    704             case PM_RECIPE_SOURCE_SITE:
    705             case PM_RECIPE_SOURCE_CAMERA:
    706                 // type mismatch is a serious error
    707                 if (fileItem->type != PS_DATA_STRING) {
    708                     psAbort ("pmConfig", "%s in %s RECIPES is not of type STR", fileItem->name, sourceName);
    709                 }
    710 
    711                 // Check to see if it's currently defined
    712                 // XXX EAM : I think this check is now not needed?
    713                 int check = psMetadataLookupS32(&mdok, config->recipesSource, fileItem->name);
    714                 if (mdok && check > sourceType) {
    715                     // It's already defined with a higher priority
    716                     continue;
    717                 }
    718                 psString comment = psStringCopy("Recipe added at ");
    719                 psStringAppend(&comment, "%s from %s", sourceName, (char*)fileItem->data.V);
    720                 psTrace ("psModules.pmConfig", 3, comment);
    721                 psMetadataAddS32(config->recipesSource, PS_LIST_TAIL, fileItem->name,
    722                                  PS_META_REPLACE, comment, sourceType);
    723                 psFree(comment);
    724 
    725                 // Read the recipe file.
    726                 if (!pmConfigFileRead(&recipe, fileItem->data.V, "recipe")) {
    727                     psError(PS_ERR_IO, false, "Failed to read recipe");
    728                     psFree(recipe);  // Drop reference
    729                     psFree(recipesIter);
    730                     return false;
    731                 }
    732                 break;
    733 
    734             case PM_RECIPE_SOURCE_CL:
    735                 // type mismatch is a serious error
    736                 if (fileItem->type != PS_DATA_METADATA) {
    737                     psAbort ("pmConfig", "%s in %s RECIPES is not of type METADATA", fileItem->name, sourceName);
    738                 }
    739                 // increment the ref counter to protect the data
    740                 recipe = psMemIncrRefCounter (fileItem->data.V);
    741                 break;
    742 
    743             default:
    744                 psAbort ("pmConfig", "unknown sourceType");
    745             }
    746 
    747             // if this named recipe exists, supplement it
    748             current = psMetadataLookupMetadata (NULL, config->recipes, fileItem->name);
    749             if (current) {
    750                 psMemIncrRefCounter (current);
    751             }
    752             current = psMetadataCopy (current, recipe);
    753             psMetadataAdd(config->recipes, PS_LIST_TAIL, fileItem->name, PS_DATA_METADATA | PS_META_REPLACE, fileItem->comment, current);
    754             psFree(recipe);  // Drop reference
    755             psFree(current);  // Drop reference
    756         }
    757         psFree(recipesIter);
    758     }
    759     config->recipesRead |= sourceType;
    760 
    761     {
    762         // Having read that, we now need to check to see if any symbolic links need to be resolved
    763         psMetadataIterator *recipesIter = psMetadataIteratorAlloc(config->recipesSource, PS_LIST_HEAD, NULL);
    764         psMetadataItem *sourceItem = NULL;  // Item containing source, from iteration
    765         while ((sourceItem = psMetadataGetAndIncrement(recipesIter))) {
    766             assert(sourceItem->type == PS_TYPE_S32); // It should be this type: we put it in ourselves
    767             if (sourceItem->data.S32 == PM_RECIPE_SOURCE_SYMBOLIC) {
    768                 const char *linkName = sourceItem->comment; // The name of the link
    769                 psMetadata *linkSource = psMetadataLookupMetadata(&mdok, config->recipes, linkName); // The source
    770                 if (!mdok || !linkSource) {
    771                     // Can't yet resolve it
    772                     continue;
    773                 }
    774                 psString comment = NULL;
    775                 psStringAppend(&comment, "Symbolic link from %s", linkName);
    776                 psMetadataAdd(config->recipes, PS_LIST_TAIL, sourceItem->name,
    777                               PS_DATA_METADATA | PS_META_REPLACE, comment, linkSource);
    778                 psFree(comment);
    779             }
    780         }
    781         psFree(recipesIter);
    782     }
    783     return true;
    784 }
    785 
    786 // this function may be called several times.  it attempts to load the recipe data from one of
    787 // three locations: config->site, config->camera, and config->argv we cannot read the recipes
    788 // from config->camera until a camera has been read BUT, the argv recipes must override the
    789 // camera and site recipes.
    790 bool pmConfigReadRecipes(pmConfig *config, pmRecipeSource source)
    791 {
    792     PS_ASSERT_PTR_NON_NULL(config, false);
    793 
    794     if (!config->recipes) {
    795         config->recipes = psMetadataAlloc();
    796     }
    797 
    798     // Read the recipe file names from the site configuration and camera configuration
    799     // XXX EAM : I think it should be an error for config->site:recipes not to exist
    800     // for now, keep this as a warning
    801     if (config->site && (source & PM_RECIPE_SOURCE_SITE)) {
    802         if (!loadRecipes(config, config->site, PM_RECIPE_SOURCE_SITE, "site configuration")) {
    803             psLogMsg ("psModules.pmConfig", PS_LOG_WARN, "Failed to read recipes from site config");
    804         } else {
    805             psTrace ("psModules.pmConfig", 3, "read recipes from site config");
    806         }
    807     }
    808 
    809     // camera-specific recipes are not required : note the absence with a message
    810     // camera-specific recipes may be read for a specified camera (in pmConfigRead) or
    811     // for an identified camera (in pmConfigCameraFormatFromHeader).  the second
    812     // set should not override the first set
    813     if (config->camera && (source & PM_RECIPE_SOURCE_CAMERA) && !(config->recipesRead & PM_RECIPE_SOURCE_CAMERA)) {
    814         if (!loadRecipes(config, config->camera, PM_RECIPE_SOURCE_CAMERA, "camera configuration")) {
    815             psLogMsg ("psModules.pmConfig", PS_LOG_DETAIL, "no recipe supplied by camera config");
    816         } else {
    817             psTrace ("psModules.pmConfig", 3, "read recipes from camera config");
    818         }
    819     }
    820 
    821     // apply recipes loaded into config->arguments based on command-line arguments
    822     if (config->arguments && (source & PM_RECIPE_SOURCE_CL)) {
    823         if (!loadRecipes(config, config->arguments, PM_RECIPE_SOURCE_CL, "command-line arguments")) {
    824             psLogMsg ("psModules.pmConfig", PS_LOG_DETAIL, "no recipe supplied on command-line arguments");
    825         } else {
    826             psTrace ("psModules.pmConfig", 3, "read recipes from command-line arguments");
    827         }
    828     }
    829     /*
    830      * We may have seen real errors, but we also get false status returned by valid conditions (e.g. asking a
    831      * file for a recipe when none was provided).  For now we'll never signal an error, but this should
    832      * be reconsidered ASAP.
    833      */
    834     psErrorClear();
    835     return true;
    836 }
    837 
    838 
    839663psDB *pmConfigDB(pmConfig *config)
    840664{
     
    1057881    return newName;
    1058882}
    1059 
    1060 // search for options of the form -D KEY VALUE or -D RECIPE:KEY VALUE
    1061 bool pmConfigLoadRecipeOptions (pmConfig *config, char *flag)
    1062 {
    1063 
    1064     int argNum;
    1065 
    1066     // save the recipes onto config->arguments:RECIPES
    1067     psMetadata *recipes = psMetadataLookupMetadata(NULL, config->arguments, "RECIPES");
    1068     if (!recipes) {
    1069         recipes = psMetadataAlloc ();
    1070         psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "RECIPES",  PS_DATA_METADATA, "", recipes);
    1071     } else {
    1072         psMemIncrRefCounter (recipes); // so we can free options below if not allocated here
    1073     }
    1074 
    1075     // -D key value (all added as string)
    1076     while ((argNum = psArgumentGet (*config->argc, config->argv, flag))) {
    1077         psArgumentRemove (argNum, config->argc, config->argv);
    1078 
    1079         // do we have enough arguments?
    1080         if (argNum + 1 >= *config->argc) {
    1081             psError(PS_ERR_IO, true, "insufficient parameters for command-line argument -D");
    1082             return false;
    1083         }
    1084 
    1085         // is a target recipe specified?
    1086         char *recipeName = NULL;
    1087         char *key;
    1088         psArray *words = psStringSplitArray(config->argv[argNum], ":", false);
    1089         switch (words->n) {
    1090         case 1:
    1091             recipeName = config->defaultRecipe;
    1092             if (!config->defaultRecipe) {
    1093                 psError(PS_ERR_IO, true, "syntax error in parameter: no default recipe available; must specify recipe");
    1094                 return false;
    1095             }
    1096             key = words->data[0];
    1097             break;
    1098         case 2:
    1099             recipeName = words->data[0];
    1100             key = words->data[1];
    1101             break;
    1102         default:
    1103             psError(PS_ERR_IO, true, "syntax error in parameter");
    1104             return false;
    1105         }
    1106 
    1107         // if this recipe is already defined in recipes, supplement
    1108         psMetadata *recipe = psMetadataLookupMetadata(NULL, recipes, recipeName);
    1109         if (!recipe) {
    1110             recipe = psMetadataAlloc ();
    1111             psMetadataAddPtr (recipes, PS_LIST_TAIL, recipeName,  PS_DATA_METADATA, "", recipe);
    1112         } else {
    1113             psMemIncrRefCounter (recipe); // so we can free recipe below if not allocated here
    1114         }
    1115 
    1116         bool valid = false;
    1117         if (!strcmp (flag, "-D")) {
    1118             psMetadataAddStr (recipe, PS_LIST_TAIL, key, PS_META_REPLACE, "", config->argv[argNum+1]);
    1119             valid = true;
    1120         }
    1121         if (!strcmp (flag, "-Di")) {
    1122             psMetadataAddS32 (recipe, PS_LIST_TAIL, key, PS_META_REPLACE, "", atoi(config->argv[argNum+1]));
    1123             valid = true;
    1124         }
    1125         if (!strcmp (flag, "-Df")) {
    1126             psMetadataAddF32 (recipe, PS_LIST_TAIL, key, PS_META_REPLACE, "", atof(config->argv[argNum+1]));
    1127             valid = true;
    1128         }
    1129         if (!strcmp (flag, "-Db")) {
    1130             if (!strcasecmp (config->argv[argNum+1], "true")) {
    1131                 psMetadataAddBool (recipe, PS_LIST_TAIL, key, PS_META_REPLACE, "", true);
    1132             } else {
    1133                 psMetadataAddBool (recipe, PS_LIST_TAIL, key, PS_META_REPLACE, "", false);
    1134             }
    1135             valid = true;
    1136         }
    1137         psFree (words);
    1138         psFree (recipe);
    1139         assert (valid);  // flag may be: -D, -Df, -Di, -Db
    1140 
    1141         psArgumentRemove (argNum, config->argc, config->argv);
    1142         psArgumentRemove (argNum, config->argc, config->argv);
    1143     }
    1144     psFree (recipes);
    1145     return true;
    1146 }
    1147 
    1148 // examine command-line arguments for -recipe KEY VALUE
    1149 // if VALUE is an existing file, read as metadata and save on config->arguments with name = KEY
    1150 // if VALUE is not an exiting file, it is a symbolic lookup.  ???
    1151 bool pmConfigLoadRecipeArguments (pmConfig *config)
    1152 {
    1153 
    1154     // Go through the command-line arguments
    1155     int argNum; // Argument number for "-recipe"
    1156     while ((argNum = psArgumentGet(*config->argc, config->argv, "-recipe")) > 0) {
    1157         psArgumentRemove(argNum, config->argc, config->argv);
    1158         if (argNum + 1 >= *config->argc) {
    1159             psError(PS_ERR_IO, false, "-recipe command-line switch provided without the required recipe and source\n");
    1160             return false;
    1161         }
    1162 
    1163         const char *recipeName = psStringCopy(config->argv[argNum]); // Name of the recipe
    1164         psArgumentRemove(argNum, config->argc, config->argv);
    1165         const char *recipeSource = psStringCopy(config->argv[argNum]); // Source of the recipe
    1166         psArgumentRemove(argNum, config->argc, config->argv);
    1167 
    1168         if (access(recipeSource, R_OK) == 0) {
    1169             // The source is a file: load onto config->arguments
    1170             // save the recipes onto config->arguments:RECIPES
    1171             psMetadata *recipes = psMetadataLookupMetadata(NULL, config->arguments, "RECIPES");
    1172             if (!recipes) {
    1173                 recipes = psMetadataAlloc ();
    1174                 psMetadataAddPtr (config->arguments, PS_LIST_TAIL, "RECIPES",  PS_DATA_METADATA, "", recipes);
    1175             } else {
    1176                 psMemIncrRefCounter (recipes); // so we can free options below if not allocated here
    1177             }
    1178 
    1179             psMetadata *recipe = NULL;      // Recipe from file
    1180             if (pmConfigFileRead(&recipe, recipeSource, "recipe")) {
    1181                 psString comment = psStringCopy("Recipe added at command line from ");
    1182                 psStringAppend(&comment, "%s", recipeSource);
    1183                 psMetadataAdd(recipes, PS_LIST_TAIL, recipeName, PS_DATA_METADATA | PS_META_REPLACE, comment, recipe);
    1184                 psFree(comment);
    1185                 psFree(recipe);                 // Drop reference
    1186             } else {
    1187                 psAbort ("pmConfig.c", "error reading config file %s\n", recipeSource);
    1188             }
    1189             psFree (recipes);
    1190         } else {
    1191             // Assume it's a symbolic reference to something that's not yet read in
    1192             psMetadataAddS32(config->recipesSource, PS_LIST_TAIL, recipeName, PS_META_REPLACE,
    1193                              recipeSource, PM_RECIPE_SOURCE_SYMBOLIC);
    1194         }
    1195         psTrace ("psModules.pmConfig", 3, "read recipe %s from %s", recipeName, recipeSource);
    1196         psFree(recipeName);
    1197         psFree(recipeSource);
    1198     } // Iterating through the command-line arguments
    1199 
    1200     return true;
    1201 }
    1202 
    1203 # if (0)
    1204 
    1205     // Is the source a symbolic reference?
    1206     // XXX EAM : need to be careful about hierachy and overrides
    1207     psMetadata *extant = psMetadataLookupMetadata(&mdok, config->recipes, recipeSource); // Does it exist?
    1208 if (mdok && extant)
    1209 {
    1210     psString comment = psStringCopy("Recipe added from command line as symbolic link to ");
    1211     psStringAppend(&comment, "%s", recipeSource);
    1212     psMetadataAdd(config->recipes, PS_LIST_TAIL, recipeName, PS_DATA_METADATA | PS_META_REPLACE,
    1213                   comment, extant);
    1214     psFree(comment);
    1215     // Put the source in the comment, so we can retrieve it again if we need it
    1216     psMetadataAddS32(config->recipesSource, PS_LIST_TAIL, recipeName, PS_META_REPLACE,
    1217                      recipeSource, PM_RECIPE_SOURCE_SYMBOLIC);
    1218 
    1219 } else
    1220 
    1221     # endif
    1222 
Note: See TracChangeset for help on using the changeset viewer.