Changeset 3945
- Timestamp:
- May 16, 2005, 9:43:53 AM (21 years ago)
- Location:
- trunk/psLib
- Files:
-
- 3 added
- 16 edited
-
src/astronomy/psAstronomyErrors.dat (modified) (1 diff)
-
src/astronomy/psAstronomyErrors.h (modified) (2 diffs)
-
src/collections/psMetadata.c (modified) (13 diffs)
-
src/collections/psMetadata.h (modified) (4 diffs)
-
src/collections/psMetadataIO.c (modified) (19 diffs)
-
src/collections/psMetadataIO.h (modified) (2 diffs)
-
src/types/psMetadata.c (modified) (13 diffs)
-
src/types/psMetadata.h (modified) (4 diffs)
-
src/types/psMetadataConfig.c (modified) (19 diffs)
-
src/types/psMetadataConfig.h (modified) (2 diffs)
-
src/xml/psXML.c (modified) (19 diffs)
-
src/xml/psXML.h (modified) (2 diffs)
-
test/collections/test1.config (added)
-
test/collections/test2.config (added)
-
test/collections/test3.config (added)
-
test/collections/tst_psMetadataIO.c (modified) (2 diffs)
-
test/collections/verified/tst_psMetadataIO.stderr (modified) (1 diff)
-
test/collections/verified/tst_psMetadataIO.stdout (modified) (1 diff)
-
test/collections/verified/tst_psMetadata_01.stdout (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/psLib/src/astronomy/psAstronomyErrors.dat
r3441 r3945 66 66 psMetadataIO_TAG_MISMATCH Start tag, %s and end tag, %s do not agree. 67 67 psMetadataIO_TAG_UNKNOWN Invalid end tag name, %s. 68 68 psMetadataIO_TYPE_DUPLICATE Specified type, %s, on line %u of %s is already defined. 69 psMetadataIO_DUPLICATE_MULTI Duplicate MULTI specifier on line %u of %s. -
trunk/psLib/src/astronomy/psAstronomyErrors.h
r3441 r3945 7 7 * @author Robert DeSonia, MHPCC 8 8 * 9 * @version $Revision: 1.1 4$ $Name: not supported by cvs2svn $10 * @date $Date: 2005-0 3-17 19:01:01$9 * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $ 10 * @date $Date: 2005-05-16 19:43:06 $ 11 11 * 12 12 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 83 83 #define PS_ERRORTEXT_psMetadataIO_TAG_MISMATCH "Start tag, %s and end tag, %s do not agree." 84 84 #define PS_ERRORTEXT_psMetadataIO_TAG_UNKNOWN "Invalid end tag name, %s." 85 #define PS_ERRORTEXT_psMetadataIO_TYPE_DUPLICATE "Specified type, %s, on line %u of %s is already defined." 86 #define PS_ERRORTEXT_psMetadataIO_DUPLICATE_MULTI "Duplicate MULTI specifier on line %u of %s." 85 87 //~End 86 88 -
trunk/psLib/src/collections/psMetadata.c
r3780 r3945 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1.6 1$ $Name: not supported by cvs2svn $15 * @date $Date: 2005-0 4-28 19:52:48$14 * @version $Revision: 1.62 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2005-05-16 19:43:53 $ 16 16 * 17 17 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 38 38 #include "psAstronomyErrors.h" 39 39 #include "psConstants.h" 40 #include "psLogMsg.h" 41 42 /******************************************************************************/ 43 /* DEFINE STATEMENTS */ 44 /******************************************************************************/ 45 46 /** Maximum size of a string */ 47 #define MAX_STRING_LENGTH 1024 48 49 /******************************************************************************/ 50 /* TYPE DEFINITIONS */ 51 /******************************************************************************/ 52 53 // None 54 55 /*****************************************************************************/ 56 /* GLOBAL VARIABLES */ 57 /*****************************************************************************/ 58 59 // None 60 61 /*****************************************************************************/ 62 /* FILE STATIC VARIABLES */ 63 /*****************************************************************************/ 40 64 41 65 static psS32 metadataId = 0; 66 67 /*****************************************************************************/ 68 /* FUNCTION IMPLEMENTATION - LOCAL */ 69 /*****************************************************************************/ 42 70 43 71 static psMetadataItem* makeMetaMulti(psHash* table, const char* key, psMetadataItem* existing) … … 48 76 } 49 77 78 // move any existing entry into a psList 79 psList* newList = psListAlloc(existing); 50 80 51 81 psMetadataItem* item = psMetadataItemAlloc(key, 52 82 PS_META_MULTI, 53 "List of Metadata Items", 54 NULL); 55 56 psListAdd(item->data.list,PS_LIST_TAIL,existing); 83 "", 84 newList); 57 85 58 86 if (existing != NULL) { … … 60 88 } 61 89 62 psHashAdd(table, key, item); // put in the new MULTI list entry 63 64 // free local references of newly allocated item. 90 psHashAdd(table, key, item); // put in the new entry 91 92 // free local references of newly allocated items. 93 psFree(newList); 65 94 psFree(item); 66 95 … … 80 109 psFree(metadataItem->name); 81 110 psFree(metadataItem->comment); 82 if (! PS_META_IS_PRIMITIVE(type)) { 111 112 if(!PS_META_IS_PRIMITIVE(type)) { 83 113 psFree(metadataItem->data.V); 84 114 } … … 104 134 psFree(metadata->list); 105 135 psFree(metadata->table); 136 106 137 } 107 138 … … 146 177 { 147 178 psMetadataItem* metadataItem = NULL; 148 char tmp; 149 int nBytes; 179 150 180 151 181 PS_PTR_CHECK_NULL(name,NULL); … … 158 188 psMemSetDeallocator(metadataItem, (psFreeFcn) metadataItemFree); 159 189 160 // set metadata item comment 190 // Allocate and set metadata item comment 191 metadataItem->comment = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH); 161 192 if (comment == NULL) { 162 193 // Per SDRS, null isn't allowed, must use "" instead 163 metadataItem->comment = psStringCopy("");194 strncpy(metadataItem->comment, "", MAX_STRING_LENGTH); 164 195 } else { 165 metadataItem->comment = psStringCopy(comment);196 strncpy(metadataItem->comment, comment, MAX_STRING_LENGTH); 166 197 } 167 198 … … 173 204 174 205 // Allocate and set metadata item name 175 nBytes = vsnprintf(&tmp, 0, name, argPtr) + 1; 176 metadataItem->name = (char *)psAlloc(sizeof(char) * nBytes); 206 metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH); 177 207 vsprintf(metadataItem->name, name, argPtr); 178 208 … … 193 223 case PS_META_STR: 194 224 // Perform copy of input strings 195 metadataItem->data.V = psStringCopy(va_arg(argPtr, char *)); 196 break; 197 case PS_META_MULTI: 198 // MULTI needs to create a psList entry, value must be NULL 199 metadataItem->data.list = psListAlloc(NULL); 225 metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH); 200 226 break; 201 227 case PS_META_LIST: … … 207 233 case PS_META_ASTROM: 208 234 case PS_META_UNKNOWN: 235 case PS_META_META: 236 case PS_META_MULTI: 209 237 // Copy of input data not performed due to variability of data types 210 238 metadataItem->data.V = psMemIncrRefCounter(va_arg(argPtr, psPtr)); … … 258 286 259 287 // See if key is already in table 260 existingEntry = psMetadataLookup(md, key); 261 262 // if replace is set, remove any existing items of the same key 263 if (existingEntry != NULL && (flags & PS_META_REPLACE) != 0) { 264 psMetadataRemove(md,0,key); 265 existingEntry = NULL; 266 } 267 268 // if the metadataItem is MULTI, just create a MULTI node. 288 existingEntry = (psMetadataItem*)psHashLookup(mdTable, key); 289 269 290 if (metadataItem->type == PS_META_MULTI) { 270 if (metadataItem->data.list == NULL || metadataItem->data.list->size > 0) { 271 psError(PS_ERR_BAD_PARAMETER_VALUE,true, 272 "Specified PS_META_MULTI item is not defined properly " 273 "(list allocated with zero size)."); 274 return false; 275 } 276 277 // make sure the existing entry is PS_META_MULTI 291 // the incoming entry is PS_META_MULTI 292 293 // force the hash entry to be PS_META_MULTI 278 294 existingEntry = makeMetaMulti(mdTable,key,existingEntry); 279 295 296 // add all the items in the incoming entry to metadata 297 psList* list = metadataItem->data.list; 298 if (list != NULL) { 299 psListIterator* iter = psListIteratorAlloc(list,PS_LIST_HEAD,true); 300 psMetadataItem* listItem; 301 while ((listItem=(psMetadataItem*)psListGetAndIncrement(iter)) != NULL) { 302 psMetadataAddItem(md,listItem,location,flags); 303 } 304 psFree(iter); 305 } 306 280 307 return true; // all done. 281 308 } 282 309 283 310 // how the item is added to the hash depends on prior existence, flags, etc. 284 if(existingEntry == NULL) { // no prior existence 285 // Node doesn't already exist - Add new metadata item to metadata collection's hash 286 if(!psHashAdd(mdTable, key, metadataItem)) { 287 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key); 288 return false; 289 } 290 } else { 311 if(existingEntry != NULL) { // prior existence 291 312 if (existingEntry->type == PS_META_MULTI || (flags & PS_META_DUPLICATE_OK) != 0) { 292 313 // duplicate entries allowed - add another entry. 293 314 294 // make sure the existing hashentry is PS_META_MULTI315 // make sure the existing entry is PS_META_MULTI 295 316 existingEntry = makeMetaMulti(mdTable,key,existingEntry); 296 317 297 // add to the hash key's list ofentries318 // add to the hash's list of duplicate entries 298 319 if (! psListAdd(existingEntry->data.list, PS_LIST_TAIL, metadataItem) ) { 299 320 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key); 300 321 return false; 301 322 } 323 } else if ((flags & PS_META_REPLACE) != 0) { 324 // replace entry instead of creating a duplicate entry. 325 326 // remove the existing entry from metadata 327 psMetadataRemove(md,0,key); 328 329 // treat as if new (added to list below) 330 if(!psHashAdd(mdTable, key, metadataItem)) { 331 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key); 332 return false; 333 } 334 335 // Generate warning that item has been replaced 336 psLogMsg(__func__,PS_LOG_WARN,"Metadata item %s has been replaced", 337 existingEntry->name); 302 338 } else { 303 // error on duplicate entry.339 // default is to error on duplicate entry. 304 340 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 305 341 PS_ERRORTEXT_psMetadata_DUPLICATE_NOT_ALLOWED); 306 342 return false; 307 343 } 308 } 309 310 // finally, add the metadataItem to the metadata's list. 344 } else { 345 // OK, this is a new item. 346 347 // Node doesn't exist - Add new metadata item to metadata collection's hash 348 if(!psHashAdd(mdTable, key, metadataItem)) { 349 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key); 350 return false; 351 } 352 } 353 311 354 if(!psListAdd(mdList, location, metadataItem)) { 312 355 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key); … … 363 406 METADATA_ADD_TYPE(LookupTable,psLookupTable*,PS_META_LOOKUPTABLE) 364 407 METADATA_ADD_TYPE(Unknown,void*,PS_META_UNKNOWN) 408 METADATA_ADD_TYPE(Metadata,psMetadata*,PS_META_META) 365 409 366 410 psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key) -
trunk/psLib/src/collections/psMetadata.h
r3684 r3945 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1.4 4$ $Name: not supported by cvs2svn $14 * @date $Date: 2005-0 4-08 17:58:57$13 * @version $Revision: 1.45 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2005-05-16 19:43:53 $ 15 15 * 16 16 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 51 51 PS_META_ASTROM, ///< Astrometric coefficients (Stored as item.data.V). 52 52 PS_META_UNKNOWN, ///< Other data (Stored as item.data.V). 53 PS_META_MULTI ///< Used internally, do not create an metadata item of this type. 53 PS_META_MULTI, ///< Used internally, do not create an metadata item of this type. 54 PS_META_META ///< Metadata data (Stored as item.data.md). 54 55 } psMetadataType; 55 56 … … 105 106 } 106 107 psMetadataIterator; 107 108 108 109 109 /** Metadata item data structure. … … 316 316 psBool psMetadataAddUnknown(psMetadata* md, psS32 location, const char* name, 317 317 const char* comment, psPtr value); 318 psBool psMetadataAddMetadata(psMetadata* md, psS32 location, const char* name, 319 const char* comment, psMetadata* value); 318 320 319 321 /** Remove an item from metadata collection. -
trunk/psLib/src/collections/psMetadataIO.c
r3769 r3945 8 8 * 9 9 * @author Ross Harman, MHPCC 10 * @author Eric Van Alst, MHPCC 10 11 * 11 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2005-0 4-26 19:53:30$12 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-05-16 19:43:53 $ 13 14 * 14 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 33 34 #include "psConstants.h" 34 35 #include "psAstronomyErrors.h" 35 36 36 37 37 /******************************************************************************/ … … 53 53 return NULL; 54 54 55 /** Free and null temporary variables used by config file parser */56 #define CLEAR_TEMPS() \57 if(strName) { \58 psFree(strName); \59 strName = NULL; \60 } \61 if(strType) { \62 psFree(strType); \63 strType = NULL; \64 } \65 if(strValue) { \66 psFree(strValue); \67 strValue = NULL; \68 } \69 if(strComment) { \70 psFree(strComment); \71 strComment = NULL; \72 }73 74 55 /** Maximum size of a FITS line */ 75 56 #define FITS_LINE_SIZE 80 … … 105 86 static void initMetadataItemXml(void *ctx, char *tagName); 106 87 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts); 107 108 /** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 109 * must be null terminated. */ 88 static psMetadata* getMetadataType(char *linePtr); 89 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 90 ; 91 static void parseLevelInfoFree(p_psParseLevelInfo* info); 92 static psBool parseLine(psS32* level, psArray* levelArray, 93 char* linePtr, psS32 lineCount, char* fileName, psBool overwrite); 94 static psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 95 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags); 96 97 static void parseLevelInfoFree(p_psParseLevelInfo* info) 98 { 99 psFree(info->nonUniqueKeyArray); 100 psFree(info->typeArray); 101 psFree(info->templateArray); 102 psFree(info->name); 103 psFree(info->metadata); 104 } 105 106 // Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 107 // must be null terminated. 110 108 psBool ignoreLine(char *inString) 111 109 { … … 121 119 122 120 123 / **Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null124 * terminated copy of the original input string. */ 125 char *cleanString(char *inString, psS32 sLen )121 // Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null 122 // terminated copy of the original input string. 123 char *cleanString(char *inString, psS32 sLen, psBool ignoreComment) 126 124 { 127 125 char *ptrB = NULL; … … 129 127 char *cleaned = NULL; 130 128 131 129 // Initialize begining of string pointer 132 130 ptrB = inString; 133 131 134 /* Skip over leading # or whitespace */ 135 while (isspace(*ptrB) || *ptrB=='#') { 136 ptrB++; 137 } 138 139 /* Skip over trailing whitespace, null terminators, and # characters */ 132 // Skip over leading # or whitespace 133 if(ignoreComment) { 134 while (isspace(*ptrB) || *ptrB=='#') { 135 ptrB++; 136 } 137 } else { 138 while (isspace(*ptrB)) { 139 ptrB++; 140 } 141 } 142 143 // Skip over trailing whitespace, null terminators, and # characters 140 144 ptrE = inString + sLen; 141 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 142 ptrE--; 145 if(ignoreComment) { 146 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 147 ptrE--; 148 } 149 } else { 150 while(isspace(*ptrE) || *ptrE=='\0') { 151 ptrE--; 152 } 143 153 } 144 154 … … 152 162 } 153 163 154 / ** Count repeat occurances of a single character within a line. The input string must be null terminated. */164 // Count repeat occurances of a single character within a line. The input string must be null terminated. 155 165 psS32 repeatedChars(char *inString, char ch) 156 166 { 157 167 psS32 count = 0; 158 159 168 160 169 while(*inString!='\0') { … … 168 177 } 169 178 170 / **Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location171 * the beginning of the string. Tokens are newly allocated null terminated strings. */ 172 char* getToken(char **inString, char *delimiter, psS32 *status )179 // Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location 180 // the beginning of the string. Tokens are newly allocated null terminated strings. 181 char* getToken(char **inString, char *delimiter, psS32 *status, psBool ignoreComment) 173 182 { 174 183 char *cleanToken = NULL; 184 char *convertChar = NULL; 175 185 psS32 sLen = 0; 176 186 187 // Convert tab characters to white space 188 while((convertChar=strchr(*inString,'\t')) != NULL ) { 189 *convertChar = ' '; 190 } 177 191 178 192 // Skip over leading whitespace … … 186 200 187 201 // Create new, cleaned, and null terminated token 188 cleanToken = cleanString(*inString, sLen );202 cleanToken = cleanString(*inString, sLen,ignoreComment); 189 203 190 204 // Move to end of token … … 197 211 } 198 212 199 / **Returns single parsed value as a double precision number. The input string must be cleaned and null200 * terminated. */ 213 // Returns single parsed value as a double precision number. The input string must be cleaned and null 214 // terminated. 201 215 double parseValue(char *inString, psS32 *status) 202 216 { 203 217 char *end = NULL; 204 218 double value = 0.0; 205 206 219 207 220 value = strtod(inString, &end); … … 235 248 psVector* parseVector(char *inString, psElemType elemType, psS32 *status) 236 249 { 237 char *end = NULL; 238 char *saveValue = NULL; 239 psS32 i = 0; 240 psS32 numValues = 0; 241 double value = 0.0; 242 psVector *vec = NULL; 243 250 char* end = NULL; 251 char* saveValue = NULL; 252 psS32 i = 0; 253 psS32 numValues = 0; 254 double value = 0.0; 255 psVector* vec = NULL; 244 256 245 257 // Cycle through string and count entries … … 274 286 vec->data.U8[i++] = (psU8)value; 275 287 break; 288 case PS_TYPE_U16: 289 vec->data.U16[i++] = (psU16)value; 290 break; 291 case PS_TYPE_U32: 292 vec->data.U32[i++] = (psU32)value; 293 break; 294 case PS_TYPE_U64: 295 vec->data.U64[i++] = (psU64)value; 296 break; 297 case PS_TYPE_S8: 298 vec->data.S8[i++] = (psS8)value; 299 break; 300 case PS_TYPE_S16: 301 vec->data.S16[i++] = (psS16)value; 302 break; 276 303 case PS_TYPE_S32: 277 304 vec->data.S32[i++] = (psS32)value; 305 break; 306 case PS_TYPE_S64: 307 vec->data.S64[i++] = (psS64)value; 278 308 break; 279 309 case PS_TYPE_F32: … … 303 333 /* FUNCTION IMPLEMENTATION - PUBLIC */ 304 334 /*****************************************************************************/ 335 336 p_psParseLevelInfo* p_psParseLevelInfoAlloc(void) 337 { 338 339 p_psParseLevelInfo* info = NULL; 340 341 // Allocate memory for parse level info 342 info = (p_psParseLevelInfo*)psAlloc(sizeof(p_psParseLevelInfo)); 343 344 // If allocation successful then initialize members 345 if(info != NULL) { 346 347 info->nonUniqueKeyArray = psArrayAlloc(10); 348 info->nonUniqueKeyArray->n = 0; 349 350 info->typeArray = psArrayAlloc(10); 351 info->typeArray->n = 0; 352 353 info->templateArray = psArrayAlloc(10); 354 info->templateArray->n = 0; 355 356 info->metadata = NULL; 357 info->name = NULL; 358 359 // Set memory deallocator 360 psMemSetDeallocator(info,(psFreeFcn)parseLevelInfoFree); 361 } 362 return info; 363 } 305 364 306 365 bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem) … … 500 559 } 501 560 561 static psMetadata* getMetadataType(char* linePtr) 562 { 563 psMetadata* metadataTemplate = NULL; 564 psS32 status = 0; 565 char* token = NULL; 566 psMetadataItem* tempItem = NULL; 567 568 // Loop through line and generate metadata items for each token found 569 while((token = getToken(&linePtr," ",&status,false)) != NULL ) { 570 571 // If not allocated then allocate new metadata 572 if(metadataTemplate == NULL) { 573 metadataTemplate = psMetadataAlloc(); 574 } 575 576 // Look for comment indicator # 577 if(strstr(token,"#") != 0) { 578 psFree(token); 579 break; 580 } 581 582 // Create metadata item to represent token read 583 tempItem = psMetadataItemAllocStr(token,"",""); 584 if(tempItem == NULL) { 585 psFree(metadataTemplate); 586 psFree(token); 587 metadataTemplate = NULL; 588 break; 589 } 590 591 // Add item to template 592 if(!psMetadataAddItem(metadataTemplate, tempItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 593 psFree(metadataTemplate); 594 psFree(tempItem); 595 psFree(token); 596 metadataTemplate = NULL; 597 break; 598 } 599 psFree(tempItem); 600 psFree(token); 601 } 602 603 return metadataTemplate; 604 } 605 606 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 607 { 608 psMetadata* md = NULL; 609 psS32 items = 0; 610 char* token = NULL; 611 psS32 status = 0; 612 psMetadataItem* mdItem = NULL; 613 psMetadataItem* templateItem = NULL; 614 psListIterator* iter = NULL; 615 616 // Determine the number of items in template 617 items = template->list->size; 618 if(items > 0 ) { 619 620 // Allocate metadata 621 md = psMetadataAlloc() 622 ; 623 624 // Point to first item in template 625 iter = psListIteratorAlloc(template-> 626 list,PS_LIST_HEAD,true); 627 628 // For each item in template parse line string for values 629 for(psS32 i = 0; 630 i < items; 631 i++) { 632 633 // Get template item 634 templateItem = psListGetAndIncrement(iter) 635 ; 636 if(templateItem == NULL) { 637 psFree(md); 638 md = NULL; 639 break; 640 } 641 642 // Get the next token on the line 643 token = getToken(&linePtr," ",&status,false); 644 if(token != NULL) { 645 // Allocate metadata item 646 mdItem = psMetadataItemAllocStr(templateItem->name,templateItem->comment,token); 647 if(mdItem == NULL) { 648 psFree(md); 649 md = NULL; 650 psFree(token); 651 break; 652 } 653 // Add item to metadata 654 if(!psMetadataAddItem(md, mdItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 655 psFree(md); 656 md = NULL; 657 psFree(mdItem); 658 psFree(token); 659 break; 660 } 661 psFree(mdItem); 662 } else { 663 // Missing items 664 psFree(md); 665 md = NULL; 666 break; 667 } 668 669 psFree(token); 670 } 671 psFree(iter); 672 } 673 return md; 674 } 675 676 psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 677 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags) 678 { 679 psBool returnValue = true; 680 psBool addStatus = false; 681 psMetadataType mdType = PS_META_UNKNOWN; 682 psElemType vectorType = PS_TYPE_S8; 683 char* strType = NULL; 684 char* strValue = NULL; 685 char* strComment = NULL; 686 psS32 status = 0; 687 psMetadata* md = NULL; 688 psF64 tempDbl = 0.0; 689 psBool tempBool = false; 690 psS32 tempInt = 0; 691 psVector* tempVec = NULL; 692 char* tempStr = NULL; 693 psArray* nonUniqueKeys = NULL; 694 psBool typeFound = false; 695 psArray* typeArray = NULL; 696 psArray* templateArray = NULL; 697 psMetadata* tempMeta = NULL; 698 p_psParseLevelInfo* nextLevelInfo = NULL; 699 700 // Get the metadata item type 701 strType = getToken(&linePtr, " ", &status,true); 702 703 // Check for no type 704 if(strType==NULL) { 705 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 706 fileName); 707 returnValue = false; 708 } else { 709 710 // Set metadata type based on type token 711 712 // Check if the keyName specifies a vector and if so use strType token to find vector type 713 if(*keyName == '@') { 714 mdType = PS_META_VEC; 715 // Get the type of vector 716 if(!strncmp(strType, "U8", 2)) { 717 vectorType = PS_TYPE_U8; 718 } else if (!strncmp(strType,"U16",3)) { 719 vectorType = PS_TYPE_U16; 720 } else if (!strncmp(strType,"U32",3)) { 721 vectorType = PS_TYPE_U32; 722 } else if (!strncmp(strType,"U64",3)) { 723 vectorType = PS_TYPE_U64; 724 } else if (!strncmp(strType,"S8",2)) { 725 vectorType = PS_TYPE_S8; 726 } else if (!strncmp(strType,"S16",3)) { 727 vectorType = PS_TYPE_S16; 728 } else if (!strncmp(strType,"S32",3)) { 729 vectorType = PS_TYPE_S32; 730 } else if (!strncmp(strType,"S64",3)) { 731 vectorType = PS_TYPE_S64; 732 } else if (!strncmp(strType,"F32",3)) { 733 vectorType = PS_TYPE_F32; 734 } else if (!strncmp(strType,"F64",3)) { 735 vectorType = PS_TYPE_F64; 736 } else { 737 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, "", keyName, 738 strType, lineCount, fileName); 739 psFree(strType); 740 return false; 741 } 742 } else if(!strncmp(strType, "STR", 3)) { 743 mdType = PS_META_STR; 744 } else if(!strncmp(strType, "BOOL", 4)) { 745 mdType = PS_META_BOOL; 746 } else if(!strncmp(strType, "S32", 3)) { 747 mdType = PS_META_S32; 748 } else if(!strncmp(strType, "F32", 3)) { 749 mdType = PS_META_F32; 750 } else if(!strncmp(strType, "F64", 3)) { 751 mdType = PS_META_F64; 752 } else if(!strncmp(strType, "MULTI", 5)) { 753 mdType = PS_META_MULTI; 754 } else if(!strncmp(strType, "METADATA", 8)) { 755 mdType = PS_META_META; 756 } else { 757 // Search through user types 758 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 759 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 760 for(psS32 k = 0; k < typeArray->n; k++) { 761 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 762 tempMeta = setMetadataItem((psMetadata*)templateArray->data[k],linePtr); 763 if(tempMeta != NULL) { 764 // Add metadata item 765 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 766 addStatus = psMetadataAdd(md,PS_LIST_TAIL,keyName,PS_META_META | flags,"",tempMeta); 767 // Check for add failure 768 if (! addStatus) { 769 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, 770 keyName, lineCount, fileName); 771 psFree(strType); 772 psFree(tempMeta); 773 return false; 774 } 775 psFree(tempMeta); 776 } else { 777 // Metadata type read error 778 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, 779 keyName,lineCount,fileName); 780 psFree(strType); 781 return false; 782 } 783 typeFound = true; 784 break; 785 } 786 } 787 if(!typeFound) { 788 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 789 strType, lineCount,fileName); 790 psFree(strType); 791 return false; 792 } else { 793 psFree(strType); 794 return true; 795 } 796 } 797 } 798 799 // If type is not MULTI or META then get the value and comment 800 if((mdType != PS_META_MULTI) && (mdType != PS_META_META)) { 801 // Get the metadata item value if there is one. 802 status = 0; 803 strValue = getToken(&linePtr, "#", &status,true); 804 if(status) { 805 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 806 fileName); 807 psFree(strType); 808 psFree(strValue); 809 return false; 810 } 811 if(strValue==NULL) { 812 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 813 fileName); 814 psFree(strType); 815 psFree(strValue); 816 return false; 817 } 818 // Not all lines will have comments, so NULL is ok. 819 status = 0; 820 strComment = getToken(&linePtr,"~", &status,true); 821 if(status) { 822 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 823 fileName); 824 psFree(strType); 825 psFree(strValue); 826 psFree(strComment); 827 } 828 } 829 830 // Need to add item to metadata so get pointer to metadata 831 status = 0; 832 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 833 nonUniqueKeys = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray; 834 switch(mdType) { 835 case PS_META_STR: 836 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 837 mdType | flags, 838 strComment, strValue); 839 break; 840 case PS_META_BOOL: 841 tempBool = parseBool(strValue, &status); 842 if(!status) { 843 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 844 mdType | flags, 845 strComment, tempBool); 846 } else { 847 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 848 strType, lineCount, fileName); 849 returnValue = false; 850 } 851 break; 852 case PS_META_F32: 853 case PS_META_F64: 854 tempDbl = parseValue(strValue, &status); 855 if(!status) { 856 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 857 mdType | flags, 858 strComment, tempDbl); 859 } else { 860 psError(PS_ERR_IO, true, 861 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, strType, lineCount, 862 fileName); 863 returnValue = false; 864 } 865 break; 866 case PS_META_S32: 867 tempInt = (psS32)parseValue(strValue, &status); 868 if(!status) { 869 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 870 mdType | flags, 871 strComment, tempInt); 872 } else { 873 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 874 strType, lineCount, fileName); 875 returnValue = false; 876 } 877 break; 878 case PS_META_VEC: 879 tempVec = parseVector(strValue, vectorType, &status); 880 if(!status) { 881 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName+1, 882 mdType | flags, 883 strComment, tempVec); 884 } else { 885 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 886 strType, lineCount, fileName); 887 returnValue = false; 888 } 889 psFree(tempVec); 890 break; 891 case PS_META_MULTI: 892 // Add key to non-unique array of keys 893 // Check for duplicate MULTI lines 894 addStatus = true; 895 for(psS32 k=0; k < nonUniqueKeys->n; k++) { 896 if(strcmp(keyName,(char*)nonUniqueKeys->data[k]) == 0) { 897 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_DUPLICATE_MULTI, 898 lineCount,fileName); 899 psFree(strType); 900 return false; 901 } 902 } 903 tempStr = psStringCopy(keyName); 904 nonUniqueKeys = psArrayAdd(nonUniqueKeys,0,tempStr); 905 addStatus = true; 906 psFree(tempStr); 907 break; 908 case PS_META_META: 909 // Create next level info 910 nextLevelInfo = p_psParseLevelInfoAlloc(); 911 // Create new metadata 912 nextLevelInfo->metadata = psMetadataAlloc(); 913 // Save name of metadata 914 nextLevelInfo->name = psStringCopy(keyName); 915 // Add next level to levelArray 916 levelArray = psArrayAdd(levelArray,1,nextLevelInfo); 917 psFree(nextLevelInfo); 918 // Increment level counter 919 (*level)++; 920 addStatus = true; 921 break; 922 default: 923 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 924 lineCount,fileName); 925 break; 926 } 927 928 // Check if the add status was successful 929 if (! addStatus) { 930 // psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, keyName, lineCount, 931 // fileName); 932 returnValue = false; 933 } 934 935 psFree(strComment); 936 psFree(strValue); 937 psFree(strType); 938 939 return returnValue; 940 } 941 942 psBool parseLine(psS32* level, psArray* levelArray, char* linePtr, 943 psS32 lineCount, char* fileName, psBool overwrite) 944 { 945 psBool returnValue = true; 946 psMetadataFlags flags = PS_META_DEFAULT; 947 char* keyName = NULL; 948 psS32 status = 0; 949 psS32 limit = 0; 950 psMetadata* tempTemplate = NULL; 951 char* strType = NULL; 952 psArray* typeArray = NULL; 953 psArray* templateArray = NULL; 954 p_psParseLevelInfo* upperLevelInfo = NULL; 955 p_psParseLevelInfo* lowerLevelInfo = NULL; 956 psBool addStatus = 0; 957 958 // Set flags if overwrite specified 959 if(overwrite) { 960 flags = PS_META_REPLACE; 961 } 962 963 // If line is not a comment or blank, then extract data 964 if(!ignoreLine(linePtr)) { 965 966 // Check for more than one '@' in a line 967 if(repeatedChars(linePtr, '@') > 1) { 968 psError(PS_ERR_IO, true, 969 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 970 return false; 971 } 972 973 // Get metadata item name 974 keyName = getToken(&linePtr, " ", &status,true); 975 if(status) { 976 psError(PS_ERR_IO, true, 977 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "keyName", lineCount, fileName); 978 psFree(keyName); 979 return false; 980 } 981 982 // Check for special keyName values "TYPE", "END" 983 if(strcmp(keyName,"TYPE") == 0 ) { 984 // Get the type name 985 strType = getToken(&linePtr," ",&status,true); 986 if(strType == NULL) { 987 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL,"type",lineCount, 988 fileName); 989 psFree(keyName); 990 return false; 991 } 992 tempTemplate = getMetadataType(linePtr); 993 // Check if type was parsed succesfully 994 if(tempTemplate != NULL) { 995 // Access type array 996 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 997 // Check if type already exists in array 998 for(psS32 k=0; k < typeArray->n; k++) { 999 // Compare type name with the list of current types 1000 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 1001 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_TYPE_DUPLICATE, 1002 strType,lineCount,fileName); 1003 psFree(tempTemplate); 1004 psFree(keyName); 1005 psFree(strType); 1006 return false; 1007 } 1008 } 1009 // Add key name to array of type 1010 typeArray = psArrayAdd(typeArray,1,strType); 1011 // Add template to array of templates 1012 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 1013 templateArray = psArrayAdd(templateArray,1,tempTemplate); 1014 psFree(tempTemplate); 1015 } else { 1016 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 1017 strType,lineCount,fileName); 1018 psFree(keyName); 1019 psFree(strType); 1020 return false; 1021 } 1022 psFree(strType); 1023 } else if (strcmp(keyName,"END") == 0 ) { 1024 if(*level > 0) { 1025 upperLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level-1])); 1026 lowerLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level])); 1027 // Check name in nonunique list 1028 for(psS32 k=0; k < upperLevelInfo->nonUniqueKeyArray->n; k++) { 1029 if(strcmp(upperLevelInfo->nonUniqueKeyArray->data[k],lowerLevelInfo->name) == 0) { 1030 flags = PS_META_DUPLICATE_OK; 1031 break; 1032 } 1033 } 1034 // Add metadata to upper level metadata 1035 addStatus = psMetadataAdd(upperLevelInfo->metadata, 1036 PS_LIST_TAIL,lowerLevelInfo->name, 1037 PS_META_META | flags, 1038 "", 1039 lowerLevelInfo->metadata); 1040 if(!addStatus) { 1041 psFree(keyName); 1042 return false; 1043 } else { 1044 // Remove lower info level 1045 if(!psArrayRemove(levelArray,levelArray->data[*level])) { 1046 psFree(keyName); 1047 return false; 1048 } 1049 psFree(lowerLevelInfo); 1050 (*level)--; 1051 } 1052 } else { 1053 psFree(keyName); 1054 return false; 1055 } 1056 } else { 1057 // Check if key name present in array of non-unique key names 1058 limit = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray->n; 1059 for(psS32 k=0; k < limit; k++) { 1060 char* name = (char*)((p_psParseLevelInfo*) 1061 (levelArray->data[*level]))->nonUniqueKeyArray->data[k]; 1062 if(strcmp(name,keyName) == 0) { 1063 flags = PS_META_DUPLICATE_OK; 1064 } 1065 } 1066 // Parse metadataItem 1067 if(!parseMetadataItem(keyName,level, levelArray, linePtr, lineCount, fileName, flags)) { 1068 psFree(keyName); 1069 return false; 1070 } 1071 } 1072 psFree(keyName); 1073 } 1074 return returnValue; 1075 } 1076 502 1077 psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite) 503 1078 { 504 psBool tempBool; 505 char *line = NULL; 506 char *strName = NULL; 507 char *strType = NULL; 508 char *strValue = NULL; 509 char *strComment = NULL; 510 char *linePtr = NULL; 511 psElemType vecType = 0; 512 psS32 status = 0; 513 psU32 lineCount = 0; 514 psF64 tempDbl = 0.0; 515 psS32 tempInt = 0.0; 516 psVector *tempVec = NULL; 517 FILE *fp = NULL; 518 psMetadataType mdType; 519 psMetadataFlags flags; 520 psBool addStatus; 521 522 // Check for nulls 1079 FILE* fp = NULL; 1080 char* line = NULL; 1081 char* linePtr = NULL; 1082 psArray* parseLevelInfoArray = NULL; 1083 psS32 lineCount = 0; 1084 psS32 nestingLevel = 0; 1085 p_psParseLevelInfo* topLevelInfo = NULL; 1086 1087 // Check for NULL file name 523 1088 PS_PTR_CHECK_NULL(fileName,NULL); 1089 1090 // Check for NULL nFail 1091 PS_PTR_CHECK_NULL(nFail,NULL); 1092 1093 // Attempt to open specified file 524 1094 if((fp=fopen(fileName, "r")) == NULL) { 525 1095 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName); … … 532 1102 } 533 1103 1104 // Allocate array to store parse level information 1105 parseLevelInfoArray = psArrayAlloc(10); 1106 parseLevelInfoArray->n = 0; 1107 1108 // Set parse level info for the top level 1109 topLevelInfo = p_psParseLevelInfoAlloc(); 1110 topLevelInfo->metadata = psMemIncrRefCounter(md); 1111 parseLevelInfoArray = psArrayAdd(parseLevelInfoArray,1,topLevelInfo); 1112 psFree(topLevelInfo); 1113 534 1114 // Create reusable line for continuous read 535 1115 line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char)); … … 541 1121 linePtr = line; 542 1122 lineCount++; 543 CLEAR_TEMPS(); 544 545 // If line is not a comment or blank, then extract data 546 if(!ignoreLine(linePtr)) { 547 548 // Check for more than one '*' or '@' in a line 549 if(repeatedChars(linePtr, '@') > 1) { 550 (*nFail)++; 551 psError(PS_ERR_IO, true, 552 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 553 continue; 554 } else if(repeatedChars(linePtr, '*') > 1) { 555 (*nFail)++; 556 psError(PS_ERR_IO, true, 557 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName); 558 continue; 559 } else if(repeatedChars(linePtr, '~') > 0) { 560 (*nFail)++; 561 psError(PS_ERR_IO, true, 562 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName); 563 continue; 564 } 565 566 // Get metadata item name 567 strName = getToken(&linePtr, " ", &status); 568 if(strName==NULL || status) { 569 (*nFail)++; 570 status = 0; 571 psError(PS_ERR_IO, true, 572 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName); 573 continue; 574 } 575 576 flags = (overwrite) ? PS_META_REPLACE : PS_META_DEFAULT; 577 578 // Get the metadata item type 579 strType = getToken(&linePtr, " ", &status); 580 if(strType==NULL) { 581 (*nFail)++; 582 status = 0; 583 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 584 fileName); 585 continue; 586 } else { 587 char* tempStrType = strType; 588 if(*strType == '*') { 589 flags = PS_META_DUPLICATE_OK; 590 tempStrType = strType+1; 591 } 592 593 if(!strncmp(tempStrType, "STR", 3)) { 594 mdType = PS_META_STR; 595 } else if(!strncmp(tempStrType, "BOOL", 4)) { 596 mdType = PS_META_BOOL; 597 } else if(!strncmp(tempStrType, "S32", 3)) { 598 mdType = PS_META_S32; 599 } else if(!strncmp(tempStrType, "F32", 3)) { 600 mdType = PS_META_F32; 601 } else if(!strncmp(tempStrType, "F64", 3)) { 602 mdType = PS_META_F64; 603 } else { 604 (*nFail)++; 605 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount, 606 fileName); 607 continue; 608 } 609 } 610 611 if(*strName == '@') { 612 vecType = PS_META_PRIMITIVE_TYPE(mdType); 613 mdType = PS_META_VEC; 614 } 615 616 // Get the metadata item value if there is one. 617 strValue = getToken(&linePtr, "#", &status); 618 if(status) { 619 (*nFail)++; 620 status = 0; 621 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 622 fileName); 623 continue; 624 } 625 if(strValue==NULL) { 626 (*nFail)++; 627 status = 0; 628 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 629 fileName); 630 continue; 631 } 632 633 // Not all lines will have comments, so NULL is ok. 634 strComment = getToken(&linePtr,"~", &status); 635 if(status) { 636 (*nFail)++; 637 status = 0; 638 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 639 fileName); 640 continue; 641 } 642 643 // Create and add metadata item to metadata and parse values 644 switch (mdType) { 645 case PS_META_STR: 646 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 647 mdType | flags, 648 strComment, strValue); 649 break; 650 case PS_META_VEC: 651 tempVec = parseVector(strValue, vecType, &status); 652 if(!status) { 653 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName+1, 654 mdType | flags, 655 strComment, tempVec); 656 } else { 657 status = 0; 658 (*nFail)++; 659 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 660 strType, lineCount, fileName); 661 continue; 662 } 663 psFree(tempVec); 664 break; 665 case PS_META_BOOL: 666 tempBool = parseBool(strValue, &status); 667 if(!status) { 668 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 669 mdType | flags, 670 strComment, tempBool); 671 } else { 672 status = 0; 673 (*nFail)++; 674 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 675 strType, lineCount, fileName); 676 continue; 677 } 678 break; 679 case PS_META_S32: 680 tempInt = (psS32)parseValue(strValue, &status); 681 if(!status) { 682 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 683 mdType | flags, 684 strComment, tempInt); 685 } else { 686 status = 0; 687 (*nFail)++; 688 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 689 strType, lineCount, fileName); 690 continue; 691 } 692 break; 693 case PS_META_F32: 694 case PS_META_F64: 695 tempDbl = parseValue(strValue, &status); 696 if(!status) { 697 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 698 mdType | flags, 699 strComment, tempDbl); 700 } else { 701 status = 0; 702 (*nFail)++; 703 psError(PS_ERR_IO, true, 704 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount, 705 fileName); 706 continue; 707 } 708 break; 709 default: 710 (*nFail)++; 711 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount, 712 fileName); 713 continue; 714 } // switch 715 if (! addStatus) { 716 (*nFail)++; 717 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount, 718 fileName); 719 } 720 721 } // if ignoreLine 722 } // while loop 723 1123 1124 if(!parseLine(&nestingLevel,parseLevelInfoArray,linePtr,lineCount,(char*)fileName,overwrite)) { 1125 (*nFail)++; 1126 } 1127 } 1128 1129 // Free parse array and line buffer 1130 psFree(parseLevelInfoArray); 724 1131 psFree(line); 725 1132 1133 // Check if any failed lined detected 1134 if( (*nFail) != 0) { 1135 psFree(md); 1136 md = NULL; 1137 } 726 1138 return md; 727 1139 } 1140 728 1141 729 1142 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts) … … 750 1163 751 1164 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 752 psTagName = psStringCopy( (const char*)tagName);1165 psTagName = psStringCopy(tagName); 753 1166 754 1167 // Metadata containter for housing element attributes used by other SAX events … … 774 1187 775 1188 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 776 psAttName = psStringCopy( (const char*)attName);777 psAttValue = psStringCopy( (const char*)attValue);1189 psAttName = psStringCopy(attName); 1190 psAttValue = psStringCopy(attValue); 778 1191 psHashAdd(htAtts, psAttName, psAttValue); 779 1192 psFree(psAttName); … … 1082 1495 1083 1496 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 1084 psEndTagName = psStringCopy( (const char*)tagName);1497 psEndTagName = psStringCopy(tagName); 1085 1498 1086 1499 // Compare start and end tag names -
trunk/psLib/src/collections/psMetadataIO.h
r3381 r3945 10 10 * @author Robert DeSonia, MHPCC 11 11 * 12 * @version $Revision: 1. 9$ $Name: not supported by cvs2svn $13 * @date $Date: 2005-0 3-07 20:58:50$12 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-05-16 19:43:53 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 21 21 /// @{ 22 22 23 typedef struct 24 { 25 psArray* nonUniqueKeyArray; 26 psArray* typeArray; 27 psArray* templateArray; 28 psMetadata* metadata; 29 char* name; 30 } 31 p_psParseLevelInfo; 32 33 p_psParseLevelInfo* p_psParseLevelInfoAlloc(void); 23 34 24 35 /** Print metadata item to file. -
trunk/psLib/src/types/psMetadata.c
r3780 r3945 12 12 * @author Ross Harman, MHPCC 13 13 * 14 * @version $Revision: 1.6 1$ $Name: not supported by cvs2svn $15 * @date $Date: 2005-0 4-28 19:52:48$14 * @version $Revision: 1.62 $ $Name: not supported by cvs2svn $ 15 * @date $Date: 2005-05-16 19:43:53 $ 16 16 * 17 17 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 38 38 #include "psAstronomyErrors.h" 39 39 #include "psConstants.h" 40 #include "psLogMsg.h" 41 42 /******************************************************************************/ 43 /* DEFINE STATEMENTS */ 44 /******************************************************************************/ 45 46 /** Maximum size of a string */ 47 #define MAX_STRING_LENGTH 1024 48 49 /******************************************************************************/ 50 /* TYPE DEFINITIONS */ 51 /******************************************************************************/ 52 53 // None 54 55 /*****************************************************************************/ 56 /* GLOBAL VARIABLES */ 57 /*****************************************************************************/ 58 59 // None 60 61 /*****************************************************************************/ 62 /* FILE STATIC VARIABLES */ 63 /*****************************************************************************/ 40 64 41 65 static psS32 metadataId = 0; 66 67 /*****************************************************************************/ 68 /* FUNCTION IMPLEMENTATION - LOCAL */ 69 /*****************************************************************************/ 42 70 43 71 static psMetadataItem* makeMetaMulti(psHash* table, const char* key, psMetadataItem* existing) … … 48 76 } 49 77 78 // move any existing entry into a psList 79 psList* newList = psListAlloc(existing); 50 80 51 81 psMetadataItem* item = psMetadataItemAlloc(key, 52 82 PS_META_MULTI, 53 "List of Metadata Items", 54 NULL); 55 56 psListAdd(item->data.list,PS_LIST_TAIL,existing); 83 "", 84 newList); 57 85 58 86 if (existing != NULL) { … … 60 88 } 61 89 62 psHashAdd(table, key, item); // put in the new MULTI list entry 63 64 // free local references of newly allocated item. 90 psHashAdd(table, key, item); // put in the new entry 91 92 // free local references of newly allocated items. 93 psFree(newList); 65 94 psFree(item); 66 95 … … 80 109 psFree(metadataItem->name); 81 110 psFree(metadataItem->comment); 82 if (! PS_META_IS_PRIMITIVE(type)) { 111 112 if(!PS_META_IS_PRIMITIVE(type)) { 83 113 psFree(metadataItem->data.V); 84 114 } … … 104 134 psFree(metadata->list); 105 135 psFree(metadata->table); 136 106 137 } 107 138 … … 146 177 { 147 178 psMetadataItem* metadataItem = NULL; 148 char tmp; 149 int nBytes; 179 150 180 151 181 PS_PTR_CHECK_NULL(name,NULL); … … 158 188 psMemSetDeallocator(metadataItem, (psFreeFcn) metadataItemFree); 159 189 160 // set metadata item comment 190 // Allocate and set metadata item comment 191 metadataItem->comment = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH); 161 192 if (comment == NULL) { 162 193 // Per SDRS, null isn't allowed, must use "" instead 163 metadataItem->comment = psStringCopy("");194 strncpy(metadataItem->comment, "", MAX_STRING_LENGTH); 164 195 } else { 165 metadataItem->comment = psStringCopy(comment);196 strncpy(metadataItem->comment, comment, MAX_STRING_LENGTH); 166 197 } 167 198 … … 173 204 174 205 // Allocate and set metadata item name 175 nBytes = vsnprintf(&tmp, 0, name, argPtr) + 1; 176 metadataItem->name = (char *)psAlloc(sizeof(char) * nBytes); 206 metadataItem->name = (char *)psAlloc(sizeof(char) * MAX_STRING_LENGTH); 177 207 vsprintf(metadataItem->name, name, argPtr); 178 208 … … 193 223 case PS_META_STR: 194 224 // Perform copy of input strings 195 metadataItem->data.V = psStringCopy(va_arg(argPtr, char *)); 196 break; 197 case PS_META_MULTI: 198 // MULTI needs to create a psList entry, value must be NULL 199 metadataItem->data.list = psListAlloc(NULL); 225 metadataItem->data.V = psStringNCopy(va_arg(argPtr, char *), MAX_STRING_LENGTH); 200 226 break; 201 227 case PS_META_LIST: … … 207 233 case PS_META_ASTROM: 208 234 case PS_META_UNKNOWN: 235 case PS_META_META: 236 case PS_META_MULTI: 209 237 // Copy of input data not performed due to variability of data types 210 238 metadataItem->data.V = psMemIncrRefCounter(va_arg(argPtr, psPtr)); … … 258 286 259 287 // See if key is already in table 260 existingEntry = psMetadataLookup(md, key); 261 262 // if replace is set, remove any existing items of the same key 263 if (existingEntry != NULL && (flags & PS_META_REPLACE) != 0) { 264 psMetadataRemove(md,0,key); 265 existingEntry = NULL; 266 } 267 268 // if the metadataItem is MULTI, just create a MULTI node. 288 existingEntry = (psMetadataItem*)psHashLookup(mdTable, key); 289 269 290 if (metadataItem->type == PS_META_MULTI) { 270 if (metadataItem->data.list == NULL || metadataItem->data.list->size > 0) { 271 psError(PS_ERR_BAD_PARAMETER_VALUE,true, 272 "Specified PS_META_MULTI item is not defined properly " 273 "(list allocated with zero size)."); 274 return false; 275 } 276 277 // make sure the existing entry is PS_META_MULTI 291 // the incoming entry is PS_META_MULTI 292 293 // force the hash entry to be PS_META_MULTI 278 294 existingEntry = makeMetaMulti(mdTable,key,existingEntry); 279 295 296 // add all the items in the incoming entry to metadata 297 psList* list = metadataItem->data.list; 298 if (list != NULL) { 299 psListIterator* iter = psListIteratorAlloc(list,PS_LIST_HEAD,true); 300 psMetadataItem* listItem; 301 while ((listItem=(psMetadataItem*)psListGetAndIncrement(iter)) != NULL) { 302 psMetadataAddItem(md,listItem,location,flags); 303 } 304 psFree(iter); 305 } 306 280 307 return true; // all done. 281 308 } 282 309 283 310 // how the item is added to the hash depends on prior existence, flags, etc. 284 if(existingEntry == NULL) { // no prior existence 285 // Node doesn't already exist - Add new metadata item to metadata collection's hash 286 if(!psHashAdd(mdTable, key, metadataItem)) { 287 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key); 288 return false; 289 } 290 } else { 311 if(existingEntry != NULL) { // prior existence 291 312 if (existingEntry->type == PS_META_MULTI || (flags & PS_META_DUPLICATE_OK) != 0) { 292 313 // duplicate entries allowed - add another entry. 293 314 294 // make sure the existing hashentry is PS_META_MULTI315 // make sure the existing entry is PS_META_MULTI 295 316 existingEntry = makeMetaMulti(mdTable,key,existingEntry); 296 317 297 // add to the hash key's list ofentries318 // add to the hash's list of duplicate entries 298 319 if (! psListAdd(existingEntry->data.list, PS_LIST_TAIL, metadataItem) ) { 299 320 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key); 300 321 return false; 301 322 } 323 } else if ((flags & PS_META_REPLACE) != 0) { 324 // replace entry instead of creating a duplicate entry. 325 326 // remove the existing entry from metadata 327 psMetadataRemove(md,0,key); 328 329 // treat as if new (added to list below) 330 if(!psHashAdd(mdTable, key, metadataItem)) { 331 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key); 332 return false; 333 } 334 335 // Generate warning that item has been replaced 336 psLogMsg(__func__,PS_LOG_WARN,"Metadata item %s has been replaced", 337 existingEntry->name); 302 338 } else { 303 // error on duplicate entry.339 // default is to error on duplicate entry. 304 340 psError(PS_ERR_BAD_PARAMETER_VALUE, true, 305 341 PS_ERRORTEXT_psMetadata_DUPLICATE_NOT_ALLOWED); 306 342 return false; 307 343 } 308 } 309 310 // finally, add the metadataItem to the metadata's list. 344 } else { 345 // OK, this is a new item. 346 347 // Node doesn't exist - Add new metadata item to metadata collection's hash 348 if(!psHashAdd(mdTable, key, metadataItem)) { 349 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_TABLE_FAILED,key); 350 return false; 351 } 352 } 353 311 354 if(!psListAdd(mdList, location, metadataItem)) { 312 355 psError(PS_ERR_UNKNOWN,false,PS_ERRORTEXT_psMetadata_ADD_COLLECTION_FAILED,key); … … 363 406 METADATA_ADD_TYPE(LookupTable,psLookupTable*,PS_META_LOOKUPTABLE) 364 407 METADATA_ADD_TYPE(Unknown,void*,PS_META_UNKNOWN) 408 METADATA_ADD_TYPE(Metadata,psMetadata*,PS_META_META) 365 409 366 410 psBool psMetadataRemove(psMetadata *md, psS32 where, const char *key) -
trunk/psLib/src/types/psMetadata.h
r3684 r3945 11 11 * @author Ross Harman, MHPCC 12 12 * 13 * @version $Revision: 1.4 4$ $Name: not supported by cvs2svn $14 * @date $Date: 2005-0 4-08 17:58:57$13 * @version $Revision: 1.45 $ $Name: not supported by cvs2svn $ 14 * @date $Date: 2005-05-16 19:43:53 $ 15 15 * 16 16 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 51 51 PS_META_ASTROM, ///< Astrometric coefficients (Stored as item.data.V). 52 52 PS_META_UNKNOWN, ///< Other data (Stored as item.data.V). 53 PS_META_MULTI ///< Used internally, do not create an metadata item of this type. 53 PS_META_MULTI, ///< Used internally, do not create an metadata item of this type. 54 PS_META_META ///< Metadata data (Stored as item.data.md). 54 55 } psMetadataType; 55 56 … … 105 106 } 106 107 psMetadataIterator; 107 108 108 109 109 /** Metadata item data structure. … … 316 316 psBool psMetadataAddUnknown(psMetadata* md, psS32 location, const char* name, 317 317 const char* comment, psPtr value); 318 psBool psMetadataAddMetadata(psMetadata* md, psS32 location, const char* name, 319 const char* comment, psMetadata* value); 318 320 319 321 /** Remove an item from metadata collection. -
trunk/psLib/src/types/psMetadataConfig.c
r3769 r3945 8 8 * 9 9 * @author Ross Harman, MHPCC 10 * @author Eric Van Alst, MHPCC 10 11 * 11 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2005-0 4-26 19:53:30$12 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-05-16 19:43:53 $ 13 14 * 14 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 33 34 #include "psConstants.h" 34 35 #include "psAstronomyErrors.h" 35 36 36 37 37 /******************************************************************************/ … … 53 53 return NULL; 54 54 55 /** Free and null temporary variables used by config file parser */56 #define CLEAR_TEMPS() \57 if(strName) { \58 psFree(strName); \59 strName = NULL; \60 } \61 if(strType) { \62 psFree(strType); \63 strType = NULL; \64 } \65 if(strValue) { \66 psFree(strValue); \67 strValue = NULL; \68 } \69 if(strComment) { \70 psFree(strComment); \71 strComment = NULL; \72 }73 74 55 /** Maximum size of a FITS line */ 75 56 #define FITS_LINE_SIZE 80 … … 105 86 static void initMetadataItemXml(void *ctx, char *tagName); 106 87 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts); 107 108 /** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 109 * must be null terminated. */ 88 static psMetadata* getMetadataType(char *linePtr); 89 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 90 ; 91 static void parseLevelInfoFree(p_psParseLevelInfo* info); 92 static psBool parseLine(psS32* level, psArray* levelArray, 93 char* linePtr, psS32 lineCount, char* fileName, psBool overwrite); 94 static psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 95 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags); 96 97 static void parseLevelInfoFree(p_psParseLevelInfo* info) 98 { 99 psFree(info->nonUniqueKeyArray); 100 psFree(info->typeArray); 101 psFree(info->templateArray); 102 psFree(info->name); 103 psFree(info->metadata); 104 } 105 106 // Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 107 // must be null terminated. 110 108 psBool ignoreLine(char *inString) 111 109 { … … 121 119 122 120 123 / **Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null124 * terminated copy of the original input string. */ 125 char *cleanString(char *inString, psS32 sLen )121 // Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null 122 // terminated copy of the original input string. 123 char *cleanString(char *inString, psS32 sLen, psBool ignoreComment) 126 124 { 127 125 char *ptrB = NULL; … … 129 127 char *cleaned = NULL; 130 128 131 129 // Initialize begining of string pointer 132 130 ptrB = inString; 133 131 134 /* Skip over leading # or whitespace */ 135 while (isspace(*ptrB) || *ptrB=='#') { 136 ptrB++; 137 } 138 139 /* Skip over trailing whitespace, null terminators, and # characters */ 132 // Skip over leading # or whitespace 133 if(ignoreComment) { 134 while (isspace(*ptrB) || *ptrB=='#') { 135 ptrB++; 136 } 137 } else { 138 while (isspace(*ptrB)) { 139 ptrB++; 140 } 141 } 142 143 // Skip over trailing whitespace, null terminators, and # characters 140 144 ptrE = inString + sLen; 141 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 142 ptrE--; 145 if(ignoreComment) { 146 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 147 ptrE--; 148 } 149 } else { 150 while(isspace(*ptrE) || *ptrE=='\0') { 151 ptrE--; 152 } 143 153 } 144 154 … … 152 162 } 153 163 154 / ** Count repeat occurances of a single character within a line. The input string must be null terminated. */164 // Count repeat occurances of a single character within a line. The input string must be null terminated. 155 165 psS32 repeatedChars(char *inString, char ch) 156 166 { 157 167 psS32 count = 0; 158 159 168 160 169 while(*inString!='\0') { … … 168 177 } 169 178 170 / **Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location171 * the beginning of the string. Tokens are newly allocated null terminated strings. */ 172 char* getToken(char **inString, char *delimiter, psS32 *status )179 // Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location 180 // the beginning of the string. Tokens are newly allocated null terminated strings. 181 char* getToken(char **inString, char *delimiter, psS32 *status, psBool ignoreComment) 173 182 { 174 183 char *cleanToken = NULL; 184 char *convertChar = NULL; 175 185 psS32 sLen = 0; 176 186 187 // Convert tab characters to white space 188 while((convertChar=strchr(*inString,'\t')) != NULL ) { 189 *convertChar = ' '; 190 } 177 191 178 192 // Skip over leading whitespace … … 186 200 187 201 // Create new, cleaned, and null terminated token 188 cleanToken = cleanString(*inString, sLen );202 cleanToken = cleanString(*inString, sLen,ignoreComment); 189 203 190 204 // Move to end of token … … 197 211 } 198 212 199 / **Returns single parsed value as a double precision number. The input string must be cleaned and null200 * terminated. */ 213 // Returns single parsed value as a double precision number. The input string must be cleaned and null 214 // terminated. 201 215 double parseValue(char *inString, psS32 *status) 202 216 { 203 217 char *end = NULL; 204 218 double value = 0.0; 205 206 219 207 220 value = strtod(inString, &end); … … 235 248 psVector* parseVector(char *inString, psElemType elemType, psS32 *status) 236 249 { 237 char *end = NULL; 238 char *saveValue = NULL; 239 psS32 i = 0; 240 psS32 numValues = 0; 241 double value = 0.0; 242 psVector *vec = NULL; 243 250 char* end = NULL; 251 char* saveValue = NULL; 252 psS32 i = 0; 253 psS32 numValues = 0; 254 double value = 0.0; 255 psVector* vec = NULL; 244 256 245 257 // Cycle through string and count entries … … 274 286 vec->data.U8[i++] = (psU8)value; 275 287 break; 288 case PS_TYPE_U16: 289 vec->data.U16[i++] = (psU16)value; 290 break; 291 case PS_TYPE_U32: 292 vec->data.U32[i++] = (psU32)value; 293 break; 294 case PS_TYPE_U64: 295 vec->data.U64[i++] = (psU64)value; 296 break; 297 case PS_TYPE_S8: 298 vec->data.S8[i++] = (psS8)value; 299 break; 300 case PS_TYPE_S16: 301 vec->data.S16[i++] = (psS16)value; 302 break; 276 303 case PS_TYPE_S32: 277 304 vec->data.S32[i++] = (psS32)value; 305 break; 306 case PS_TYPE_S64: 307 vec->data.S64[i++] = (psS64)value; 278 308 break; 279 309 case PS_TYPE_F32: … … 303 333 /* FUNCTION IMPLEMENTATION - PUBLIC */ 304 334 /*****************************************************************************/ 335 336 p_psParseLevelInfo* p_psParseLevelInfoAlloc(void) 337 { 338 339 p_psParseLevelInfo* info = NULL; 340 341 // Allocate memory for parse level info 342 info = (p_psParseLevelInfo*)psAlloc(sizeof(p_psParseLevelInfo)); 343 344 // If allocation successful then initialize members 345 if(info != NULL) { 346 347 info->nonUniqueKeyArray = psArrayAlloc(10); 348 info->nonUniqueKeyArray->n = 0; 349 350 info->typeArray = psArrayAlloc(10); 351 info->typeArray->n = 0; 352 353 info->templateArray = psArrayAlloc(10); 354 info->templateArray->n = 0; 355 356 info->metadata = NULL; 357 info->name = NULL; 358 359 // Set memory deallocator 360 psMemSetDeallocator(info,(psFreeFcn)parseLevelInfoFree); 361 } 362 return info; 363 } 305 364 306 365 bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem) … … 500 559 } 501 560 561 static psMetadata* getMetadataType(char* linePtr) 562 { 563 psMetadata* metadataTemplate = NULL; 564 psS32 status = 0; 565 char* token = NULL; 566 psMetadataItem* tempItem = NULL; 567 568 // Loop through line and generate metadata items for each token found 569 while((token = getToken(&linePtr," ",&status,false)) != NULL ) { 570 571 // If not allocated then allocate new metadata 572 if(metadataTemplate == NULL) { 573 metadataTemplate = psMetadataAlloc(); 574 } 575 576 // Look for comment indicator # 577 if(strstr(token,"#") != 0) { 578 psFree(token); 579 break; 580 } 581 582 // Create metadata item to represent token read 583 tempItem = psMetadataItemAllocStr(token,"",""); 584 if(tempItem == NULL) { 585 psFree(metadataTemplate); 586 psFree(token); 587 metadataTemplate = NULL; 588 break; 589 } 590 591 // Add item to template 592 if(!psMetadataAddItem(metadataTemplate, tempItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 593 psFree(metadataTemplate); 594 psFree(tempItem); 595 psFree(token); 596 metadataTemplate = NULL; 597 break; 598 } 599 psFree(tempItem); 600 psFree(token); 601 } 602 603 return metadataTemplate; 604 } 605 606 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 607 { 608 psMetadata* md = NULL; 609 psS32 items = 0; 610 char* token = NULL; 611 psS32 status = 0; 612 psMetadataItem* mdItem = NULL; 613 psMetadataItem* templateItem = NULL; 614 psListIterator* iter = NULL; 615 616 // Determine the number of items in template 617 items = template->list->size; 618 if(items > 0 ) { 619 620 // Allocate metadata 621 md = psMetadataAlloc() 622 ; 623 624 // Point to first item in template 625 iter = psListIteratorAlloc(template-> 626 list,PS_LIST_HEAD,true); 627 628 // For each item in template parse line string for values 629 for(psS32 i = 0; 630 i < items; 631 i++) { 632 633 // Get template item 634 templateItem = psListGetAndIncrement(iter) 635 ; 636 if(templateItem == NULL) { 637 psFree(md); 638 md = NULL; 639 break; 640 } 641 642 // Get the next token on the line 643 token = getToken(&linePtr," ",&status,false); 644 if(token != NULL) { 645 // Allocate metadata item 646 mdItem = psMetadataItemAllocStr(templateItem->name,templateItem->comment,token); 647 if(mdItem == NULL) { 648 psFree(md); 649 md = NULL; 650 psFree(token); 651 break; 652 } 653 // Add item to metadata 654 if(!psMetadataAddItem(md, mdItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 655 psFree(md); 656 md = NULL; 657 psFree(mdItem); 658 psFree(token); 659 break; 660 } 661 psFree(mdItem); 662 } else { 663 // Missing items 664 psFree(md); 665 md = NULL; 666 break; 667 } 668 669 psFree(token); 670 } 671 psFree(iter); 672 } 673 return md; 674 } 675 676 psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 677 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags) 678 { 679 psBool returnValue = true; 680 psBool addStatus = false; 681 psMetadataType mdType = PS_META_UNKNOWN; 682 psElemType vectorType = PS_TYPE_S8; 683 char* strType = NULL; 684 char* strValue = NULL; 685 char* strComment = NULL; 686 psS32 status = 0; 687 psMetadata* md = NULL; 688 psF64 tempDbl = 0.0; 689 psBool tempBool = false; 690 psS32 tempInt = 0; 691 psVector* tempVec = NULL; 692 char* tempStr = NULL; 693 psArray* nonUniqueKeys = NULL; 694 psBool typeFound = false; 695 psArray* typeArray = NULL; 696 psArray* templateArray = NULL; 697 psMetadata* tempMeta = NULL; 698 p_psParseLevelInfo* nextLevelInfo = NULL; 699 700 // Get the metadata item type 701 strType = getToken(&linePtr, " ", &status,true); 702 703 // Check for no type 704 if(strType==NULL) { 705 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 706 fileName); 707 returnValue = false; 708 } else { 709 710 // Set metadata type based on type token 711 712 // Check if the keyName specifies a vector and if so use strType token to find vector type 713 if(*keyName == '@') { 714 mdType = PS_META_VEC; 715 // Get the type of vector 716 if(!strncmp(strType, "U8", 2)) { 717 vectorType = PS_TYPE_U8; 718 } else if (!strncmp(strType,"U16",3)) { 719 vectorType = PS_TYPE_U16; 720 } else if (!strncmp(strType,"U32",3)) { 721 vectorType = PS_TYPE_U32; 722 } else if (!strncmp(strType,"U64",3)) { 723 vectorType = PS_TYPE_U64; 724 } else if (!strncmp(strType,"S8",2)) { 725 vectorType = PS_TYPE_S8; 726 } else if (!strncmp(strType,"S16",3)) { 727 vectorType = PS_TYPE_S16; 728 } else if (!strncmp(strType,"S32",3)) { 729 vectorType = PS_TYPE_S32; 730 } else if (!strncmp(strType,"S64",3)) { 731 vectorType = PS_TYPE_S64; 732 } else if (!strncmp(strType,"F32",3)) { 733 vectorType = PS_TYPE_F32; 734 } else if (!strncmp(strType,"F64",3)) { 735 vectorType = PS_TYPE_F64; 736 } else { 737 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, "", keyName, 738 strType, lineCount, fileName); 739 psFree(strType); 740 return false; 741 } 742 } else if(!strncmp(strType, "STR", 3)) { 743 mdType = PS_META_STR; 744 } else if(!strncmp(strType, "BOOL", 4)) { 745 mdType = PS_META_BOOL; 746 } else if(!strncmp(strType, "S32", 3)) { 747 mdType = PS_META_S32; 748 } else if(!strncmp(strType, "F32", 3)) { 749 mdType = PS_META_F32; 750 } else if(!strncmp(strType, "F64", 3)) { 751 mdType = PS_META_F64; 752 } else if(!strncmp(strType, "MULTI", 5)) { 753 mdType = PS_META_MULTI; 754 } else if(!strncmp(strType, "METADATA", 8)) { 755 mdType = PS_META_META; 756 } else { 757 // Search through user types 758 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 759 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 760 for(psS32 k = 0; k < typeArray->n; k++) { 761 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 762 tempMeta = setMetadataItem((psMetadata*)templateArray->data[k],linePtr); 763 if(tempMeta != NULL) { 764 // Add metadata item 765 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 766 addStatus = psMetadataAdd(md,PS_LIST_TAIL,keyName,PS_META_META | flags,"",tempMeta); 767 // Check for add failure 768 if (! addStatus) { 769 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, 770 keyName, lineCount, fileName); 771 psFree(strType); 772 psFree(tempMeta); 773 return false; 774 } 775 psFree(tempMeta); 776 } else { 777 // Metadata type read error 778 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, 779 keyName,lineCount,fileName); 780 psFree(strType); 781 return false; 782 } 783 typeFound = true; 784 break; 785 } 786 } 787 if(!typeFound) { 788 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 789 strType, lineCount,fileName); 790 psFree(strType); 791 return false; 792 } else { 793 psFree(strType); 794 return true; 795 } 796 } 797 } 798 799 // If type is not MULTI or META then get the value and comment 800 if((mdType != PS_META_MULTI) && (mdType != PS_META_META)) { 801 // Get the metadata item value if there is one. 802 status = 0; 803 strValue = getToken(&linePtr, "#", &status,true); 804 if(status) { 805 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 806 fileName); 807 psFree(strType); 808 psFree(strValue); 809 return false; 810 } 811 if(strValue==NULL) { 812 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 813 fileName); 814 psFree(strType); 815 psFree(strValue); 816 return false; 817 } 818 // Not all lines will have comments, so NULL is ok. 819 status = 0; 820 strComment = getToken(&linePtr,"~", &status,true); 821 if(status) { 822 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 823 fileName); 824 psFree(strType); 825 psFree(strValue); 826 psFree(strComment); 827 } 828 } 829 830 // Need to add item to metadata so get pointer to metadata 831 status = 0; 832 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 833 nonUniqueKeys = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray; 834 switch(mdType) { 835 case PS_META_STR: 836 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 837 mdType | flags, 838 strComment, strValue); 839 break; 840 case PS_META_BOOL: 841 tempBool = parseBool(strValue, &status); 842 if(!status) { 843 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 844 mdType | flags, 845 strComment, tempBool); 846 } else { 847 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 848 strType, lineCount, fileName); 849 returnValue = false; 850 } 851 break; 852 case PS_META_F32: 853 case PS_META_F64: 854 tempDbl = parseValue(strValue, &status); 855 if(!status) { 856 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 857 mdType | flags, 858 strComment, tempDbl); 859 } else { 860 psError(PS_ERR_IO, true, 861 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, strType, lineCount, 862 fileName); 863 returnValue = false; 864 } 865 break; 866 case PS_META_S32: 867 tempInt = (psS32)parseValue(strValue, &status); 868 if(!status) { 869 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 870 mdType | flags, 871 strComment, tempInt); 872 } else { 873 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 874 strType, lineCount, fileName); 875 returnValue = false; 876 } 877 break; 878 case PS_META_VEC: 879 tempVec = parseVector(strValue, vectorType, &status); 880 if(!status) { 881 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName+1, 882 mdType | flags, 883 strComment, tempVec); 884 } else { 885 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 886 strType, lineCount, fileName); 887 returnValue = false; 888 } 889 psFree(tempVec); 890 break; 891 case PS_META_MULTI: 892 // Add key to non-unique array of keys 893 // Check for duplicate MULTI lines 894 addStatus = true; 895 for(psS32 k=0; k < nonUniqueKeys->n; k++) { 896 if(strcmp(keyName,(char*)nonUniqueKeys->data[k]) == 0) { 897 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_DUPLICATE_MULTI, 898 lineCount,fileName); 899 psFree(strType); 900 return false; 901 } 902 } 903 tempStr = psStringCopy(keyName); 904 nonUniqueKeys = psArrayAdd(nonUniqueKeys,0,tempStr); 905 addStatus = true; 906 psFree(tempStr); 907 break; 908 case PS_META_META: 909 // Create next level info 910 nextLevelInfo = p_psParseLevelInfoAlloc(); 911 // Create new metadata 912 nextLevelInfo->metadata = psMetadataAlloc(); 913 // Save name of metadata 914 nextLevelInfo->name = psStringCopy(keyName); 915 // Add next level to levelArray 916 levelArray = psArrayAdd(levelArray,1,nextLevelInfo); 917 psFree(nextLevelInfo); 918 // Increment level counter 919 (*level)++; 920 addStatus = true; 921 break; 922 default: 923 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 924 lineCount,fileName); 925 break; 926 } 927 928 // Check if the add status was successful 929 if (! addStatus) { 930 // psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, keyName, lineCount, 931 // fileName); 932 returnValue = false; 933 } 934 935 psFree(strComment); 936 psFree(strValue); 937 psFree(strType); 938 939 return returnValue; 940 } 941 942 psBool parseLine(psS32* level, psArray* levelArray, char* linePtr, 943 psS32 lineCount, char* fileName, psBool overwrite) 944 { 945 psBool returnValue = true; 946 psMetadataFlags flags = PS_META_DEFAULT; 947 char* keyName = NULL; 948 psS32 status = 0; 949 psS32 limit = 0; 950 psMetadata* tempTemplate = NULL; 951 char* strType = NULL; 952 psArray* typeArray = NULL; 953 psArray* templateArray = NULL; 954 p_psParseLevelInfo* upperLevelInfo = NULL; 955 p_psParseLevelInfo* lowerLevelInfo = NULL; 956 psBool addStatus = 0; 957 958 // Set flags if overwrite specified 959 if(overwrite) { 960 flags = PS_META_REPLACE; 961 } 962 963 // If line is not a comment or blank, then extract data 964 if(!ignoreLine(linePtr)) { 965 966 // Check for more than one '@' in a line 967 if(repeatedChars(linePtr, '@') > 1) { 968 psError(PS_ERR_IO, true, 969 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 970 return false; 971 } 972 973 // Get metadata item name 974 keyName = getToken(&linePtr, " ", &status,true); 975 if(status) { 976 psError(PS_ERR_IO, true, 977 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "keyName", lineCount, fileName); 978 psFree(keyName); 979 return false; 980 } 981 982 // Check for special keyName values "TYPE", "END" 983 if(strcmp(keyName,"TYPE") == 0 ) { 984 // Get the type name 985 strType = getToken(&linePtr," ",&status,true); 986 if(strType == NULL) { 987 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL,"type",lineCount, 988 fileName); 989 psFree(keyName); 990 return false; 991 } 992 tempTemplate = getMetadataType(linePtr); 993 // Check if type was parsed succesfully 994 if(tempTemplate != NULL) { 995 // Access type array 996 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 997 // Check if type already exists in array 998 for(psS32 k=0; k < typeArray->n; k++) { 999 // Compare type name with the list of current types 1000 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 1001 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_TYPE_DUPLICATE, 1002 strType,lineCount,fileName); 1003 psFree(tempTemplate); 1004 psFree(keyName); 1005 psFree(strType); 1006 return false; 1007 } 1008 } 1009 // Add key name to array of type 1010 typeArray = psArrayAdd(typeArray,1,strType); 1011 // Add template to array of templates 1012 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 1013 templateArray = psArrayAdd(templateArray,1,tempTemplate); 1014 psFree(tempTemplate); 1015 } else { 1016 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 1017 strType,lineCount,fileName); 1018 psFree(keyName); 1019 psFree(strType); 1020 return false; 1021 } 1022 psFree(strType); 1023 } else if (strcmp(keyName,"END") == 0 ) { 1024 if(*level > 0) { 1025 upperLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level-1])); 1026 lowerLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level])); 1027 // Check name in nonunique list 1028 for(psS32 k=0; k < upperLevelInfo->nonUniqueKeyArray->n; k++) { 1029 if(strcmp(upperLevelInfo->nonUniqueKeyArray->data[k],lowerLevelInfo->name) == 0) { 1030 flags = PS_META_DUPLICATE_OK; 1031 break; 1032 } 1033 } 1034 // Add metadata to upper level metadata 1035 addStatus = psMetadataAdd(upperLevelInfo->metadata, 1036 PS_LIST_TAIL,lowerLevelInfo->name, 1037 PS_META_META | flags, 1038 "", 1039 lowerLevelInfo->metadata); 1040 if(!addStatus) { 1041 psFree(keyName); 1042 return false; 1043 } else { 1044 // Remove lower info level 1045 if(!psArrayRemove(levelArray,levelArray->data[*level])) { 1046 psFree(keyName); 1047 return false; 1048 } 1049 psFree(lowerLevelInfo); 1050 (*level)--; 1051 } 1052 } else { 1053 psFree(keyName); 1054 return false; 1055 } 1056 } else { 1057 // Check if key name present in array of non-unique key names 1058 limit = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray->n; 1059 for(psS32 k=0; k < limit; k++) { 1060 char* name = (char*)((p_psParseLevelInfo*) 1061 (levelArray->data[*level]))->nonUniqueKeyArray->data[k]; 1062 if(strcmp(name,keyName) == 0) { 1063 flags = PS_META_DUPLICATE_OK; 1064 } 1065 } 1066 // Parse metadataItem 1067 if(!parseMetadataItem(keyName,level, levelArray, linePtr, lineCount, fileName, flags)) { 1068 psFree(keyName); 1069 return false; 1070 } 1071 } 1072 psFree(keyName); 1073 } 1074 return returnValue; 1075 } 1076 502 1077 psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite) 503 1078 { 504 psBool tempBool; 505 char *line = NULL; 506 char *strName = NULL; 507 char *strType = NULL; 508 char *strValue = NULL; 509 char *strComment = NULL; 510 char *linePtr = NULL; 511 psElemType vecType = 0; 512 psS32 status = 0; 513 psU32 lineCount = 0; 514 psF64 tempDbl = 0.0; 515 psS32 tempInt = 0.0; 516 psVector *tempVec = NULL; 517 FILE *fp = NULL; 518 psMetadataType mdType; 519 psMetadataFlags flags; 520 psBool addStatus; 521 522 // Check for nulls 1079 FILE* fp = NULL; 1080 char* line = NULL; 1081 char* linePtr = NULL; 1082 psArray* parseLevelInfoArray = NULL; 1083 psS32 lineCount = 0; 1084 psS32 nestingLevel = 0; 1085 p_psParseLevelInfo* topLevelInfo = NULL; 1086 1087 // Check for NULL file name 523 1088 PS_PTR_CHECK_NULL(fileName,NULL); 1089 1090 // Check for NULL nFail 1091 PS_PTR_CHECK_NULL(nFail,NULL); 1092 1093 // Attempt to open specified file 524 1094 if((fp=fopen(fileName, "r")) == NULL) { 525 1095 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName); … … 532 1102 } 533 1103 1104 // Allocate array to store parse level information 1105 parseLevelInfoArray = psArrayAlloc(10); 1106 parseLevelInfoArray->n = 0; 1107 1108 // Set parse level info for the top level 1109 topLevelInfo = p_psParseLevelInfoAlloc(); 1110 topLevelInfo->metadata = psMemIncrRefCounter(md); 1111 parseLevelInfoArray = psArrayAdd(parseLevelInfoArray,1,topLevelInfo); 1112 psFree(topLevelInfo); 1113 534 1114 // Create reusable line for continuous read 535 1115 line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char)); … … 541 1121 linePtr = line; 542 1122 lineCount++; 543 CLEAR_TEMPS(); 544 545 // If line is not a comment or blank, then extract data 546 if(!ignoreLine(linePtr)) { 547 548 // Check for more than one '*' or '@' in a line 549 if(repeatedChars(linePtr, '@') > 1) { 550 (*nFail)++; 551 psError(PS_ERR_IO, true, 552 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 553 continue; 554 } else if(repeatedChars(linePtr, '*') > 1) { 555 (*nFail)++; 556 psError(PS_ERR_IO, true, 557 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName); 558 continue; 559 } else if(repeatedChars(linePtr, '~') > 0) { 560 (*nFail)++; 561 psError(PS_ERR_IO, true, 562 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName); 563 continue; 564 } 565 566 // Get metadata item name 567 strName = getToken(&linePtr, " ", &status); 568 if(strName==NULL || status) { 569 (*nFail)++; 570 status = 0; 571 psError(PS_ERR_IO, true, 572 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName); 573 continue; 574 } 575 576 flags = (overwrite) ? PS_META_REPLACE : PS_META_DEFAULT; 577 578 // Get the metadata item type 579 strType = getToken(&linePtr, " ", &status); 580 if(strType==NULL) { 581 (*nFail)++; 582 status = 0; 583 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 584 fileName); 585 continue; 586 } else { 587 char* tempStrType = strType; 588 if(*strType == '*') { 589 flags = PS_META_DUPLICATE_OK; 590 tempStrType = strType+1; 591 } 592 593 if(!strncmp(tempStrType, "STR", 3)) { 594 mdType = PS_META_STR; 595 } else if(!strncmp(tempStrType, "BOOL", 4)) { 596 mdType = PS_META_BOOL; 597 } else if(!strncmp(tempStrType, "S32", 3)) { 598 mdType = PS_META_S32; 599 } else if(!strncmp(tempStrType, "F32", 3)) { 600 mdType = PS_META_F32; 601 } else if(!strncmp(tempStrType, "F64", 3)) { 602 mdType = PS_META_F64; 603 } else { 604 (*nFail)++; 605 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount, 606 fileName); 607 continue; 608 } 609 } 610 611 if(*strName == '@') { 612 vecType = PS_META_PRIMITIVE_TYPE(mdType); 613 mdType = PS_META_VEC; 614 } 615 616 // Get the metadata item value if there is one. 617 strValue = getToken(&linePtr, "#", &status); 618 if(status) { 619 (*nFail)++; 620 status = 0; 621 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 622 fileName); 623 continue; 624 } 625 if(strValue==NULL) { 626 (*nFail)++; 627 status = 0; 628 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 629 fileName); 630 continue; 631 } 632 633 // Not all lines will have comments, so NULL is ok. 634 strComment = getToken(&linePtr,"~", &status); 635 if(status) { 636 (*nFail)++; 637 status = 0; 638 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 639 fileName); 640 continue; 641 } 642 643 // Create and add metadata item to metadata and parse values 644 switch (mdType) { 645 case PS_META_STR: 646 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 647 mdType | flags, 648 strComment, strValue); 649 break; 650 case PS_META_VEC: 651 tempVec = parseVector(strValue, vecType, &status); 652 if(!status) { 653 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName+1, 654 mdType | flags, 655 strComment, tempVec); 656 } else { 657 status = 0; 658 (*nFail)++; 659 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 660 strType, lineCount, fileName); 661 continue; 662 } 663 psFree(tempVec); 664 break; 665 case PS_META_BOOL: 666 tempBool = parseBool(strValue, &status); 667 if(!status) { 668 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 669 mdType | flags, 670 strComment, tempBool); 671 } else { 672 status = 0; 673 (*nFail)++; 674 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 675 strType, lineCount, fileName); 676 continue; 677 } 678 break; 679 case PS_META_S32: 680 tempInt = (psS32)parseValue(strValue, &status); 681 if(!status) { 682 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 683 mdType | flags, 684 strComment, tempInt); 685 } else { 686 status = 0; 687 (*nFail)++; 688 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 689 strType, lineCount, fileName); 690 continue; 691 } 692 break; 693 case PS_META_F32: 694 case PS_META_F64: 695 tempDbl = parseValue(strValue, &status); 696 if(!status) { 697 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 698 mdType | flags, 699 strComment, tempDbl); 700 } else { 701 status = 0; 702 (*nFail)++; 703 psError(PS_ERR_IO, true, 704 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount, 705 fileName); 706 continue; 707 } 708 break; 709 default: 710 (*nFail)++; 711 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount, 712 fileName); 713 continue; 714 } // switch 715 if (! addStatus) { 716 (*nFail)++; 717 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount, 718 fileName); 719 } 720 721 } // if ignoreLine 722 } // while loop 723 1123 1124 if(!parseLine(&nestingLevel,parseLevelInfoArray,linePtr,lineCount,(char*)fileName,overwrite)) { 1125 (*nFail)++; 1126 } 1127 } 1128 1129 // Free parse array and line buffer 1130 psFree(parseLevelInfoArray); 724 1131 psFree(line); 725 1132 1133 // Check if any failed lined detected 1134 if( (*nFail) != 0) { 1135 psFree(md); 1136 md = NULL; 1137 } 726 1138 return md; 727 1139 } 1140 728 1141 729 1142 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts) … … 750 1163 751 1164 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 752 psTagName = psStringCopy( (const char*)tagName);1165 psTagName = psStringCopy(tagName); 753 1166 754 1167 // Metadata containter for housing element attributes used by other SAX events … … 774 1187 775 1188 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 776 psAttName = psStringCopy( (const char*)attName);777 psAttValue = psStringCopy( (const char*)attValue);1189 psAttName = psStringCopy(attName); 1190 psAttValue = psStringCopy(attValue); 778 1191 psHashAdd(htAtts, psAttName, psAttValue); 779 1192 psFree(psAttName); … … 1082 1495 1083 1496 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 1084 psEndTagName = psStringCopy( (const char*)tagName);1497 psEndTagName = psStringCopy(tagName); 1085 1498 1086 1499 // Compare start and end tag names -
trunk/psLib/src/types/psMetadataConfig.h
r3381 r3945 10 10 * @author Robert DeSonia, MHPCC 11 11 * 12 * @version $Revision: 1. 9$ $Name: not supported by cvs2svn $13 * @date $Date: 2005-0 3-07 20:58:50$12 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-05-16 19:43:53 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 21 21 /// @{ 22 22 23 typedef struct 24 { 25 psArray* nonUniqueKeyArray; 26 psArray* typeArray; 27 psArray* templateArray; 28 psMetadata* metadata; 29 char* name; 30 } 31 p_psParseLevelInfo; 32 33 p_psParseLevelInfo* p_psParseLevelInfoAlloc(void); 23 34 24 35 /** Print metadata item to file. -
trunk/psLib/src/xml/psXML.c
r3769 r3945 8 8 * 9 9 * @author Ross Harman, MHPCC 10 * @author Eric Van Alst, MHPCC 10 11 * 11 * @version $Revision: 1.2 5$ $Name: not supported by cvs2svn $12 * @date $Date: 2005-0 4-26 19:53:30$12 * @version $Revision: 1.26 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-05-16 19:43:53 $ 13 14 * 14 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 33 34 #include "psConstants.h" 34 35 #include "psAstronomyErrors.h" 35 36 36 37 37 /******************************************************************************/ … … 53 53 return NULL; 54 54 55 /** Free and null temporary variables used by config file parser */56 #define CLEAR_TEMPS() \57 if(strName) { \58 psFree(strName); \59 strName = NULL; \60 } \61 if(strType) { \62 psFree(strType); \63 strType = NULL; \64 } \65 if(strValue) { \66 psFree(strValue); \67 strValue = NULL; \68 } \69 if(strComment) { \70 psFree(strComment); \71 strComment = NULL; \72 }73 74 55 /** Maximum size of a FITS line */ 75 56 #define FITS_LINE_SIZE 80 … … 105 86 static void initMetadataItemXml(void *ctx, char *tagName); 106 87 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts); 107 108 /** Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 109 * must be null terminated. */ 88 static psMetadata* getMetadataType(char *linePtr); 89 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 90 ; 91 static void parseLevelInfoFree(p_psParseLevelInfo* info); 92 static psBool parseLine(psS32* level, psArray* levelArray, 93 char* linePtr, psS32 lineCount, char* fileName, psBool overwrite); 94 static psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 95 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags); 96 97 static void parseLevelInfoFree(p_psParseLevelInfo* info) 98 { 99 psFree(info->nonUniqueKeyArray); 100 psFree(info->typeArray); 101 psFree(info->templateArray); 102 psFree(info->name); 103 psFree(info->metadata); 104 } 105 106 // Determines if a line is blank (whitespace only) or a commentline. It returns true if so. The input string 107 // must be null terminated. 110 108 psBool ignoreLine(char *inString) 111 109 { … … 121 119 122 120 123 / **Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null124 * terminated copy of the original input string. */ 125 char *cleanString(char *inString, psS32 sLen )121 // Removes leading and trailing whitespace and # characters from a string. The cleaned string is a new null 122 // terminated copy of the original input string. 123 char *cleanString(char *inString, psS32 sLen, psBool ignoreComment) 126 124 { 127 125 char *ptrB = NULL; … … 129 127 char *cleaned = NULL; 130 128 131 129 // Initialize begining of string pointer 132 130 ptrB = inString; 133 131 134 /* Skip over leading # or whitespace */ 135 while (isspace(*ptrB) || *ptrB=='#') { 136 ptrB++; 137 } 138 139 /* Skip over trailing whitespace, null terminators, and # characters */ 132 // Skip over leading # or whitespace 133 if(ignoreComment) { 134 while (isspace(*ptrB) || *ptrB=='#') { 135 ptrB++; 136 } 137 } else { 138 while (isspace(*ptrB)) { 139 ptrB++; 140 } 141 } 142 143 // Skip over trailing whitespace, null terminators, and # characters 140 144 ptrE = inString + sLen; 141 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 142 ptrE--; 145 if(ignoreComment) { 146 while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') { 147 ptrE--; 148 } 149 } else { 150 while(isspace(*ptrE) || *ptrE=='\0') { 151 ptrE--; 152 } 143 153 } 144 154 … … 152 162 } 153 163 154 / ** Count repeat occurances of a single character within a line. The input string must be null terminated. */164 // Count repeat occurances of a single character within a line. The input string must be null terminated. 155 165 psS32 repeatedChars(char *inString, char ch) 156 166 { 157 167 psS32 count = 0; 158 159 168 160 169 while(*inString!='\0') { … … 168 177 } 169 178 170 / **Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location171 * the beginning of the string. Tokens are newly allocated null terminated strings. */ 172 char* getToken(char **inString, char *delimiter, psS32 *status )179 // Returns cleaned token based on delimiter, but not including delimiter. Also changes the pointer location 180 // the beginning of the string. Tokens are newly allocated null terminated strings. 181 char* getToken(char **inString, char *delimiter, psS32 *status, psBool ignoreComment) 173 182 { 174 183 char *cleanToken = NULL; 184 char *convertChar = NULL; 175 185 psS32 sLen = 0; 176 186 187 // Convert tab characters to white space 188 while((convertChar=strchr(*inString,'\t')) != NULL ) { 189 *convertChar = ' '; 190 } 177 191 178 192 // Skip over leading whitespace … … 186 200 187 201 // Create new, cleaned, and null terminated token 188 cleanToken = cleanString(*inString, sLen );202 cleanToken = cleanString(*inString, sLen,ignoreComment); 189 203 190 204 // Move to end of token … … 197 211 } 198 212 199 / **Returns single parsed value as a double precision number. The input string must be cleaned and null200 * terminated. */ 213 // Returns single parsed value as a double precision number. The input string must be cleaned and null 214 // terminated. 201 215 double parseValue(char *inString, psS32 *status) 202 216 { 203 217 char *end = NULL; 204 218 double value = 0.0; 205 206 219 207 220 value = strtod(inString, &end); … … 235 248 psVector* parseVector(char *inString, psElemType elemType, psS32 *status) 236 249 { 237 char *end = NULL; 238 char *saveValue = NULL; 239 psS32 i = 0; 240 psS32 numValues = 0; 241 double value = 0.0; 242 psVector *vec = NULL; 243 250 char* end = NULL; 251 char* saveValue = NULL; 252 psS32 i = 0; 253 psS32 numValues = 0; 254 double value = 0.0; 255 psVector* vec = NULL; 244 256 245 257 // Cycle through string and count entries … … 274 286 vec->data.U8[i++] = (psU8)value; 275 287 break; 288 case PS_TYPE_U16: 289 vec->data.U16[i++] = (psU16)value; 290 break; 291 case PS_TYPE_U32: 292 vec->data.U32[i++] = (psU32)value; 293 break; 294 case PS_TYPE_U64: 295 vec->data.U64[i++] = (psU64)value; 296 break; 297 case PS_TYPE_S8: 298 vec->data.S8[i++] = (psS8)value; 299 break; 300 case PS_TYPE_S16: 301 vec->data.S16[i++] = (psS16)value; 302 break; 276 303 case PS_TYPE_S32: 277 304 vec->data.S32[i++] = (psS32)value; 305 break; 306 case PS_TYPE_S64: 307 vec->data.S64[i++] = (psS64)value; 278 308 break; 279 309 case PS_TYPE_F32: … … 303 333 /* FUNCTION IMPLEMENTATION - PUBLIC */ 304 334 /*****************************************************************************/ 335 336 p_psParseLevelInfo* p_psParseLevelInfoAlloc(void) 337 { 338 339 p_psParseLevelInfo* info = NULL; 340 341 // Allocate memory for parse level info 342 info = (p_psParseLevelInfo*)psAlloc(sizeof(p_psParseLevelInfo)); 343 344 // If allocation successful then initialize members 345 if(info != NULL) { 346 347 info->nonUniqueKeyArray = psArrayAlloc(10); 348 info->nonUniqueKeyArray->n = 0; 349 350 info->typeArray = psArrayAlloc(10); 351 info->typeArray->n = 0; 352 353 info->templateArray = psArrayAlloc(10); 354 info->templateArray->n = 0; 355 356 info->metadata = NULL; 357 info->name = NULL; 358 359 // Set memory deallocator 360 psMemSetDeallocator(info,(psFreeFcn)parseLevelInfoFree); 361 } 362 return info; 363 } 305 364 306 365 bool psMetadataItemPrint(FILE * fd, const char *format, const psMetadataItem* metadataItem) … … 500 559 } 501 560 561 static psMetadata* getMetadataType(char* linePtr) 562 { 563 psMetadata* metadataTemplate = NULL; 564 psS32 status = 0; 565 char* token = NULL; 566 psMetadataItem* tempItem = NULL; 567 568 // Loop through line and generate metadata items for each token found 569 while((token = getToken(&linePtr," ",&status,false)) != NULL ) { 570 571 // If not allocated then allocate new metadata 572 if(metadataTemplate == NULL) { 573 metadataTemplate = psMetadataAlloc(); 574 } 575 576 // Look for comment indicator # 577 if(strstr(token,"#") != 0) { 578 psFree(token); 579 break; 580 } 581 582 // Create metadata item to represent token read 583 tempItem = psMetadataItemAllocStr(token,"",""); 584 if(tempItem == NULL) { 585 psFree(metadataTemplate); 586 psFree(token); 587 metadataTemplate = NULL; 588 break; 589 } 590 591 // Add item to template 592 if(!psMetadataAddItem(metadataTemplate, tempItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 593 psFree(metadataTemplate); 594 psFree(tempItem); 595 psFree(token); 596 metadataTemplate = NULL; 597 break; 598 } 599 psFree(tempItem); 600 psFree(token); 601 } 602 603 return metadataTemplate; 604 } 605 606 static psMetadata* setMetadataItem(psMetadata* template, char* linePtr) 607 { 608 psMetadata* md = NULL; 609 psS32 items = 0; 610 char* token = NULL; 611 psS32 status = 0; 612 psMetadataItem* mdItem = NULL; 613 psMetadataItem* templateItem = NULL; 614 psListIterator* iter = NULL; 615 616 // Determine the number of items in template 617 items = template->list->size; 618 if(items > 0 ) { 619 620 // Allocate metadata 621 md = psMetadataAlloc() 622 ; 623 624 // Point to first item in template 625 iter = psListIteratorAlloc(template-> 626 list,PS_LIST_HEAD,true); 627 628 // For each item in template parse line string for values 629 for(psS32 i = 0; 630 i < items; 631 i++) { 632 633 // Get template item 634 templateItem = psListGetAndIncrement(iter) 635 ; 636 if(templateItem == NULL) { 637 psFree(md); 638 md = NULL; 639 break; 640 } 641 642 // Get the next token on the line 643 token = getToken(&linePtr," ",&status,false); 644 if(token != NULL) { 645 // Allocate metadata item 646 mdItem = psMetadataItemAllocStr(templateItem->name,templateItem->comment,token); 647 if(mdItem == NULL) { 648 psFree(md); 649 md = NULL; 650 psFree(token); 651 break; 652 } 653 // Add item to metadata 654 if(!psMetadataAddItem(md, mdItem, PS_LIST_TAIL, PS_META_DEFAULT)) { 655 psFree(md); 656 md = NULL; 657 psFree(mdItem); 658 psFree(token); 659 break; 660 } 661 psFree(mdItem); 662 } else { 663 // Missing items 664 psFree(md); 665 md = NULL; 666 break; 667 } 668 669 psFree(token); 670 } 671 psFree(iter); 672 } 673 return md; 674 } 675 676 psBool parseMetadataItem(char* keyName, psS32* level, psArray* levelArray, 677 char* linePtr, psS32 lineCount, char* fileName, psMetadataFlags flags) 678 { 679 psBool returnValue = true; 680 psBool addStatus = false; 681 psMetadataType mdType = PS_META_UNKNOWN; 682 psElemType vectorType = PS_TYPE_S8; 683 char* strType = NULL; 684 char* strValue = NULL; 685 char* strComment = NULL; 686 psS32 status = 0; 687 psMetadata* md = NULL; 688 psF64 tempDbl = 0.0; 689 psBool tempBool = false; 690 psS32 tempInt = 0; 691 psVector* tempVec = NULL; 692 char* tempStr = NULL; 693 psArray* nonUniqueKeys = NULL; 694 psBool typeFound = false; 695 psArray* typeArray = NULL; 696 psArray* templateArray = NULL; 697 psMetadata* tempMeta = NULL; 698 p_psParseLevelInfo* nextLevelInfo = NULL; 699 700 // Get the metadata item type 701 strType = getToken(&linePtr, " ", &status,true); 702 703 // Check for no type 704 if(strType==NULL) { 705 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 706 fileName); 707 returnValue = false; 708 } else { 709 710 // Set metadata type based on type token 711 712 // Check if the keyName specifies a vector and if so use strType token to find vector type 713 if(*keyName == '@') { 714 mdType = PS_META_VEC; 715 // Get the type of vector 716 if(!strncmp(strType, "U8", 2)) { 717 vectorType = PS_TYPE_U8; 718 } else if (!strncmp(strType,"U16",3)) { 719 vectorType = PS_TYPE_U16; 720 } else if (!strncmp(strType,"U32",3)) { 721 vectorType = PS_TYPE_U32; 722 } else if (!strncmp(strType,"U64",3)) { 723 vectorType = PS_TYPE_U64; 724 } else if (!strncmp(strType,"S8",2)) { 725 vectorType = PS_TYPE_S8; 726 } else if (!strncmp(strType,"S16",3)) { 727 vectorType = PS_TYPE_S16; 728 } else if (!strncmp(strType,"S32",3)) { 729 vectorType = PS_TYPE_S32; 730 } else if (!strncmp(strType,"S64",3)) { 731 vectorType = PS_TYPE_S64; 732 } else if (!strncmp(strType,"F32",3)) { 733 vectorType = PS_TYPE_F32; 734 } else if (!strncmp(strType,"F64",3)) { 735 vectorType = PS_TYPE_F64; 736 } else { 737 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, "", keyName, 738 strType, lineCount, fileName); 739 psFree(strType); 740 return false; 741 } 742 } else if(!strncmp(strType, "STR", 3)) { 743 mdType = PS_META_STR; 744 } else if(!strncmp(strType, "BOOL", 4)) { 745 mdType = PS_META_BOOL; 746 } else if(!strncmp(strType, "S32", 3)) { 747 mdType = PS_META_S32; 748 } else if(!strncmp(strType, "F32", 3)) { 749 mdType = PS_META_F32; 750 } else if(!strncmp(strType, "F64", 3)) { 751 mdType = PS_META_F64; 752 } else if(!strncmp(strType, "MULTI", 5)) { 753 mdType = PS_META_MULTI; 754 } else if(!strncmp(strType, "METADATA", 8)) { 755 mdType = PS_META_META; 756 } else { 757 // Search through user types 758 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 759 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 760 for(psS32 k = 0; k < typeArray->n; k++) { 761 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 762 tempMeta = setMetadataItem((psMetadata*)templateArray->data[k],linePtr); 763 if(tempMeta != NULL) { 764 // Add metadata item 765 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 766 addStatus = psMetadataAdd(md,PS_LIST_TAIL,keyName,PS_META_META | flags,"",tempMeta); 767 // Check for add failure 768 if (! addStatus) { 769 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, 770 keyName, lineCount, fileName); 771 psFree(strType); 772 psFree(tempMeta); 773 return false; 774 } 775 psFree(tempMeta); 776 } else { 777 // Metadata type read error 778 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, 779 keyName,lineCount,fileName); 780 psFree(strType); 781 return false; 782 } 783 typeFound = true; 784 break; 785 } 786 } 787 if(!typeFound) { 788 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 789 strType, lineCount,fileName); 790 psFree(strType); 791 return false; 792 } else { 793 psFree(strType); 794 return true; 795 } 796 } 797 } 798 799 // If type is not MULTI or META then get the value and comment 800 if((mdType != PS_META_MULTI) && (mdType != PS_META_META)) { 801 // Get the metadata item value if there is one. 802 status = 0; 803 strValue = getToken(&linePtr, "#", &status,true); 804 if(status) { 805 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 806 fileName); 807 psFree(strType); 808 psFree(strValue); 809 return false; 810 } 811 if(strValue==NULL) { 812 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 813 fileName); 814 psFree(strType); 815 psFree(strValue); 816 return false; 817 } 818 // Not all lines will have comments, so NULL is ok. 819 status = 0; 820 strComment = getToken(&linePtr,"~", &status,true); 821 if(status) { 822 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 823 fileName); 824 psFree(strType); 825 psFree(strValue); 826 psFree(strComment); 827 } 828 } 829 830 // Need to add item to metadata so get pointer to metadata 831 status = 0; 832 md = ((p_psParseLevelInfo*)(levelArray->data[*level]))->metadata; 833 nonUniqueKeys = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray; 834 switch(mdType) { 835 case PS_META_STR: 836 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 837 mdType | flags, 838 strComment, strValue); 839 break; 840 case PS_META_BOOL: 841 tempBool = parseBool(strValue, &status); 842 if(!status) { 843 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 844 mdType | flags, 845 strComment, tempBool); 846 } else { 847 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 848 strType, lineCount, fileName); 849 returnValue = false; 850 } 851 break; 852 case PS_META_F32: 853 case PS_META_F64: 854 tempDbl = parseValue(strValue, &status); 855 if(!status) { 856 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 857 mdType | flags, 858 strComment, tempDbl); 859 } else { 860 psError(PS_ERR_IO, true, 861 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, strType, lineCount, 862 fileName); 863 returnValue = false; 864 } 865 break; 866 case PS_META_S32: 867 tempInt = (psS32)parseValue(strValue, &status); 868 if(!status) { 869 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName, 870 mdType | flags, 871 strComment, tempInt); 872 } else { 873 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 874 strType, lineCount, fileName); 875 returnValue = false; 876 } 877 break; 878 case PS_META_VEC: 879 tempVec = parseVector(strValue, vectorType, &status); 880 if(!status) { 881 addStatus = psMetadataAdd(md, PS_LIST_TAIL, keyName+1, 882 mdType | flags, 883 strComment, tempVec); 884 } else { 885 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, keyName, 886 strType, lineCount, fileName); 887 returnValue = false; 888 } 889 psFree(tempVec); 890 break; 891 case PS_META_MULTI: 892 // Add key to non-unique array of keys 893 // Check for duplicate MULTI lines 894 addStatus = true; 895 for(psS32 k=0; k < nonUniqueKeys->n; k++) { 896 if(strcmp(keyName,(char*)nonUniqueKeys->data[k]) == 0) { 897 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_DUPLICATE_MULTI, 898 lineCount,fileName); 899 psFree(strType); 900 return false; 901 } 902 } 903 tempStr = psStringCopy(keyName); 904 nonUniqueKeys = psArrayAdd(nonUniqueKeys,0,tempStr); 905 addStatus = true; 906 psFree(tempStr); 907 break; 908 case PS_META_META: 909 // Create next level info 910 nextLevelInfo = p_psParseLevelInfoAlloc(); 911 // Create new metadata 912 nextLevelInfo->metadata = psMetadataAlloc(); 913 // Save name of metadata 914 nextLevelInfo->name = psStringCopy(keyName); 915 // Add next level to levelArray 916 levelArray = psArrayAdd(levelArray,1,nextLevelInfo); 917 psFree(nextLevelInfo); 918 // Increment level counter 919 (*level)++; 920 addStatus = true; 921 break; 922 default: 923 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 924 lineCount,fileName); 925 break; 926 } 927 928 // Check if the add status was successful 929 if (! addStatus) { 930 // psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, keyName, lineCount, 931 // fileName); 932 returnValue = false; 933 } 934 935 psFree(strComment); 936 psFree(strValue); 937 psFree(strType); 938 939 return returnValue; 940 } 941 942 psBool parseLine(psS32* level, psArray* levelArray, char* linePtr, 943 psS32 lineCount, char* fileName, psBool overwrite) 944 { 945 psBool returnValue = true; 946 psMetadataFlags flags = PS_META_DEFAULT; 947 char* keyName = NULL; 948 psS32 status = 0; 949 psS32 limit = 0; 950 psMetadata* tempTemplate = NULL; 951 char* strType = NULL; 952 psArray* typeArray = NULL; 953 psArray* templateArray = NULL; 954 p_psParseLevelInfo* upperLevelInfo = NULL; 955 p_psParseLevelInfo* lowerLevelInfo = NULL; 956 psBool addStatus = 0; 957 958 // Set flags if overwrite specified 959 if(overwrite) { 960 flags = PS_META_REPLACE; 961 } 962 963 // If line is not a comment or blank, then extract data 964 if(!ignoreLine(linePtr)) { 965 966 // Check for more than one '@' in a line 967 if(repeatedChars(linePtr, '@') > 1) { 968 psError(PS_ERR_IO, true, 969 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 970 return false; 971 } 972 973 // Get metadata item name 974 keyName = getToken(&linePtr, " ", &status,true); 975 if(status) { 976 psError(PS_ERR_IO, true, 977 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "keyName", lineCount, fileName); 978 psFree(keyName); 979 return false; 980 } 981 982 // Check for special keyName values "TYPE", "END" 983 if(strcmp(keyName,"TYPE") == 0 ) { 984 // Get the type name 985 strType = getToken(&linePtr," ",&status,true); 986 if(strType == NULL) { 987 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL,"type",lineCount, 988 fileName); 989 psFree(keyName); 990 return false; 991 } 992 tempTemplate = getMetadataType(linePtr); 993 // Check if type was parsed succesfully 994 if(tempTemplate != NULL) { 995 // Access type array 996 typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray; 997 // Check if type already exists in array 998 for(psS32 k=0; k < typeArray->n; k++) { 999 // Compare type name with the list of current types 1000 if(strcmp(strType,(char*)typeArray->data[k]) == 0) { 1001 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_TYPE_DUPLICATE, 1002 strType,lineCount,fileName); 1003 psFree(tempTemplate); 1004 psFree(keyName); 1005 psFree(strType); 1006 return false; 1007 } 1008 } 1009 // Add key name to array of type 1010 typeArray = psArrayAdd(typeArray,1,strType); 1011 // Add template to array of templates 1012 templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray; 1013 templateArray = psArrayAdd(templateArray,1,tempTemplate); 1014 psFree(tempTemplate); 1015 } else { 1016 psError(PS_ERR_IO,true,PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, 1017 strType,lineCount,fileName); 1018 psFree(keyName); 1019 psFree(strType); 1020 return false; 1021 } 1022 psFree(strType); 1023 } else if (strcmp(keyName,"END") == 0 ) { 1024 if(*level > 0) { 1025 upperLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level-1])); 1026 lowerLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level])); 1027 // Check name in nonunique list 1028 for(psS32 k=0; k < upperLevelInfo->nonUniqueKeyArray->n; k++) { 1029 if(strcmp(upperLevelInfo->nonUniqueKeyArray->data[k],lowerLevelInfo->name) == 0) { 1030 flags = PS_META_DUPLICATE_OK; 1031 break; 1032 } 1033 } 1034 // Add metadata to upper level metadata 1035 addStatus = psMetadataAdd(upperLevelInfo->metadata, 1036 PS_LIST_TAIL,lowerLevelInfo->name, 1037 PS_META_META | flags, 1038 "", 1039 lowerLevelInfo->metadata); 1040 if(!addStatus) { 1041 psFree(keyName); 1042 return false; 1043 } else { 1044 // Remove lower info level 1045 if(!psArrayRemove(levelArray,levelArray->data[*level])) { 1046 psFree(keyName); 1047 return false; 1048 } 1049 psFree(lowerLevelInfo); 1050 (*level)--; 1051 } 1052 } else { 1053 psFree(keyName); 1054 return false; 1055 } 1056 } else { 1057 // Check if key name present in array of non-unique key names 1058 limit = ((p_psParseLevelInfo*)(levelArray->data[*level]))->nonUniqueKeyArray->n; 1059 for(psS32 k=0; k < limit; k++) { 1060 char* name = (char*)((p_psParseLevelInfo*) 1061 (levelArray->data[*level]))->nonUniqueKeyArray->data[k]; 1062 if(strcmp(name,keyName) == 0) { 1063 flags = PS_META_DUPLICATE_OK; 1064 } 1065 } 1066 // Parse metadataItem 1067 if(!parseMetadataItem(keyName,level, levelArray, linePtr, lineCount, fileName, flags)) { 1068 psFree(keyName); 1069 return false; 1070 } 1071 } 1072 psFree(keyName); 1073 } 1074 return returnValue; 1075 } 1076 502 1077 psMetadata* psMetadataParseConfig(psMetadata* md, psU32 *nFail, const char *fileName, psBool overwrite) 503 1078 { 504 psBool tempBool; 505 char *line = NULL; 506 char *strName = NULL; 507 char *strType = NULL; 508 char *strValue = NULL; 509 char *strComment = NULL; 510 char *linePtr = NULL; 511 psElemType vecType = 0; 512 psS32 status = 0; 513 psU32 lineCount = 0; 514 psF64 tempDbl = 0.0; 515 psS32 tempInt = 0.0; 516 psVector *tempVec = NULL; 517 FILE *fp = NULL; 518 psMetadataType mdType; 519 psMetadataFlags flags; 520 psBool addStatus; 521 522 // Check for nulls 1079 FILE* fp = NULL; 1080 char* line = NULL; 1081 char* linePtr = NULL; 1082 psArray* parseLevelInfoArray = NULL; 1083 psS32 lineCount = 0; 1084 psS32 nestingLevel = 0; 1085 p_psParseLevelInfo* topLevelInfo = NULL; 1086 1087 // Check for NULL file name 523 1088 PS_PTR_CHECK_NULL(fileName,NULL); 1089 1090 // Check for NULL nFail 1091 PS_PTR_CHECK_NULL(nFail,NULL); 1092 1093 // Attempt to open specified file 524 1094 if((fp=fopen(fileName, "r")) == NULL) { 525 1095 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_OPEN_FAILED, fileName); … … 532 1102 } 533 1103 1104 // Allocate array to store parse level information 1105 parseLevelInfoArray = psArrayAlloc(10); 1106 parseLevelInfoArray->n = 0; 1107 1108 // Set parse level info for the top level 1109 topLevelInfo = p_psParseLevelInfoAlloc(); 1110 topLevelInfo->metadata = psMemIncrRefCounter(md); 1111 parseLevelInfoArray = psArrayAdd(parseLevelInfoArray,1,topLevelInfo); 1112 psFree(topLevelInfo); 1113 534 1114 // Create reusable line for continuous read 535 1115 line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char)); … … 541 1121 linePtr = line; 542 1122 lineCount++; 543 CLEAR_TEMPS(); 544 545 // If line is not a comment or blank, then extract data 546 if(!ignoreLine(linePtr)) { 547 548 // Check for more than one '*' or '@' in a line 549 if(repeatedChars(linePtr, '@') > 1) { 550 (*nFail)++; 551 psError(PS_ERR_IO, true, 552 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '@', lineCount, fileName); 553 continue; 554 } else if(repeatedChars(linePtr, '*') > 1) { 555 (*nFail)++; 556 psError(PS_ERR_IO, true, 557 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '*', lineCount, fileName); 558 continue; 559 } else if(repeatedChars(linePtr, '~') > 0) { 560 (*nFail)++; 561 psError(PS_ERR_IO, true, 562 PS_ERRORTEXT_psMetadataIO_FILE_MULTIPLE_CHAR, '~', lineCount, fileName); 563 continue; 564 } 565 566 // Get metadata item name 567 strName = getToken(&linePtr, " ", &status); 568 if(strName==NULL || status) { 569 (*nFail)++; 570 status = 0; 571 psError(PS_ERR_IO, true, 572 PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "name", lineCount, fileName); 573 continue; 574 } 575 576 flags = (overwrite) ? PS_META_REPLACE : PS_META_DEFAULT; 577 578 // Get the metadata item type 579 strType = getToken(&linePtr, " ", &status); 580 if(strType==NULL) { 581 (*nFail)++; 582 status = 0; 583 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "type",lineCount, 584 fileName); 585 continue; 586 } else { 587 char* tempStrType = strType; 588 if(*strType == '*') { 589 flags = PS_META_DUPLICATE_OK; 590 tempStrType = strType+1; 591 } 592 593 if(!strncmp(tempStrType, "STR", 3)) { 594 mdType = PS_META_STR; 595 } else if(!strncmp(tempStrType, "BOOL", 4)) { 596 mdType = PS_META_BOOL; 597 } else if(!strncmp(tempStrType, "S32", 3)) { 598 mdType = PS_META_S32; 599 } else if(!strncmp(tempStrType, "F32", 3)) { 600 mdType = PS_META_F32; 601 } else if(!strncmp(tempStrType, "F64", 3)) { 602 mdType = PS_META_F64; 603 } else { 604 (*nFail)++; 605 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, strType, lineCount, 606 fileName); 607 continue; 608 } 609 } 610 611 if(*strName == '@') { 612 vecType = PS_META_PRIMITIVE_TYPE(mdType); 613 mdType = PS_META_VEC; 614 } 615 616 // Get the metadata item value if there is one. 617 strValue = getToken(&linePtr, "#", &status); 618 if(status) { 619 (*nFail)++; 620 status = 0; 621 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 622 fileName); 623 continue; 624 } 625 if(strValue==NULL) { 626 (*nFail)++; 627 status = 0; 628 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "value", lineCount, 629 fileName); 630 continue; 631 } 632 633 // Not all lines will have comments, so NULL is ok. 634 strComment = getToken(&linePtr,"~", &status); 635 if(status) { 636 (*nFail)++; 637 status = 0; 638 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_ELEMENT_NULL, "comment", lineCount, 639 fileName); 640 continue; 641 } 642 643 // Create and add metadata item to metadata and parse values 644 switch (mdType) { 645 case PS_META_STR: 646 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 647 mdType | flags, 648 strComment, strValue); 649 break; 650 case PS_META_VEC: 651 tempVec = parseVector(strValue, vecType, &status); 652 if(!status) { 653 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName+1, 654 mdType | flags, 655 strComment, tempVec); 656 } else { 657 status = 0; 658 (*nFail)++; 659 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 660 strType, lineCount, fileName); 661 continue; 662 } 663 psFree(tempVec); 664 break; 665 case PS_META_BOOL: 666 tempBool = parseBool(strValue, &status); 667 if(!status) { 668 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 669 mdType | flags, 670 strComment, tempBool); 671 } else { 672 status = 0; 673 (*nFail)++; 674 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 675 strType, lineCount, fileName); 676 continue; 677 } 678 break; 679 case PS_META_S32: 680 tempInt = (psS32)parseValue(strValue, &status); 681 if(!status) { 682 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 683 mdType | flags, 684 strComment, tempInt); 685 } else { 686 status = 0; 687 (*nFail)++; 688 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, 689 strType, lineCount, fileName); 690 continue; 691 } 692 break; 693 case PS_META_F32: 694 case PS_META_F64: 695 tempDbl = parseValue(strValue, &status); 696 if(!status) { 697 addStatus = psMetadataAdd(md, PS_LIST_TAIL, strName, 698 mdType | flags, 699 strComment, tempDbl); 700 } else { 701 status = 0; 702 (*nFail)++; 703 psError(PS_ERR_IO, true, 704 PS_ERRORTEXT_psMetadataIO_PARSE_FAILED, strValue, strName, strType, lineCount, 705 fileName); 706 continue; 707 } 708 break; 709 default: 710 (*nFail)++; 711 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_FILE_TYPE_INVALID, mdType, lineCount, 712 fileName); 713 continue; 714 } // switch 715 if (! addStatus) { 716 (*nFail)++; 717 psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineCount, 718 fileName); 719 } 720 721 } // if ignoreLine 722 } // while loop 723 1123 1124 if(!parseLine(&nestingLevel,parseLevelInfoArray,linePtr,lineCount,(char*)fileName,overwrite)) { 1125 (*nFail)++; 1126 } 1127 } 1128 1129 // Free parse array and line buffer 1130 psFree(parseLevelInfoArray); 724 1131 psFree(line); 725 1132 1133 // Check if any failed lined detected 1134 if( (*nFail) != 0) { 1135 psFree(md); 1136 md = NULL; 1137 } 726 1138 return md; 727 1139 } 1140 728 1141 729 1142 static void saxStartElement(void *ctx, const xmlChar *tagName, const xmlChar **atts) … … 750 1163 751 1164 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 752 psTagName = psStringCopy( (const char*)tagName);1165 psTagName = psStringCopy(tagName); 753 1166 754 1167 // Metadata containter for housing element attributes used by other SAX events … … 774 1187 775 1188 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 776 psAttName = psStringCopy( (const char*)attName);777 psAttValue = psStringCopy( (const char*)attValue);1189 psAttName = psStringCopy(attName); 1190 psAttValue = psStringCopy(attValue); 778 1191 psHashAdd(htAtts, psAttName, psAttValue); 779 1192 psFree(psAttName); … … 1082 1495 1083 1496 // Copy XML strings to psStrings to avoid libxml2/psLib memory corruption problems 1084 psEndTagName = psStringCopy( (const char*)tagName);1497 psEndTagName = psStringCopy(tagName); 1085 1498 1086 1499 // Compare start and end tag names -
trunk/psLib/src/xml/psXML.h
r3381 r3945 10 10 * @author Robert DeSonia, MHPCC 11 11 * 12 * @version $Revision: 1. 9$ $Name: not supported by cvs2svn $13 * @date $Date: 2005-0 3-07 20:58:50$12 * @version $Revision: 1.10 $ $Name: not supported by cvs2svn $ 13 * @date $Date: 2005-05-16 19:43:53 $ 14 14 * 15 15 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 21 21 /// @{ 22 22 23 typedef struct 24 { 25 psArray* nonUniqueKeyArray; 26 psArray* typeArray; 27 psArray* templateArray; 28 psMetadata* metadata; 29 char* name; 30 } 31 p_psParseLevelInfo; 32 33 p_psParseLevelInfo* p_psParseLevelInfoAlloc(void); 23 34 24 35 /** Print metadata item to file. -
trunk/psLib/test/collections/tst_psMetadataIO.c
r3779 r3945 4 4 * 5 5 * This test driver contains the following tests for psMetadata: 6 * Test A - Read config file with overwrite set true 7 * Test B - Read config file with overwrite set false 8 * Test C - Read config file without auto-allocation of metadata 9 * Test D - Attempt to use null fileName argument 10 * Test E - Attempt to open nonexistant file 11 * Test F - Free psMetadata 6 * Read config file with overwrite set true 7 * Read config file with overwrite set false 8 * Attempt to use null fileName argument 9 * Attempt to open nonexistant file 12 10 * 13 11 * @author Ross Harman, MHPCC 14 12 * @author Robert DeSonia, MHPCC 13 * @author Eric Van Alst, MHPCC 15 14 * 16 * @version $Revision: 1.1 4$ $Name: not supported by cvs2svn $17 * @date $Date: 2005-0 4-28 02:45:12$15 * @version $Revision: 1.15 $ $Name: not supported by cvs2svn $ 16 * @date $Date: 2005-05-16 19:41:40 $ 18 17 * 19 18 * Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii … … 25 24 #include "psTest.h" 26 25 27 static void printMetadataItem(psMetadataItem *metadataItem, char *spaces); 28 static void printMetadata(psMetadata *metadata); 29 static void printMetadataList(psList *metadataItemList, char* spaces); 30 static void printMetadataTable(psHash *mdTable); 31 32 static void printMetadata(psMetadata *metadata) 33 { 34 printf("Contents of metadata list:\n"); 35 printMetadataList(metadata->list, " "); 36 printf("\nContents of metadata table:\n"); 37 printMetadataTable(metadata->table); 38 } 39 40 static void printMetadataList(psList *metadataItemList, char* spaces) 41 { 42 psMetadataItem *entryChild = NULL; 43 26 static psS32 testMetadataParseConfig(void); 27 static psS32 testMetadataParseConfig1(void); 28 static psS32 testMetadataParseConfig2(void); 29 30 testDescription tests[] = { 31 {testMetadataParseConfig,000,"psMetadataParseConfig",0,false}, 32 {testMetadataParseConfig1,000,"psMetadataParseConfig",0,false}, 33 {testMetadataParseConfig2,000,"psMetadataParseConfig",0,false}, 34 {NULL} 35 }; 36 37 static void writeMetadataItem(psMetadataItem* metadataIem, char* indentStr); 38 static void writeMetadata(psMetadata* metadata, char* indentStr); 39 static void writeMetadataList(psList *metadataItemList, char* indentStr); 40 41 static psBool checkFailedLines(psS32 failedLines, psS32 expectedFailedLines, char* configFile); 42 static psBool checkNumberOfItems(psMetadata* md, psS32 expectedItems, char* configFile); 43 static psBool checkItemName(psMetadataItem* mdItem, char* expectedName, char* configFile); 44 static psBool checkItemType(psMetadataItem* mdItem, psS32 expectedType, char* configFile); 45 static psBool checkItemComment(psMetadataItem* mdItem, char* expectedComment, char* configFile); 46 47 #define ERROR_TOL 0.0001 48 49 const char testConfig3[] = "test3.config"; 50 const psS32 testConfig3Fails = 1; 51 52 const char testConfig2[] = "test2.config"; 53 const psS32 testConfig2Fails = 17; 54 55 // SDR-14 test config file #1 56 const char testConfig1[] = "test1.config"; 57 const psS32 testConfig1FailsOverwrite = 0; 58 const psS32 testConfig1Fails = 1; 59 const psS32 testConfig1Items = 25; 60 const char* testConfig1KeyOverwrite[] = 61 { 62 "Double","String","boolean","primes","comment", 63 "comment","comment","comment","comment","Float", 64 "boolean1","negprimes","vector1","vector2","vector3", 65 "vector4","vector5","vector6","vector7","vector8", 66 "CELL.00", "CELL.01","MYCELL","MYCELL","cell" 67 }; 68 const char* testConfig1CommentOverwrite[] = 69 { 70 "This is a comment","comment","The value of 'boolean' is 'true'","These are prime numbers", 71 "","","","","", 72 "This generates a warning, and, if 'overwrite' is 'false', is ignored","The value of 'boolean' is 'false'", 73 "","","","","", 74 "","","","", 75 "","","","A number","" 76 }; 77 const psMetadataType testConfig1TypeOverwrite[] = 78 { 79 PS_META_F64, PS_META_STR, PS_META_BOOL, PS_META_VEC, PS_META_STR, 80 PS_META_STR, PS_META_STR, PS_META_STR, PS_META_STR, PS_META_F64, 81 PS_META_BOOL, PS_META_VEC, PS_META_VEC, PS_META_VEC, PS_META_VEC, 82 PS_META_VEC, PS_META_VEC, PS_META_VEC, PS_META_VEC, PS_META_VEC, 83 PS_META_META, PS_META_META, PS_META_META, PS_META_S32, PS_META_META 84 }; 85 const psS32 testConfig1ValueS32Overwrite[] = 86 { 87 0, 0, 0, 0, 0, 88 0, 0, 0, 0, 0, 89 0, 0, 0, 0, 0, 90 0, 0, 0, 0, 0, 91 0, 0, 0, 123, 0 92 }; 93 const psF32 testConfig1ValueF32Overwrite[] = 94 { 95 0.0, 0.0, 0.0, 0.0, 0.0, 96 0.0, 0.0, 0.0, 0.0, 0.0, 97 0.0, 0.0, 0.0, 0.0, 0.0, 98 0.0, 0.0, 0.0, 0.0, 0.0, 99 0.0, 0.0, 0.0, 0.0, 0.0 100 }; 101 const psF64 testConfig1ValueF64Overwrite[] = 102 { 103 1.23456789, 0.0, 0.0, 0.0, 0.0, 104 0.0, 0.0, 0.0, 0.0, 1.23456, 105 0.0, 0.0, 0.0, 0.0, 0.0, 106 0.0, 0.0, 0.0, 0.0, 0.0, 107 0.0, 0.0, 0.0, 0.0, 0.0 108 }; 109 const psBool testConfig1ValueBoolOverwrite[] = 110 { 111 false, false, true, false, false, 112 false, false, false, false, false, 113 false, false, false, false, false, 114 false, false, false, false, false, 115 false, false, false, false, false 116 }; 117 const char* testConfig1ValueStrOverwrite[] = 118 { 119 "", "This is the string that forms the value","","","This", 120 "is","a","non-unique","key","", 121 "","","","","", 122 "","","","","", 123 "","","","","" 124 }; 125 const psS32 testConfig1ValueVecItemsU8 = 7; 126 const psElemType testConfig1ValueVecTypeU8 = PS_TYPE_U8; 127 const psU8 testConfig1ValueVecValueU8[] = 128 { 129 2, 3, 5, 7, 11, 13, 17 130 }; 131 const psS32 testConfig1ValueVecItemsS8 = 8; 132 const psElemType testConfig1ValueVecTypeS8 = PS_TYPE_S8; 133 const psS8 testConfig1ValueVecValueS8[] = 134 { 135 -2, -3, -5, -7, -11, -13, -17, -19 136 }; 137 const psS32 testConfig1ValueVecItemsU16 = 5; 138 const psElemType testConfig1ValueVecTypeU16 = PS_TYPE_U16; 139 const psU16 testConfig1ValueVecValueU16[] = 140 { 141 0, 1, 2, 4, 8 142 }; 143 const psS32 testConfig1ValueVecItemsU32 = 6; 144 const psElemType testConfig1ValueVecTypeU32 = PS_TYPE_U32; 145 const psU32 testConfig1ValueVecValueU32[] = 146 { 147 0, 8, 16, 32, 64, 128 148 }; 149 const psS32 testConfig1ValueVecItemsU64 = 3; 150 const psElemType testConfig1ValueVecTypeU64 = PS_TYPE_U64; 151 const psU64 testConfig1ValueVecValueU64[] = 152 { 153 0, 64, 256 154 }; 155 const psS32 testConfig1ValueVecItemsS16 = 5; 156 const psElemType testConfig1ValueVecTypeS16 = PS_TYPE_S16; 157 const psS16 testConfig1ValueVecValueS16[] = 158 { 159 -2, -1, 0, 1, 2 160 }; 161 const psS32 testConfig1ValueVecItemsS32 = 6; 162 const psElemType testConfig1ValueVecTypeS32 = PS_TYPE_S32; 163 const psS32 testConfig1ValueVecValueS32[] = 164 { 165 -4, -2, 0, 2, 4, 6 166 }; 167 const psS32 testConfig1ValueVecItemsS64 = 7; 168 const psElemType testConfig1ValueVecTypeS64 = PS_TYPE_S64; 169 const psS64 testConfig1ValueVecValueS64[] = 170 { 171 -16, -4, 0, 4, 16, 36, 64 172 }; 173 const psS32 testConfig1ValueVecItemsF32 = 4; 174 const psElemType testConfig1ValueVecTypeF32 = PS_TYPE_F32; 175 const psF32 testConfig1ValueVecValueF32[] = 176 { 177 -1.03, 1.04, -1.05, 1.06 178 }; 179 const psS32 testConfig1ValueVecItemsF64 = 5; 180 const psElemType testConfig1ValueVecTypeF64 = PS_TYPE_F64; 181 const psF64 testConfig1ValueVecValueF64[] = 182 { 183 -2.22, 2.21, -2.20, 2.19, -2.18 184 }; 185 const psS32 testConfig1ValueMetaItems1 = 3; 186 const char* testConfig1ValueMetaNames1[] = 187 { 188 "EXTNAME","BIASSEC","CHIP" 189 }; 190 const psMetadataType testConfig1ValueMetaTypes1[] = 191 { 192 PS_META_STR, PS_META_STR, PS_META_STR 193 }; 194 const char* testConfig1ValueMetaValue1[] = 195 { 196 "CCD00","BSEC-00","CHIP.00" 197 }; 198 const psS32 testConfig1ValueMetaItems2 = 3; 199 const char* testConfig1ValueMetaNames2[] = 200 { 201 "EXTNAME","BIASSEC","CHIP" 202 }; 203 const psMetadataType testConfig1ValueMetaTypes2[] = 204 { 205 PS_META_STR, PS_META_STR, PS_META_STR 206 }; 207 const char* testConfig1ValueMetaValue2[] = 208 { 209 "CCD01","BSEC-01","CHIP.00" 210 }; 211 const psS32 testConfig1ValueMetaItems3 = 4; 212 const char* testConfig1ValueMetaNames3[] = 213 { 214 "EXTNAME","BIASSEC","CHIP","NCELL" 215 }; 216 const psMetadataType testConfig1ValueMetaTypes3[] = 217 { 218 PS_META_STR, PS_META_STR, PS_META_STR, PS_META_S32 219 }; 220 const char* testConfig1ValueMetaValueStr3[] = 221 { 222 "CCD00","BSEC-00","CHIP.00","" 223 }; 224 const psS32 testConfig1ValueMetaValueS323[] = 225 { 226 0, 0, 0, 24 227 }; 228 229 static void writeMetadata(psMetadata* metadata, char* indentStr) 230 { 231 writeMetadataList(metadata->list, indentStr); 232 } 233 234 static void writeMetadataList(psList* metadataItemList, char* indentStr) 235 { 236 psMetadataItem* entryChild = NULL; 237 psMetadataItem* searchChild = NULL; 238 psArray* nonUniqueKeyArray = NULL; 239 psBool keyFound = false; 240 char* tempKey = NULL; 241 242 // Allocate iterator for moving through metadata list 44 243 psListIterator* iter = psListIteratorAlloc(metadataItemList, PS_LIST_HEAD, true); 45 46 while ( (entryChild=psListGetAndIncrement(iter)) != NULL) { 47 printMetadataItem(entryChild, spaces); 244 psListIterator* searchIter = psListIteratorAlloc(metadataItemList, PS_LIST_HEAD, true); 245 246 // Allocate array for nonUnique key names 247 nonUniqueKeyArray = psArrayAlloc(10); 248 nonUniqueKeyArray->n = 0; 249 250 251 // Loop through all items in the list 252 while ( (entryChild = psListGetAndIncrement(iter)) != NULL) { 253 // Search list for another entry with same key name 254 // Check if last entry 255 if(iter->index != metadataItemList->size) { 256 // Set search iterator to index 257 if(!psListIteratorSet(searchIter,iter->index) ) { 258 psError(PS_ERR_UNKNOWN,true,"Error searching list for multiple keys"); 259 break; 260 } 261 keyFound = false; 262 while ( (searchChild = psListGetAndIncrement(searchIter)) != NULL) { 263 if(strcmp(entryChild->name,searchChild->name) == 0) { 264 // Search nonUnique key array 265 for(psS32 i = 0; i < nonUniqueKeyArray->n; i++) { 266 if(strcmp(entryChild->name,nonUniqueKeyArray->data[i]) == 0) { 267 keyFound = true; 268 } 269 } 270 if(!keyFound) { 271 // Add key to non-unique array 272 tempKey = psStringCopy(entryChild->name); 273 nonUniqueKeyArray = psArrayAdd(nonUniqueKeyArray,1,tempKey); 274 psFree(tempKey); 275 276 // Print MULTI line 277 printf("%-25s MULTI\n",entryChild->name); 278 279 // Break out of loop 280 break; 281 } 282 } 283 } 284 } 285 writeMetadataItem(entryChild,indentStr); 48 286 } 49 287 50 288 psFree(iter); 51 } 52 53 static void printMetadataTable(psHash *mdTable) 54 { 55 psS32 i; 56 psHashBucket* ptr = NULL; 57 for(i=0; i<mdTable->nbucket; i++) { 58 ptr = mdTable->buckets[i]; 59 while (ptr != NULL) { 60 printMetadataItem(ptr->data, " "); 61 ptr = ptr->next; 62 } 63 } 64 } 65 66 static void printMetadataItem(psMetadataItem *metadataItem, char *spaces) 67 { 68 char* vecStr; 69 70 printf("%sKey Name: %8s ", spaces, metadataItem->name); 71 printf("Key mdType: 0x%08x ", metadataItem->type); 72 73 switch (metadataItem->type) { 74 case PS_META_MULTI: 75 printf("Key Value: %17c", ' '); 289 psFree(searchIter); 290 psFree(nonUniqueKeyArray); 291 } 292 293 char* vectorToConfigString(psVector* vector) 294 { 295 psS32 maxLength = 256; 296 297 char* str = psAlloc(sizeof(char)*maxLength+1); 298 299 if (vector == NULL) { 300 snprintf(str,maxLength, "NULL"); 301 return str; 302 } 303 304 int size = vector->n; 305 306 if (size == 0) { 307 snprintf(str,maxLength, " "); 308 return str; 309 } 310 311 char* tempStr = psAlloc(sizeof(char)*maxLength+1); 312 *str = '\0'; 313 bool full = false; 314 315 #define APPEND_ELEMENTS_CASE(TYPE, NATIVE_TYPE, FORMAT) \ 316 case PS_TYPE_##TYPE: \ 317 strcat(str,#TYPE); \ 318 for(psS32 i = 0; i < (strlen(str)-6); i++) { \ 319 strcat(str," "); \ 320 } \ 321 for (lcv=0; lcv < size && ! full; lcv++) { \ 322 snprintf(tempStr, maxLength, "%s" FORMAT, prefix, (NATIVE_TYPE) (vector->data.TYPE[lcv])); \ 323 strncat(str,tempStr,maxLength); \ 324 full = (strlen(str) > maxLength-2); \ 325 prefix = ","; \ 326 } \ 327 break; 328 329 int lcv; 330 char* prefix = " "; 331 switch(vector->type.type) { 332 APPEND_ELEMENTS_CASE(S8,char,"%hd") 333 APPEND_ELEMENTS_CASE(S16,short int,"%hd") 334 APPEND_ELEMENTS_CASE(S32,int,"%d") 335 APPEND_ELEMENTS_CASE(S64,long,"%ld") 336 APPEND_ELEMENTS_CASE(U8,unsigned char,"%hu") 337 APPEND_ELEMENTS_CASE(U16,unsigned short,"%hu") 338 APPEND_ELEMENTS_CASE(U32,unsigned int, "%u") 339 APPEND_ELEMENTS_CASE(U64,unsigned long,"%lu") 340 APPEND_ELEMENTS_CASE(F32,double,"%g") 341 APPEND_ELEMENTS_CASE(F64,double,"%g") 342 default: 343 snprintf(str,maxLength,"INVALID TYPE"); 76 344 break; 345 } 346 347 psFree(tempStr); 348 349 return str; 350 } 351 352 353 static void writeMetadataItem(psMetadataItem *metadataItem, char* indentStr) 354 { 355 char* vecStr; 356 357 switch(metadataItem->type) { 77 358 case PS_META_BOOL: 78 printf(" Key Value: %15d ",metadataItem->data.B);359 printf("%s%-25s BOOL %40d",indentStr,metadataItem->name,metadataItem->data.B); 79 360 break; 80 361 case PS_META_S32: 81 printf(" Key Value: %15d ",metadataItem->data.S32);362 printf("%s%-25s S32 %40d",indentStr,metadataItem->name,metadataItem->data.S32); 82 363 break; 83 364 case PS_META_F32: 84 printf(" Key Value: %15.3f ",metadataItem->data.F32);365 printf("%s%-25s F32 %40f",indentStr,metadataItem->name,metadataItem->data.F32); 85 366 break; 86 367 case PS_META_F64: 87 printf(" Key Value: %15.3f ",metadataItem->data.F64);368 printf("%s%-25s F64 %40lf",indentStr,metadataItem->name,metadataItem->data.F64); 88 369 break; 89 370 case PS_META_VEC: 90 vecStr = (char*) psVectorToString((psVector*)metadataItem->data.V, 15);91 printf(" Key Value: %15s ",vecStr);371 vecStr = (char*)vectorToConfigString((psVector*)metadataItem->data.V); 372 printf("%s@%-24s %s",indentStr,metadataItem->name,vecStr); 92 373 psFree(vecStr); 93 374 break; 94 375 case PS_META_STR: 95 printf("Key Value: %15s ", (char*)metadataItem->data.V); 376 printf("%s%-25s STR %40s",indentStr,metadataItem->name,(char*)metadataItem->data.V); 377 break; 378 case PS_META_META: 379 printf("%s%-25s METADATA\n",indentStr,metadataItem->name); 380 writeMetadata((psMetadata*)metadataItem->data.md," "); 96 381 break; 97 382 default: 98 printf("Bad type: 0x%08x ", metadataItem->type); 99 } 100 printf("Key Comment: %s\n", metadataItem->comment); 101 102 if(metadataItem->data.V && metadataItem->type==PS_META_MULTI) { 103 printMetadataList(metadataItem->data.V, " "); 104 } 105 } 106 383 printf("#%s%-24s BAD TYPE=%d",indentStr,metadataItem->name,metadataItem->type); 384 break; 385 } 386 if(strlen(metadataItem->comment) > 0) { 387 printf(" # %-20s\n",metadataItem->comment); 388 } else { 389 printf("\n"); 390 } 391 } 392 393 static psBool checkFailedLines(psS32 failedLines, psS32 expectedFailedLines, char* configFile) 394 { 395 psBool returnValue = true; 396 397 // Verify the expected number of failed lines 398 if(failedLines != expectedFailedLines) { 399 psError(PS_ERR_UNKNOWN,true,"File: %s : Number of failed lines = %d not as expected %d", 400 configFile,failedLines,expectedFailedLines); 401 returnValue = false; 402 } 403 return returnValue; 404 } 405 406 static psBool checkNumberOfItems(psMetadata* md, psS32 expectedItems, char* configFile) 407 { 408 psBool returnValue = true; 409 410 // Verify the number of items in metadata 411 if(md->list->size != expectedItems) { 412 psError(PS_ERR_UNKNOWN,true,"File: %s : Number of items = %d not as expected %d", 413 configFile,md->list->size, expectedItems); 414 returnValue = false; 415 } 416 return returnValue; 417 } 418 419 static psBool checkItemName(psMetadataItem* mdItem, char* expectedName, char* configFile) 420 { 421 psBool returnValue = true; 422 423 // Compare key names 424 if(strcmp(mdItem->name,expectedName) != 0) { 425 psError(PS_ERR_UNKNOWN,true,"File: %s : Key name %s not as expected %s", 426 configFile,mdItem->name,expectedName); 427 returnValue = false; 428 } 429 430 return returnValue; 431 } 432 433 static psBool checkItemType(psMetadataItem* mdItem, psS32 expectedType, char* configFile) 434 { 435 psBool returnValue = true; 436 437 // Compare types 438 if(mdItem->type != expectedType) { 439 psError(PS_ERR_UNKNOWN,true,"File: %s : Type %d not as expected %d", 440 configFile,mdItem->type,expectedType); 441 returnValue = false; 442 } 443 return returnValue; 444 } 445 446 static psBool checkItemComment(psMetadataItem* mdItem, char* expectedComment, char* configFile) 447 { 448 psBool returnValue = true; 449 450 // Compare comments 451 if(strcmp(mdItem->comment,expectedComment) != 0) { 452 psError(PS_ERR_UNKNOWN,true,"File: %s : Comment %s not as expected %s", 453 configFile,mdItem->comment,expectedComment); 454 returnValue = false; 455 } 456 return returnValue; 457 } 107 458 108 459 psS32 main(psS32 argc, char* argv[]) 109 460 { 110 // Test A - Read config file with overwrite set true 111 printPositiveTestHeader(stdout, "psMetadata", "Test A - Read config file with overwrite set true"); 112 psMetadata *metadata1 = NULL; 113 psU32 failedLines1 = 0; 114 metadata1 = psMetadataParseConfig(metadata1, &failedLines1, "test.config", true); 115 printf("Failed lines: %d Expected: 6\n", failedLines1); 116 printMetadata(metadata1); 117 printFooter(stdout, "psMetadata", "Test A - Read config file with overwrite set true", true); 118 119 120 // Test B - Read config file with overwrite set false 121 printPositiveTestHeader(stdout, "psMetadata", "Test B - Read config file with overwrite set false"); 122 psMetadata *metadata2 = NULL; 123 psU32 failedLines2 = 0; 124 metadata2 = psMetadataParseConfig(metadata2, &failedLines2, "test.config", false); 125 printf("Failed lines: %d Expected: 7 ", failedLines2); 126 printMetadata(metadata2); 127 printFooter(stdout, "psMetadata", "Test B - Read config file with overwrite set false", true); 128 129 130 // Test C - Read config file without auto-allocation of metadata 131 printPositiveTestHeader(stdout, "psMetadata", "Test C - Read config file without auto-allocation of metadata"); 132 psMetadata *metadata3 = psMetadataAlloc(); 133 psU32 failedLines3 = 0; 134 metadata3 = psMetadataParseConfig(metadata3, &failedLines3, "test.config", true); 135 printf("Failed lines: %d Expected: 6 ", failedLines3); 136 printMetadata(metadata3); 137 printFooter(stdout, "psMetadata", "Test C - Read config file without auto-allocation of metadata", true); 138 139 140 // Test D - Attempt to use null fileName argument 141 printNegativeTestHeader(stdout,"psMetadataIO", "Test D - Attempt to use null fileName argument", 142 "Null failedLines not allowed", 0); 143 psMetadataParseConfig(metadata1, &failedLines1, NULL, true); 144 printFooter(stdout, "psMetadata", "Test D - Attempt to use null fileName argument", true); 145 146 147 // Test E - Attempt to open nonexistant file 148 printNegativeTestHeader(stdout,"psMetadataIO", "Test E - Attempt to open nonexistant file", 149 "Error opening file", 0); 150 psMetadataParseConfig(metadata1, &failedLines1, "abcedfg", true); 151 printFooter(stdout, "psMetadata", "Test E - Attempt to open nonexistant file", true); 152 153 154 // Test F - Free psMetadata 155 printPositiveTestHeader(stdout, "psMetadata", "Test F - Free psMetadata"); 461 psLogSetLevel(PS_LOG_INFO); 462 463 if( !runTestSuite(stderr,"psMetadataParseConfig",tests,argc,argv)) { 464 return 1; 465 } 466 467 return 0; 468 } 469 470 psS32 testMetadataParseConfig(void) 471 { 472 psMetadata* metadata1 = NULL; 473 psMetadataItem* entryChild = NULL; 474 psS32 failedLines = 0; 475 psListIterator* iter = NULL; 476 psListIterator* mdIter = NULL; 477 psMetadataItem* mdChild = NULL; 478 psS32 metaCounter = 0; 479 psS32 mdCounter = 0; 480 481 // Read config file test1.config with overwrite set true 482 metadata1 = psMetadataParseConfig(metadata1,&failedLines,testConfig1,true); 483 // Verify the expected number of failed lines 484 if(!checkFailedLines(failedLines,testConfig1FailsOverwrite,(char*)testConfig1)) { 485 return 1; 486 } 487 // Verify the number of items in metadata 488 if(!checkNumberOfItems(metadata1,testConfig1Items,(char*)testConfig1)) { 489 return 2; 490 } 491 // Verify metadata item quads 492 iter = psListIteratorAlloc(metadata1->list, PS_LIST_HEAD, true); 493 for(psS32 i = 0; i < testConfig1Items; i++) { 494 // Get list item 495 entryChild = psListGetAndIncrement(iter); 496 497 // Verify end of list not reached prematurely 498 if(entryChild == NULL) { 499 psError(PS_ERR_UNKNOWN,true,"End of list encountered at %d not as expected %d", 500 i,testConfig1Items); 501 return i*10+1; 502 } 503 // Verify name 504 if(!checkItemName(entryChild,(char*)testConfig1KeyOverwrite[i],(char*)testConfig1)) { 505 return i*10+2; 506 } 507 // Verify type 508 if(!checkItemType(entryChild,testConfig1TypeOverwrite[i],(char*)testConfig1)) { 509 return i*10+3; 510 } 511 // Verify comment 512 if(!checkItemComment(entryChild,(char*)testConfig1CommentOverwrite[i],(char*)testConfig1)) { 513 return i*10+4; 514 } 515 // Compare values 516 switch(entryChild->type) { 517 case PS_META_S32: 518 if(entryChild->data.S32 != testConfig1ValueS32Overwrite[i]) { 519 psError(PS_ERR_UNKNOWN,true,"File: %s : Value %d not as expected %d", 520 testConfig1,entryChild->data.S32, testConfig1ValueS32Overwrite[i]); 521 return i*10+5; 522 } 523 break; 524 case PS_META_F32: 525 if(fabs(entryChild->data.F32 - testConfig1ValueF32Overwrite[i]) > ERROR_TOL) { 526 psError(PS_ERR_UNKNOWN,true,"File: %s : Value %f not as expected %f", 527 testConfig1,entryChild->data.F32, testConfig1ValueF32Overwrite[i]); 528 return i*10+5; 529 } 530 break; 531 case PS_META_F64: 532 if(fabs(entryChild->data.F64 - testConfig1ValueF64Overwrite[i]) > ERROR_TOL) { 533 psError(PS_ERR_UNKNOWN,true,"File: %s : Value %lf not as expected %lf", 534 testConfig1,entryChild->data.F64, testConfig1ValueF64Overwrite[i]); 535 return i*10+5; 536 } 537 break; 538 case PS_META_BOOL: 539 if(entryChild->data.B != testConfig1ValueBoolOverwrite[i]) { 540 psError(PS_ERR_UNKNOWN,true,"File: %s : Value %d not as expected %d", 541 testConfig1,entryChild->data.B,testConfig1ValueBoolOverwrite[i]); 542 return i*10+5; 543 } 544 break; 545 case PS_META_STR: 546 if(strcmp(entryChild->data.V,testConfig1ValueStrOverwrite[i]) != 0) { 547 psError(PS_ERR_UNKNOWN,true,"File: %s : Value %s not as expected %s", 548 testConfig1,entryChild->data.V,testConfig1ValueStrOverwrite[i]); 549 return i*10+5; 550 } 551 break; 552 case PS_META_VEC: 553 // Verify the correct number of entries 554 switch(((psVector*)(entryChild->data.V))->type.type) { 555 case PS_TYPE_U8: 556 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsU8) { 557 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 558 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsU8); 559 return i*10+5; 560 } 561 // Verify the correct type 562 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeU8) { 563 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 564 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeU8); 565 return i*10+5; 566 } 567 // Verify the values in vector 568 for(psS32 j = 0; j < testConfig1ValueVecItemsU8; j++) { 569 if(((psVector*)entryChild->data.V)->data.U8[j] != testConfig1ValueVecValueU8[j]) { 570 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %d not as expected %d", 571 testConfig1,j,((psVector*)entryChild->data.V)->data.U8[j], 572 testConfig1ValueVecValueU8[j]); 573 return i*10+5*j; 574 } 575 } 576 break; 577 case PS_TYPE_U16: 578 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsU16) { 579 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 580 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsU16); 581 return i*10+5; 582 } 583 // Verify the correct type 584 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeU16) { 585 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 586 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeU16); 587 return i*10+5; 588 } 589 // Verify the values in vector 590 for(psS32 j = 0; j < testConfig1ValueVecItemsU16; j++) { 591 if(((psVector*)entryChild->data.V)->data.U16[j] != testConfig1ValueVecValueU16[j]) { 592 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %d not as expected %d", 593 testConfig1,j,((psVector*)entryChild->data.V)->data.U16[j], 594 testConfig1ValueVecValueU16[j]); 595 return i*10+5*j; 596 } 597 } 598 break; 599 case PS_TYPE_U32: 600 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsU32) { 601 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 602 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsU32); 603 return i*10+5; 604 } 605 // Verify the correct type 606 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeU32) { 607 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 608 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeU32); 609 return i*10+5; 610 } 611 // Verify the values in vector 612 for(psS32 j = 0; j < testConfig1ValueVecItemsU32; j++) { 613 if(((psVector*)entryChild->data.V)->data.U32[j] != testConfig1ValueVecValueU32[j]) { 614 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %d not as expected %d", 615 testConfig1,j,((psVector*)entryChild->data.V)->data.U32[j], 616 testConfig1ValueVecValueU32[j]); 617 return i*10+5*j; 618 } 619 } 620 break; 621 case PS_TYPE_U64: 622 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsU64) { 623 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 624 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsU64); 625 return i*10+5; 626 } 627 // Verify the correct type 628 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeU64) { 629 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 630 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeU64); 631 return i*10+5; 632 } 633 // Verify the values in vector 634 for(psS32 j = 0; j < testConfig1ValueVecItemsU64; j++) { 635 if(((psVector*)entryChild->data.V)->data.U64[j] != testConfig1ValueVecValueU64[j]) { 636 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %ld not as expected %ld", 637 testConfig1,j,((psVector*)entryChild->data.V)->data.U64[j], 638 testConfig1ValueVecValueU64[j]); 639 return i*10+5*j; 640 } 641 } 642 break; 643 case PS_TYPE_S8: 644 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsS8) { 645 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 646 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsS8); 647 return i*10+5; 648 } 649 // Verify the correct type 650 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeS8) { 651 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 652 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeS8); 653 return i*10+5; 654 } 655 // Verify the values in vector 656 for(psS32 j = 0; j < testConfig1ValueVecItemsS8; j++) { 657 if(((psVector*)entryChild->data.V)->data.S8[j] != testConfig1ValueVecValueS8[j]) { 658 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %d not as expected %d", 659 testConfig1,j,((psVector*)entryChild->data.V)->data.S8[j], 660 testConfig1ValueVecValueS8[j]); 661 return i*10+5*j; 662 } 663 } 664 break; 665 case PS_TYPE_S16: 666 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsS16) { 667 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 668 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsS16); 669 return i*10+5; 670 } 671 // Verify the correct type 672 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeS16) { 673 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 674 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeS16); 675 return i*10+5; 676 } 677 // Verify the values in vector 678 for(psS32 j = 0; j < testConfig1ValueVecItemsS16; j++) { 679 if(((psVector*)entryChild->data.V)->data.S16[j] != testConfig1ValueVecValueS16[j]) { 680 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %d not as expected %d", 681 testConfig1,j,((psVector*)entryChild->data.V)->data.S16[j], 682 testConfig1ValueVecValueS16[j]); 683 return i*10+5*j; 684 } 685 } 686 break; 687 case PS_TYPE_S32: 688 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsS32) { 689 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 690 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsS32); 691 return i*10+5; 692 } 693 // Verify the correct type 694 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeS32) { 695 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 696 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeS32); 697 return i*10+5; 698 } 699 // Verify the values in vector 700 for(psS32 j = 0; j < testConfig1ValueVecItemsS32; j++) { 701 if(((psVector*)entryChild->data.V)->data.S32[j] != testConfig1ValueVecValueS32[j]) { 702 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %d not as expected %d", 703 testConfig1,j,((psVector*)entryChild->data.V)->data.S32[j], 704 testConfig1ValueVecValueS32[j]); 705 return i*10+5*j; 706 } 707 } 708 break; 709 case PS_TYPE_S64: 710 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsS64) { 711 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 712 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsS64); 713 return i*10+5; 714 } 715 // Verify the correct type 716 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeS64) { 717 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 718 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeS64); 719 return i*10+5; 720 } 721 // Verify the values in vector 722 for(psS32 j = 0; j < testConfig1ValueVecItemsS64; j++) { 723 if(((psVector*)entryChild->data.V)->data.S64[j] != testConfig1ValueVecValueS64[j]) { 724 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %ld not as expected %ld", 725 testConfig1,j,((psVector*)entryChild->data.V)->data.S64[j], 726 testConfig1ValueVecValueS64[j]); 727 return i*10+5*j; 728 } 729 } 730 break; 731 case PS_TYPE_F32: 732 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsF32) { 733 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 734 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsF32); 735 return i*10+5; 736 } 737 // Verify the correct type 738 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeF32) { 739 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 740 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeF32); 741 return i*10+5; 742 } 743 // Verify the values in vector 744 for(psS32 j = 0; j < testConfig1ValueVecItemsF32; j++) { 745 if(fabs(((psVector*)entryChild->data.V)->data.F32[j]-testConfig1ValueVecValueF32[j]) 746 > ERROR_TOL) { 747 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %f not as expected %f", 748 testConfig1,j,((psVector*)entryChild->data.V)->data.F32[j], 749 testConfig1ValueVecValueF32[j]); 750 return i*10+5*j; 751 } 752 } 753 break; 754 case PS_TYPE_F64: 755 if(((psVector*)(entryChild->data.V))->n != testConfig1ValueVecItemsF64) { 756 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector entries %d not as expected %d", 757 testConfig1,((psVector*)(entryChild->data.V))->n,testConfig1ValueVecItemsF64); 758 return i*10+5; 759 } 760 // Verify the correct type 761 if(((psVector*)(entryChild->data.V))->type.type != testConfig1ValueVecTypeF64) { 762 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector type %d not as expected %s", 763 testConfig1,((psVector*)entryChild->data.V)->type.type,testConfig1ValueVecTypeF64); 764 return i*10+5; 765 } 766 // Verify the values in vector 767 for(psS32 j = 0; j < testConfig1ValueVecItemsF64; j++) { 768 if(fabs(((psVector*)entryChild->data.V)->data.F64[j]-testConfig1ValueVecValueF64[j]) 769 > ERROR_TOL) { 770 psError(PS_ERR_UNKNOWN,true,"File: %s : Vector data[%d] = %lf not as expected %lf", 771 testConfig1,j,((psVector*)entryChild->data.V)->data.F64[j], 772 testConfig1ValueVecValueF64[j]); 773 return i*10+5*j; 774 } 775 } 776 break; 777 default: 778 break; 779 } 780 break; 781 case PS_META_META: 782 if(metaCounter == 0) { 783 // Check if number of items is as expected 784 if(entryChild->data.md->list->size != testConfig1ValueMetaItems1) { 785 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 1 items %d not as expected %d", 786 testConfig1,entryChild->data.md->list->size,testConfig1ValueMetaItems1); 787 return i*10+6; 788 } 789 // Loop through metadata items 790 mdIter = psListIteratorAlloc(entryChild->data.md->list, PS_LIST_HEAD, true); 791 mdCounter = 0; 792 while ( (mdChild = psListGetAndIncrement(mdIter)) != NULL) { 793 if(strcmp(mdChild->name,testConfig1ValueMetaNames1[mdCounter]) != 0) { 794 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 1 name[%d] %s not as expected %s", 795 testConfig1,mdCounter,mdChild->name,testConfig1ValueMetaNames1[mdCounter]); 796 return i*10+6*mdCounter; 797 } 798 if(mdChild->type != testConfig1ValueMetaTypes1[mdCounter]) { 799 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 1 type[%d] %d not as expected %d", 800 testConfig1,mdCounter,mdChild->type,testConfig1ValueMetaTypes1[mdCounter]); 801 return i*10+6*mdCounter; 802 } 803 if(strcmp((char*)mdChild->data.V,testConfig1ValueMetaValue1[mdCounter]) != 0) { 804 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 1 value[%d] %s not as expected %s", 805 testConfig1,mdCounter,(char*)mdChild->data.V,testConfig1ValueMetaValue1[mdCounter]); 806 return i*10+6*mdCounter; 807 } 808 mdCounter++; 809 } 810 psFree(mdIter); 811 } else if(metaCounter == 1) { 812 // Check if number of items is as expected 813 if(entryChild->data.md->list->size != testConfig1ValueMetaItems2) { 814 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 2 items %d not as expected %d", 815 testConfig1,entryChild->data.md->list->size,testConfig1ValueMetaItems2); 816 return i*10+6; 817 } 818 // Loop through metadata items 819 mdIter = psListIteratorAlloc(entryChild->data.md->list, PS_LIST_HEAD, true); 820 mdCounter = 0; 821 while ( (mdChild = psListGetAndIncrement(mdIter)) != NULL) { 822 if(strcmp(mdChild->name,testConfig1ValueMetaNames2[mdCounter]) != 0) { 823 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 2 name[%d] %s not as expected %s", 824 testConfig1,mdCounter,mdChild->name,testConfig1ValueMetaNames2[mdCounter]); 825 return i*10+6*mdCounter; 826 } 827 if(mdChild->type != testConfig1ValueMetaTypes2[mdCounter]) { 828 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 2 type[%d] %d not as expected %d", 829 testConfig1,mdCounter,mdChild->type,testConfig1ValueMetaTypes2[mdCounter]); 830 return i*10+6*mdCounter; 831 } 832 if(strcmp((char*)mdChild->data.V,testConfig1ValueMetaValue2[mdCounter]) != 0) { 833 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 2 value[%d] %s not as expected %s", 834 testConfig1,mdCounter,(char*)mdChild->data.V,testConfig1ValueMetaValue2[mdCounter]); 835 return i*10+6*mdCounter; 836 } 837 mdCounter++; 838 } 839 psFree(mdIter); 840 } else if(metaCounter == 2) { 841 // Check if number of items is as expected 842 if(entryChild->data.md->list->size != testConfig1ValueMetaItems3) { 843 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 3 items %d not as expected %d", 844 testConfig1,entryChild->data.md->list->size,testConfig1ValueMetaItems3); 845 return i*10+6; 846 } 847 // Loop through metadata items 848 mdIter = psListIteratorAlloc(entryChild->data.md->list, PS_LIST_HEAD, true); 849 mdCounter = 0; 850 while ( (mdChild = psListGetAndIncrement(mdIter)) != NULL) { 851 if(strcmp(mdChild->name,testConfig1ValueMetaNames3[mdCounter]) != 0) { 852 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 3 name[%d] %s not as expected %s", 853 testConfig1,mdCounter,mdChild->name,testConfig1ValueMetaNames3[mdCounter]); 854 return i*10+6*mdCounter; 855 } 856 if(mdChild->type != testConfig1ValueMetaTypes3[mdCounter]) { 857 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 3 type[%d] %d not as expected %d", 858 testConfig1,mdCounter,mdChild->type,testConfig1ValueMetaTypes3[mdCounter]); 859 return i*10+6*mdCounter; 860 } 861 switch(mdChild->type) { 862 case PS_META_STR: 863 if(strcmp((char*)mdChild->data.V,testConfig1ValueMetaValueStr3[mdCounter]) != 0) { 864 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 3 value[%d] %s not as expected %s", 865 testConfig1,mdCounter,(char*)mdChild->data.V, 866 testConfig1ValueMetaValueStr3[mdCounter]); 867 return i*10+6*mdCounter; 868 } 869 break; 870 case PS_META_S32: 871 if(mdChild->data.S32 != testConfig1ValueMetaValueS323[mdCounter]) { 872 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 3 value[%d] %d not as expected %d", 873 testConfig1,mdCounter,mdChild->data.S32, 874 testConfig1ValueMetaValueS323[mdCounter]); 875 return i*10+6*mdCounter; 876 } 877 break; 878 default: 879 psError(PS_ERR_UNKNOWN,true,"File: %s : Metadata 3 value[%d] unknown type", 880 testConfig1,mdCounter); 881 return i*10+6*mdCounter; 882 break; 883 } 884 mdCounter++; 885 } 886 psFree(mdIter); 887 } 888 metaCounter++; 889 break; 890 default: 891 psError(PS_ERR_UNKNOWN,true,"Unexpected type %d encountered",entryChild->type); 892 return i*10+5; 893 break; 894 } 895 } 896 897 writeMetadata(metadata1,""); 898 156 899 psFree(metadata1); 157 psFree(metadata2);158 psFree(metadata3);159 if(psMemCheckLeaks(0, NULL, stdout,false)) {160 psError(PS_ERR_UNKNOWN,true,"Memory leak detected");161 return 10;162 }163 psMemCheckCorruption(0);164 psS32 nBad = psMemCheckCorruption(0);165 if(nBad) {166 printf("ERROR: Found %d bad memory blocks\n", nBad);167 }168 printFooter(stdout, "psMetadata", "Test F - Free psMetadata", true);169 170 900 171 901 return 0; 172 902 } 903 904 psS32 testMetadataParseConfig1(void) 905 { 906 psMetadata* metadata1 = NULL; 907 psS32 failedLines = 0; 908 909 // Read config file test2.config with overwrite set true 910 // This file contains parse errors 911 psLogMsg(__func__,PS_LOG_INFO,"Following should generate parse error message"); 912 metadata1 = psMetadataParseConfig(metadata1,&failedLines,testConfig2,true); 913 // Verify the expected number of failed lines 914 if(!checkFailedLines(failedLines,testConfig2Fails,(char*)testConfig2)) { 915 return 1; 916 } 917 // Verify return value is null 918 if(metadata1 != NULL) { 919 psError(PS_ERR_UNKNOWN,true,"Expected a NULL return for failed parse"); 920 return 2; 921 } 922 923 // Attempt parse a non-existant file 924 psLogMsg(__func__,PS_LOG_INFO,"Following should generate error message"); 925 metadata1 = psMetadataParseConfig(metadata1,&failedLines,"ab.config",true); 926 if(metadata1 != NULL) { 927 psError(PS_ERR_UNKNOWN,true,"Expected a NULL return for non-existant file"); 928 return 3; 929 } 930 931 // Attempt parse with NULL failed lines ptr 932 psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message for NULL failed lines arg"); 933 metadata1 = psMetadataParseConfig(metadata1,NULL,testConfig2,true); 934 if(metadata1 != NULL) { 935 psError(PS_ERR_UNKNOWN,true,"Expected a NULL return for NULL failed lines argument"); 936 return 4; 937 } 938 939 // Attempt parse with NULL file name 940 psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error message for NULL file name arg"); 941 metadata1 = psMetadataParseConfig(metadata1,&failedLines,NULL,true); 942 if(metadata1 != NULL) { 943 psError(PS_ERR_UNKNOWN,true,"Expected a NULL return for NULL filename argument"); 944 return 5; 945 } 946 947 psFree(metadata1); 948 949 return 0; 950 } 951 952 psS32 testMetadataParseConfig2(void) 953 { 954 psMetadata* metadata1 = NULL; 955 psS32 failedLines = 0; 956 957 // Read config file test1.config with overwrite set false 958 psLogMsg(__func__,PS_LOG_INFO,"Following should generate an error of duplicate key names"); 959 metadata1 = psMetadataParseConfig(metadata1,&failedLines,testConfig3,false); 960 // Verify the expected number of failed lines 961 if(!checkFailedLines(failedLines,testConfig3Fails,(char*)testConfig3)) { 962 return 1; 963 } 964 if(metadata1 != NULL) { 965 psError(PS_ERR_UNKNOWN,true,"Expected a NULL return for failed due to overwrite false"); 966 return 2; 967 } 968 psFree(metadata1); 969 970 return 0; 971 } 972 -
trunk/psLib/test/collections/verified/tst_psMetadataIO.stderr
r3690 r3945 1 /***************************** TESTPOINT ******************************************\ 2 * TestFile: tst_psMetadataIO.c * 3 * TestPoint: psMetadataParseConfig{psMetadataParseConfig} * 4 * TestType: Positive * 5 \**********************************************************************************/ 6 7 <DATE><TIME>|<HOST>|W|psMetadataAddItem 8 Metadata item Float has been replaced 9 10 ---> TESTPOINT PASSED (psMetadataParseConfig{psMetadataParseConfig} | tst_psMetadataIO.c) 11 12 /***************************** TESTPOINT ******************************************\ 13 * TestFile: tst_psMetadataIO.c * 14 * TestPoint: psMetadataParseConfig{psMetadataParseConfig} * 15 * TestType: Positive * 16 \**********************************************************************************/ 17 18 <DATE><TIME>|<HOST>|I|testMetadataParseConfig1 19 Following should generate parse error message 20 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 21 Failed to parse the value 'X' of metadata item boolean, type BOOL, on line 2 of test2.config. 22 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 23 Failed to read a metadata value on line 4 of test2.config. 24 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 25 Failed to read a metadata value on line 7 of test2.config. 26 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 27 Failed to parse the value 'x,y,z' of metadata item @vector1, type U8, on line 8 of test2.config. 28 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 29 Failed to read a metadata type on line 9 of test2.config. 30 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 31 Failed to read a metadata value on line 9 of test2.config. 32 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 33 Failed to parse the value '' of metadata item @vector3, type F8, on line 10 of test2.config. 34 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 35 Duplicate MULTI specifier on line 14 of test2.config. 36 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 37 Metadata type 'CELL', found on line 17 of test2.config, is not invalid. 38 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 39 Failed to parse the value 'aabb' of metadata item value1, type F64, on line 20 of test2.config. 40 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 41 Failed to parse the value 'ccdd' of metadata item value2, type S32, on line 21 of test2.config. 42 <DATE><TIME>|<HOST>|E|parseLine (FILE:LINENO) 43 More than one '@' character not allowed. Found on line 24 of test2.config. 44 <DATE><TIME>|<HOST>|E|parseLine (FILE:LINENO) 45 Failed to read a metadata type on line 27 of test2.config. 46 <DATE><TIME>|<HOST>|E|parseLine (FILE:LINENO) 47 Specified type, CELL, on line 31 of test2.config is already defined. 48 <DATE><TIME>|<HOST>|E|psMetadataAddItem (FILE:LINENO) 49 Duplicate metadata item name is not allowed. Use a psMetadataFlags option to allow such action. 50 <DATE><TIME>|<HOST>|E|parseLine (FILE:LINENO) 51 Metadata type 'NEWCELL', found on line 37 of test2.config, is not invalid. 52 <DATE><TIME>|<HOST>|E|parseMetadataItem (FILE:LINENO) 53 Failed to read a metadata OURCELL on line 40 of test2.config. 54 <DATE><TIME>|<HOST>|E|parseLine (FILE:LINENO) 55 Metadata type 'NEWCELL1', found on line 43 of test2.config, is not invalid. 56 <DATE><TIME>|<HOST>|I|testMetadataParseConfig1 57 Following should generate error message 1 58 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 2 Failed to parse the value '9876.54qqq32' of metadata item xPosition, type F64, on line 89 of test.config. 59 Failed to open file 'ab.config'. Check if it exists and it has the proper permissions. 60 <DATE><TIME>|<HOST>|I|testMetadataParseConfig1 61 Following should generate an error message for NULL failed lines arg 3 62 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 4 Failed to read a metadata value on line 95 of test.config. 63 Unallowable operation: nFail is NULL. 64 <DATE><TIME>|<HOST>|I|testMetadataParseConfig1 65 Following should generate an error message for NULL file name arg 5 66 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 6 Metadata type '99.999', found on line 101 of test.config, is not invalid. 7 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 8 More than one '*' character not allowed. Found on line 107 of test.config. 9 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 10 More than one '@' character not allowed. Found on line 113 of test.config. 11 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 12 More than one '~' character not allowed. Found on line 119 of test.config. 13 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 14 Failed to parse the value '9876.54qqq32' of metadata item xPosition, type F64, on line 89 of test.config. 15 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 16 Failed to read a metadata value on line 95 of test.config. 17 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 18 Metadata type '99.999', found on line 101 of test.config, is not invalid. 19 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 20 More than one '*' character not allowed. Found on line 107 of test.config. 21 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 22 More than one '@' character not allowed. Found on line 113 of test.config. 23 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 24 More than one '~' character not allowed. Found on line 119 of test.config. 67 Unallowable operation: fileName is NULL. 68 69 ---> TESTPOINT PASSED (psMetadataParseConfig{psMetadataParseConfig} | tst_psMetadataIO.c) 70 71 /***************************** TESTPOINT ******************************************\ 72 * TestFile: tst_psMetadataIO.c * 73 * TestPoint: psMetadataParseConfig{psMetadataParseConfig} * 74 * TestType: Positive * 75 \**********************************************************************************/ 76 77 <DATE><TIME>|<HOST>|I|testMetadataParseConfig2 78 Following should generate an error of duplicate key names 25 79 <DATE><TIME>|<HOST>|E|psMetadataAddItem (FILE:LINENO) 26 80 Duplicate metadata item name is not allowed. Use a psMetadataFlags option to allow such action. 27 81 <DATE><TIME>|<HOST>|E|psMetadataAddV (FILE:LINENO) 28 82 Failed to add metadata item to metadata collection list. 29 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 30 Duplicate Metadata item, speed, found on line 127 of test.config. Overwrite not allowed. 31 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 32 Failed to parse the value '9876.54qqq32' of metadata item xPosition, type F64, on line 89 of test.config. 33 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 34 Failed to read a metadata value on line 95 of test.config. 35 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 36 Metadata type '99.999', found on line 101 of test.config, is not invalid. 37 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 38 More than one '*' character not allowed. Found on line 107 of test.config. 39 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 40 More than one '@' character not allowed. Found on line 113 of test.config. 41 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 42 More than one '~' character not allowed. Found on line 119 of test.config. 43 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 44 Unallowable operation: fileName is NULL. 45 <DATE><TIME>|<HOST>|E|psMetadataParseConfig (FILE:LINENO) 46 Failed to open file 'abcedfg'. Check if it exists and it has the proper permissions. 83 84 ---> TESTPOINT PASSED (psMetadataParseConfig{psMetadataParseConfig} | tst_psMetadataIO.c) 85 -
trunk/psLib/test/collections/verified/tst_psMetadataIO.stdout
r3779 r3945 1 /***************************** TESTPOINT ******************************************\ 2 * TestFile: tst_psMetadataIO.c * 3 * TestPoint: psMetadata{Test A - Read config file with overwrite set true} * 4 * TestType: Positive * 5 \**********************************************************************************/ 1 Double F64 1.234568 # This is a comment 2 String STR This is the string that forms the value # comment 3 boolean BOOL 1 # The value of 'boolean' is 'true' 4 @primes U8 2,3,5,7,11,13,17 # These are prime numbers 5 comment MULTI 6 comment STR This 7 comment STR is 8 comment STR a 9 comment STR non-unique 10 comment STR key 11 Float F64 1.234560 # This generates a warning, and, if 'overwrite' is 'false', is ignored 12 boolean1 BOOL 0 # The value of 'boolean' is 'false' 13 @negprimes S8 -2,-3,-5,-7,-11,-13,-17,-19 14 @vector1 U16 0,1,2,4,8 15 @vector2 U32 0,8,16,32,64,128 16 @vector3 U64 0,64,256 17 @vector4 S16 -2,-1,0,1,2 18 @vector5 S32 -4,-2,0,2,4,6 19 @vector6 S64 -16,-4,0,4,16,36,64 20 @vector7 F32 -1.03,1.04,-1.05,1.06 21 @vector8 F64 -2.22,2.21,-2.2,2.19,-2.18 22 CELL.00 METADATA 23 EXTNAME STR CCD00 24 BIASSEC STR BSEC-00 25 CHIP STR CHIP.00 6 26 7 Failed lines: 6 Expected: 6 8 Contents of metadata list: 9 Key Name: pi Key mdType: 0x00000408 Key Value: 3.142 Key Comment: Definition of pi 10 Key Name: altitude Key mdType: 0x00000104 Key Value: 10000 Key Comment: 11 Key Name: time Key mdType: 0x00000404 Key Value: 1234.568 Key Comment: 12 Key Name: myBool Key mdType: 0x00001301 Key Value: 0 Key Comment: F, f, 0, T, t, 1 are also acceptable 13 Key Name: title1 Key mdType: 0x00010001 Key Value: Hello world Key Comment: This is a comment for the string value 14 Key Name: title2 Key mdType: 0x00010001 Key Value: Good bye world Key Comment: STRING or STR may be used as the string type 15 Key Name: primes Key mdType: 0x00010002 Key Value: [2,3,5,7,...] Key Comment: These are prime numbers 16 Key Name: negatives Key mdType: 0x00010002 Key Value: [-1,-2,-3,...] Key Comment: 17 Key Name: comment Key mdType: 0x00010001 Key Value: This Key Comment: 18 Key Name: comment Key mdType: 0x00010001 Key Value: is Key Comment: 19 Key Name: comment Key mdType: 0x00010001 Key Value: an Key Comment: 20 Key Name: comment Key mdType: 0x00010001 Key Value: ugly Key Comment: 21 Key Name: comment Key mdType: 0x00010001 Key Value: comment Key Comment: 22 Key Name: comment Key mdType: 0x00010001 Key Value: but Key Comment: 23 Key Name: comment Key mdType: 0x00010001 Key Value: still Key Comment: 24 Key Name: comment Key mdType: 0x00010001 Key Value: valid Key Comment: 25 Key Name: speed Key mdType: 0x00000404 Key Value: 66.660 Key Comment: 27 CELL.01 METADATA 28 EXTNAME STR CCD01 29 BIASSEC STR BSEC-01 30 CHIP STR CHIP.00 26 31 27 Contents of metadata table: 28 Key Name: comment Key mdType: 0x0001000a Key Value: Key Comment: List of Metadata Items 29 Key Name: comment Key mdType: 0x00010001 Key Value: This Key Comment: 30 Key Name: comment Key mdType: 0x00010001 Key Value: is Key Comment: 31 Key Name: comment Key mdType: 0x00010001 Key Value: an Key Comment: 32 Key Name: comment Key mdType: 0x00010001 Key Value: ugly Key Comment: 33 Key Name: comment Key mdType: 0x00010001 Key Value: comment Key Comment: 34 Key Name: comment Key mdType: 0x00010001 Key Value: but Key Comment: 35 Key Name: comment Key mdType: 0x00010001 Key Value: still Key Comment: 36 Key Name: comment Key mdType: 0x00010001 Key Value: valid Key Comment: 37 Key Name: title2 Key mdType: 0x00010001 Key Value: Good bye world Key Comment: STRING or STR may be used as the string type 38 Key Name: time Key mdType: 0x00000404 Key Value: 1234.568 Key Comment: 39 Key Name: negatives Key mdType: 0x00010002 Key Value: [-1,-2,-3,...] Key Comment: 40 Key Name: pi Key mdType: 0x00000408 Key Value: 3.142 Key Comment: Definition of pi 41 Key Name: myBool Key mdType: 0x00001301 Key Value: 0 Key Comment: F, f, 0, T, t, 1 are also acceptable 42 Key Name: primes Key mdType: 0x00010002 Key Value: [2,3,5,7,...] Key Comment: These are prime numbers 43 Key Name: altitude Key mdType: 0x00000104 Key Value: 10000 Key Comment: 44 Key Name: speed Key mdType: 0x00000404 Key Value: 66.660 Key Comment: 45 Key Name: title1 Key mdType: 0x00010001 Key Value: Hello world Key Comment: This is a comment for the string value 32 MYCELL MULTI 33 MYCELL METADATA 34 EXTNAME STR CCD00 35 BIASSEC STR BSEC-00 36 CHIP STR CHIP.00 37 NCELL S32 24 46 38 47 ---> TESTPOINT PASSED (psMetadata{Test A - Read config file with overwrite set true} | tst_psMetadataIO.c) 39 MYCELL S32 123 # A number 40 cell METADATA 41 foo METADATA 42 bar STR BAZ 43 ping STR PONG 48 44 49 /***************************** TESTPOINT ******************************************\ 50 * TestFile: tst_psMetadataIO.c * 51 * TestPoint: psMetadata{Test B - Read config file with overwrite set false} * 52 * TestType: Positive * 53 \**********************************************************************************/ 45 EXTNAME STR CCD00 46 BIASSEC STR BSEC-00 47 CHIP STR CHIP.00 48 NCELL S32 12 54 49 55 Failed lines: 7 Expected: 7 Contents of metadata list:56 Key Name: pi Key mdType: 0x00000408 Key Value: 3.142 Key Comment: Definition of pi57 Key Name: altitude Key mdType: 0x00000104 Key Value: 10000 Key Comment:58 Key Name: time Key mdType: 0x00000404 Key Value: 1234.568 Key Comment:59 Key Name: myBool Key mdType: 0x00001301 Key Value: 0 Key Comment: F, f, 0, T, t, 1 are also acceptable60 Key Name: title1 Key mdType: 0x00010001 Key Value: Hello world Key Comment: This is a comment for the string value61 Key Name: title2 Key mdType: 0x00010001 Key Value: Good bye world Key Comment: STRING or STR may be used as the string type62 Key Name: primes Key mdType: 0x00010002 Key Value: [2,3,5,7,...] Key Comment: These are prime numbers63 Key Name: negatives Key mdType: 0x00010002 Key Value: [-1,-2,-3,...] Key Comment:64 Key Name: comment Key mdType: 0x00010001 Key Value: This Key Comment:65 Key Name: comment Key mdType: 0x00010001 Key Value: is Key Comment:66 Key Name: comment Key mdType: 0x00010001 Key Value: an Key Comment:67 Key Name: comment Key mdType: 0x00010001 Key Value: ugly Key Comment:68 Key Name: comment Key mdType: 0x00010001 Key Value: comment Key Comment:69 Key Name: comment Key mdType: 0x00010001 Key Value: but Key Comment:70 Key Name: comment Key mdType: 0x00010001 Key Value: still Key Comment:71 Key Name: comment Key mdType: 0x00010001 Key Value: valid Key Comment:72 Key Name: speed Key mdType: 0x00000404 Key Value: 55.550 Key Comment:73 74 Contents of metadata table:75 Key Name: comment Key mdType: 0x0001000a Key Value: Key Comment: List of Metadata Items76 Key Name: comment Key mdType: 0x00010001 Key Value: This Key Comment:77 Key Name: comment Key mdType: 0x00010001 Key Value: is Key Comment:78 Key Name: comment Key mdType: 0x00010001 Key Value: an Key Comment:79 Key Name: comment Key mdType: 0x00010001 Key Value: ugly Key Comment:80 Key Name: comment Key mdType: 0x00010001 Key Value: comment Key Comment:81 Key Name: comment Key mdType: 0x00010001 Key Value: but Key Comment:82 Key Name: comment Key mdType: 0x00010001 Key Value: still Key Comment:83 Key Name: comment Key mdType: 0x00010001 Key Value: valid Key Comment:84 Key Name: title2 Key mdType: 0x00010001 Key Value: Good bye world Key Comment: STRING or STR may be used as the string type85 Key Name: time Key mdType: 0x00000404 Key Value: 1234.568 Key Comment:86 Key Name: negatives Key mdType: 0x00010002 Key Value: [-1,-2,-3,...] Key Comment:87 Key Name: pi Key mdType: 0x00000408 Key Value: 3.142 Key Comment: Definition of pi88 Key Name: myBool Key mdType: 0x00001301 Key Value: 0 Key Comment: F, f, 0, T, t, 1 are also acceptable89 Key Name: primes Key mdType: 0x00010002 Key Value: [2,3,5,7,...] Key Comment: These are prime numbers90 Key Name: altitude Key mdType: 0x00000104 Key Value: 10000 Key Comment:91 Key Name: speed Key mdType: 0x00000404 Key Value: 55.550 Key Comment:92 Key Name: title1 Key mdType: 0x00010001 Key Value: Hello world Key Comment: This is a comment for the string value93 94 ---> TESTPOINT PASSED (psMetadata{Test B - Read config file with overwrite set false} | tst_psMetadataIO.c)95 96 /***************************** TESTPOINT ******************************************\97 * TestFile: tst_psMetadataIO.c *98 * TestPoint: psMetadata{Test C - Read config file without auto-allocation of metadata} *99 * TestType: Positive *100 \**********************************************************************************/101 102 Failed lines: 6 Expected: 6 Contents of metadata list:103 Key Name: pi Key mdType: 0x00000408 Key Value: 3.142 Key Comment: Definition of pi104 Key Name: altitude Key mdType: 0x00000104 Key Value: 10000 Key Comment:105 Key Name: time Key mdType: 0x00000404 Key Value: 1234.568 Key Comment:106 Key Name: myBool Key mdType: 0x00001301 Key Value: 0 Key Comment: F, f, 0, T, t, 1 are also acceptable107 Key Name: title1 Key mdType: 0x00010001 Key Value: Hello world Key Comment: This is a comment for the string value108 Key Name: title2 Key mdType: 0x00010001 Key Value: Good bye world Key Comment: STRING or STR may be used as the string type109 Key Name: primes Key mdType: 0x00010002 Key Value: [2,3,5,7,...] Key Comment: These are prime numbers110 Key Name: negatives Key mdType: 0x00010002 Key Value: [-1,-2,-3,...] Key Comment:111 Key Name: comment Key mdType: 0x00010001 Key Value: This Key Comment:112 Key Name: comment Key mdType: 0x00010001 Key Value: is Key Comment:113 Key Name: comment Key mdType: 0x00010001 Key Value: an Key Comment:114 Key Name: comment Key mdType: 0x00010001 Key Value: ugly Key Comment:115 Key Name: comment Key mdType: 0x00010001 Key Value: comment Key Comment:116 Key Name: comment Key mdType: 0x00010001 Key Value: but Key Comment:117 Key Name: comment Key mdType: 0x00010001 Key Value: still Key Comment:118 Key Name: comment Key mdType: 0x00010001 Key Value: valid Key Comment:119 Key Name: speed Key mdType: 0x00000404 Key Value: 66.660 Key Comment:120 121 Contents of metadata table:122 Key Name: comment Key mdType: 0x0001000a Key Value: Key Comment: List of Metadata Items123 Key Name: comment Key mdType: 0x00010001 Key Value: This Key Comment:124 Key Name: comment Key mdType: 0x00010001 Key Value: is Key Comment:125 Key Name: comment Key mdType: 0x00010001 Key Value: an Key Comment:126 Key Name: comment Key mdType: 0x00010001 Key Value: ugly Key Comment:127 Key Name: comment Key mdType: 0x00010001 Key Value: comment Key Comment:128 Key Name: comment Key mdType: 0x00010001 Key Value: but Key Comment:129 Key Name: comment Key mdType: 0x00010001 Key Value: still Key Comment:130 Key Name: comment Key mdType: 0x00010001 Key Value: valid Key Comment:131 Key Name: title2 Key mdType: 0x00010001 Key Value: Good bye world Key Comment: STRING or STR may be used as the string type132 Key Name: time Key mdType: 0x00000404 Key Value: 1234.568 Key Comment:133 Key Name: negatives Key mdType: 0x00010002 Key Value: [-1,-2,-3,...] Key Comment:134 Key Name: pi Key mdType: 0x00000408 Key Value: 3.142 Key Comment: Definition of pi135 Key Name: myBool Key mdType: 0x00001301 Key Value: 0 Key Comment: F, f, 0, T, t, 1 are also acceptable136 Key Name: primes Key mdType: 0x00010002 Key Value: [2,3,5,7,...] Key Comment: These are prime numbers137 Key Name: altitude Key mdType: 0x00000104 Key Value: 10000 Key Comment:138 Key Name: speed Key mdType: 0x00000404 Key Value: 66.660 Key Comment:139 Key Name: title1 Key mdType: 0x00010001 Key Value: Hello world Key Comment: This is a comment for the string value140 141 ---> TESTPOINT PASSED (psMetadata{Test C - Read config file without auto-allocation of metadata} | tst_psMetadataIO.c)142 143 /***************************** TESTPOINT ******************************************\144 * TestFile: tst_psMetadataIO.c *145 * TestPoint: psMetadataIO{Test D - Attempt to use null fileName argument} *146 * TestType: Negative *147 * ExpectedErrorText: Null failedLines not allowed *148 * ExpectedStatusValue: 0 *149 \**********************************************************************************/150 151 152 ---> TESTPOINT PASSED (psMetadata{Test D - Attempt to use null fileName argument} | tst_psMetadataIO.c)153 154 /***************************** TESTPOINT ******************************************\155 * TestFile: tst_psMetadataIO.c *156 * TestPoint: psMetadataIO{Test E - Attempt to open nonexistant file} *157 * TestType: Negative *158 * ExpectedErrorText: Error opening file *159 * ExpectedStatusValue: 0 *160 \**********************************************************************************/161 162 163 ---> TESTPOINT PASSED (psMetadata{Test E - Attempt to open nonexistant file} | tst_psMetadataIO.c)164 165 /***************************** TESTPOINT ******************************************\166 * TestFile: tst_psMetadataIO.c *167 * TestPoint: psMetadata{Test F - Free psMetadata} *168 * TestType: Positive *169 \**********************************************************************************/170 171 172 ---> TESTPOINT PASSED (psMetadata{Test F - Free psMetadata} | tst_psMetadataIO.c)173 -
trunk/psLib/test/collections/verified/tst_psMetadata_01.stdout
r3779 r3945 44 44 Key Name: PCOUNT Key mdType: 0x00000104 Key Value: 0 Key Comment: required keyword; must = 0 45 45 Key Name: XTENSION Key mdType: 0x00010001 Key Value: 'IMAGE ' Key Comment: IMAGE extension 46 Key Name: BITPIX Key mdType: 0x0001000a Key Value: Key Comment: List of Metadata Items46 Key Name: BITPIX Key mdType: 0x0001000a Key Value: Key Comment: 47 47 Key Name: BITPIX Key mdType: 0x00000104 Key Value: -64 Key Comment: number of bits per data pixel 48 48 Key Name: BITPIX Key mdType: 0x00000104 Key Value: -64 Key Comment: number of bits per data pixel 49 49 Key Name: GCOUNT Key mdType: 0x00000104 Key Value: 1 Key Comment: required keyword; must = 1 50 Key Name: HISTORY Key mdType: 0x0001000a Key Value: Key Comment: List of Metadata Items50 Key Name: HISTORY Key mdType: 0x0001000a Key Value: Key Comment: 51 51 Key Name: HISTORY Key mdType: 0x00010001 Key Value: Key Comment: File modified by user 'harman' with fv on 2004-08-04T<DATE> 52 52 Key Name: HISTORY Key mdType: 0x00010001 Key Value: Key Comment: File modified by user 'harman' with fv on 2004-08-04T<DATE> … … 81 81 Key Name: GCOUNT Key mdType: 0x00000104 Key Value: 1 Key Comment: required keyword; must = 1 82 82 Key Name: BITPIX Key mdType: 0x00000104 Key Value: -64 Key Comment: number of bits per data pixel 83 Key Name: HISTORY Key mdType: 0x0001000a Key Value: Key Comment: List of Metadata Items83 Key Name: HISTORY Key mdType: 0x0001000a Key Value: Key Comment: 84 84 Key Name: HISTORY Key mdType: 0x00010001 Key Value: Key Comment: File modified by user 'harman' with fv on 2004-08-04T<DATE> 85 85 Key Name: HISTORY Key mdType: 0x00010001 Key Value: Key Comment: File modified by user 'harman' with fv on 2004-08-04T<DATE>
Note:
See TracChangeset
for help on using the changeset viewer.
