Index: /trunk/psLib/src/types/psLookupTable.c
===================================================================
--- /trunk/psLib/src/types/psLookupTable.c	(revision 12286)
+++ /trunk/psLib/src/types/psLookupTable.c	(revision 12287)
@@ -7,6 +7,6 @@
 *  @author Ross Harman, MHPCC
 *
-*  @version $Revision: 1.48 $ $Name: not supported by cvs2svn $
-*  @date $Date: 2007-02-08 21:57:02 $
+*  @version $Revision: 1.49 $ $Name: not supported by cvs2svn $
+*  @date $Date: 2007-03-07 02:42:22 $
 *
 *  Copyright 2004-2005 Maui High Performance Computing Center, Univ. of Hawaii
@@ -27,4 +27,5 @@
 #include <inttypes.h>
 
+#include "psAbort.h"
 #include "psMemory.h"
 #include "psString.h"
@@ -67,8 +68,4 @@
 static char *cleanString(char *inString, int sLen);
 static char* getToken(char **inString, char *delimiter, psParseErrorType *status);
-static psS32 parseS32(char *inString, psParseErrorType *status);
-static psS64 parseS64(char *inString, psParseErrorType *status);
-static psF32 parseF32(char *inString, psParseErrorType *status);
-static psF64 parseF64(char *inString, psParseErrorType *status);
 static void parseValue(psVector *vec, psU64 index, char* strValue, psParseErrorType *status);
 static void lookupTableFree(psLookupTable* table);
