irplib_plugin.c

00001 /* $Id: irplib_plugin.c,v 1.33 2011/10/07 08:08:34 llundin Exp $
00002  *
00003  * This file is part of the irplib package 
00004  * Copyright (C) 2002,2003 European Southern Observatory
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License, or
00009  * (at your option) any later version.
00010  *
00011  * This program is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with this program; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02111-1307  USA
00019  */
00020 
00021 /*
00022  * $Author: llundin $
00023  * $Date: 2011/10/07 08:08:34 $
00024  * $Revision: 1.33 $
00025  * $Name: naco-4_3_0 $
00026  */
00027 
00028 /*-----------------------------------------------------------------------------
00029                                 Includes
00030  -----------------------------------------------------------------------------*/
00031 
00032 #ifdef HAVE_CONFIG_H
00033 #include <config.h>
00034 #endif
00035 
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include <assert.h>
00039 
00040 #include <cpl.h>
00041 
00042 
00043 #include "irplib_plugin.h"
00044 
00045 /*----------------------------------------------------------------------------*/
00055 /*----------------------------------------------------------------------------*/
00056 
00057 /*-----------------------------------------------------------------------------
00058                                 Defines
00059  -----------------------------------------------------------------------------*/
00060 
00061 /* Maximum line length in SOF-file */
00062 #ifndef LINE_LEN_MAX
00063 #define LINE_LEN_MAX 1024
00064 #endif
00065 
00066 /* This device provides quite-random data */
00067 #define DEV_RANDOM "/dev/urandom"
00068 
00069 /* Copied from cpl_tools.h */
00070 #define recipe_assert(bool) \
00071   ((bool) ? (cpl_msg_debug(cpl_func, \
00072      "OK in " __FILE__ " line %d (CPL-error state: '%s' in %s): %s",__LINE__, \
00073        cpl_error_get_message(), cpl_error_get_where(), #bool), 0) \
00074           : (cpl_msg_error(cpl_func, \
00075      "Failure in " __FILE__ " line %d (CPL-error state: '%s' in %s): %s", \
00076       __LINE__, cpl_error_get_message(), cpl_error_get_where(), #bool), 1))
00077 
00078 
00079 
00080 /*-----------------------------------------------------------------------------
00081                             Private Function prototypes
00082  -----------------------------------------------------------------------------*/
00083 
00084 static const cpl_parameter * irplib_parameterlist_get(const cpl_parameterlist *,
00085                                                       const char *,
00086                                                       const char *,
00087                                                       const char *);
00088 
00089 static void recipe_parameterlist_set(cpl_parameterlist *);
00090 static cpl_boolean irplib_plugin_has_sof_from_env(const cpl_plugin *,
00091                                                   const char *);
00092 
00093 static void recipe_frameset_load(cpl_frameset *, const char *);
00094 
00095 static void recipe_sof_test_devfile(cpl_plugin *, const char *, size_t,
00096                                    const char *[]);
00097 static void recipe_sof_test_image_empty(cpl_plugin *, size_t, const char *[]);
00098 static void recipe_sof_test_local(cpl_plugin *);
00099 static void recipe_sof_test_from_env(cpl_plugin *);
00100 static void recipe_frameset_empty(cpl_frameset *);
00101 static void recipe_frameset_test_frame(const cpl_frame *);
00102 static void recipe_frameset_test_frameset_diff(const cpl_frameset *,
00103                                                const cpl_frameset *);
00104 
00105 static cpl_errorstate inistate;
00106 
00109 /*-----------------------------------------------------------------------------
00110                             Function definitions
00111  -----------------------------------------------------------------------------*/
00112 
00113 /*----------------------------------------------------------------------------*/
00123 /*----------------------------------------------------------------------------*/
00124 const char * irplib_parameterlist_get_string(const cpl_parameterlist * self,
00125                                              const char * instrume,
00126                                              const char * recipe,
00127                                              const char * parameter)
00128 {
00129 
00130     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00131                                                          recipe, parameter);
00132     const char * value;
00133 
00134     cpl_ensure(par != NULL, cpl_error_get_code(), NULL);
00135 
00136     value = cpl_parameter_get_string(par);
00137 
00138     if (value == NULL) (void)cpl_error_set_where(cpl_func);
00139 
00140     return value;
00141 
00142 }
00143 
00144 /*----------------------------------------------------------------------------*/
00154 /*----------------------------------------------------------------------------*/
00155 cpl_boolean irplib_parameterlist_get_bool(const cpl_parameterlist * self,
00156                                           const char * instrume,
00157                                           const char * recipe,
00158                                           const char * parameter)
00159 {
00160 
00161     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00162                                                          recipe, parameter);
00163     cpl_errorstate        prestate = cpl_errorstate_get();
00164     cpl_boolean           value;
00165 
00166 
00167     cpl_ensure(par != NULL, cpl_error_get_code(), CPL_FALSE);
00168 
00169     value = cpl_parameter_get_bool(par);
00170 
00171     if (!cpl_errorstate_is_equal(prestate)) (void)cpl_error_set_where(cpl_func);
00172 
00173     return value;
00174 
00175 }
00176 
00177 
00178 /*----------------------------------------------------------------------------*/
00188 /*----------------------------------------------------------------------------*/
00189 int irplib_parameterlist_get_int(const cpl_parameterlist * self,
00190                                  const char * instrume,
00191                                  const char * recipe,
00192                                  const char * parameter)
00193 {
00194 
00195     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00196                                                          recipe, parameter);
00197     cpl_errorstate        prestate = cpl_errorstate_get();
00198     int                   value;
00199 
00200 
00201     cpl_ensure(par != NULL, cpl_error_get_code(), 0);
00202 
00203     value = cpl_parameter_get_int(par);
00204 
00205     if (!cpl_errorstate_is_equal(prestate)) (void)cpl_error_set_where(cpl_func);
00206 
00207     return value;
00208 }
00209 
00210 /*----------------------------------------------------------------------------*/
00220 /*----------------------------------------------------------------------------*/
00221 double irplib_parameterlist_get_double(const cpl_parameterlist * self,
00222                                        const char * instrume,
00223                                        const char * recipe,
00224                                        const char * parameter)
00225 {
00226 
00227     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00228                                                          recipe, parameter);
00229     cpl_errorstate        prestate = cpl_errorstate_get();
00230     double                value;
00231 
00232 
00233     cpl_ensure(par != NULL, cpl_error_get_code(), 0.0);
00234 
00235     value = cpl_parameter_get_double(par);
00236 
00237     if (!cpl_errorstate_is_equal(prestate)) (void)cpl_error_set_where(cpl_func);
00238 
00239     return value;
00240 }
00241 
00242 /*----------------------------------------------------------------------------*/
00256 /*----------------------------------------------------------------------------*/
00257 cpl_error_code irplib_parameterlist_set_string(cpl_parameterlist * self,
00258                                                const char * instrume,
00259                                                const char * recipe,
00260                                                const char * parameter,
00261                                                const char * defvalue,
00262                                                const char * alias,
00263                                                const char * context,
00264                                                const char * man)
00265 {
00266 
00267     cpl_error_code  error;
00268     cpl_parameter * par;
00269     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00270                                             parameter);
00271 
00272     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00273     
00274     par = cpl_parameter_new_value(paramname, CPL_TYPE_STRING, man, context,
00275                                   defvalue);
00276     cpl_free(paramname);
00277 
00278     cpl_ensure_code(par != NULL, cpl_error_get_code());
00279     
00280     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00281                                     alias ? alias : parameter);
00282     cpl_ensure_code(!error, error);
00283 
00284     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00285     cpl_ensure_code(!error, error);
00286 
00287     error = cpl_parameterlist_append(self, par);
00288     cpl_ensure_code(!error, error);
00289     
00290     return CPL_ERROR_NONE;
00291 }
00292 
00293 
00294 /*----------------------------------------------------------------------------*/
00308 /*----------------------------------------------------------------------------*/
00309 cpl_error_code irplib_parameterlist_set_bool(cpl_parameterlist * self,
00310                                              const char * instrume,
00311                                              const char * recipe,
00312                                              const char * parameter,
00313                                              cpl_boolean  defvalue,
00314                                              const char * alias,
00315                                              const char * context,
00316                                              const char * man)
00317 {
00318 
00319     cpl_error_code  error;
00320     cpl_parameter * par;
00321     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00322                                             parameter);
00323 
00324     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00325     
00326     par = cpl_parameter_new_value(paramname, CPL_TYPE_BOOL, man, context,
00327                                   defvalue);
00328     cpl_free(paramname);
00329 
00330     cpl_ensure_code(par != NULL, cpl_error_get_code());
00331     
00332     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00333                                     alias ? alias : parameter);
00334     cpl_ensure_code(!error, error);
00335     
00336     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00337     cpl_ensure_code(!error, error);
00338 
00339     error = cpl_parameterlist_append(self, par);
00340     cpl_ensure_code(!error, error);
00341     
00342     return CPL_ERROR_NONE;
00343 }
00344 
00345 
00346 
00347 /*----------------------------------------------------------------------------*/
00361 /*----------------------------------------------------------------------------*/
00362 cpl_error_code irplib_parameterlist_set_int(cpl_parameterlist * self,
00363                                             const char * instrume,
00364                                             const char * recipe,
00365                                             const char * parameter,
00366                                             int         defvalue,
00367                                             const char * alias,
00368                                             const char * context,
00369                                             const char * man)
00370 {
00371 
00372     cpl_error_code  error;
00373     cpl_parameter * par;
00374     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00375                                             parameter);
00376 
00377     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00378     
00379     par = cpl_parameter_new_value(paramname, CPL_TYPE_INT, man, context,
00380                                   defvalue);
00381     cpl_free(paramname);
00382 
00383     cpl_ensure_code(par != NULL, cpl_error_get_code());
00384     
00385     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00386                                     alias ? alias : parameter);
00387     cpl_ensure_code(!error, error);
00388     
00389     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00390     cpl_ensure_code(!error, error);
00391 
00392     error = cpl_parameterlist_append(self, par);
00393     cpl_ensure_code(!error, error);
00394     
00395     return CPL_ERROR_NONE;
00396 }
00397 
00398 
00399 /*----------------------------------------------------------------------------*/
00413 /*----------------------------------------------------------------------------*/
00414 cpl_error_code irplib_parameterlist_set_double(cpl_parameterlist * self,
00415                                                const char * instrume,
00416                                                const char * recipe,
00417                                                const char * parameter,
00418                                                double       defvalue,
00419                                                const char * alias,
00420                                                const char * context,
00421                                                const char * man)
00422 {
00423 
00424     cpl_error_code  error;
00425     cpl_parameter * par;
00426     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00427                                             parameter);
00428 
00429     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00430     
00431     par = cpl_parameter_new_value(paramname, CPL_TYPE_DOUBLE, man, context,
00432                                   defvalue);
00433     cpl_free(paramname);
00434 
00435     cpl_ensure_code(par != NULL, cpl_error_get_code());
00436     
00437     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00438                                     alias ? alias : parameter);
00439     cpl_ensure_code(!error, error);
00440     
00441     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00442     cpl_ensure_code(!error, error);
00443 
00444     error = cpl_parameterlist_append(self, par);
00445     cpl_ensure_code(!error, error);
00446     
00447     return CPL_ERROR_NONE;
00448 }
00449 
00450 
00451 /*----------------------------------------------------------------------------*/
00465 /*----------------------------------------------------------------------------*/
00466 int irplib_plugin_test(cpl_pluginlist * self, size_t nstr, const char *astr[]) {
00467 
00468     cpl_plugin     * plugin;
00469     cpl_recipe     * recipe;
00470     int            (*recipe_create) (cpl_plugin *);
00471     int            (*recipe_exec  ) (cpl_plugin *);
00472     int            (*recipe_deinit) (cpl_plugin *);
00473     cpl_error_code error;
00474     FILE         * stream;
00475     cpl_boolean    is_debug;
00476 
00477 
00478     is_debug = cpl_msg_get_level() <= CPL_MSG_DEBUG ? CPL_TRUE : CPL_FALSE;
00479 
00480     /* Modified from CPL unit tests */
00481     stream = is_debug ? stdout : fopen("/dev/null", "a");
00482 
00483     inistate = cpl_errorstate_get();
00484 
00485     assert( nstr == 0 || astr != NULL );
00486 
00487     plugin = cpl_pluginlist_get_first(self);
00488 
00489     if (plugin == NULL) {
00490         cpl_msg_warning(cpl_func, "With an empty pluginlist, "
00491                         "no tests can be made");
00492         return 0;
00493     }
00494 
00495     cpl_plugin_dump(plugin, stream);
00496 
00497     recipe_create = cpl_plugin_get_init(plugin);
00498     cpl_test( recipe_create != NULL);
00499 
00500     recipe_exec   = cpl_plugin_get_exec(plugin);
00501     cpl_test( recipe_exec != NULL);
00502 
00503     recipe_deinit = cpl_plugin_get_deinit(plugin);
00504     cpl_test( recipe_deinit != NULL);
00505 
00506     /* Only plugins of type recipe are tested (further)  */
00507     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00508         cpl_msg_warning(cpl_func, "This plugin is not of type recipe, "
00509                       "cannot test further");
00510         return 0;
00511     }
00512 
00513     cpl_test_zero(recipe_create(plugin));
00514 
00515     recipe = (cpl_recipe *) plugin;
00516 
00517     cpl_test_nonnull( recipe->parameters );
00518 
00519     recipe_parameterlist_set(recipe->parameters);
00520 
00521     cpl_parameterlist_dump(recipe->parameters, stream);
00522 
00523     recipe->frames = cpl_frameset_new();
00524 
00525     if (irplib_plugin_has_sof_from_env(plugin, "RECIPE_SOF_PATH")) {
00526 
00527         recipe_sof_test_from_env(plugin);
00528 
00529     } else {
00530 
00531         const cpl_msg_severity msg_level = cpl_msg_get_level();
00532 
00533         /* Unless the CPL_MSG_LEVEL has been explicitly set, turn off
00534            terminal messaging completely while inside this function */
00535         if (getenv("CPL_MSG_LEVEL") == NULL) cpl_msg_set_level(CPL_MSG_OFF);
00536 
00537         cpl_msg_info(cpl_func,"Checking handling of pre-existing CPL error "
00538                      "state - may produce warning(s)/error(s):");
00539         cpl_error_set(cpl_func, CPL_ERROR_EOL);
00540         /* Call recipe and expect non-zero return code */
00541         cpl_test( recipe_exec(plugin) );
00542         /* Expect also the CPL error code to be preserved */
00543         cpl_test_error( CPL_ERROR_EOL );
00544 
00545         cpl_msg_info(cpl_func,"Checking handling of empty frameset - "
00546                      "may produce warning(s)/error(s):");
00547         /* Call recipe and expect non-zero return code */
00548         cpl_test( recipe_exec(plugin) );
00549         error = cpl_error_get_code();
00550         /* Expect also the CPL error code to be set */
00551         cpl_test_error( error );
00552         cpl_test( error );
00553 
00554         cpl_msg_info(cpl_func,"Checking handling of dummy frameset - "
00555                      "may produce warning(s)/error(s):");
00556         do {
00557             cpl_frame * f = cpl_frame_new();
00558             error = cpl_frame_set_filename(f, "/dev/null");
00559             cpl_test_eq_error(error, CPL_ERROR_NONE);
00560             error = cpl_frame_set_tag(f, "RECIPE_DUMMY_TAG");
00561             cpl_test_eq_error(error, CPL_ERROR_NONE);
00562             error = cpl_frameset_insert(recipe->frames, f);
00563             cpl_test_eq_error(error, CPL_ERROR_NONE);
00564 
00565             /* Call recipe and expect non-zero return code */
00566             cpl_test( recipe_exec(plugin) );
00567             error = cpl_error_get_code();
00568             /* Expect also the CPL error code to be set */
00569             cpl_test_error( error );
00570             cpl_test( error );
00571 
00572             error = cpl_frameset_erase_frame(recipe->frames, f);
00573             cpl_test_eq_error(error, CPL_ERROR_NONE);
00574 
00575         } while (0);
00576 
00577 #ifdef IRPLIB_TEST_RANDOM_SOF
00578         recipe_sof_test_devfile(plugin, DEV_RANDOM, nstr, astr);
00579 #endif
00580 
00581         recipe_sof_test_devfile(plugin, "/dev/null", nstr, astr);
00582 
00583         recipe_sof_test_devfile(plugin, ".", nstr, astr);
00584 
00585         recipe_sof_test_image_empty(plugin, nstr, astr);
00586 
00587         recipe_sof_test_local(plugin);
00588 
00589         cpl_msg_set_level(msg_level);
00590 
00591     }
00592 
00593     cpl_frameset_delete(recipe->frames);
00594 
00595     error = recipe_deinit(plugin);
00596     cpl_test_eq_error(error, CPL_ERROR_NONE);
00597 
00598     if (stream != stdout) fclose(stream);
00599 
00600     return 0;
00601 }
00602 
00605 /*----------------------------------------------------------------------------*/
00615 /*----------------------------------------------------------------------------*/
00616 static void recipe_parameterlist_set(cpl_parameterlist * self)
00617 {
00618 
00619     cpl_parameter * p = cpl_parameterlist_get_first(self);
00620 
00621     for (; p != NULL; p = cpl_parameterlist_get_next(self)) {
00622 
00623         const char * envvar;
00624         const char * svalue;
00625 
00626         /* FIXME: Needed ? */
00627         if (cpl_parameter_get_default_flag(p)) continue;
00628 
00629         cpl_msg_debug(cpl_func, __FILE__ " line %u: OK", __LINE__);
00630 
00631         envvar = cpl_parameter_get_alias(p, CPL_PARAMETER_MODE_ENV);
00632         svalue = envvar ? getenv(envvar) : NULL;
00633 
00634         switch (cpl_parameter_get_type(p)) {
00635         case CPL_TYPE_BOOL: {
00636             const int value
00637                 = svalue ? atoi(svalue) : cpl_parameter_get_default_bool(p);
00638             cpl_parameter_set_bool(p, value);
00639             break;
00640         }
00641         case CPL_TYPE_INT: {
00642             const int value
00643                 = svalue ? atoi(svalue) : cpl_parameter_get_default_int(p);
00644             cpl_parameter_set_int(p, value);
00645             break;
00646         }
00647         case CPL_TYPE_DOUBLE: {
00648             const double value
00649                 = svalue ? atof(svalue) : cpl_parameter_get_default_double(p);
00650             cpl_parameter_set_double(p, value);
00651             break;
00652         }
00653         case CPL_TYPE_STRING:
00654             {
00655                 const char * s_default = cpl_parameter_get_default_string(p);
00656                 /* Replace NULL with "" */
00657                 const char * value
00658                     = svalue ? svalue : (s_default ? s_default : "");
00659                 cpl_parameter_set_string(p, value);
00660                 break;
00661             }
00662 
00663         default:
00664             assert( 0 ); /* It is a testing error to reach this point */
00665         }
00666     }
00667 }
00668 
00669 
00670 /*----------------------------------------------------------------------------*/
00680 /*----------------------------------------------------------------------------*/
00681 static void recipe_sof_test_devfile(cpl_plugin * plugin, const char * filename,
00682                                     size_t nstr, const char *astr[])
00683 {
00684     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00685     int       (*recipe_exec) (cpl_plugin *);
00686     cpl_frameset * copy;
00687     cpl_error_code error;
00688     size_t i;
00689 
00690 
00691     if (nstr < 1) return;
00692     if (filename == NULL) return;
00693 
00694     cpl_msg_info(cpl_func, "Testing recipe with %u %s as input ",
00695                  (unsigned)nstr, filename);
00696 
00697     for (i = 0; i < nstr; i++) {
00698         cpl_frame * f = cpl_frame_new();
00699 
00700         error = cpl_frame_set_filename(f, filename);
00701         cpl_test_eq_error(error, CPL_ERROR_NONE);
00702 
00703         error = cpl_frame_set_tag(f, astr[i]);
00704         cpl_test_eq_error(error, CPL_ERROR_NONE);
00705 
00706         error = cpl_frameset_insert(recipe->frames, f);
00707         cpl_test_eq_error(error, CPL_ERROR_NONE);
00708     }
00709 
00710     copy = cpl_frameset_duplicate(recipe->frames);
00711 
00712     recipe_exec = cpl_plugin_get_exec(plugin);
00713     cpl_test( recipe_exec != NULL);
00714 
00715     /* Call recipe and expect non-zero return code */
00716     cpl_test( recipe_exec(plugin) );
00717     error = cpl_error_get_code();
00718     /* Expect also the CPL error code to be set */
00719     cpl_test_error( error );
00720     cpl_test( error );
00721 
00722     recipe_frameset_test_frameset_diff(recipe->frames, copy);
00723 
00724     recipe_frameset_empty(recipe->frames);
00725 
00726     cpl_frameset_delete(copy);
00727 
00728     return;
00729 }
00730 
00731 /*----------------------------------------------------------------------------*/
00738 /*----------------------------------------------------------------------------*/
00739 static void recipe_sof_test_image_empty(cpl_plugin * plugin, size_t nstr,
00740                                         const char *astr[])
00741 {
00742     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00743     int       (*recipe_exec) (cpl_plugin *);
00744     cpl_frameset * copy;
00745     cpl_error_code error;
00746     size_t i;
00747     cpl_frame * frame;
00748     cpl_image * iempty;
00749 
00750 
00751     if (nstr < 1) return;
00752 
00753     cpl_msg_info(cpl_func, "Testing recipe with %u empty images as input ",
00754                  (unsigned)nstr);
00755 
00756     iempty = cpl_image_new(13, 17, CPL_TYPE_FLOAT);
00757     cpl_test_nonnull(iempty);
00758 
00759     for (i = 0; i < nstr; i++) {
00760         cpl_frame * f = cpl_frame_new();
00761         char * rawname = cpl_sprintf("raw%05u.fits", (unsigned)(i+1));
00762 
00763         error = cpl_image_save(iempty, rawname,CPL_BPP_IEEE_FLOAT, NULL,
00764                                CPL_IO_DEFAULT);
00765         cpl_test_eq_error(error, CPL_ERROR_NONE);
00766 
00767         error = cpl_frame_set_filename(f, rawname);
00768         cpl_test_eq_error(error, CPL_ERROR_NONE);
00769 
00770         error = cpl_frame_set_tag(f, astr[i]);
00771         cpl_test_eq_error(error, CPL_ERROR_NONE);
00772 
00773         error = cpl_frameset_insert(recipe->frames, f);
00774         cpl_test_eq_error(error, CPL_ERROR_NONE);
00775 
00776         cpl_free(rawname);
00777     }
00778     cpl_image_delete(iempty);
00779 
00780     copy = cpl_frameset_duplicate(recipe->frames);
00781 
00782     recipe_exec = cpl_plugin_get_exec(plugin);
00783     cpl_test(recipe_exec != NULL);
00784 
00785     /* Call recipe and expect non-zero return code */
00786     cpl_test( recipe_exec(plugin) );
00787     error = cpl_error_get_code();
00788     /* Expect also the CPL error code to be set */
00789     cpl_test_error( error );
00790     cpl_test( error );
00791 
00792     for (frame = cpl_frameset_get_first(recipe->frames); frame != NULL;
00793          frame = cpl_frameset_get_next(recipe->frames))
00794         {
00795             cpl_test_zero( remove(cpl_frame_get_filename(frame)) );
00796         }
00797 
00798     recipe_frameset_test_frameset_diff(recipe->frames, copy);
00799 
00800     recipe_frameset_empty(recipe->frames);
00801 
00802     cpl_frameset_delete(copy);
00803 
00804     return;
00805 }
00806 
00807 
00808 /*----------------------------------------------------------------------------*/
00816 /*----------------------------------------------------------------------------*/
00817 cpl_boolean irplib_plugin_has_sof_from_env(const cpl_plugin * plugin,
00818                                            const char * envname)
00819 {
00820     const char      * recipename = cpl_plugin_get_name(plugin);
00821     const char      * sof_path   = envname ? getenv(envname) : NULL;
00822     cpl_frameset    * frames;
00823     char            * sof_name;
00824     const cpl_frame * ffirst;
00825 
00826     cpl_ensure(plugin  != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
00827     cpl_ensure(envname != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
00828     cpl_ensure(recipename != NULL, CPL_ERROR_DATA_NOT_FOUND, CPL_FALSE);
00829     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), CPL_FALSE);
00830 
00831     if (sof_path == NULL) return CPL_FALSE;
00832 
00833     sof_name = cpl_sprintf("%s/%s.sof", sof_path, recipename);
00834 
00835     frames = cpl_frameset_new();
00836     recipe_frameset_load(frames, sof_name);
00837 
00838     ffirst = cpl_frameset_get_first_const(frames);
00839 
00840     cpl_free(sof_name);
00841     cpl_frameset_delete(frames);
00842 
00843     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), CPL_FALSE);
00844 
00845     return ffirst ? CPL_TRUE : CPL_FALSE;
00846 
00847 }
00848 
00849 /*----------------------------------------------------------------------------*/
00856 /*----------------------------------------------------------------------------*/
00857 static void recipe_sof_test_from_env(cpl_plugin * plugin)
00858 {
00859     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00860     const char * recipename = cpl_plugin_get_name(plugin);
00861     const char * var_name = "RECIPE_SOF_PATH";
00862     const char * sof_path = getenv(var_name);
00863     cpl_error_code error;
00864 
00865     char * sof_name;
00866 
00867     if (sof_path == NULL) {
00868         cpl_msg_warning(cpl_func, "Environment variable %s is unset: "
00869                         "No SOFs to check", var_name);
00870         return;
00871     }
00872 
00873     cpl_msg_debug(cpl_func, "Checking for SOFs in %s", sof_path);
00874 
00875     cpl_test_nonnull( recipename );
00876     if (recipename == NULL) return;
00877 
00878     sof_name = cpl_sprintf("%s/%s.sof", sof_path, recipename);
00879 
00880     cpl_msg_debug(cpl_func, "Checking for SOF %s", sof_name);
00881     
00882     recipe_frameset_load(recipe->frames, sof_name);
00883 
00884     if (!cpl_frameset_is_empty(recipe->frames)) {
00885 
00886         int          (*recipe_exec  ) (cpl_plugin *);
00887         cpl_frameset * copy = cpl_frameset_duplicate(recipe->frames);
00888 
00889         recipe_exec   = cpl_plugin_get_exec(plugin);
00890         cpl_test(recipe_exec != NULL);
00891 
00892         cpl_msg_info(cpl_func,"Checking handling of SOF: %s", sof_name);
00893 
00894         /* Call recipe and expect zero return code */
00895         cpl_test_zero( recipe_exec(plugin) );
00896         /* Expect also the CPL error code to be clear */
00897         cpl_test_error(CPL_ERROR_NONE);
00898 
00899         error = cpl_dfs_update_product_header(recipe->frames);
00900         cpl_test_eq_error(error, CPL_ERROR_NONE);
00901 
00902         recipe_frameset_test_frameset_diff(recipe->frames, copy);
00903 
00904         recipe_frameset_empty(recipe->frames);
00905 
00906         cpl_frameset_delete(copy);
00907 
00908     }
00909 
00910     cpl_free(sof_name);
00911 
00912     return;
00913 }
00914 
00915 
00916 
00917 /*----------------------------------------------------------------------------*/
00924 /*----------------------------------------------------------------------------*/
00925 static void recipe_sof_test_local(cpl_plugin * plugin)
00926 {
00927     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00928     const char * recipename = cpl_plugin_get_name(plugin);
00929     cpl_error_code error;
00930     char * sof_name = cpl_sprintf("%s.sof", recipename);
00931 
00932     cpl_msg_debug(cpl_func, "Checking for SOF %s", sof_name);
00933     
00934     recipe_frameset_load(recipe->frames, sof_name);
00935 
00936     if (!cpl_frameset_is_empty(recipe->frames)) {
00937 
00938         int          (*recipe_exec  ) (cpl_plugin *);
00939         cpl_frameset * copy = cpl_frameset_duplicate(recipe->frames);
00940 
00941         recipe_exec   = cpl_plugin_get_exec(plugin);
00942         cpl_test(recipe_exec != NULL);
00943 
00944         cpl_msg_info(cpl_func,"Checking handling of SOF: %s", sof_name);
00945 
00946         /* Call recipe and expect zero return code */
00947         cpl_test_zero( recipe_exec(plugin) );
00948         /* Expect also the CPL error code to be clear */
00949         cpl_test_error(CPL_ERROR_NONE);
00950 
00951         error = cpl_dfs_update_product_header(recipe->frames);
00952         cpl_test_eq_error( error, CPL_ERROR_NONE );
00953 
00954         recipe_frameset_test_frameset_diff(recipe->frames, copy);
00955 
00956         recipe_frameset_empty(recipe->frames);
00957 
00958         cpl_frameset_delete(copy);
00959     }
00960 
00961     cpl_free(sof_name);
00962 
00963     return;
00964 }
00965 
00966 
00967 
00968 
00969 /**********************************************************************/
00983 /**********************************************************************/
00984 
00985 static void recipe_frameset_load(cpl_frameset * set, const char *name)
00986 {
00987 
00988     FILE *fp;
00989     char line[LINE_LEN_MAX];
00990     char path[LINE_LEN_MAX], group[LINE_LEN_MAX], tag[LINE_LEN_MAX];
00991     int line_number;
00992 
00993     assert( set != NULL );
00994     assert( name != NULL );
00995 
00996     fp = fopen(name, "r");
00997     if (fp == NULL) {
00998         cpl_msg_debug(cpl_func, "Unable to open SOF file '%s'", name);
00999         return;
01000     }
01001 
01002     /* Loop over all the lines in the set-of-frames file */
01003     for (line_number = 0; fgets(line, LINE_LEN_MAX - 1, fp); line_number++) {
01004 
01005         cpl_frame_group grp;
01006         cpl_frame * frame;
01007         int n;
01008 
01009         if (line[0] == '#') continue;
01010 
01011         n = sscanf(line, "%s %s %s", path, tag, group);
01012 
01013         if (n < 1) {
01014             cpl_msg_warning(cpl_func, "Spurious line no. %d in %s: %s",
01015                             line_number, name, line);
01016             break;
01017         }
01018 
01019         /* Allocate a new frame */
01020         frame = cpl_frame_new();
01021 
01022         /* Set the filename component of the frame */
01023         cpl_frame_set_filename(frame, path);
01024 
01025         /* Set the tag component of the frame (or set a default) */
01026         cpl_frame_set_tag(frame, n == 1 ? "" : tag);
01027 
01028         cpl_frameset_insert(set, frame);
01029 
01030         /* Set the group component of the frame (or set a default) */
01031         if (n < 3) continue;
01032 
01033         if (!strcmp(group, CPL_FRAME_GROUP_RAW_ID))
01034             grp = CPL_FRAME_GROUP_RAW;
01035         else if (!strcmp(group, CPL_FRAME_GROUP_CALIB_ID))
01036             grp = CPL_FRAME_GROUP_CALIB;
01037         else if (!strcmp(group, CPL_FRAME_GROUP_PRODUCT_ID))
01038             grp = CPL_FRAME_GROUP_PRODUCT;
01039         else
01040             grp = CPL_FRAME_GROUP_NONE;
01041 
01042         cpl_frame_set_group(frame, grp);
01043     }
01044 
01045     fclose(fp);
01046 
01047     return;
01048 
01049 }
01050 
01051 
01052 /*----------------------------------------------------------------------------*/
01062 /*----------------------------------------------------------------------------*/
01063 static
01064 const cpl_parameter * irplib_parameterlist_get(const cpl_parameterlist * self,
01065                                                const char * instrume,
01066                                                const char * recipe,
01067                                                const char * parameter)
01068 {
01069 
01070     char                * paramname;
01071     const cpl_parameter * par;
01072 
01073 
01074     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, NULL);
01075     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, NULL);
01076     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, NULL);
01077 
01078     paramname = cpl_sprintf("%s.%s.%s", instrume, recipe, parameter);
01079 
01080     par = cpl_parameterlist_find_const(self, paramname);
01081 
01082     if (par == NULL) (void)cpl_error_set_message(cpl_func,
01083                                                  cpl_error_get_code()
01084                                                  ? cpl_error_get_code()
01085                                                  : CPL_ERROR_DATA_NOT_FOUND,
01086                                                  "%s", paramname);
01087 
01088     cpl_free(paramname);
01089     
01090     return par;
01091 
01092 }
01093 
01094 
01095 /*----------------------------------------------------------------------------*/
01121 /*----------------------------------------------------------------------------*/
01122 static void recipe_frameset_empty(cpl_frameset * self)
01123 {
01124     cpl_frame * f;
01125 
01126     if (self == NULL) {
01127         cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
01128         return;
01129     }
01130 
01131     for (f = cpl_frameset_get_first(self); f != NULL;
01132          f = cpl_frameset_get_first(self))
01133         {
01134             cpl_frameset_erase_frame(self, f);
01135         }
01136 }
01137 
01138 
01139 /*----------------------------------------------------------------------------*/
01159 /*----------------------------------------------------------------------------*/
01160 static void recipe_frameset_test_frame(const cpl_frame * self)
01161 {
01162 
01163     cpl_msg_info(cpl_func, "Validating new frame: %s",
01164                  cpl_frame_get_filename(self));
01165 
01166     cpl_test_nonnull(self);
01167 
01168     /* Frame must be tagged */
01169     cpl_test_nonnull(cpl_frame_get_tag(self));
01170 
01171     /* New frames must be products */
01172     cpl_test_eq(cpl_frame_get_group(self), CPL_FRAME_GROUP_PRODUCT);
01173 
01174     if (cpl_frame_get_type(self) != CPL_FRAME_TYPE_PAF) {
01175         /* All but PAF (?) must be FITS */
01176         cpl_test_fits(cpl_frame_get_filename(self));
01177     } else {
01178         /* Frame must at least have a filename */
01179         cpl_test_nonnull(cpl_frame_get_filename(self));
01180     }
01181 }
01182 
01183 /*----------------------------------------------------------------------------*/
01204 /*----------------------------------------------------------------------------*/
01205 static void recipe_frameset_test_frameset_diff(const cpl_frameset * self,
01206                                                const cpl_frameset * other)
01207 {
01208 
01209     const cpl_frame * frame = cpl_frameset_get_first_const(other);
01210 
01211     /* First verify that filenames in other are non-NULL */
01212     for (;frame != NULL; frame = cpl_frameset_get_next_const(other)) {
01213         const char * file = cpl_frame_get_filename(frame);
01214 
01215         if (file == NULL) {
01216             cpl_test_nonnull(cpl_frame_get_filename(frame));
01217             break;
01218         }
01219     }
01220     if (frame != NULL) return;
01221 
01222     frame = cpl_frameset_get_first_const(self);
01223 
01224     for (;frame != NULL; frame = cpl_frameset_get_next_const(self)) {
01225         const cpl_frame * cmp  = cpl_frameset_get_first_const(other);
01226         const char * file = cpl_frame_get_filename(frame);
01227 
01228         if (file == NULL) {
01229             cpl_test_nonnull(cpl_frame_get_filename(frame));
01230             continue;
01231         }
01232 
01233         for (;cmp != NULL; cmp = cpl_frameset_get_next_const(other)) {
01234             const char * cfile = cpl_frame_get_filename(cmp);
01235 
01236             if (!strcmp(file, cfile)) break;
01237 
01238         }
01239         if (cmp == NULL) {
01240             /* frame is new */
01241             recipe_frameset_test_frame(frame);
01242         }
01243     }
01244 }

Generated on Mon Feb 6 14:42:06 2012 for NACO Pipeline Reference Manual by  doxygen 1.5.8