Index: trunk/psLib/src/types/psMetadataConfig.c
===================================================================
--- trunk/psLib/src/types/psMetadataConfig.c	(revision 9912)
+++ trunk/psLib/src/types/psMetadataConfig.c	(revision 9916)
@@ -10,6 +10,6 @@
 *  @author Eric Van Alst, MHPCC
 *
-*  @version $Revision: 1.112 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2006-11-09 00:03:44 $
+*  @version $Revision: 1.113 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2006-11-09 01:58:52 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, University of Hawaii
@@ -68,4 +68,22 @@
 static psString formatMetadataItem(psMetadataItem *item);
 static psArray *p_psMetadataKeyArray(psMetadata *md);
+static bool parseGeneric(char* keyName,
+                         psS32* level,
+                         psArray* levelArray,
+                         char* linePtr,
+                         psS32 lineCount,
+                         psMetadataFlags flags);
+static bool parseType(char* keyName,
+                      psS32* level,
+                      psArray* levelArray,
+                      char* linePtr,
+                      psS32 lineCount,
+                      psMetadataFlags flags);
+static bool parseMetadataEnd(char* keyName,
+                             psS32* level,
+                             psArray* levelArray,
+                             char* linePtr,
+                             psS32 lineCount,
+                             psMetadataFlags flags);
 
 
@@ -1102,5 +1120,4 @@
 {
     psMetadataFlags     flags  = PS_META_DEFAULT;
-    psS32               status = 0;
 
     // Set flags if overwrite specified
@@ -1116,4 +1133,6 @@
 
     // Check for more than one '@' in a line
+    // XXX this logic is wrong -- there's no reason a @ can't appear in a
+    // comment
     if (repeatedChars(linePtr, '@') > 1) {
         psError(PS_ERR_IO, true,
@@ -1123,4 +1142,5 @@
 
     // Get metadata item name
+    psS32               status = 0;
     char *keyName = getToken(&linePtr, " ", &status, true);
     if (status) {
@@ -1132,117 +1152,40 @@
 
     // Check for special keyName values "TYPE", "END"
-    if (strcmp(keyName,"TYPE") == 0 ) {
-        // Get the type name
-        char *strType = getToken(&linePtr, " ", &status, true);
-        if(!strType) {
-            psError(PS_ERR_IO,true,
-                    _("Failed to read item type on line %u."), lineCount);
-            psFree(keyName);
-            return false;
-        }
-        if (status) {
-            psError(PS_ERR_IO, true,
-                    _("Failed to read item type on line %u."), lineCount);
-            psFree(strType);
-            psFree(keyName);
-            return false;
-        }
-
-        // attempt to parse the TYPE line into a template metadata
-        psMetadata *tempTemplate = getMetadataType(linePtr);
-        if (!tempTemplate) {
-            psError(PS_ERR_IO,true,
-                    _("Metadata type '%s', found on line %u, is invalid."),
-                    strType,lineCount);
-            psFree(keyName);
-            psFree(strType);
-            return false;
-        }
-
-        // Access type array
-        psArray *typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray;
-
-        // Check if type already exists in array
-        for (psS32 k = 0; k < psArrayLength(typeArray); k++) {
-            // Compare type name with the list of current types
-            if (strcmp(strType,(char*)typeArray->data[k]) == 0) {
-                psError(PS_ERR_IO,true,
-                        _("Specified type, %s, on line %u is already defined."),
-                        strType, lineCount);
-                psFree(tempTemplate);
-                psFree(keyName);
-                psFree(strType);
-                return false;
-            }
-        }
-
-        // Add key name to array of type
-        typeArray = psArrayAdd(typeArray, 1, strType);
-        psFree(strType);
-
-        // Add template to array of templates
-        psArray *templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray;
-        psArrayAdd(templateArray, 1, tempTemplate);
-        psFree(tempTemplate);
-
-        return true;
-    }
-
     if (strcmp(keyName, "END") == 0) {
-        if ((*level) < 1) {
-            psFree(keyName);
-            return false;
-        }
-
-        # if 1
-        p_psParseLevelInfo *upperLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level-1]));
-        p_psParseLevelInfo *lowerLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level]));
-        // Check name in nonunique list
-        for (psS32 k = 0; k < psArrayLength(upperLevelInfo->nonUniqueKeyArray); k++) {
-            if (strcmp(upperLevelInfo->nonUniqueKeyArray->data[k], lowerLevelInfo->name) == 0) {
-                flags = PS_META_DUPLICATE_OK;
-                break;
-            }
-        }
-        #endif
-
-        char *strValue = NULL;
-        strValue = getToken(&linePtr, "#", &status, true);
-        char *strComment = NULL;
-        // XXX why is there a ~ here?
-        strComment = getToken(&linePtr, "~", &status, true);
-
-        // Add metadata to upper level metadata
-        if (!psMetadataAdd(upperLevelInfo->metadata,
-                           PS_LIST_TAIL, lowerLevelInfo->name,
-                           PS_DATA_METADATA | flags,
-                           strComment, //"",
-                           lowerLevelInfo->metadata)) {
-            // This is pretty much a non-recoverable error - perhaps there
-            // should be a way of signalling non-recoverable parse errors
-            psError(PS_ERR_UNKNOWN, false, "failed to add metadata item");
-            psFree(strValue);
-            psFree(strComment);
-            psFree(keyName);
-            return false;
-        }
-
-        // Remove lower info level
-        if(!psArrayRemoveIndex(levelArray, *level)) {
-            psError(PS_ERR_UNKNOWN, false, "failed to remove array item");
-            psFree(strValue);
-            psFree(strComment);
-            psFree(keyName);
-        }
-
-        // the END just moved us up one nesting level
-        (*level)--;
-
-        psFree(strValue);
-        psFree(strComment);
-        psFree(keyName);
-
-        return true;
-    }
+        if (!parseMetadataEnd(keyName, level, levelArray, linePtr, lineCount, flags)) {
+            goto FAIL;
+        }
+    } else if (strcmp(keyName,"TYPE") == 0 ) {
+        if (!parseType(keyName, level, levelArray, linePtr, lineCount, flags)) {
+            goto FAIL;
+        }
+    } else {
+        if (!parseGeneric(keyName, level, levelArray, linePtr, lineCount, flags)) {
+            goto FAIL;
+        }
+    }
+
+    psFree(keyName);
+
+    return true;
+
+FAIL:
+    psError(PS_ERR_UNKNOWN, false,
+            _("Failed to parse line %u: %s."), lineCount, linePtr);
+    psFree(keyName);
+    return false;
+}
+
+static bool parseGeneric(char* keyName,
+                         psS32* level,
+                         psArray* levelArray,
+                         char* linePtr,
+                         psS32 lineCount,
+                         psMetadataFlags flags)
+{
+    PS_ASSERT_PTR_NON_NULL(keyName, false);
+    PS_ASSERT_PTR_NON_NULL(level, false);
+    PS_ASSERT_PTR_NON_NULL(levelArray, false);
+    PS_ASSERT_PTR_NON_NULL(linePtr, false);
 
     // Check if key name present in array of non-unique key names
@@ -1258,8 +1201,135 @@
     // Parse metadataItem
     if (!parseMetadataItem(keyName, level, levelArray, linePtr, lineCount, flags)) {
-        psFree(keyName);
         return false;
     }
-    psFree(keyName);
+
+    return true;
+}
+
+static bool parseType(char* keyName,
+                      psS32* level,
+                      psArray* levelArray,
+                      char* linePtr,
+                      psS32 lineCount,
+                      psMetadataFlags flags)
+{
+    PS_ASSERT_PTR_NON_NULL(keyName, false);
+    PS_ASSERT_PTR_NON_NULL(level, false);
+    PS_ASSERT_PTR_NON_NULL(levelArray, false);
+    PS_ASSERT_PTR_NON_NULL(linePtr, false);
+
+    // Get the type name
+    psS32 status = 0;
+    char *strType = getToken(&linePtr, " ", &status, true);
+    if(!strType) {
+        psError(PS_ERR_IO,true,
+                _("Failed to read item type on line %u."), lineCount);
+        return false;
+    }
+    if (status) {
+        psError(PS_ERR_IO, true,
+                _("Failed to read item type on line %u."), lineCount);
+        psFree(strType);
+        return false;
+    }
+
+    // attempt to parse the TYPE line into a template metadata
+    psMetadata *tempTemplate = getMetadataType(linePtr);
+    if (!tempTemplate) {
+        psError(PS_ERR_IO,true,
+                _("Metadata type '%s', found on line %u, is invalid."),
+                strType,lineCount);
+        psFree(strType);
+        return false;
+    }
+
+    // Access type array
+    psArray *typeArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->typeArray;
+
+    // Check if type already exists in array
+    for (psS32 k = 0; k < psArrayLength(typeArray); k++) {
+        // Compare type name with the list of current types
+        if (strcmp(strType, (char*)typeArray->data[k]) == 0) {
+            psError(PS_ERR_IO,true,
+                    _("Specified type, %s, on line %u is already defined."),
+                    strType, lineCount);
+            psFree(tempTemplate);
+            psFree(strType);
+            return false;
+        }
+    }
+
+    // Add key name to array of type
+    typeArray = psArrayAdd(typeArray, 0, strType);
+    psFree(strType);
+
+    // Add template to array of templates
+    psArray *templateArray = ((p_psParseLevelInfo*)(levelArray->data[*level]))->templateArray;
+    psArrayAdd(templateArray, 0, tempTemplate);
+    psFree(tempTemplate);
+
+    return true;
+}
+
+static bool parseMetadataEnd(char* keyName,
+                             psS32* level,
+                             psArray* levelArray,
+                             char* linePtr,
+                             psS32 lineCount,
+                             psMetadataFlags flags)
+{
+    PS_ASSERT_PTR_NON_NULL(keyName, false);
+    PS_ASSERT_PTR_NON_NULL(level, false);
+    PS_ASSERT_PTR_NON_NULL(levelArray, false);
+    PS_ASSERT_PTR_NON_NULL(linePtr, false);
+
+    if ((*level) < 1) {
+        psError(PS_ERR_UNKNOWN, false, "can not END the top level metadata");
+        return false;
+    }
+
+    p_psParseLevelInfo *upperLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level-1]));
+    p_psParseLevelInfo *lowerLevelInfo = ((p_psParseLevelInfo*)(levelArray->data[*level]));
+    // Check name in nonunique list
+    for (psS32 k = 0; k < psArrayLength(upperLevelInfo->nonUniqueKeyArray); k++) {
+        if (strcmp(upperLevelInfo->nonUniqueKeyArray->data[k], lowerLevelInfo->name) == 0) {
+            flags = PS_META_DUPLICATE_OK;
+            break;
+        }
+    }
+
+    char *strValue = NULL;
+    psS32 status = 0;
+    strValue = getToken(&linePtr, "#", &status, true);
+    char *strComment = NULL;
+    // XXX why is there a ~ here?
+    strComment = getToken(&linePtr, "~", &status, true);
+
+    // Add metadata to upper level metadata
+    if (!psMetadataAdd(upperLevelInfo->metadata,
+                       PS_LIST_TAIL, lowerLevelInfo->name,
+                       PS_DATA_METADATA | flags,
+                       strComment, //"",
+                       lowerLevelInfo->metadata)) {
+        // This is pretty much a non-recoverable error - perhaps there
+        // should be a way of signalling non-recoverable parse errors
+        psError(PS_ERR_UNKNOWN, false, "failed to add metadata item");
+        psFree(strValue);
+        psFree(strComment);
+        return false;
+    }
+
+    // Remove lower info level
+    if(!psArrayRemoveIndex(levelArray, *level)) {
+        psError(PS_ERR_UNKNOWN, false, "failed to remove array item");
+        psFree(strValue);
+        psFree(strComment);
+    }
+
+    // the END just moved us up one nesting level
+    (*level)--;
+
+    psFree(strValue);
+    psFree(strComment);
 
     return true;
@@ -1365,5 +1435,5 @@
     psFree(topLevelInfo);
 
-    psList *doc = psStringSplit(str, "\n", false);
+    psList *doc = psStringSplit(str, "\n", true);
     if (!doc) {
         psError(PS_ERR_UNKNOWN, false, "failed to split string: %s", str);