@@ -78,6 +75,6 @@
 static bool ignoreLine(char *inString)
 {
-    while(*inString!='\0' && *inString!='#') {
-        if(!isspace(*inString)) {
+    while (*inString!='\0' && *inString!='#') {
+        if (!isspace(*inString)) {
             return false;
         }
@@ -106,5 +103,5 @@
     // Skip over trailing whitespace, null terminators, and # characters
     ptrE = inString + sLen;
-    while(isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
+    while (isspace(*ptrE) || *ptrE=='\0' || *ptrE=='#') {
         ptrE--;
     }
@@ -131,5 +128,5 @@
 
     // Skip over leading whitespace
-    while(isspace(**inString)) {
+    while (isspace(**inString)) {
         (*inString)++;
     }
@@ -137,5 +134,5 @@
     // Length of token, not including delimiter
     sLen = strcspn(*inString, delimiter);
-    if(sLen) {
+    if (sLen) {
 
         // Create new, cleaned, and null terminated token
@@ -145,5 +142,5 @@
         (*inString) += sLen;
     }
-    /*    else if(**inString!='\0' && sLen==0) {
+    /*    else if (**inString!='\0' && sLen==0) {
             *status = PS_PARSE_ERROR_GENERAL;
         }
@@ -152,80 +149,26 @@
 }
 
-/* Returns single parsed value as a psS32. The input string must be cleaned and
-   null terminated. */
-static psS32 parseS32(char *inString,
-                      psParseErrorType *status)
-{
-    char *end = NULL;
-    psS32 value = 0.0;
-
-
-    value = (psS32)strtol(inString, &end, 0);
-    if(*end != '\0' && !isspace(*end)) {
-        *status = PS_PARSE_ERROR_VALUE;
-    }
-    /*    else if(inString==end) {
-            *status = PS_PARSE_ERROR_VALUE;
-        }
-    */
-    return value;
-}
-
-/* Returns single parsed value as a psS64. The input string must be cleaned and
-   null terminated. */
-static psS64 parseS64(char *inString,
-                      psParseErrorType *status)
-{
-    char *end = NULL;
-    psS64 value = 0.0;
-
-    value = (psS64)strtoll(inString, &end, 0);
-    if(*end != '\0' && !isspace(*end)) {
-        *status = PS_PARSE_ERROR_VALUE;
-    }
-    /*    else if(inString==end) {
-            *status = PS_PARSE_ERROR_VALUE;
-        }
-    */
-    return value;
-}
-
-/* Returns single parsed value as a psF32. The input string must be cleaned and
-   null terminated. */
-static psF32 parseF32(char *inString,
-                      psParseErrorType *status)
-{
-    char *end = NULL;
-    psF32 value = 0.0;
-
-    value = (psF32)strtof(inString, &end);
-    if(*end != '\0' && !isspace(*end)) {
-        *status = PS_PARSE_ERROR_VALUE;
-    }
-    /*    else if(inString==end) {
-            *status = PS_PARSE_ERROR_VALUE;
-        }
-    */
-    return value;
-}
-
-/* Returns single parsed value as a psF64. The input string must be cleaned and
-   null terminated. */
-static psF64 parseF64(char *inString,
-                      psParseErrorType *status)
-{
-    char *end = NULL;
-    psF64 value = 0.0;
-
-    value = (psF64)strtod(inString, &end);
-    if(*end != '\0' && !isspace(*end)) {
-        *status = PS_PARSE_ERROR_VALUE;
-    }
-    /*    else if(inString==end) {
-            *status = PS_PARSE_ERROR_VALUE;
-        }
-    */
-    return value;
-}
+#define PARSE_VALUE_INT_CASE(TYPE, FUNC) \
+    case PS_TYPE_##TYPE: { \
+        char *end = NULL; \
+        ps##TYPE value = FUNC(strValue, &end, 0); \
+        if (*end != '\0' && !isspace(*end)) { \
+            *status = PS_PARSE_ERROR_VALUE; \
+        } \
+        vec->data.TYPE[index] = value; \
+        return; \
+    }
+
+#define PARSE_VALUE_FLOAT_CASE(TYPE, FUNC) \
+    case PS_TYPE_##TYPE: { \
+        char *end = NULL; \
+        ps##TYPE value = FUNC(strValue, &end); \
+        if (*end != '\0' && !isspace(*end)) { \
+            *status = PS_PARSE_ERROR_VALUE; \
+        } \
+        vec->data.TYPE[index] = value; \
+        return; \
+    }
+
 
 /* Returns single parsed value as a double precision number. The input string must be
@@ -236,32 +179,13 @@
                        psParseErrorType *status)
 {
-    psElemType type;
-
-
-    /*    if(vec == NULL) {
-            *status = 1;
-            return;
-        }
-    */
-    type = vec->type.type;
-
-    switch(type) {
-    case PS_TYPE_S32:
-        vec->data.S32[index] = parseS32(strValue, status);
-        break;
-    case PS_TYPE_S64:
-        vec->data.S64[index] = parseS64(strValue, status);
-        break;
-    case PS_TYPE_F32:
-        vec->data.F32[index] = parseF32(strValue, status);
-        break;
-    case PS_TYPE_F64:
-    default:
-        vec->data.F64[index] = parseF64(strValue, status);
-        break;
-        //    default:
-        //        *status = PS_PARSE_ERROR_TYPE;
-    }
-
+    switch (vec->type.type) {
+        PARSE_VALUE_INT_CASE(S32, strtol);
+        PARSE_VALUE_INT_CASE(S64, strtoll);
+        PARSE_VALUE_FLOAT_CASE(F32, strtof);
+        PARSE_VALUE_FLOAT_CASE(F64, strtod);
+      default:
+        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Bad type for vector: %x.\n", vec->type.type);
+        *status = PS_PARSE_ERROR_TYPE;
+    }
     return;
 }
@@ -269,7 +193,8 @@
 static void lookupTableFree(psLookupTable* table)
 {
+    assert(table);
     psFree(table->values);
-    psFree((void *)table->filename);
-    psFree((void *)table->format);
+    psFree(table->filename);
+    psFree(table->format);
 }
 
@@ -292,14 +217,8 @@
                                     long indexCol)
 {
-    // Can't read table if you don't know its name
-    PS_ASSERT_PTR_NON_NULL(filename,NULL);
-
-    // Can't read table if you don't know its format
-    PS_ASSERT_PTR_NON_NULL(format,NULL);
-
-    psLookupTable *outTable = NULL;
-
-    // Allocate lookup table
-    outTable = (psLookupTable*)p_psAlloc(file, lineno, func, sizeof(psLookupTable));
+    PS_ASSERT_STRING_NON_EMPTY(filename,NULL);
+    PS_ASSERT_STRING_NON_EMPTY(format,NULL);
+
+    psLookupTable *outTable = p_psAlloc(file, lineno, func, sizeof(psLookupTable));
 
     // Set deallocator
@@ -324,115 +243,10 @@
 }
 
-#define UPDATE_VALID_TO_FROM(TABLE)                                             \
-switch (TABLE->index->type.type) {                                              \
-case PS_TYPE_U8:                                                                \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U8[0];                         \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U8[TABLE->index->n-1];         \
-    break;                                                                      \
-case PS_TYPE_S8:                                                                \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S8[0];                         \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S8[TABLE->index->n-1];         \
-    break;                                                                      \
-case PS_TYPE_U16:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U16[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U16[TABLE->index->n-1];        \
-    break;                                                                      \
-case PS_TYPE_S16:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S16[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S16[TABLE->index->n-1];        \
-    break;                                                                      \
-case PS_TYPE_U32:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U32[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U32[TABLE->index->n-1];        \
-    break;                                                                      \
-case PS_TYPE_S32:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S32[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S32[TABLE->index->n-1];        \
-    break;                                                                      \
-case PS_TYPE_U64:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.U64[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.U64[TABLE->index->n-1];        \
-    break;                                                                      \
-case PS_TYPE_S64:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.S64[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.S64[TABLE->index->n-1];        \
-    break;                                                                      \
-case PS_TYPE_F32:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.F32[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.F32[TABLE->index->n-1];        \
-    break;                                                                      \
-case PS_TYPE_F64:                                                               \
-    *(double *)&TABLE->validFrom = (psF64)TABLE->index->data.F64[0];                        \
-    *(double *)&TABLE->validTo   = (psF64)TABLE->index->data.F64[TABLE->index->n-1];        \
-    break;                                                                      \
-default:                                                                        \
-    *(double *)&TABLE->validFrom = (psF64)0;                                                \
-    *(double *)&TABLE->validTo   = (psF64)0;                                                \
-    break;                                                                      \
-}
-
-#define COPY_VECTOR_VALUES(VEC_OUT,INDEX_OUT,VEC_IN,INDEX_IN)                              \
-switch(((psVector*)(VEC_IN))->type.type) {                                                 \
-case PS_TYPE_U8:                                                                           \
-    ((psVector*)VEC_OUT)->data.U8[INDEX_OUT] = ((psVector*)VEC_IN)->data.U8[INDEX_IN];     \
-    break;                                                                                 \
-case PS_TYPE_U16:                                                                          \
-    ((psVector*)VEC_OUT)->data.U16[INDEX_OUT] = ((psVector*)VEC_IN)->data.U16[INDEX_IN];   \
-    break;                                                                                 \
-case PS_TYPE_U32:                                                                          \
-    ((psVector*)VEC_OUT)->data.U32[INDEX_OUT] = ((psVector*)VEC_IN)->data.U32[INDEX_IN];   \
-    break;                                                                                 \
-case PS_TYPE_U64:                                                                          \
-    ((psVector*)VEC_OUT)->data.U64[INDEX_OUT] = ((psVector*)VEC_IN)->data.U64[INDEX_IN];   \
-    break;                                                                                 \
-case PS_TYPE_S8:                                                                           \
-    ((psVector*)VEC_OUT)->data.S8[INDEX_OUT] = ((psVector*)VEC_IN)->data.S8[INDEX_IN];     \
-    break;                                                                                 \
-case PS_TYPE_S16:                                                                          \
-    ((psVector*)VEC_OUT)->data.S16[INDEX_OUT] = ((psVector*)VEC_IN)->data.S16[INDEX_IN];   \
-    break;                                                                                 \
-case PS_TYPE_S32:                                                                          \
-    ((psVector*)VEC_OUT)->data.S32[INDEX_OUT] = ((psVector*)VEC_IN)->data.S32[INDEX_IN];   \
-    if(INDEX_OUT == 0) {                                                                   \
-        validFrom = ((psVector*)VEC_OUT)->data.S32[INDEX_OUT];                             \
-    }                                                                                      \
-    if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
-        validTo = ((psVector*)VEC_OUT)->data.S32[INDEX_OUT];                               \
-    }                                                                                      \
-    break;                                                                                 \
-case PS_TYPE_S64:                                                                          \
-    ((psVector*)VEC_OUT)->data.S64[INDEX_OUT] = ((psVector*)VEC_IN)->data.S64[INDEX_IN];   \
-    if(INDEX_OUT == 0) {                                                                   \
-        validFrom = ((psVector*)VEC_OUT)->data.S64[INDEX_OUT];                             \
-    }                                                                                      \
-    if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
-        validTo = ((psVector*)VEC_OUT)->data.S64[INDEX_OUT];                               \
-    }                                                                                      \
-    break;                                                                                 \
-case PS_TYPE_F32:                                                                          \
-    ((psVector*)VEC_OUT)->data.F32[INDEX_OUT] = ((psVector*)VEC_IN)->data.F32[INDEX_IN];   \
-    if(INDEX_OUT == 0) {                                                                   \
-        validFrom = ((psVector*)VEC_OUT)->data.F32[INDEX_OUT];                             \
-    }                                                                                      \
-    if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
-        validTo = ((psVector*)VEC_OUT)->data.F32[INDEX_OUT];                               \
-    }                                                                                      \
-    break;                                                                                 \
-case PS_TYPE_F64:                                                                          \
-    ((psVector*)VEC_OUT)->data.F64[INDEX_OUT] = ((psVector*)VEC_IN)->data.F64[INDEX_IN];   \
-    if(INDEX_OUT == 0) {                                                                   \
-        validFrom = ((psVector*)VEC_OUT)->data.F64[INDEX_OUT];                             \
-    }                                                                                      \
-    if(INDEX_OUT == ((psVector*)VEC_OUT)->n-1 ) {                                          \
-        validTo = ((psVector*)VEC_OUT)->data.F64[INDEX_OUT];                               \
-    }                                                                                      \
-    break;                                                                                 \
-default:                                                                                   \
-    break;                                                                                 \
-}
-
 psArray *psVectorsReadFromFile(const char *filename,
                                const char *format)
 {
+    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
+    PS_ASSERT_STRING_NON_EMPTY(format, NULL);
+
     psArray*          outputArray = NULL;
     psVector*         colVector   = NULL;
@@ -447,10 +261,4 @@
     psParseErrorType  parseStatus = PS_PARSE_SUCCESS;
 
-    // Check for nul file name
-    PS_ASSERT_PTR_NON_NULL(filename,NULL);
-
-    // Parse format string for valid string
-    PS_ASSERT_PTR_NON_NULL(format,NULL);
-
     // Create temp pointer which can then be used several times
     tempFormat = format;
@@ -461,8 +269,8 @@
     // Parse the format string to determine how many vectors
     // and whether the format string is valid
-    while((strValue=getToken((char**)&tempFormat," \t",&parseStatus))) {
+    while ((strValue = getToken((char**)&tempFormat, " \t", &parseStatus))) {
 
         // Check for %d format sub string
-        if(strcmp(strValue,"\%d") == 0 ) {
+        if (strcmp(strValue,"\%d") == 0 ) {
             numCols++;
             colVector = psVectorAlloc(1,PS_TYPE_S32);
@@ -498,8 +306,8 @@
     // If the format string was parsed successfully and return numCols the
     // prepare to open file and read values
-    if(numCols > 0) {
+    if (numCols > 0) {
 
         // Open specified file
-        if((fp=fopen(filename, "r")) == NULL) {
+        if ((fp=fopen(filename, "r")) == NULL) {
             psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed to open file %s."),
                     filename);
@@ -514,5 +322,5 @@
 
             // Loop through file to get numRows, numCols, and column data types
-            while((fgets(line, MAX_STRING_LENGTH, fp) != NULL) &&
+            while ((fgets(line, MAX_STRING_LENGTH, fp) != NULL) &&
                     (parseStatus == PS_PARSE_SUCCESS))   {
 
@@ -521,5 +329,5 @@
 
                 // If line is not a comment or blank, then extract data
-                if(!ignoreLine(linePtr)) {
+                if (!ignoreLine(linePtr)) {
                     numRows++;
 
@@ -530,5 +338,5 @@
 
                     // Loop through format and line strings to get values in text table file
-                    while((strValue=getToken((char**)&tempFormat," \t",&parseStatus))
+                    while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus))
                             && (strNum=getToken((char**)&linePtr," \t",&parseStatus)) ) {
                         // Set column vector
@@ -536,5 +344,5 @@
 
                         // Set column entries based on format string defining the type
-                        if(strcmp(strValue,"\%d") == 0 ) {
+                        if (strcmp(strValue,"\%d") == 0 ) {
                             colVector = psVectorRecycle(colVector, numRows,
                                                         colVector->type.type);
@@ -564,5 +372,5 @@
                         // If the file line was not parsed successful report
                         // error and return NULL
-                        if(parseStatus != PS_PARSE_SUCCESS) {
+                        if (parseStatus != PS_PARSE_SUCCESS) {
                             psError(PS_ERR_UNKNOWN, true,
                                     "Parsing text file failed.");
@@ -615,26 +423,9 @@
                                      const char *func,
                                      psLookupTable *table,
-                                     const psArray *vectors,
+                                     psArray *vectors,
                                      long indexCol)
 {
-    psLookupTable* outputTable = NULL;
-    bool         sortNeeded  = false;
-    psF64          validTo     = 0;
-    psF64          validFrom   = 0;
-
-    // Check for NULL input table
-    // XXX table/outputtable should be allocated if NULL
-    PS_ASSERT_PTR_NON_NULL(table,NULL);
-
-    // Check for NULL vectors
-    PS_ASSERT_PTR_NON_NULL(vectors,NULL);
-
-    // Check for invalid index column
-    if(indexCol < 0 ) {
-        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
-                "Index column cannot be less than zero");
-        return NULL;
-    }
-
+    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NULL);
+    PS_ASSERT_ARRAY_NON_NULL(vectors, NULL);
     if (indexCol >= vectors->n) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Index column, %ld, is larger"
@@ -643,85 +434,112 @@
     }
 
-    psVector* indexColumnVector = vectors->data[indexCol];
-    psS32  numRows = indexColumnVector->n;
-    psS32  numCols = vectors->n;
+    psVector *indexVector = vectors->data[indexCol]; // The vector that provides the index
+    long numRows = indexVector->n;      // Number of rows in table
+    long numCols = vectors->n;          // Number of columns in table
+
+#define CHECK_SORT_CASE(TYPE) \
+    case PS_TYPE_##TYPE: \
+        for (long i = 1; i < numRows; i++) { \
+             if (indexVector->data.TYPE[i] < indexVector->data.TYPE[i - 1]) { \
+                 sortNeeded = true; \
+                 break; \
+             } \
+         } \
+         break;
 
     // Check if array is sorted on the index column
-    psVector* sortedIndex = psVectorAlloc(numRows,PS_TYPE_U32);
-    sortedIndex = psVectorSortIndex(sortedIndex,indexColumnVector);
-    for(psS32 i = 0; i < numRows; i++ ) {
-        if(sortedIndex->data.U32[i] != i) {
-            sortNeeded = true;
-            break;
-        }
-    }
-
-    // Check if it is necessary to sort value vectors
-    if(sortNeeded) {
-        // Allocate new array to contain sorted vectors
-        psArray* newValueArray = psArrayAlloc(numCols);
-        for(psS32 j = 0; j < numCols; j++) {
-            psS32 type = ((psVector*)(vectors->data[j]))->type.type;
-            newValueArray->data[j] = psVectorAlloc(numRows,type);
-        }
-
-        // Populate new array/vectors with sorted values
-        for(psS32 i = 0; i < numRows; i++) {
-            // Populate new index vector
-            psU32 sortIndex = sortedIndex->data.U32[i];
-            // For every column populate new value vectors
-            for(psS32 j=0; j < numCols; j++) {
-                COPY_VECTOR_VALUES(newValueArray->data[j],i,vectors->data[j], sortIndex)
+    bool sortNeeded  = false;           // Do we need to sort?
+    switch (indexVector->type.type) {
+        CHECK_SORT_CASE(U8);
+        CHECK_SORT_CASE(U16);
+        CHECK_SORT_CASE(U32);
+        CHECK_SORT_CASE(U64);
+        CHECK_SORT_CASE(S8);
+        CHECK_SORT_CASE(S16);
+        CHECK_SORT_CASE(S32);
+        CHECK_SORT_CASE(S64);
+        CHECK_SORT_CASE(F32);
+        CHECK_SORT_CASE(F64);
+      default:
+        psAbort("Should never get here: bad type.");
+    }
+
+    if (sortNeeded) {
+        psVector *sortedIndex = psVectorSortIndex(NULL, indexVector); // Indices for sorting
+        psArray *newValues = psArrayAlloc(numCols);
+        for (long i = 0; i < numCols; i++) {
+            psVector *oldVector = vectors->data[i]; // Vector of interest
+            psVector *newVector = psVectorAlloc(numRows, oldVector->type.type);
+            newValues->data[i] = newVector;
+
+#define REARRANGE_CASE(TYPE) \
+    case PS_TYPE_##TYPE: \
+        for (long j = 0; j < numRows; j++) { \
+            newVector->data.TYPE[j] = oldVector->data.TYPE[sortedIndex->data.S32[j]]; \
+        } \
+        break;
+
+            switch (oldVector->type.type) {
+                REARRANGE_CASE(U8);
+                REARRANGE_CASE(U16);
+                REARRANGE_CASE(U32);
+                REARRANGE_CASE(U64);
+                REARRANGE_CASE(S8);
+                REARRANGE_CASE(S16);
+                REARRANGE_CASE(S32);
+                REARRANGE_CASE(S64);
+                REARRANGE_CASE(F32);
+                REARRANGE_CASE(F64);
+              default:
+                psAbort("Should never get here: bad type.");
             }
         }
-        // Assign new vector value to table
-        table->index = newValueArray->data[indexCol];
-        // Assign new value vectors to table array
-        table->values = newValueArray;
-        // Assign indexCol
-        table->indexCol = indexCol;
-        // Assign validTo and validFrom values
-        UPDATE_VALID_TO_FROM(table)
-
-        // Set return value
-        outputTable = table;
-
+
+        psFree(sortedIndex);
+        table->values = newValues;
     } else {
-        // Index vector is already sorted
-        // Assign array vector specified by indexCol to table index vector
-        // and increment memory ref
-        table->index = vectors->data[indexCol];
-        table->values = (psArray*)vectors;
-        psMemIncrRefCounter((psArray*)vectors);
-
-        // Assign indexCol
-        table->indexCol = indexCol;
-        // Assign validTo and validFrom values
-        UPDATE_VALID_TO_FROM(table);
-
-        // Set return value
-        outputTable = table;
-    }
-
-    // Free sort vector
-    psFree(sortedIndex);
-
-    return outputTable;
+        table->values = psMemIncrRefCounter(vectors);
+    }
+
+    table->index = psMemIncrRefCounter(table->values->data[indexCol]);
+    table->indexCol = indexCol;
+
+#define SET_VALID_CASE(TYPE) \
+    case PS_TYPE_##TYPE: \
+        *(double*)&table->validFrom = table->index->data.TYPE[0]; \
+        *(double*)&table->validTo   = table->index->data.TYPE[numRows - 1]; \
+        break;
+
+    switch (table->index->type.type) {
+        SET_VALID_CASE(U8);
+        SET_VALID_CASE(U16);
+        SET_VALID_CASE(U32);
+        SET_VALID_CASE(U64);
+        SET_VALID_CASE(S8);
+        SET_VALID_CASE(S16);
+        SET_VALID_CASE(S32);
+        SET_VALID_CASE(S64);
+        SET_VALID_CASE(F32);
+        SET_VALID_CASE(F64);
+      default:
+        psAbort("Should never get here: bad type.");
+    }
+
+    return table;
 }
 
 long psLookupTableRead(psLookupTable* table)
 {
+    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, 0);
+
     long            numRows  = 0;
     psArray*        vectors  = NULL;
     psLookupTable*  outTable = NULL;
 
-    // Check if the input table is NULL then return 0
-    PS_ASSERT_PTR_NON_NULL(table,0);
-
     // Read vectors from file specified in table
     vectors = psVectorsReadFromFile(table->filename, table->format);
 
     // Check for valid array after reading from file
-    if(vectors != NULL) {
+    if (vectors != NULL) {
 
         // Import vector into table
@@ -731,5 +549,5 @@
 
         // Update the number of rows read if outTable is not NULL
-        if(outTable != NULL) {
+        if (outTable != NULL) {
             numRows = table->index->n;
         }
@@ -780,32 +598,32 @@
 switch (TABLE->index->type.type) {                                      \
 case PS_TYPE_S32:                                                       \
-    if( (psS32)index < TABLE->index->data.S32[0] ) {                    \
+    if ( (psS32)index < TABLE->index->data.S32[0] ) {                    \
         return NAN;                                                     \
     }                                                                   \
-    if( (psS32)index > TABLE->index->data.S32[numRows-1] ) {            \
+    if ( (psS32)index > TABLE->index->data.S32[numRows-1] ) {            \
         return NAN;                                                     \
     }                                                                   \
     break;                                                              \
 case PS_TYPE_S64:                                                       \
-    if( (psS64)index < TABLE->index->data.S64[0] ) {                    \
+    if ( (psS64)index < TABLE->index->data.S64[0] ) {                    \
         return NAN;                                                     \
     }                                                                   \
-    if( (psS64)index > TABLE->index->data.S64[numRows-1] ) {            \
+    if ( (psS64)index > TABLE->index->data.S64[numRows-1] ) {            \
         return NAN;                                                     \
     }                                                                   \
     break;                                                              \
 case PS_TYPE_F32:                                                       \
-    if( (psF32)index < TABLE->index->data.F32[0] ) {                    \
+    if ( (psF32)index < TABLE->index->data.F32[0] ) {                    \
         return NAN;                                                     \
     }                                                                   \
-    if( (psF32)index > TABLE->index->data.F32[numRows-1] ) {            \
+    if ( (psF32)index > TABLE->index->data.F32[numRows-1] ) {            \
         return NAN;                                                     \
     }                                                                   \
     break;                                                              \
 case PS_TYPE_F64:                                                       \
-    if( index < TABLE->index->data.F64[0] ) {                           \
+    if ( index < TABLE->index->data.F64[0] ) {                           \
         return NAN;                                                     \
     }                                                                   \
-    if( index > TABLE->index->data.F64[numRows-1] ) {                   \
+    if ( index > TABLE->index->data.F64[numRows-1] ) {                   \
         return NAN;                                                     \
     }                                                                   \
@@ -820,4 +638,11 @@
                                 long column)
 {
+    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NAN);
+    // Ensuring information exists
+    PS_ASSERT_VECTOR_NON_NULL(table->index, NAN);
+    PS_ASSERT_ARRAY_NON_NULL(table->values, NAN);
+    PS_ASSERT_INT_WITHIN_RANGE(column, 0, (int)table->values->n - 1, NAN);
+    PS_ASSERT_VECTOR_NON_NULL((psVector*)table->values->data[column], NAN);
+
     psU64 hiIdx = 0;
     psU64 loIdx = 0;
@@ -832,19 +657,9 @@
     psArray *values = NULL;
 
-    // Check for NULL table
-    PS_ASSERT_PTR_NON_NULL(table,NAN);
-
     indexVec = table->index;
     values = table->values;
     numRows = table->index->n;
     numCols = table->values->n;
-    PS_ASSERT_PTR_NON_NULL(indexVec,NAN);
-    PS_ASSERT_PTR_NON_NULL(values,NAN);
-    PS_ASSERT_INT_UNEQUAL(numRows, 0,NAN);
-    PS_ASSERT_INT_UNEQUAL(numCols, 0,NAN);
-    PS_ASSERT_INT_WITHIN_RANGE(column, 0, (int)(numCols-1), NAN);
-
     valuesVec = (psVector*)values->data[column];
-    PS_ASSERT_PTR_NON_NULL(indexVec,NAN);
 
     // Verify the index is within the bounds of the table
@@ -853,8 +668,8 @@
     // Find location in table where specified index is between to entries
     CONVERT_VALUE_TO_F64(indexVec, 0, convertVal)
-    while(index > convertVal ) {
+    while (index > convertVal ) {
         hiIdx++;
         /*  XXX:  following is unreachable.
-                if(hiIdx >= numRows) {
+                if (hiIdx >= numRows) {
                     psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                             _("High index too big, %" PRIu64 "."), hiIdx);
@@ -867,5 +682,5 @@
     // Check for negative low index and generate error
     loIdx = hiIdx--;
-    if(loIdx < 0) {
+    if (loIdx < 0) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 _("Low index too small, %" PRIu64 "."), loIdx);
@@ -877,5 +692,5 @@
     CONVERT_VALUE_TO_F64(indexVec, loIdx, convertVal);
     denom -= convertVal;
-    if(fabs(denom) < FLT_EPSILON) {
+    if (fabs(denom) < FLT_EPSILON) {
         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
                 _("Divide by zero error during interpolation."));
@@ -897,20 +712,17 @@
                                       double index)
 {
-    long numCols = 0;
-    psVector *outVector = NULL;
-
-    // Error checks
-    PS_ASSERT_PTR_NON_NULL(table,NULL);
-    PS_ASSERT_PTR_NON_NULL(table->values,NULL);
-    numCols = table->values->n;
-    PS_ASSERT_INT_UNEQUAL(numCols, 0,NULL);
-
-    // Create output vector
-    outVector = psVectorAlloc(numCols, PS_TYPE_F64);
+    PS_ASSERT_LOOKUPTABLE_NON_NULL(table, NULL);
+    // Ensuring information exists
+    PS_ASSERT_VECTOR_NON_NULL(table->index, NULL);
+    PS_ASSERT_ARRAY_NON_NULL(table->values, NULL);
+
+    long numCols = table->values->n;
+    psVector *outVector = psVectorAlloc(numCols, PS_TYPE_F64);
 
     // Fill vectors with results and status of results
-    for(psU64 i=0; i<numCols; i++) {
+    // XXX: This algorithm must be changed to something more efficient!
+    for (long i = 0; i < numCols; i++) {
         outVector->data.F64[i] = psLookupTableInterpolate(table, index, i);
-        if(isnan(outVector->data.F64[i])) {
+        if (isnan(outVector->data.F64[i])) {
             // Free allocated vector
             psFree(outVector);
