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/pmConceptsRead.c

    r7017 r7278  
    11#include <stdio.h>
     2#include <assert.h>
    23
    34#include "pslib.h"
     
    2122                                 )
    2223{
     24    assert(concept);
     25    assert(pattern);
     26
    2327    switch (pattern->type) {
    2428    case PS_DATA_STRING: {
     
    5357                        )
    5458{
    55     if (concept) {
    56         psMetadataItem *parsed = NULL;  // The parsed concept
    57         if (spec->parse) {
    58             parsed = spec->parse(concept, spec->blank, cameraFormat, fpa, chip, cell);
    59         } else {
    60             parsed = parsePlain(concept, spec->blank);
    61         }
    62 
    63         // Plug the parsed concept into a new psMetadataItem, so each "concept" has its own version that can
    64         // be altered without affecting the others.  Also, so that we maintain the template name and comment.
    65         psMetadataItem *cleaned = NULL;     // Item that's been cleaned up --- correct name and comment
    66         switch (spec->blank->type) {
    67         case PS_DATA_STRING:
    68             cleaned = psMetadataItemAllocStr(spec->blank->name, spec->blank->comment, parsed->data.V);
    69             break;
    70         case PS_DATA_S32:
    71             cleaned = psMetadataItemAllocS32(spec->blank->name, spec->blank->comment, parsed->data.S32);
    72             break;
    73         case PS_DATA_F32:
    74             cleaned = psMetadataItemAllocF32(spec->blank->name, spec->blank->comment, parsed->data.F32);
    75             break;
    76         case PS_DATA_F64:
    77             cleaned = psMetadataItemAllocF64(spec->blank->name, spec->blank->comment, parsed->data.F64);
    78             break;
    79         default:
    80             cleaned = psMetadataItemAlloc(spec->blank->name, parsed->type, spec->blank->comment,
    81                                           parsed->data.V);
    82         }
    83         psFree(parsed);
    84         psMetadataAddItem(target, cleaned, PS_LIST_TAIL, PS_META_REPLACE);
    85         psFree(cleaned);                 // Drop reference
    86         return true;
    87     }
    88 
    89     return false;
     59    assert(spec);
     60    assert(cameraFormat);
     61    assert(target);
     62
     63    if (!concept) {
     64        return false;
     65    }
     66
     67    psMetadataItem *parsed = NULL;  // The parsed concept
     68    if (spec->parse) {
     69        parsed = spec->parse(concept, spec->blank, cameraFormat, fpa, chip, cell);
     70    } else {
     71        parsed = parsePlain(concept, spec->blank);
     72    }
     73
     74    // Plug the parsed concept into a new psMetadataItem, so each "concept" has its own version that can
     75    // be altered without affecting the others.  Also, so that we maintain the template name and comment.
     76    psMetadataItem *cleaned = NULL;     // Item that's been cleaned up --- correct name and comment
     77    switch (spec->blank->type) {
     78    case PS_DATA_STRING:
     79        cleaned = psMetadataItemAllocStr(spec->blank->name, spec->blank->comment, parsed->data.V);
     80        break;
     81    case PS_DATA_S32:
     82        cleaned = psMetadataItemAllocS32(spec->blank->name, spec->blank->comment, parsed->data.S32);
     83        break;
     84    case PS_DATA_F32:
     85        cleaned = psMetadataItemAllocF32(spec->blank->name, spec->blank->comment, parsed->data.F32);
     86        break;
     87    case PS_DATA_F64:
     88        cleaned = psMetadataItemAllocF64(spec->blank->name, spec->blank->comment, parsed->data.F64);
     89        break;
     90    default:
     91        cleaned = psMetadataItemAlloc(spec->blank->name, parsed->type, spec->blank->comment,
     92                                      parsed->data.V);
     93    }
     94    psFree(parsed);
     95    psMetadataAddItem(target, cleaned, PS_LIST_TAIL, PS_META_REPLACE);
     96    psFree(cleaned);                 // Drop reference
     97    return true;
    9098}
    9199
     
    100108                             )
    101109{
    102     if (cell) {
    103         pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
    104         if (! hdu) {
    105             return false;
    106         }
    107         psMetadata *cameraFormat = hdu->format; // The camera format
    108         psMetadata *cellConfig = cell->config; // The camera configuration for this cell
    109         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    110         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    111         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    112             pmConceptSpec *spec = specItem->data.V; // The specification
    113             psString name = specItem->name; // The concept name
    114             psMetadataItem *conceptItem = psMetadataLookup(cellConfig, name); // The concept, or NULL
    115             psMetadataItem *value = NULL; // The value of the concept
    116             if (conceptItem) {
    117                 if (conceptItem->type == PS_DATA_STRING) {
    118                     // Check the SOURCE
    119                     psString nameSource = NULL; // String with the concept name and ".SOURCE" added
    120                     psStringAppend(&nameSource, "%s.SOURCE", name);
    121                     bool mdok = true;       // Status of MD lookup
    122                     psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
    123                     psFree(nameSource);
    124                     if (mdok && strlen(source) > 0 && strcasecmp(source, "VALUE") == 0) {
    125                         value = conceptItem;
    126                         conceptParse(spec, value, cameraFormat, target, NULL, NULL, cell);
    127                     } else if (source && (strlen(source) == 0 || strcasecmp(source, "HEADER") != 0)) {
    128                         // We leave "HEADER" to pmConceptsReadFromHeader
    129                         psError(PS_ERR_IO, true, "%s isn't HEADER or VALUE --- can't read %s\n", source,
    130                                 name);
    131                         continue;
    132                     }
    133                 } else {
    134                     // Another type --- should be OK
    135                     conceptParse(spec, conceptItem, cameraFormat, target, NULL, NULL, cell);
     110    PS_ASSERT_PTR_NON_NULL(specs, false);
     111    PS_ASSERT_PTR_NON_NULL(target, false);
     112    if (!cell) {
     113        return false;
     114    }
     115
     116    pmHDU *hdu = pmHDUGetLowest(NULL, NULL, cell); // The HDU at the lowest level
     117    if (! hdu) {
     118        return false;
     119    }
     120    psMetadata *cameraFormat = hdu->format; // The camera format
     121    psMetadata *cellConfig = cell->config; // The camera configuration for this cell
     122    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     123    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     124    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     125        pmConceptSpec *spec = specItem->data.V; // The specification
     126        psString name = specItem->name; // The concept name
     127        psMetadataItem *conceptItem = psMetadataLookup(cellConfig, name); // The concept, or NULL
     128        psMetadataItem *value = NULL; // The value of the concept
     129        if (conceptItem) {
     130            if (conceptItem->type == PS_DATA_STRING) {
     131                // Check the SOURCE
     132                psString nameSource = NULL; // String with the concept name and ".SOURCE" added
     133                psStringAppend(&nameSource, "%s.SOURCE", name);
     134                bool mdok = true;       // Status of MD lookup
     135                psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
     136                psFree(nameSource);
     137                if (mdok && strlen(source) > 0 && strcasecmp(source, "VALUE") == 0) {
     138                    value = conceptItem;
     139                    conceptParse(spec, value, cameraFormat, target, NULL, NULL, cell);
     140                } else if (source && (strlen(source) == 0 || strcasecmp(source, "HEADER") != 0)) {
     141                    // We leave "HEADER" to pmConceptsReadFromHeader
     142                    psError(PS_ERR_IO, true, "%s isn't HEADER or VALUE --- can't read %s\n", source,
     143                            name);
     144                    continue;
    136145                }
     146            } else {
     147                // Another type --- should be OK
     148                conceptParse(spec, conceptItem, cameraFormat, target, NULL, NULL, cell);
    137149            }
    138150        }
    139         psFree(specsIter);
    140         return true;
    141     }
    142     return false;
     151    }
     152    psFree(specsIter);
     153    return true;
    143154}
    144155
     
    151162                               )
    152163{
     164    PS_ASSERT_PTR_NON_NULL(specs, false);
     165    PS_ASSERT_PTR_NON_NULL(target, false);
     166
    153167    pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
    154168    if (!hdu) {
     
    158172    bool mdok = true;                   // Status of MD lookup
    159173    psMetadata *defaults = psMetadataLookupMD(&mdok, cameraFormat, "DEFAULTS"); // The DEFAULTS spec
    160     if (mdok && defaults) {
    161         pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
    162         psMetadata *cameraFormat = hdu->format; // The camera format
    163         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    164         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    165         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    166             pmConceptSpec *spec = specItem->data.V; // The specification
    167             psString name = specItem->name; // The concept name
    168             psMetadataItem *conceptItem = psMetadataLookup(defaults, name); // The concept, or NULL
    169             conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
    170         }
    171         psFree(specsIter);
    172         return true;
    173     }
    174     return false;
     174    if (!mdok || !defaults) {
     175        return false;
     176    }
     177    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     178    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     179    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     180        pmConceptSpec *spec = specItem->data.V; // The specification
     181        psString name = specItem->name; // The concept name
     182        psMetadataItem *conceptItem = psMetadataLookup(defaults, name); // The concept, or NULL
     183        conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
     184    }
     185    psFree(specsIter);
     186    return true;
    175187}
    176188
     
    183195                             )
    184196{
     197    PS_ASSERT_PTR_NON_NULL(specs, false);
     198    PS_ASSERT_PTR_NON_NULL(target, false);
     199
    185200    pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
    186201    if (!hdu) {
     
    190205    bool mdok = true;                   // Status of MD lookup
    191206    psMetadata *transSpec = psMetadataLookupMD(&mdok, cameraFormat, "TRANSLATION"); // The TRANSLATION spec
    192     if (mdok && transSpec) {
    193         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    194         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    195         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    196             pmConceptSpec *spec = specItem->data.V; // The specification
    197             psString name = specItem->name; // The concept name
    198             psMetadataItem *headerItem = NULL; // The value of the concept from the header
    199             // First check the cell configuration
    200             if (cell && cell->config) {
    201                 psMetadataItem *conceptItem = psMetadataLookup(cell->config, name); // The concept, or NULL
    202                 if (conceptItem) {
    203                     // Check the SOURCE
    204                     psString nameSource = NULL; // String with the concept name and ".SOURCE" added
    205                     psStringAppend(&nameSource, "%s.SOURCE", name);
    206                     psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
    207                     psFree(nameSource);
    208                     if (mdok && strlen(source) && strcasecmp(source, "HEADER") == 0) {
    209                         headerItem = psMetadataLookup(hdu->header, conceptItem->data.V);
     207    if (!mdok || !transSpec) {
     208        return false;
     209    }
     210
     211    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     212    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     213    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     214        pmConceptSpec *spec = specItem->data.V; // The specification
     215        psString name = specItem->name; // The concept name
     216        psMetadataItem *headerItem = NULL; // The value of the concept from the header
     217        // First check the cell configuration
     218        if (cell && cell->config) {
     219            psMetadataItem *conceptItem = psMetadataLookup(cell->config, name); // The concept, or NULL
     220            if (conceptItem) {
     221                // Check the SOURCE
     222                psString nameSource = NULL; // String with the concept name and ".SOURCE" added
     223                psStringAppend(&nameSource, "%s.SOURCE", name);
     224                psString source = psMetadataLookupStr(&mdok, cell->config, nameSource); // The source
     225                psFree(nameSource);
     226                if (mdok && strlen(source) && strcasecmp(source, "HEADER") == 0) {
     227                    headerItem = psMetadataLookup(hdu->header, conceptItem->data.V);
     228                }
     229                // Leave the error handling to pmConceptsFromCamera, which should already have been called
     230            }
     231        }
     232        if (! headerItem) {
     233            psString keywords = psMetadataLookupStr(&mdok, transSpec, name); // The FITS keywords
     234            if (mdok && strlen(keywords) > 0) {
     235                // In case there are multiple headers
     236                psList *keys = psStringSplit(keywords, " ,;", true); // List of keywords
     237                if (keys->n == 1) {
     238                    // Only one key --- proceed as usual
     239                    headerItem = psMetadataLookup(hdu->header, keywords);
     240                } else {
     241                    psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator
     242                    psString key = NULL; // Item from iteration
     243                    psList *values = psListAlloc(NULL); // List containing the values
     244                    while ((key = psListGetAndIncrement(keysIter))) {
     245                        psMetadataItem *value = psMetadataLookup(hdu->header, key);
     246                        psListAdd(values, PS_LIST_TAIL, value);
    210247                    }
    211                     // Leave the error handling to pmConceptsFromCamera, which should already have been called
     248                    psFree(keysIter);
     249                    headerItem = psMetadataItemAlloc(name, PS_DATA_LIST, specItem->comment, values);
     250                    psFree(values);
    212251                }
     252                psFree(keys);
    213253            }
    214             if (! headerItem) {
    215                 psString keywords = psMetadataLookupStr(&mdok, transSpec, name); // The FITS keywords
    216                 if (mdok && strlen(keywords) > 0) {
    217                     // In case there are multiple headers
    218                     psList *keys = psStringSplit(keywords, " ,;", true); // List of keywords
    219                     if (keys->n == 1) {
    220                         // Only one key --- proceed as usual
    221                         headerItem = psMetadataLookup(hdu->header, keywords);
    222                     } else {
    223                         psListIterator *keysIter = psListIteratorAlloc(keys, PS_LIST_HEAD, false); // Iterator
    224                         psString key = NULL; // Item from iteration
    225                         psList *values = psListAlloc(NULL); // List containing the values
    226                         while ((key = psListGetAndIncrement(keysIter))) {
    227                             psMetadataItem *value = psMetadataLookup(hdu->header, key);
    228                             psListAdd(values, PS_LIST_TAIL, value);
    229                         }
    230                         psFree(keysIter);
    231                         headerItem = psMetadataItemAlloc(name, PS_DATA_LIST, specItem->comment, values);
    232                         psFree(values);
    233                     }
    234                     psFree(keys);
    235                 }
    236             }
    237 
    238             // This will also clean up the name
    239             conceptParse(spec, headerItem, cameraFormat, target, fpa, chip, cell);
    240254        }
    241         psFree(specsIter);
    242         return true;
    243     }
    244     return false;
     255
     256        // This will also clean up the name
     257        conceptParse(spec, headerItem, cameraFormat, target, fpa, chip, cell);
     258    }
     259    psFree(specsIter);
     260    return true;
    245261}
    246262
     
    255271                               )
    256272{
     273    PS_ASSERT_PTR_NON_NULL(specs, false);
     274    PS_ASSERT_PTR_NON_NULL(target, false);
     275
    257276    #ifdef OMIT_PSDB
     277
    258278    return false;
    259279    #else
     
    266286    bool mdok = true;                   // Status of MD lookup
    267287    psMetadata *dbSpec = psMetadataLookupMD(&mdok, cameraFormat, "DATABSE"); // The DATABASE spec
    268     if (mdok && dbSpec) {
    269         pmHDU *hdu = pmHDUGetLowest(fpa, chip, cell); // The HDU at the lowest level
    270         psMetadata *cameraFormat = hdu->format; // The camera format
    271         psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
    272         psMetadataItem *specItem = NULL;    // Item from the specs metadata
    273         while ((specItem = psMetadataGetAndIncrement(specsIter))) {
    274             pmConceptSpec *spec = specItem->data.V; // The specification
    275             psString name = specItem->name; // The concept name
    276 
    277             psMetadata *dbLookup = psMetadataLookupMD(&mdok, dbSpec, name);
    278             if (mdok && dbLookup) {
    279                 const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); // Table name
    280                 // Names of the "where" columns
    281                 const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
    282                 // Values of the "where" columns
    283                 const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
    284 
    285                 // Now, need to get the "given"s
    286                 if (strlen(givenCols) > 0 || strlen(givenPS) > 0) {
    287                     psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
    288                     psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
    289                     psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
    290                     if (cols->n != values->n) {
     288    if (!mdok || !dbSpec) {
     289        return false;
     290    }
     291
     292    psMetadataIterator *specsIter = psMetadataIteratorAlloc(specs, PS_LIST_HEAD, NULL); // Iterator
     293    psMetadataItem *specItem = NULL;    // Item from the specs metadata
     294    while ((specItem = psMetadataGetAndIncrement(specsIter))) {
     295        pmConceptSpec *spec = specItem->data.V; // The specification
     296        psString name = specItem->name; // The concept name
     297
     298        psMetadata *dbLookup = psMetadataLookupMD(&mdok, dbSpec, name);
     299        if (mdok && dbLookup) {
     300            const char *tableName = psMetadataLookupStr(&mdok, dbLookup, "TABLE"); // Table name
     301            // Names of the "where" columns
     302            const char *givenCols = psMetadataLookupStr(&mdok, dbLookup, "GIVENDBCOL");
     303            // Values of the "where" columns
     304            const char *givenPS = psMetadataLookupStr(&mdok, dbLookup, "GIVENPS");
     305
     306            // Now, need to get the "given"s
     307            if (strlen(givenCols) > 0 || strlen(givenPS) > 0) {
     308                psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
     309                psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
     310                psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
     311                if (cols->n != values->n) {
     312                    psLogMsg(__func__, PS_LOG_WARN,
     313                             "The GIVENDBCOL and GIVENPS entries for %s do not have "
     314                             "the same number of entries --- ignored.\n", name);
     315                } else {
     316                    // Iterators for the lists
     317                    psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
     318                    psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
     319                    char *column = NULL;    // Name of the column
     320                    while ((column = psListGetAndIncrement(colsIter))) {
     321                        char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
     322                        if (!strlen(column) || !strlen(name)) {
     323                            psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
     324                                     " empty --- ignored.\n", name);
     325                        } else {
     326                            // Search for the value name
     327                            psMetadataItem *item = NULL; // The value
     328                            if (!item && cell) {
     329                                item = psMetadataLookup(cell->concepts, dependName);
     330                            }
     331                            if (!item && chip) {
     332                                item = psMetadataLookup(chip->concepts, dependName);
     333                            }
     334                            if (!item && fpa) {
     335                                item = psMetadataLookup(fpa->concepts, dependName);
     336                            }
     337                            if (! item) {
     338                                psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB"
     339                                         " lookup on %s --- ignored.\n", dependName, name);
     340                            } else {
     341                                // We need to create a new psMetadataItem.  I don't think we can't
     342                                // simply hack the existing one, since that could conceivably cause
     343                                // memory leaks
     344                                psMetadataItem *newItem = psMetadataItemAlloc(name, item->type,
     345                                                          item->comment,
     346                                                          item->data.V);
     347                                psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
     348                                psFree(newItem);
     349                            }
     350                        }
     351                        psFree(dependName);
     352                        psFree(column);
     353                    } // Iterating through the columns
     354                    psFree(colsIter);
     355                    psFree(valuesIter);
     356
     357                    psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
     358                    // Note that we use limit=2 in order to test if there are multiple rows returned
     359
     360                    psMetadataItem *conceptItem = NULL; // The final result of the DB lookup
     361                    if (dbResult->n == 0) {
    291362                        psLogMsg(__func__, PS_LOG_WARN,
    292                                  "The GIVENDBCOL and GIVENPS entries for %s do not have "
    293                                  "the same number of entries --- ignored.\n", name);
     363                                 "Unable to find any rows in DB for %s --- ignored\n", name);
    294364                    } else {
    295                         // Iterators for the lists
    296                         psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
    297                         psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
    298                         char *column = NULL;    // Name of the column
    299                         while ((column = psListGetAndIncrement(colsIter))) {
    300                             char *dependName = psListGetAndIncrement(valuesIter); // Name for the value
    301                             if (!strlen(column) || !strlen(name)) {
    302                                 psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
    303                                          " empty --- ignored.\n", name);
    304                             } else {
    305                                 // Search for the value name
    306                                 psMetadataItem *item = NULL; // The value
    307                                 if (!item && cell) {
    308                                     item = psMetadataLookup(cell->concepts, dependName);
    309                                 }
    310                                 if (!item && chip) {
    311                                     item = psMetadataLookup(chip->concepts, dependName);
    312                                 }
    313                                 if (!item && fpa) {
    314                                     item = psMetadataLookup(fpa->concepts, dependName);
    315                                 }
    316                                 if (! item) {
    317                                     psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB"
    318                                              " lookup on %s --- ignored.\n", dependName, name);
    319                                 } else {
    320                                     // We need to create a new psMetadataItem.  I don't think we can't
    321                                     // simply hack the existing one, since that could conceivably cause
    322                                     // memory leaks
    323                                     psMetadataItem *newItem = psMetadataItemAlloc(name, item->type,
    324                                                               item->comment,
    325                                                               item->data.V);
    326                                     psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
    327                                     psFree(newItem);
    328                                 }
    329                             }
    330                             psFree(dependName);
    331                             psFree(column);
    332                         } // Iterating through the columns
    333                         psFree(colsIter);
    334                         psFree(valuesIter);
    335 
    336                         psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
    337                         // Note that we use limit=2 in order to test if there are multiple rows returned
    338 
    339                         psMetadataItem *conceptItem = NULL; // The final result of the DB lookup
    340                         if (dbResult->n == 0) {
     365                        if (dbResult-> n > 1) {
    341366                            psLogMsg(__func__, PS_LOG_WARN,
    342                                      "Unable to find any rows in DB for %s --- ignored\n", name);
    343                         } else {
    344                             if (dbResult-> n > 1) {
    345                                 psLogMsg(__func__, PS_LOG_WARN,
    346                                          "Multiple rows returned in DB lookup for %s --- "
    347                                          " using the first one only.\n", name);
    348                             }
    349                             conceptItem = (psMetadataItem*)dbResult->data[0];
     367                                     "Multiple rows returned in DB lookup for %s --- "
     368                                     " using the first one only.\n", name);
    350369                        }
    351 
    352                         // Now we have the result
    353                         conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
    354 
     370                        conceptItem = (psMetadataItem*)dbResult->data[0];
    355371                    }
    356                     psFree(cols);
    357                     psFree(values);
     372
     373                    // Now we have the result
     374                    conceptParse(spec, conceptItem, cameraFormat, target, fpa, chip, cell);
     375
    358376                }
    359             } // Doing the "given"s.
    360 
    361         } // Iterating through the concept specifications
    362         psFree(specsIter);
    363 
    364         return true;
    365     }
    366     return false;
     377                psFree(cols);
     378                psFree(values);
     379            }
     380        } // Doing the "given"s.
     381
     382    } // Iterating through the concept specifications
     383    psFree(specsIter);
     384
     385    return true;
    367386    #endif
    368387}
    369388
    370389
    371 
    372 
    373 #ifdef OLD
    374 
    375 psMetadataItem *pmConceptReadFromCamera(pmCell *cell, // The cell
    376                                         const char *concept // Name of concept
    377                                        )
    378 {
    379     if (cell) {
    380         psMetadata *camera = cell->config; // Camera configuration
    381         psMetadataItem *item = psMetadataLookup(camera, concept);
    382         return item;
    383     }
    384     return NULL;
    385 }
    386 
    387 psMetadataItem *pmConceptReadFromHeader(pmFPA *fpa, // The FPA that contains the chip
    388                                         pmChip *chip, // The chip that contains the cell
    389                                         pmCell *cell, // The cell
    390                                         const char *concept // Name of concept
    391                                        )
    392 {
    393     bool mdStatus = true;               // Status of MD lookup
    394     psMetadata *translation = psMetadataLookupMD(&mdStatus, fpa->camera, "TRANSLATION"); // FITS translation
    395     if (! mdStatus) {
    396         psError(PS_ERR_IO, false, "Unable to find TRANSLATION in camera configuration.\n");
    397         return NULL;
    398     }
    399 
    400     // Look for how to translate the concept into a FITS header name
    401     const char *keyword = psMetadataLookupStr(&mdStatus, translation, concept);
    402     if (mdStatus && strlen(keyword) > 0) {
    403         // We have a FITS header to look up --- search each level
    404         if (cell && cell->hdu) {
    405             psMetadataItem *cellItem = psMetadataLookup(cell->hdu->header, keyword);
    406             if (cellItem) {
    407                 // XXX: Need to clean up before returning
    408                 return cellItem;
    409             }
    410         }
    411 
    412         if (chip && chip->hdu) {
    413             psMetadataItem *chipItem = psMetadataLookup(chip->hdu->header, keyword);
    414             if (chipItem) {
    415                 // XXX: Need to clean up before returning
    416                 return chipItem;
    417             }
    418         }
    419 
    420         if (fpa->hdu) {
    421             psMetadataItem *fpaItem = psMetadataLookup(fpa->hdu->header, keyword);
    422             if (fpaItem) {
    423                 // XXX: Need to clean up before returning
    424                 return fpaItem;
    425             }
    426         }
    427     }
    428 
    429     // No header value
    430     return NULL;
    431 }
    432 
    433 
    434 // Look for a default
    435 psMetadataItem *pmConceptReadFromDefault(pmFPA *fpa, // The FPA that contains the chip
    436         pmChip *chip, // The chip that contains the cell
    437         pmCell *cell, // The cell
    438         const char *concept // Name of concept
    439                                         )
    440 {
    441     bool mdOK = true;                   // Status of MD lookup
    442     psMetadata *defaults = psMetadataLookupMD(&mdOK, fpa->camera, "DEFAULTS");
    443     if (! mdOK) {
    444         psError(PS_ERR_IO, false, "Unable to find DEFAULTS in camera configuration.\n");
    445         return NULL;
    446     }
    447 
    448     psMetadataItem *defItem = psMetadataLookup(defaults, concept);
    449     if (defItem) {
    450         if (defItem->type == PS_DATA_METADATA) {
    451             // A dependent default
    452             psTrace(__func__, 7, "Evaluating dependent default....\n");
    453             psMetadata *dependents = defItem->data.V; // The list of dependents
    454             // Find out what it depends on
    455             psString dependName = psStringCopy(concept);
    456             psStringAppend(&dependName, ".DEPEND");
    457             psString dependsOn = psMetadataLookupStr(&mdOK, defaults, dependName);
    458             if (! mdOK) {
    459                 psError(PS_ERR_IO, false, "Unable to find %s in camera configuration for dependent default"
    460                         " --- ignored\n", dependName);
    461                 // XXX: Need to clean up before returning
    462                 return NULL;
    463             }
    464             psFree(dependName);
    465             // Find the value of the dependent concept
    466             psMetadataItem *depItem = pmConceptReadFromHeader(fpa, chip, cell, dependsOn);
    467             if (! depItem) {
    468                 psError(PS_ERR_IO, true, "Unable to find value for %s (required for %s)\n", dependsOn,
    469                         concept);
    470                 return NULL;
    471             }
    472             if (depItem->type != PS_DATA_STRING) {
    473                 psError(PS_ERR_IO, true, "Value of %s is not of type string, as required for dependency"
    474                         " --- ignored.\n", dependsOn);
    475             }
    476 
    477             defItem = psMetadataLookup(dependents, depItem->data.V);    // This is now what we were after
    478         }
    479     }
    480 
    481     // XXX: Need to clean up before returning
    482     return defItem;                     // defItem is either NULL or points to what was desired
    483 }
    484 
    485 
    486 // Look for a database lookup
    487 // XXX: Not tested
    488 psMetadataItem *pmConceptReadFromDB(pmFPA *fpa, // The FPA that contains the chip
    489                                     pmChip *chip, // The chip that contains the cell
    490                                     pmCell *cell, // The cell
    491                                     psDB *db, // DB handle
    492                                     const char *concept // Name of concept
    493                                    )
    494 {
    495     if (! db) {
    496         // No database initialised
    497         return NULL;
    498     }
    499 
    500     bool mdStatus = true;               // Status of MD lookup
    501     psMetadata *database = psMetadataLookupMD(&mdStatus, fpa->camera, "DATABASE");
    502     if (! mdStatus) {
    503         // No error, because not everyone needs to use the DB
    504         return NULL;
    505     }
    506 
    507     psMetadata *dbLookup = psMetadataLookupMD(&mdStatus, database, concept);
    508     if (dbLookup) {
    509         const char *tableName = psMetadataLookupStr(&mdStatus, dbLookup, "TABLE"); // Name of the table
    510         // const char *colName = psMetadataLookupStr(&mdStatus, dbLookup, "COLUMN"); // Name of the column
    511         const char *givenCols = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENDBCOL"); // Name of "where"
    512         // columns
    513         const char *givenPS = psMetadataLookupStr(&mdStatus, dbLookup, "GIVENPS"); // Values for "where"
    514         // columns
    515 
    516         // Now, need to get the "given"s
    517         if (strlen(givenCols) || strlen(givenPS)) {
    518             psList *cols = psStringSplit(givenCols, ",;", true); // List of column names
    519             psList *values = psStringSplit(givenPS, ",;", true); // List of value names for the columns
    520             psMetadata *selection = psMetadataAlloc(); // The stuff to select in the DB
    521             if (cols->n != values->n) {
    522                 psLogMsg(__func__, PS_LOG_WARN, "The GIVENDBCOL and GIVENPS entries for %s do not have "
    523                          "the same number of entries --- ignored.\n", concept);
    524             } else {
    525                 // Iterators for the lists
    526                 psListIterator *colsIter = psListIteratorAlloc(cols, PS_LIST_HEAD, false);
    527                 psListIterator *valuesIter = psListIteratorAlloc(values, PS_LIST_HEAD, false);
    528                 char *column = NULL;    // Name of the column
    529                 while ((column = psListGetAndIncrement(colsIter))) {
    530                     char *name = psListGetAndIncrement(valuesIter); // Name for the value
    531                     if (!strlen(column) || !strlen(name)) {
    532                         psLogMsg(__func__, PS_LOG_WARN, "One of the columns or value names for %s is "
    533                                  " empty --- ignored.\n", concept);
    534                     } else {
    535                         // Search for the value name
    536                         psMetadataItem *item = pmConceptReadFromHeader(fpa, chip, cell, name);
    537                         if (! item) {
    538                             item = pmConceptReadFromDefault(fpa, chip, cell, name);
    539                         }
    540                         if (! item) {
    541                             psLogMsg(__func__, PS_LOG_ERROR, "Unable to find the value name %s for DB "
    542                                      " lookup on %s --- ignored.\n", name, concept);
    543                         } else {
    544                             // We need to create a new psMetadataItem.  I don't think we can't simply hack
    545                             // the existing one, since that could conceivably cause memory leaks
    546                             psMetadataItem *newItem = psMetadataItemAlloc(concept, item->type,
    547                                                       item->comment, item->data.V);
    548                             psMetadataAddItem(selection, newItem, PS_LIST_TAIL, PS_META_REPLACE);
    549                             psFree(newItem);
    550                         }
    551                     }
    552                     psFree(name);
    553                     psFree(column);
    554                 } // Iterating through the columns
    555                 psFree(colsIter);
    556                 psFree(valuesIter);
    557 
    558                 psArray *dbResult = psDBSelectRows(db, tableName, selection, 2); // Lookup result
    559                 // Note that we use limit=2 in order to test if there are multiple rows returned
    560 
    561                 psMetadataItem *result = NULL; // The final result of the DB lookup
    562                 if (dbResult->n == 0) {
    563                     psLogMsg(__func__, PS_LOG_WARN, "Unable to find any rows in DB for %s --- ignored\n",
    564                              concept);
    565                 } else {
    566                     if (dbResult-> n > 1) {
    567                         psLogMsg(__func__, PS_LOG_WARN, "Multiple rows returned in DB lookup for %s --- "
    568                                  " using the first one only.\n", concept);
    569                     }
    570                     result = (psMetadataItem*)dbResult->data[0];
    571                 }
    572                 // XXX: Need to clean up before returning
    573                 return result;
    574             }
    575             psFree(cols);
    576             psFree(values);
    577         }
    578     } // Doing the "given"s.
    579 
    580     psAbort(__func__, "Shouldn't ever get here.\n");
    581     return NULL;
    582 }
    583 
    584 
    585 // Concept lookup
    586 psMetadataItem *pmConceptRead(pmFPA *fpa, // The FPA
    587                               pmChip *chip,// The chip
    588                               pmCell *cell, // The cell
    589                               psDB *db, // DB handle
    590                               const char *name // Concept name
    591                              )
    592 {
    593     // Try headers, database, defaults in order
    594     psMetadataItem *item = pmConceptReadFromCamera(cell, name);
    595     if (! item) {
    596         item = pmConceptReadFromHeader(fpa, chip, cell, name);
    597     }
    598     if (! item) {
    599         item = pmConceptReadFromDB(fpa, chip, cell, db, name);
    600     }
    601     if (! item) {
    602         item = pmConceptReadFromDefault(fpa, chip, cell, name);
    603     }
    604     return item; // item is either NULL, or points to what was desired
    605 }
    606 
    607 
    608 #endif
Note: See TracChangeset for help on using the changeset viewer.