IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Changeset 27774


Ignore:
Timestamp:
Apr 26, 2010, 12:25:43 PM (16 years ago)
Author:
Paul Price
Message:

Rework to allow lines of an arbitrary size. Cleaned up code too.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/types/psLookupTable.c

    r17447 r27774  
    3131#include "psString.h"
    3232#include "psError.h"
     33#include "psString.h"
     34#include "psSlurp.h"
    3335#include "psLookupTable.h"
    3436
     
    153155        char *end = NULL; \
    154156        ps##TYPE value = FUNC(strValue, &end, 0); \
    155         if (*end != '\0' && !isspace(*end)) { \
     157        if (*end != '\0' && *end != '\n' && !isspace(*end)) { \
     158            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Characters left over after parsing %s: %s", \
     159                strValue, end); \
    156160            *status = PS_PARSE_ERROR_VALUE; \
    157161        } \
     
    164168        char *end = NULL; \
    165169        ps##TYPE value = FUNC(strValue, &end); \
    166         if (*end != '\0' && !isspace(*end)) { \
     170        if (*end != '\0' && *end != '\n' && !isspace(*end)) { \
     171            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Characters left over after parsing %s: %s", \
     172                strValue, end); \
    167173            *status = PS_PARSE_ERROR_VALUE; \
    168174        } \
     
    244250}
    245251
    246 psArray *psVectorsReadFromFile(const char *filename,
    247                                const char *format)
     252psArray *psVectorsReadFromFile(const char *filename, const char *format)
    248253{
    249254    PS_ASSERT_STRING_NON_EMPTY(filename, NULL);
    250255    PS_ASSERT_STRING_NON_EMPTY(format, NULL);
    251256
    252     psArray*          outputArray = NULL;
    253     psVector*         colVector   = NULL;
    254     char*             strValue    = NULL;
    255     char*             strNum      = NULL;
    256     char*             line        = NULL;
    257     char*             linePtr     = NULL;
    258     int               numCols     = 0;
    259     int               numRows     = 0;
    260     FILE*             fp          = NULL;
    261     const char*       tempFormat  = NULL;
    262     psParseErrorType  parseStatus = PS_PARSE_SUCCESS;
    263 
    264     // Create temp pointer which can then be used several times
    265     tempFormat = format;
    266 
    267     // Create output array and set array elements to zero
    268     outputArray = psArrayAllocEmpty(INITIAL_NUM);
    269 
    270     // Parse the format string to determine how many vectors
    271     // and whether the format string is valid
    272     while ((strValue = getToken((char**)&tempFormat, " \t", &parseStatus))) {
    273 
    274         // Check for %d format sub string
     257    psArray *outputArray = psArrayAllocEmpty(INITIAL_NUM); // Array of vectors to return
     258    psParseErrorType parseStatus = PS_PARSE_SUCCESS; // Status of parsing
     259
     260    // Parse the format string to determine how many vectors and whether the format string is valid
     261    const char *tempFormat = format;    // Pointer into format
     262    psString strValue;                  // Format of interest
     263    int numCols = 0;                    // Number of columns found in format
     264    while ((strValue = getToken((char**)&tempFormat, " \t", &parseStatus)) &&
     265           parseStatus == PS_PARSE_SUCCESS) {
     266        if (strstr(strValue,"\%*") != 0) {
     267            // Don't increase number of columns
     268            continue;
     269        }
     270        psElemType type;                // Type specified
    275271        if (strcmp(strValue,"\%d") == 0 ) {
    276             numCols++;
    277             colVector = psVectorAlloc(1,PS_TYPE_S32);
    278             outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
    279             psFree(colVector);
     272            type = PS_TYPE_S32;
    280273        } else if (strcmp(strValue,"\%ld") == 0) {
    281             numCols++;
    282             colVector = psVectorAlloc(1,PS_TYPE_S64);
    283             outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
    284             psFree(colVector);
     274            type = PS_TYPE_S64;
    285275        } else if (strcmp(strValue,"\%f") == 0) {
    286             numCols++;
    287             colVector = psVectorAlloc(1,PS_TYPE_F32);
    288             outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
    289             psFree(colVector);
     276            type = PS_TYPE_F32;
    290277        } else if (strcmp(strValue,"\%lf") == 0) {
    291             numCols++;
    292             colVector = psVectorAlloc(1,PS_TYPE_F64);
    293             outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
    294             psFree(colVector);
    295         } else if (strstr(strValue,"\%*") != 0) {
    296             // Don't increase number of columns
     278            type = PS_TYPE_F64;
    297279        } else {
    298             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    299                     "Invalid format specifier");
     280            psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Invalid format specifier: %s", strValue);
    300281            psFree(strValue);
    301             numCols = 0;
    302             break;
    303         }
     282            psFree(outputArray);
     283            return NULL;
     284        }
     285        psVector *colVector = psVectorAllocEmpty(1, type); // Vector for type
     286        outputArray = psArrayAdd(outputArray, ARRAY_STRIDE, colVector);
     287        psFree(colVector);
     288        numCols++;
    304289        psFree(strValue);
     290    }
     291    if (parseStatus != PS_PARSE_SUCCESS) {
     292        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Failed to parse format at column %d: %s",
     293                numCols, strValue);
     294        psFree(strValue);
     295        psFree(outputArray);
     296        return NULL;
     297    }
     298
     299    if (numCols == 0) {
     300        // Format string parse error detected
     301        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Format string was not parsed sucessfully");
     302        psFree(outputArray);
     303        return NULL;
    305304    }
    306305
    307306    // If the format string was parsed successfully and return numCols the
    308307    // prepare to open file and read values
    309     if (numCols > 0) {
    310 
    311         // Open specified file
    312         if ((fp=fopen(filename, "r")) == NULL) {
    313             psError(PS_ERR_BAD_PARAMETER_VALUE, true, _("Failed to open file %s."),
    314                     filename);
    315             psFree(outputArray);
    316             return NULL;
    317         } else {
    318             // Initialize array index
    319             int arrayIndex = 0;
    320 
    321             // Create reusable line for continuous read
    322             line = (char*)psAlloc(MAX_STRING_LENGTH*sizeof(char));
    323 
    324             // Loop through file to get numRows, numCols, and column data types
    325             while ((fgets(line, MAX_STRING_LENGTH, fp) != NULL) &&
    326                     (parseStatus == PS_PARSE_SUCCESS))   {
    327 
    328                 // Copy pointer to line for parsing
    329                 linePtr = line;
    330 
    331                 // If line is not a comment or blank, then extract data
    332                 if (!ignoreLine(linePtr)) {
    333                     numRows++;
    334 
    335                     // Copy format pointer for parsing
    336                     tempFormat = format;
    337                     arrayIndex = 0;
    338                     parseStatus = PS_PARSE_SUCCESS;
    339 
    340                     // Loop through format and line strings to get values in text table file
    341                     while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus))
    342                             && (strNum=getToken((char**)&linePtr," \t",&parseStatus)) ) {
    343                         // Set column vector
    344                         colVector = outputArray->data[arrayIndex];
    345 
    346                         // Set column entries based on format string defining the type
    347                         if (strcmp(strValue,"\%d") == 0 ) {
    348                             colVector = psVectorRecycle(colVector, numRows,
    349                                                         colVector->type.type);
    350                             parseValue(colVector,numRows-1,strNum,&parseStatus);
    351                             arrayIndex++;
    352                         } else if (strcmp(strValue,"\%ld") == 0) {
    353                             colVector = psVectorRecycle(colVector, numRows,
    354                                                         colVector->type.type);
    355                             parseValue(colVector,numRows-1,strNum,&parseStatus);
    356                             arrayIndex++;
    357                         } else if (strcmp(strValue,"\%f") == 0) {
    358                             colVector = psVectorRecycle(colVector, numRows,
    359                                                         colVector->type.type);
    360                             parseValue(colVector,numRows-1,strNum,&parseStatus);
    361                             arrayIndex++;
    362                         } else if (strcmp(strValue,"\%lf") == 0) {
    363                             colVector = psVectorRecycle(colVector, numRows,
    364                                                         colVector->type.type);
    365                             parseValue(colVector,numRows-1,strNum,&parseStatus);
    366                             arrayIndex++;
    367                         } else if (strstr(strValue,"\%*") != 0) {
    368                             // Don't increase number of columns
    369                         }
    370                         psFree(strValue);
    371                         psFree(strNum);
    372 
    373                         // If the file line was not parsed successful report
    374                         // error and return NULL
    375                         if (parseStatus != PS_PARSE_SUCCESS) {
    376                             psError(PS_ERR_UNKNOWN, true,
    377                                     "Parsing text file failed.");
    378                             fclose(fp);
    379                             psFree(outputArray);
    380                             psFree(line);
    381                             return NULL;
    382                         }
    383                     }
    384                     if (strValue != NULL && strNum == NULL) {
    385                         psError(PS_ERR_UNKNOWN, true,
    386                                 "Parsing text file failed - missing table value(s).");
    387                         fclose(fp);
    388                         psFree(outputArray);
    389                         psFree(line);
    390                         psFree(strValue);
    391                         return NULL;
    392                     }
    393                 }  // ignore line
     308
     309    psString file = psSlurpFilename(filename); // Contents of file
     310    if (!file) {
     311        psError(psErrorCodeLast(), false, "Unable to read file of vectors");
     312        psFree(outputArray);
     313        return NULL;
     314    }
     315
     316    psArray *lines = psStringSplitArray(file, "\n", false); // Lines of file
     317    psFree(file);
     318    long numRows = 0;                                  // Number of rows
     319    for (long i = 0; i < lines->n; i++) {
     320        psString line = lines->data[i]; // Line of interest
     321        if (ignoreLine(line)) {
     322            continue;
     323        }
     324        numRows++;
     325
     326        char *linePtr = line;           // Pointer into line
     327
     328        // Copy format pointer for parsing
     329        const char *tempFormat = format; // Pointer into format
     330        long arrayIndex = 0;            // Index in array
     331        parseStatus = PS_PARSE_SUCCESS;
     332
     333        // Loop through format and line strings to get values in text table file
     334        char *strNum;                   // Number within line
     335        while ((strValue=getToken((char**)&tempFormat," \t",&parseStatus)) &&
     336               (strNum=getToken((char**)&linePtr," \t",&parseStatus)) &&
     337               parseStatus == PS_PARSE_SUCCESS) {
     338            if (strstr(strValue,"\%*") != 0) {
     339                continue;
    394340            }
    395341
    396             //Return NULL for an empty table
    397             if (numRows == 0) {
    398                 psError(PS_ERR_UNKNOWN, true,
    399                         "Parsing text file failed - input table is empty.");
    400                 fclose(fp);
     342            // Set column vector
     343            psVector *colVector = outputArray->data[arrayIndex]; // Column vector of interest
     344
     345            outputArray->data[arrayIndex] = colVector = psVectorRecycle(colVector, numRows,
     346                                                                        colVector->type.type);
     347            parseValue(colVector, numRows - 1, strNum, &parseStatus);
     348            arrayIndex++;
     349
     350            if (parseStatus != PS_PARSE_SUCCESS) {
     351                psError(PS_ERR_UNKNOWN, false, "Parsing text file failed: %s as %s", strNum, strValue);
    401352                psFree(outputArray);
    402                 psFree(line);
     353                psFree(lines);
     354                psFree(strNum);
     355                psFree(strValue);
    403356                return NULL;
    404357            }
    405 
    406             // Read on the lines in the file - close file pointer
    407             fclose(fp);
    408             psFree(line);
    409         }
    410     } else {
    411         // Format string parse error detected
    412         psError(PS_ERR_UNKNOWN, true,
    413                 "Format string was not parsed sucessfully");
     358            psFree(strValue);
     359            psFree(strNum);
     360
     361        }
     362        if (strValue != NULL && strNum == NULL) {
     363            psError(PS_ERR_UNKNOWN, true,
     364                    "Parsing text file failed - missing table value(s).");
     365            psFree(outputArray);
     366            psFree(lines);
     367            psFree(strValue);
     368            return NULL;
     369        }
     370    }
     371    if (parseStatus != PS_PARSE_SUCCESS) {
     372        psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Failed to parse format at column %d: %s",
     373                numCols, strValue);
     374        psFree(strValue);
    414375        psFree(outputArray);
    415376        return NULL;
    416377    }
     378
     379    psFree(lines);
    417380
    418381    // Return populated array
Note: See TracChangeset for help on using the changeset viewer.