Changeset 10428 for trunk/psModules/src/config/pmConfig.c
- Timestamp:
- Dec 4, 2006, 10:41:51 AM (20 years ago)
- File:
-
- 1 edited
-
trunk/psModules/src/config/pmConfig.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psModules/src/config/pmConfig.c
r10422 r10428 4 4 * @author EAM (IfA) 5 5 * 6 * @version $Revision: 1.5 6$ $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 $ 8 8 * 9 9 * Copyright 2004 Maui High Performance Computing Center, University of Hawaii … … 25 25 #include <pslib.h> 26 26 #include "pmConfig.h" 27 #include "pmConfigRecipes.h" 27 28 28 29 #define PS_SITE "PS_SITE" // Name of the environment variable containing the site config file … … 38 39 psFree(config->cameraName); 39 40 psFree(config->recipes); 40 psFree(config->recipe sSource);41 psFree(config->recipeSymbols); 41 42 psFree(config->arguments); 42 43 psFree(config->database); … … 55 56 config->recipes = psMetadataAlloc(); 56 57 config->recipesRead = PM_RECIPE_SOURCE_NONE; 57 config->recipe sSource= psMetadataAlloc();58 config->recipeSymbols = psMetadataAlloc(); 58 59 config->arguments = psMetadataAlloc(); 59 60 config->database = NULL; … … 660 661 } 661 662 662 663 // Load the recipes: each time we load a specific recipe, it overrides the metadata664 // entries for an existing recipe metadata665 static bool loadRecipes(pmConfig *config, // The configuration into which to read the recipes666 psMetadata *source, // The source configuration, from which to read the filenames667 pmRecipeSource sourceType, // The source type668 const char *sourceName // The name of the source, for error messages669 )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 lookup681 psMetadata *recipes = psMetadataLookupMetadata(&mdok, source, "RECIPES"); // The list of recipes682 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 loaded691 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); // Iterator697 psMetadataItem *fileItem = NULL; // MD item containing the filename, from recipe iteration698 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 error707 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 defined712 // 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 priority716 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 reference729 psFree(recipesIter);730 return false;731 }732 break;733 734 case PM_RECIPE_SOURCE_CL:735 // type mismatch is a serious error736 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 data740 recipe = psMemIncrRefCounter (fileItem->data.V);741 break;742 743 default:744 psAbort ("pmConfig", "unknown sourceType");745 }746 747 // if this named recipe exists, supplement it748 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 reference755 psFree(current); // Drop reference756 }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 resolved763 psMetadataIterator *recipesIter = psMetadataIteratorAlloc(config->recipesSource, PS_LIST_HEAD, NULL);764 psMetadataItem *sourceItem = NULL; // Item containing source, from iteration765 while ((sourceItem = psMetadataGetAndIncrement(recipesIter))) {766 assert(sourceItem->type == PS_TYPE_S32); // It should be this type: we put it in ourselves767 if (sourceItem->data.S32 == PM_RECIPE_SOURCE_SYMBOLIC) {768 const char *linkName = sourceItem->comment; // The name of the link769 psMetadata *linkSource = psMetadataLookupMetadata(&mdok, config->recipes, linkName); // The source770 if (!mdok || !linkSource) {771 // Can't yet resolve it772 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 of787 // three locations: config->site, config->camera, and config->argv we cannot read the recipes788 // from config->camera until a camera has been read BUT, the argv recipes must override the789 // 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 configuration799 // XXX EAM : I think it should be an error for config->site:recipes not to exist800 // for now, keep this as a warning801 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 message810 // camera-specific recipes may be read for a specified camera (in pmConfigRead) or811 // for an identified camera (in pmConfigCameraFormatFromHeader). the second812 // set should not override the first set813 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 arguments822 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 a831 * file for a recipe when none was provided). For now we'll never signal an error, but this should832 * be reconsidered ASAP.833 */834 psErrorClear();835 return true;836 }837 838 839 663 psDB *pmConfigDB(pmConfig *config) 840 664 { … … 1057 881 return newName; 1058 882 } 1059 1060 // search for options of the form -D KEY VALUE or -D RECIPE:KEY VALUE1061 bool pmConfigLoadRecipeOptions (pmConfig *config, char *flag)1062 {1063 1064 int argNum;1065 1066 // save the recipes onto config->arguments:RECIPES1067 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 here1073 }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, supplement1108 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 here1114 }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, -Db1140 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 VALUE1149 // if VALUE is an existing file, read as metadata and save on config->arguments with name = KEY1150 // 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 arguments1155 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 recipe1164 psArgumentRemove(argNum, config->argc, config->argv);1165 const char *recipeSource = psStringCopy(config->argv[argNum]); // Source of the recipe1166 psArgumentRemove(argNum, config->argc, config->argv);1167 1168 if (access(recipeSource, R_OK) == 0) {1169 // The source is a file: load onto config->arguments1170 // save the recipes onto config->arguments:RECIPES1171 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 here1177 }1178 1179 psMetadata *recipe = NULL; // Recipe from file1180 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 reference1186 } 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 in1192 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 arguments1199 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 overrides1207 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 it1216 psMetadataAddS32(config->recipesSource, PS_LIST_TAIL, recipeName, PS_META_REPLACE,1217 recipeSource, PM_RECIPE_SOURCE_SYMBOLIC);1218 1219 } else1220 1221 # endif1222
Note:
See TracChangeset
for help on using the changeset viewer.
