IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Jun 1, 2006, 2:55:23 PM (20 years ago)
Author:
Paul Price
Message:

Addition of a vast quantity of assertions in public functions. Adopted a policy of using assert() within file-static functions (since they are only called internally, any errors there are problems with the program) and using the PS_ASSERT_WHATEVER() macros within public functions. Cleaned a few things up in the process.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/psModules/src/concepts/pmConceptsWrite.c

    r7017 r7278  
    11#include <stdio.h>
     2#include <assert.h>
    23#include <strings.h>
    34#include "pslib.h"
     
    110111                                    )
    111112{
     113    assert(spec);
     114    assert(cameraFormat);
     115
    112116    if (concept) {
    113117        psMetadataItem *formatted = NULL;  // The formatted concept
     
    129133                             )
    130134{
     135    assert(hdu);
     136    assert(keyword && strlen(keyword) > 0);
     137    assert(item);
     138
    131139    if (!hdu->header) {
    132140        return false;
     
    166174                       )
    167175{
     176    assert(hdu);
     177    assert(keywords);
     178    assert(item);
     179
    168180    bool status = true;                 // Status of writing headers, to be returned
    169181    if (item->type == PS_DATA_LIST) {
     
    204216                            )
    205217{
    206     if (cell) {
    207         pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
    208         if (!hdu) {
    209             return false;
    210         }
    211         psMetadata *cameraFormat = hdu->format; // The camera format
    212         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    213         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    214         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    215             pmConceptSpec *spec = specItem->data.V; // The specification
    216             psString name = specItem->name; // The concept name
    217             psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera,
    218             // or NULL
    219             if (cameraItem) {
    220                 // Grab the concept
    221                 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept
    222                 // Formatted version
    223                 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell);
    224                 if (!formatted) {
    225                     continue;
    226                 }
    227                 psString nameSource = NULL; // String with the concept name and ".SOURCE" added
    228                 psStringAppend(&nameSource, "%s.SOURCE", name);
    229                 bool mdok = true;       // Status of MD lookup
    230                 psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
    231                 if (mdok && strlen(source) > 0) {
    232                     psTrace(__func__, 8, "%s is %s\n", nameSource, source);
    233                     if (strcasecmp(source, "HEADER") == 0) {
    234                         if (cameraItem->type != PS_DATA_STRING) {
    235                             psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not "
    236                                      "of type STR --- ignored.\n", conceptItem->name);
    237                             continue;
    238                         }
    239                         psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V);
    240                         writeHeader(hdu, cameraItem->data.V, formatted);
    241                     } else if (strcasecmp(source, "VALUE") == 0) {
    242                         psTrace(__func__, 8, "Checking %s against camera format.\n", name);
    243                         if (! compareConcepts(formatted, cameraItem)) {
    244                             psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
    245                                      "format, but the values don't match.\n", name);
    246                         }
    247                     } else {
    248                         psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't "
    249                                  "write\n", nameSource);
     218    PS_ASSERT_PTR_NON_NULL(specs, false);
     219    PS_ASSERT_PTR_NON_NULL(concepts, false);
     220    if (!cell) {
     221        return false;
     222    }
     223
     224    pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
     225    if (!hdu) {
     226        return false;
     227    }
     228    psMetadata *cameraFormat = hdu->format; // The camera format
     229    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     230    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     231    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     232        pmConceptSpec *spec = specItem->data.V; // The specification
     233        psString name = specItem->name; // The concept name
     234        psMetadataItem *cameraItem = psMetadataLookup(cell->config, name); // The concept from the camera,
     235        // or NULL
     236        if (cameraItem) {
     237            // Grab the concept
     238            psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The concept
     239            // Formatted version
     240            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, NULL, NULL, cell);
     241            if (!formatted) {
     242                continue;
     243            }
     244            psString nameSource = NULL; // String with the concept name and ".SOURCE" added
     245            psStringAppend(&nameSource, "%s.SOURCE", name);
     246            bool mdok = true;       // Status of MD lookup
     247            psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
     248            if (mdok && strlen(source) > 0) {
     249                psTrace(__func__, 8, "%s is %s\n", nameSource, source);
     250                if (strcasecmp(source, "HEADER") == 0) {
     251                    if (cameraItem->type != PS_DATA_STRING) {
     252                        psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by header, but is not "
     253                                 "of type STR --- ignored.\n", conceptItem->name);
     254                        continue;
    250255                    }
    251                 } else if (! compareConcepts(formatted, cameraItem)) {
    252                     // Assume it's specified by value
    253                     psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
    254                              "format, but the values don't match.\n", name);
    255                 }
    256                 psFree(formatted);
    257                 psFree(nameSource);
    258             }
    259 
    260         }
    261         psFree(specsIter);
    262         return true;
    263     }
    264     return false;
     256                    psTrace(__func__, 8, "Writing %s to header %s\n", name, cameraItem->data.V);
     257                    writeHeader(hdu, cameraItem->data.V, formatted);
     258                } else if (strcasecmp(source, "VALUE") == 0) {
     259                    psTrace(__func__, 8, "Checking %s against camera format.\n", name);
     260                    if (! compareConcepts(formatted, cameraItem)) {
     261                        psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
     262                                 "format, but the values don't match.\n", name);
     263                    }
     264                } else {
     265                    psLogMsg(__func__, PS_LOG_WARN, "Concept source %s isn't HEADER or VALUE --- can't "
     266                             "write\n", nameSource);
     267                }
     268            } else if (! compareConcepts(formatted, cameraItem)) {
     269                // Assume it's specified by value
     270                psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by value in the camera "
     271                         "format, but the values don't match.\n", name);
     272            }
     273            psFree(formatted);
     274            psFree(nameSource);
     275        }
     276
     277    }
     278    psFree(specsIter);
     279    return true;
    265280}
    266281
     
    272287                              )
    273288{
     289    PS_ASSERT_PTR_NON_NULL(specs, false);
     290    PS_ASSERT_PTR_NON_NULL(concepts, false);
     291
    274292    pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
    275293    if (!hdu) {
     
    279297    bool mdok = true;                   // Status of MD lookup
    280298    psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec
    281     if (mdok && defaults) {
    282         pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
    283         psMetadata *cameraFormat = hdu->format; // The camera format
    284         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    285         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    286         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    287             pmConceptSpec *spec = specItem->data.V; // The specification
    288             psString name = specItem->name; // The concept name
    289             psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS
    290             if (defaultItem) {
    291                 psMetadataItem *conceptItem = NULL; // The item from the concepts
    292                 if (defaultItem->type == PS_DATA_METADATA) {
    293                     // It's a menu --- need to look up the .DEPEND
    294                     psString dependName = NULL; // The concept name with ".DEPEND" on the end
    295                     psStringAppend(&dependName, ".DEPEND");
    296                     psString dependKey = psMetadataLookupStr(&mdok, defaults, dependName); // The keyword
    297                     psFree(dependName);
    298                     if (!mdok || !dependKey || strlen(dependKey) == 0) {
    299                         psLogMsg(__func__, PS_LOG_WARN, "Can't find %s in the DEFAULTS for %s --- ignored.\n",
    300                                  dependName, name);
    301                         continue;
    302                     }
    303                     psString dependValue = psMetadataLookupStr(&mdok, concepts, dependName); // The value
    304                     if (!mdok || !dependKey || strlen(dependKey) == 0) {
    305                         psLogMsg(__func__, PS_LOG_WARN, "Concept %s specified by %s isn't of type STR -- "
    306                                  "ignored.\n", name, dependName);
    307                         continue;
    308                     }
    309                     conceptItem = psMetadataLookup(defaultItem->data.V, dependValue);
    310                 } else {
    311                     conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
    312                 }
    313                 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
    314                 if (!formatted) {
     299    if (!mdok || !defaults) {
     300        return false;
     301    }
     302
     303    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     304    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     305    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     306        pmConceptSpec *spec = specItem->data.V; // The specification
     307        psString name = specItem->name; // The concept name
     308        psMetadataItem *defaultItem = psMetadataLookup(defaults, name); // The item from the DEFAULTS
     309        if (defaultItem) {
     310            psMetadataItem *conceptItem = NULL; // The item from the concepts
     311            if (defaultItem->type == PS_DATA_METADATA) {
     312                // It's a menu --- need to look up the .DEPEND
     313                psString dependName = NULL; // The concept name with ".DEPEND" on the end
     314                psStringAppend(&dependName, ".DEPEND");
     315                psString dependKey = psMetadataLookupStr(&mdok, defaults, dependName); // The keyword
     316                psFree(dependName);
     317                if (!mdok || !dependKey || strlen(dependKey) == 0) {
     318                    psLogMsg(__func__, PS_LOG_WARN, "Can't find %s in the DEFAULTS for %s --- ignored.\n",
     319                             dependName, name);
    315320                    continue;
    316321                }
    317                 if (! compareConcepts(formatted, defaultItem)) {
    318                     psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera "
    319                              "format, but the values don't match.\n", name);
    320                 }
    321                 psFree(formatted);
    322             }
    323         }
    324         psFree(specsIter);
    325         return true;
    326     }
    327     return false;
     322                psString dependValue = psMetadataLookupStr(&mdok, concepts, dependName); // The value
     323                if (!mdok || !dependKey || strlen(dependKey) == 0) {
     324                    psLogMsg(__func__, PS_LOG_WARN, "Concept %s specified by %s isn't of type STR -- "
     325                             "ignored.\n", name, dependName);
     326                    continue;
     327                }
     328                conceptItem = psMetadataLookup(defaultItem->data.V, dependValue);
     329            } else {
     330                conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
     331            }
     332            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
     333            if (!formatted) {
     334                continue;
     335            }
     336            if (! compareConcepts(formatted, defaultItem)) {
     337                psLogMsg(__func__, PS_LOG_WARN, "Concept %s is specified by the DEFAULTS in the camera "
     338                         "format, but the values don't match.\n", name);
     339            }
     340            psFree(formatted);
     341        }
     342    }
     343    psFree(specsIter);
     344    return true;
    328345}
    329346
     
    336353                            )
    337354{
     355    PS_ASSERT_PTR_NON_NULL(specs, false);
     356    PS_ASSERT_PTR_NON_NULL(concepts, false);
     357
    338358    pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
    339359    if (!hdu) {
     
    343363    bool mdok = true;                   // Status of MD lookup
    344364    psMetadata *translation = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec
    345     if (mdok && translation) {
    346         pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
    347         psMetadata *cameraFormat = hdu->format; // The camera format
    348         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    349         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    350         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    351             pmConceptSpec *spec = specItem->data.V; // The specification
    352             psString name = specItem->name; // The concept name
    353             psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION
    354             if (headerItem) {
    355                 if (headerItem->type != PS_DATA_STRING) {
    356                     psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---"
    357                              " ignored.", name);
    358                     continue;
    359                 }
    360                 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
    361                 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
    362                 if (!formatted) {
    363                     continue;
    364                 }
    365                 psList *keywords = psStringSplit(headerItem->data.V, " ,;", true); // List of header keywords
    366                 if (formatted->type == PS_DATA_LIST) {
    367                     psList *values = formatted->data.V; // The values for the headers
    368                     if (values->n != keywords->n) {
    369                         psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number "
    370                                  "of values for concept %s.\n", name);
     365    if (!mdok || !translation) {
     366        return false;
     367    }
     368
     369    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     370    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     371    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     372        pmConceptSpec *spec = specItem->data.V; // The specification
     373        psString name = specItem->name; // The concept name
     374        psMetadataItem *headerItem = psMetadataLookup(translation, name); // The item from the TRANSLATION
     375        if (headerItem) {
     376            if (headerItem->type != PS_DATA_STRING) {
     377                psLogMsg(__func__, PS_LOG_WARN, "TRANSLATION keyword for concept %s isn't of type STR ---"
     378                         " ignored.", name);
     379                continue;
     380            }
     381            psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
     382            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
     383            if (!formatted) {
     384                continue;
     385            }
     386            psList *keywords = psStringSplit(headerItem->data.V, " ,;", true); // List of header keywords
     387            if (formatted->type == PS_DATA_LIST) {
     388                psList *values = formatted->data.V; // The values for the headers
     389                if (values->n != keywords->n) {
     390                    psLogMsg(__func__, PS_LOG_WARN, "Number of headers specified does not match number "
     391                             "of values for concept %s.\n", name);
     392                }
     393                psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator
     394                psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false);
     395                psMetadataItem *valuesItem = NULL; // Item from list
     396                while ((valuesItem = psListGetAndIncrement(valuesIter))) {
     397                    psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list
     398                    if (strlen(keyword) > 0) {
     399                        writeHeader(hdu, keyword, formatted);
    371400                    }
    372                     psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false); // Iterator
    373                     psListIterator *keywordsIter = psListIteratorAlloc(keywords, PS_LIST_HEAD, false);
    374                     psMetadataItem *valuesItem = NULL; // Item from list
    375                     while ((valuesItem = psListGetAndIncrement(valuesIter))) {
    376                         psString keyword = psListGetAndIncrement(keywordsIter); // Keyword from the list
    377                         if (strlen(keyword) > 0) {
    378                             writeHeader(hdu, keyword, formatted);
    379                         }
    380                     }
    381                     psFree(valuesIter);
    382                     psFree(keywordsIter);
    383                 } else {
    384                     psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword
    385                     writeHeader(hdu, keyword, formatted);
    386                 }
    387                 psFree(formatted);
    388                 psFree(keywords);
    389             }
    390         }
    391         psFree(specsIter);
    392         return true;
    393     }
    394     return false;
     401                }
     402                psFree(valuesIter);
     403                psFree(keywordsIter);
     404            } else {
     405                psString keyword = psListGet(keywords, PS_LIST_HEAD); // The keyword
     406                writeHeader(hdu, keyword, formatted);
     407            }
     408            psFree(formatted);
     409            psFree(keywords);
     410        }
     411    }
     412    psFree(specsIter);
     413    return true;
    395414}
    396415
     
    404423                              )
    405424{
     425    PS_ASSERT_PTR_NON_NULL(specs, false);
     426    PS_ASSERT_PTR_NON_NULL(concepts, false);
     427
     428    if (!db) {
     429        return false;
     430    }
     431
    406432    #ifdef OMIT_PSDB
    407433    return false;
     
    415441    bool mdok = true;                   // Status of MD lookup
    416442    psMetadata *database = psMetadataLookupMD(&mdok, cameraFormat, "DATABASE"); // The DATABASE spec
    417     if (mdok && database) {
    418         pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
    419         psMetadata *cameraFormat = hdu->format; // The camera format
    420         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    421         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    422         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    423             pmConceptSpec *spec = specItem->data.V; // The specification
    424             psString name = specItem->name; // The concept name
    425 
    426             psMetadataItem *dbItem = psMetadataLookup(database, name); // The item from the DATABASE
    427             if (dbItem) {
    428                 if (dbItem->type != PS_DATA_METADATA) {
    429                     psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA "
    430                              "--- ignored.\n", name);
    431                     continue;
    432                 }
    433 
    434                 psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
    435                 psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
    436                 if (!formatted) {
    437                     continue;
    438                 }
    439 
    440                 psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest
    441                 // Name of the table
    442                 const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE");
    443                 // Name of "where" columns
    444                 const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
    445                 // Values for "where" columns
    446                 const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
    447 
    448                 // Now, need to get the "given"s
    449                 if (strlen(givenCols) || strlen(givenPS)) {
    450                     psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
    451                     psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
    452                     psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
    453                     if (cols->n != values->n) {
    454                         psLogMsg(__func__, PS_LOG_WARN,
    455                                  "The GIVENDBCOL and GIVENPS entries for %s do not have "
    456                                  "the same number of entries --- ignored.\n", name);
     443    if (!mdok || !database) {
     444        return false;
     445    }
     446    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     447    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     448    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     449        pmConceptSpec *spec = specItem->data.V; // The specification
     450        psString name = specItem->name; // The concept name
     451
     452        psMetadataItem *dbItem = psMetadataLookup(database, name); // The item from the DATABASE
     453        if (dbItem) {
     454            if (dbItem->type != PS_DATA_METADATA) {
     455                psLogMsg(__func__, PS_LOG_WARN, "DATABASE keyword for concept %s isn't of type METADATA "
     456                         "--- ignored.\n", name);
     457                continue;
     458            }
     459
     460            psMetadataItem *conceptItem = psMetadataLookup(concepts, name); // The item from the concepts
     461            psMetadataItem *formatted = conceptFormat(spec, conceptItem, cameraFormat, fpa, chip, cell);
     462            if (!formatted) {
     463                continue;
     464            }
     465
     466            psMetadata *dbLookup = dbItem->data.V; // How to look up the value of interest
     467            // Name of the table
     468            const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE");
     469            // Name of "where" columns
     470            const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
     471            // Values for "where" columns
     472            const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
     473
     474            // Now, need to get the "given"s
     475            if (strlen(givenCols) || strlen(givenPS)) {
     476                psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
     477                psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
     478                psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
     479                if (cols->n != values->n) {
     480                    psLogMsg(__func__, PS_LOG_WARN,
     481                             "The GIVENDBCOL and GIVENPS entries for %s do not have "
     482                             "the same number of entries --- ignored.\n", name);
     483                } else {
     484                    // Iterators for the lists
     485                    psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
     486                    psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
     487                    char *column = NULL;    // Name of the column
     488                    while ((column = psListGetAndIncrement(colsIter))) {
     489                        char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
     490                        if (!strlen(column) || !strlen(name)) {
     491                            psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
     492                                     " empty --- ignored.\n", name);
     493                        } else {
     494                            // Search for the value name
     495                            psMetadataItem *item = NULL; // The value
     496                            if (!item && cell) {
     497                                item = psMetadataLookup(cell->concepts, dependName);
     498                            }
     499                            if (!item && chip) {
     500                                item = psMetadataLookup(chip->concepts, dependName);
     501                            }
     502                            if (!item && fpa) {
     503                                item = psMetadataLookup(fpa->concepts, dependName);
     504                            }
     505                            if (! item) {
     506                                psLogMsg(__func__, PS_LOG_ERROR,
     507                                         "Unable to find the value name %s for DB "
     508                                         " lookup on %s --- ignored.\n", dependName, name);
     509                            } else {
     510                                // We need to create a new psMetadataItem.  I don't think we can't simply
     511                                // hack the existing one, since that could conceivably cause memory leaks
     512                                psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE);
     513                                psFree(formatted);
     514                            }
     515                        }
     516                        psFree(dependName);
     517                        psFree(column);
     518                    } // Iterating through the columns
     519                    psFree(colsIter);
     520                    psFree(valuesIter);
     521
     522                    // Check first to make sure we're only going to touch one row
     523                    psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
     524                    // Note that we use limit=2 in order to test if there are multiple rows returned
     525                    if (! dbResult || dbResult->n == 0) {
     526                        psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- "
     527                                 "ignored\n", name);
     528                        return false;
    457529                    } else {
    458                         // Iterators for the lists
    459                         psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
    460                         psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
    461                         char *column = NULL;    // Name of the column
    462                         while ((column = psListGetAndIncrement(colsIter))) {
    463                             char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
    464                             if (!strlen(column) || !strlen(name)) {
    465                                 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
    466                                          " empty --- ignored.\n", name);
    467                             } else {
    468                                 // Search for the value name
    469                                 psMetadataItem *item = NULL; // The value
    470                                 if (!item && cell) {
    471                                     item = psMetadataLookup(cell->concepts, dependName);
    472                                 }
    473                                 if (!item && chip) {
    474                                     item = psMetadataLookup(chip->concepts, dependName);
    475                                 }
    476                                 if (!item && fpa) {
    477                                     item = psMetadataLookup(fpa->concepts, dependName);
    478                                 }
    479                                 if (! item) {
    480                                     psLogMsg(__func__, PS_LOG_ERROR,
    481                                              "Unable to find the value name %s for DB "
    482                                              " lookup on %s --- ignored.\n", dependName, name);
    483                                 } else {
    484                                     // We need to create a new psMetadataItem.  I don't think we can't simply
    485                                     // hack the existing one, since that could conceivably cause memory leaks
    486                                     psMetadataAddItem(selection, formatted, PS_LIST_TAIL, PS_META_REPLACE);
    487                                     psFree(formatted);
    488                                 }
    489                             }
    490                             psFree(dependName);
    491                             psFree(column);
    492                         } // Iterating through the columns
    493                         psFree(colsIter);
    494                         psFree(valuesIter);
    495 
    496                         // Check first to make sure we're only going to touch one row
    497                         psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
    498                         // Note that we use limit=2 in order to test if there are multiple rows returned
    499                         if (! dbResult || dbResult->n == 0) {
    500                             psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- "
    501                                      "ignored\n", name);
    502                             return false;
    503                         } else {
    504                             if (dbResult->n > 1) {
    505                                 psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s "
    506                                          "--- ignored.\n", name);
    507                             }
    508                             // Update the DB
    509                             psMetadata *update = psMetadataAlloc();
    510                             psMetadataAddItem(update, conceptItem, PS_LIST_HEAD, 0);
    511                             psDBUpdateRows(db, tableName, selection, update);
    512                             psFree(update);
    513                             return true;
     530                        if (dbResult->n > 1) {
     531                            psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s "
     532                                     "--- ignored.\n", name);
    514533                        }
     534                        // Update the DB
     535                        psMetadata *update = psMetadataAlloc();
     536                        psMetadataAddItem(update, conceptItem, PS_LIST_HEAD, 0);
     537                        psDBUpdateRows(db, tableName, selection, update);
     538                        psFree(update);
     539                        return true;
    515540                    }
    516                     psFree(cols);
    517                     psFree(values);
    518                 } // Doing the "given"s.
    519             }
    520         }
    521         psFree(specsIter);
    522         return true;
    523     }
    524     return false;
     541                }
     542                psFree(cols);
     543                psFree(values);
     544            } // Doing the "given"s.
     545        }
     546    }
     547    psFree(specsIter);
     548    return true;
    525549    #endif
    526550}
    527551
    528 
    529 
    530 
    531 #if 0
    532 
    533 // Well, not really "write", but check to make sure it's there and matches
    534 bool pmConceptWriteToCamera(pmCell *cell, // The cell
    535                             psMetadataItem *concept // Concept
    536                            )
    537 {
    538     if (! cell->config) {
    539         return false;
    540     }
    541     if (cell) {
    542         psMetadataItem *item = psMetadataLookup(cell->config, concept->name); // Info we want
    543         return compareConcepts(item, concept);
    544     }
    545 
    546     return false;
    547 }
    548 
    549 // Write the concept to the header in the appropriate location
    550 bool pmConceptWriteToHeader(pmFPA *fpa, // The FPA that contains the chip
    551                             pmChip *chip, // The chip that contains the cell
    552                             pmCell *cell, // The cell
    553                             psMetadataItem *concept // Concept
    554                            )
    555 {
    556     bool mdok = true;                   // Status of MD lookup
    557     bool status = false;                // Status of setting header
    558     if (! fpa->camera) {
    559         return false;
    560     }
    561     psMetadata *translation = psMetadataLookupMD(&mdok, fpa->camera, "TRANSLATION"); // FITS translation
    562     if (! mdok) {
    563         psError(PS_ERR_IO, false, "Unable to find TRANSLATION in camera configuration.\n");
    564         return false;
    565     }
    566 
    567     // Look for how to translate the concept into a FITS header name
    568     const char *keyword = psMetadataLookupStr(&mdok, translation, concept->name);
    569     if (mdok && strlen(keyword) > 0) {
    570         psTrace(__func__, 6, "It's in keyword %s\n", keyword);
    571         psMetadataItem *headerItem = NULL; // Item to add to header
    572         // XXX: Need to expand range of types
    573         switch (concept->type) {
    574         case PS_DATA_STRING:
    575             headerItem = psMetadataItemAllocStr(keyword, concept->comment, concept->data.V);
    576             break;
    577         case PS_DATA_S32:
    578             headerItem = psMetadataItemAllocS32(keyword, concept->comment, concept->data.S32);
    579             break;
    580         case PS_DATA_F32:
    581             headerItem = psMetadataItemAllocF32(keyword, concept->comment, concept->data.F32);
    582             break;
    583         case PS_DATA_F64:
    584             headerItem = psMetadataItemAllocF64(keyword, concept->comment, concept->data.F64);
    585             break;
    586         default:
    587             headerItem = psMetadataItemAlloc(keyword, concept->type, concept->comment,
    588                                              concept->data.V); // Item for the header
    589         }
    590 
    591         // We have a FITS header to look up --- search each level
    592         if (cell && cell->hdu) {
    593             psTrace(__func__, 7, "Adding to the cell level header...\n");
    594             psMetadataAddItem(cell->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);
    595             status = true;
    596         } else if (chip && chip->hdu) {
    597             psTrace(__func__, 7, "Adding to the chip level header...\n");
    598             psMetadataAddItem(chip->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);
    599             status = true;
    600         } else if (fpa->hdu) {
    601             psTrace(__func__, 7, "Adding to the FPA level header...\n");
    602             psMetadataAddItem(fpa->hdu->header, headerItem, PS_LIST_TAIL, PS_META_REPLACE);
    603             status = true;
    604         }
    605         psFree(headerItem);
    606     }
    607 
    608     // No header value
    609     return status;
    610 }
    611 
    612 
    613 // Well, not really "write", but check to see if it's there, and matches
    614 bool pmConceptWriteToDefault(pmFPA *fpa, // The FPA that contains the chip
    615                              pmChip *chip, // The chip that contains the cell
    616                              pmCell *cell, // The cell
    617                              psMetadataItem *concept // Concept
    618                             )
    619 {
    620     bool mdOK = true;                   // Status of MD lookup
    621     if (! fpa->camera) {
    622         return false;
    623     }
    624     psMetadata *defaults = psMetadataLookupMD(&mdOK, fpa->camera, "DEFAULTS");
    625     if (! mdOK || ! defaults) {
    626         psError(PS_ERR_IO, false, "Unable to find DEFAULTS in camera configuration.\n");
    627         return false;
    628     }
    629 
    630     psMetadataItem *defItem = psMetadataLookup(defaults, concept->name);
    631     bool status = false;                // Result of checking the database
    632     if (defItem) {
    633         if (defItem->type == PS_DATA_METADATA) {
    634             // A dependent default
    635             psTrace(__func__, 7, "Evaluating dependent default....\n");
    636             psMetadata *dependents = defItem->data.V; // The list of dependents
    637             // Find out what it depends on
    638             psString dependName = psStringCopy(concept->name);
    639             psStringAppend(&dependName, ".DEPEND");
    640             psString dependsOn = psMetadataLookupStr(&mdOK, defaults, dependName);
    641             if (! mdOK) {
    642                 psError(PS_ERR_IO, false, "Unable to find %s in camera configuration for dependent default"
    643                         " --- ignored\n", dependName);
    644                 // XXX: Need to clean up before returning
    645                 return false;
    646             }
    647             psFree(dependName);
    648             // Find the value of the dependent concept
    649             psMetadataItem *depItem = pmConceptReadFromHeader(fpa, chip, cell, dependsOn);
    650             if (! depItem) {
    651                 psError(PS_ERR_IO, true, "Unable to find value for %s (required for %s)\n", dependsOn,
    652                         concept->name);
    653                 return false;
    654             }
    655             if (depItem->type != PS_DATA_STRING) {
    656                 psError(PS_ERR_IO, true, "Value of %s is not of type string, as required for dependency"
    657                         " --- ignored.\n", dependsOn);
    658             }
    659 
    660             defItem = psMetadataLookup(dependents, depItem->data.V); // This is now what we were after
    661         }
    662 
    663         status = compareConcepts(defItem, concept);
    664         if (! status) {
    665             psError(PS_ERR_IO, true, "Concept %s is specified by default in the camera configuration, "
    666                     "but doesn't match the actual value.\n", concept->name);
    667         }
    668     }
    669 
    670     // XXX: Need to clean up before returning
    671     return status;
    672 }
    673 
    674 
    675 // XXX: Not tested at all
    676 // XXX I WOULD NOT TRUST THIS FUNCTION IN THE SLIGHTEST YET! --- PAP
    677 bool pmConceptWriteToDB(pmFPA *fpa, // The FPA that contains the chip
    678                         pmChip *chip, // The chip that contains the cell
    679                         pmCell *cell, // The cell
    680                         psDB *db,    // DB handle
    681                         psMetadataItem *concept // Concept
    682                        )
    683 {
    684     if (! db) {
    685         // No database initialised
    686         return false;
    687     }
    688 
    689     bool mdStatus = true;               // Status of MD lookup
    690     if (! fpa->camera) {
    691         return false;
    692     }
    693     psMetadata *database = psMetadataLookupMD(&mdStatus, fpa->camera, "DATABASE");
    694     if (! mdStatus) {
    695         // No error, because not everyone needs to use the DB
    696         return NULL;
    697     }
    698 
    699     psMetadata *dbLookup = psMetadataLookupMD(&mdStatus, database, concept->name);
    700     if (dbLookup) {
    701         const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE"); // Name of the table
    702         //        const char *colName = psMetadataLookupStr(&mdStatus, dbLookup, "COLUMN"); // Name of the column
    703         const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL"); // Name of "where"
    704         // columns
    705         const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS"); // Values for "where"
    706         // columns
    707 
    708         // Now, need to get the "given"s
    709         if (strlen(givenCols) || strlen(givenPS)) {
    710             psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
    711             psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
    712             psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
    713             if (cols->n != values->n) {
    714                 psLogMsg(__func__, PS_LOG_WARN, "The GIVENDBCOL and GIVENPS entries for %s do not have "
    715                          "the same number of entries --- ignored.\n", concept);
    716             } else {
    717                 // Iterators for the lists
    718                 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
    719                 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
    720                 char *column = NULL;    // Name of the column
    721                 while ((column = psListGetAndIncrement(colsIter))) {
    722                     char *name = psListGetAndIncrement(valuesIter); // Name for the value
    723                     if (!strlen(column) || !strlen(name)) {
    724                         psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
    725                                  " empty --- ignored.\n", concept);
    726                     } else {
    727                         // Search for the value name
    728                         psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name);
    729                         if (! item) {
    730                             item = pmConceptReadFromDefault(fpa, chip, cell, name);
    731                         }
    732                         if (! item) {
    733                             psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB "
    734                                      " lookup on %s --- ignored.\n", name, concept);
    735                         } else {
    736                             // We need to create a new psMetadataItem.  I don't think we can't simply hack
    737                             // the existing one, since that could conceivably cause memory leaks
    738                             psMetadataItem *newItem = psMetadataItemAlloc(concept->name, item->type,
    739                                                       item->comment, item->data.V);
    740                             psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
    741                             psFree(newItem);
    742                         }
    743                     }
    744                     psFree(name);
    745                     psFree(column);
    746                 } // Iterating through the columns
    747                 psFree(colsIter);
    748                 psFree(valuesIter);
    749 
    750                 // Check first to make sure we're only going to touch one row
    751                 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
    752                 // Note that we use limit=2 in order to test if there are multiple rows returned
    753                 if (! dbResult || dbResult->n == 0) {
    754                     psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- ignored\n",
    755                              concept->name);
    756                     return false;
    757                 } else {
    758                     if (dbResult->n > 1) {
    759                         psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s --- "
    760                                  " ignored.\n", concept->name);
    761                     }
    762                     // Update the DB
    763                     psMetadata *update = psMetadataAlloc();
    764                     psMetadataAddItem(update, concept, PS_LIST_HEAD, 0);
    765                     psDBUpdateRows(db, tableName, selection, update);
    766                     psFree(update);
    767                     return true;
    768                 }
    769             }
    770             psFree(cols);
    771             psFree(values);
    772         }
    773     } // Doing the "given"s.
    774 
    775     psAbort(__func__, "Shouldn't ever get here?\n");
    776     return false;
    777 }
    778 
    779 
    780 // Concept write from item
    781 bool pmConceptWriteItem(pmFPA *fpa,     // The FPA
    782                         pmChip *chip,   // The chip
    783                         pmCell *cell,   // The cell
    784                         psDB *db,       // DB handle
    785                         psMetadataItem *concept // Concept item
    786                        )
    787 {
    788     if (! fpa->camera) {
    789         return false;
    790     }
    791 
    792     // Try headers, database, defaults in order
    793     psTrace(__func__, 3, "Trying to set concept %s...\n", concept->name);
    794     bool status = pmConceptWriteToCamera(cell, concept); // Status for return
    795     if (! status) {
    796         psTrace(__func__, 5, "Trying header....\n");
    797         status = pmConceptWriteToHeader(fpa, chip, cell, concept);
    798     }
    799     if (! status) {
    800         psTrace(__func__, 5, "Trying database....\n");
    801         status = pmConceptWriteToDB(fpa, chip, cell, db, concept);
    802     }
    803     if (! status) {
    804         psTrace(__func__, 5, "Checking defaults....\n");
    805         status = pmConceptWriteToDefault(fpa, chip, cell, concept);
    806     }
    807 
    808     if (! status) {
    809         psError(PS_ERR_IO, true, "Unable to set %s (%s).\n", concept->name, concept->comment);
    810     }
    811 
    812     return status;
    813 }
    814 
    815 
    816 // Concept write
    817 bool pmConceptWrite(pmFPA *fpa, // The FPA
    818                     pmChip *chip,// The chip
    819                     pmCell *cell,    // The cell
    820                     psDB *db, // DB handle
    821                     psMetadata *concepts, // Concepts MD from which to set
    822                     const char *name // Name of the concept
    823                    )
    824 {
    825     psMetadataItem *concept = psMetadataLookup(concepts, name);
    826     if (! concept) {
    827         psError(PS_ERR_IO, true, "No such concept as %s\n", name);
    828         return false;
    829     }
    830     return pmConceptWriteItem(fpa, chip, cell, db, concept);
    831 }
    832 
    833 #endif
Note: See TracChangeset for help on using the changeset viewer.