irplib_plugin.c

00001 /* $Id: irplib_plugin.c,v 1.30 2009/11/16 17:00:15 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: 2009/11/16 17:00:15 $
00024  * $Revision: 1.30 $
00025  * $Name: visir-3_3_1-public $
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 void recipe_frameset_load(cpl_frameset *, const char *);
00091 
00092 static void recipe_sof_test_devfile(cpl_plugin *, const char *, size_t,
00093                                    const char *[]);
00094 static void recipe_sof_test_image_empty(cpl_plugin *, size_t, const char *[]);
00095 static void recipe_sof_test_local(cpl_plugin *);
00096 static void recipe_sof_test_from_env(cpl_plugin *);
00097 static void recipe_frameset_empty(cpl_frameset *);
00098 static void recipe_frameset_test_frame(const cpl_frame *);
00099 static void recipe_frameset_test_frameset_diff(const cpl_frameset *,
00100                                                const cpl_frameset *);
00101 
00102 static cpl_errorstate inistate;
00103 
00106 /*-----------------------------------------------------------------------------
00107                             Function definitions
00108  -----------------------------------------------------------------------------*/
00109 
00110 /*----------------------------------------------------------------------------*/
00120 /*----------------------------------------------------------------------------*/
00121 const char * irplib_parameterlist_get_string(const cpl_parameterlist * self,
00122                                              const char * instrume,
00123                                              const char * recipe,
00124                                              const char * parameter)
00125 {
00126 
00127     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00128                                                          recipe, parameter);
00129     const char * value;
00130 
00131     cpl_ensure(self      != NULL, CPL_ERROR_NULL_INPUT, 0);
00132     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, 0);
00133     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, 0);
00134     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, 0);
00135 
00136 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00137     cpl_error_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, return(NULL),
00138                      "instrume=%s, recipe=%s, parameter=%s", instrume, recipe,
00139                      parameter);
00140 #else
00141     cpl_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, NULL);
00142 #endif
00143 
00144     cpl_ensure(cpl_parameter_get_type(par) == CPL_TYPE_STRING,
00145                CPL_ERROR_TYPE_MISMATCH, NULL);
00146 
00147     value = cpl_parameter_get_string(par);
00148 
00149     cpl_ensure(value != NULL, cpl_error_get_code(), NULL);
00150 
00151     return value;
00152 
00153 }
00154 
00155 /*----------------------------------------------------------------------------*/
00165 /*----------------------------------------------------------------------------*/
00166 cpl_boolean irplib_parameterlist_get_bool(const cpl_parameterlist * self,
00167                                           const char * instrume,
00168                                           const char * recipe,
00169                                           const char * parameter)
00170 {
00171 
00172     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00173                                                          recipe, parameter);
00174     cpl_errorstate  prestate = cpl_errorstate_get();
00175     cpl_boolean           value;
00176 
00177     cpl_ensure(self      != NULL, CPL_ERROR_NULL_INPUT, 0);
00178     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, 0);
00179     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, 0);
00180     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, 0);
00181 
00182 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00183     cpl_error_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, return(CPL_FALSE),
00184                      "instrume=%s, recipe=%s, parameter=%s", instrume, recipe,
00185                      parameter);
00186 #else
00187     cpl_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, CPL_FALSE);
00188 #endif
00189 
00190 
00191     cpl_ensure(cpl_parameter_get_type(par) == CPL_TYPE_BOOL,
00192                CPL_ERROR_TYPE_MISMATCH, CPL_FALSE);
00193 
00194     value = cpl_parameter_get_bool(par);
00195 
00196     if (!cpl_errorstate_is_equal(prestate)) (void)cpl_error_set_where(cpl_func);
00197 
00198     return value;
00199 
00200 }
00201 
00202 
00203 /*----------------------------------------------------------------------------*/
00213 /*----------------------------------------------------------------------------*/
00214 int irplib_parameterlist_get_int(const cpl_parameterlist * self,
00215                                  const char * instrume,
00216                                  const char * recipe,
00217                                  const char * parameter)
00218 {
00219 
00220     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00221                                                          recipe, parameter);
00222     cpl_errorstate  prestate = cpl_errorstate_get();
00223     int                   value;
00224 
00225     cpl_ensure(self      != NULL, CPL_ERROR_NULL_INPUT, 0);
00226     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, 0);
00227     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, 0);
00228     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, 0);
00229 
00230 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00231     cpl_error_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, return(0),
00232                      "instrume=%s, recipe=%s, parameter=%s", instrume, recipe,
00233                      parameter);
00234 #else
00235     cpl_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, 0);
00236 #endif
00237 
00238     cpl_ensure(cpl_parameter_get_type(par) == CPL_TYPE_INT,
00239                CPL_ERROR_TYPE_MISMATCH, 0);
00240 
00241     value = cpl_parameter_get_int(par);
00242 
00243     if (!cpl_errorstate_is_equal(prestate)) (void)cpl_error_set_where(cpl_func);
00244 
00245     return value;
00246 }
00247 
00248 /*----------------------------------------------------------------------------*/
00258 /*----------------------------------------------------------------------------*/
00259 double irplib_parameterlist_get_double(const cpl_parameterlist * self,
00260                                        const char * instrume,
00261                                        const char * recipe,
00262                                        const char * parameter)
00263 {
00264 
00265     const cpl_parameter * par = irplib_parameterlist_get(self, instrume,
00266                                                          recipe, parameter);
00267     cpl_errorstate  prestate = cpl_errorstate_get();
00268     double                value;
00269 
00270     cpl_ensure(self      != NULL, CPL_ERROR_NULL_INPUT, 0);
00271     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, 0);
00272     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, 0);
00273     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, 0);
00274 
00275 #if defined CPL_HAVE_VA_ARGS && CPL_HAVE_VA_ARGS != 0
00276     cpl_error_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, return(0.0),
00277                      "instrume=%s, recipe=%s, parameter=%s", instrume, recipe,
00278                      parameter);
00279 #else
00280     cpl_ensure(par != NULL, CPL_ERROR_DATA_NOT_FOUND, 0.0);
00281 #endif
00282 
00283     cpl_ensure(cpl_parameter_get_type(par) == CPL_TYPE_DOUBLE,
00284                CPL_ERROR_TYPE_MISMATCH, 0.0);
00285 
00286     value = cpl_parameter_get_double(par);
00287 
00288     if (!cpl_errorstate_is_equal(prestate)) (void)cpl_error_set_where(cpl_func);
00289 
00290     return value;
00291 }
00292 
00293 /*----------------------------------------------------------------------------*/
00307 /*----------------------------------------------------------------------------*/
00308 cpl_error_code irplib_parameterlist_set_string(cpl_parameterlist * self,
00309                                                const char * instrume,
00310                                                const char * recipe,
00311                                                const char * parameter,
00312                                                const char * defvalue,
00313                                                const char * alias,
00314                                                const char * context,
00315                                                const char * man)
00316 {
00317 
00318     cpl_error_code  error;
00319     cpl_parameter * par;
00320     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00321                                             parameter);
00322 
00323     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00324     
00325     par = cpl_parameter_new_value(paramname, CPL_TYPE_STRING, man, context,
00326                                   defvalue);
00327     cpl_free(paramname);
00328 
00329     cpl_ensure_code(par != NULL, cpl_error_get_code());
00330     
00331     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00332                                     alias ? alias : parameter);
00333     cpl_ensure_code(!error, error);
00334 
00335     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00336     cpl_ensure_code(!error, error);
00337 
00338     error = cpl_parameterlist_append(self, par);
00339     cpl_ensure_code(!error, error);
00340     
00341     return CPL_ERROR_NONE;
00342 }
00343 
00344 
00345 /*----------------------------------------------------------------------------*/
00359 /*----------------------------------------------------------------------------*/
00360 cpl_error_code irplib_parameterlist_set_bool(cpl_parameterlist * self,
00361                                              const char * instrume,
00362                                              const char * recipe,
00363                                              const char * parameter,
00364                                              cpl_boolean  defvalue,
00365                                              const char * alias,
00366                                              const char * context,
00367                                              const char * man)
00368 {
00369 
00370     cpl_error_code  error;
00371     cpl_parameter * par;
00372     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00373                                             parameter);
00374 
00375     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00376     
00377     par = cpl_parameter_new_value(paramname, CPL_TYPE_BOOL, man, context,
00378                                   defvalue);
00379     cpl_free(paramname);
00380 
00381     cpl_ensure_code(par != NULL, cpl_error_get_code());
00382     
00383     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00384                                     alias ? alias : parameter);
00385     cpl_ensure_code(!error, error);
00386     
00387     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00388     cpl_ensure_code(!error, error);
00389 
00390     error = cpl_parameterlist_append(self, par);
00391     cpl_ensure_code(!error, error);
00392     
00393     return CPL_ERROR_NONE;
00394 }
00395 
00396 
00397 
00398 /*----------------------------------------------------------------------------*/
00412 /*----------------------------------------------------------------------------*/
00413 cpl_error_code irplib_parameterlist_set_int(cpl_parameterlist * self,
00414                                             const char * instrume,
00415                                             const char * recipe,
00416                                             const char * parameter,
00417                                             int         defvalue,
00418                                             const char * alias,
00419                                             const char * context,
00420                                             const char * man)
00421 {
00422 
00423     cpl_error_code  error;
00424     cpl_parameter * par;
00425     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00426                                             parameter);
00427 
00428     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00429     
00430     par = cpl_parameter_new_value(paramname, CPL_TYPE_INT, man, context,
00431                                   defvalue);
00432     cpl_free(paramname);
00433 
00434     cpl_ensure_code(par != NULL, cpl_error_get_code());
00435     
00436     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00437                                     alias ? alias : parameter);
00438     cpl_ensure_code(!error, error);
00439     
00440     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00441     cpl_ensure_code(!error, error);
00442 
00443     error = cpl_parameterlist_append(self, par);
00444     cpl_ensure_code(!error, error);
00445     
00446     return CPL_ERROR_NONE;
00447 }
00448 
00449 
00450 /*----------------------------------------------------------------------------*/
00464 /*----------------------------------------------------------------------------*/
00465 cpl_error_code irplib_parameterlist_set_double(cpl_parameterlist * self,
00466                                                const char * instrume,
00467                                                const char * recipe,
00468                                                const char * parameter,
00469                                                double       defvalue,
00470                                                const char * alias,
00471                                                const char * context,
00472                                                const char * man)
00473 {
00474 
00475     cpl_error_code  error;
00476     cpl_parameter * par;
00477     char          * paramname = cpl_sprintf("%s.%s.%s", instrume, recipe,
00478                                             parameter);
00479 
00480     cpl_ensure_code(paramname != NULL, cpl_error_get_code());
00481     
00482     par = cpl_parameter_new_value(paramname, CPL_TYPE_DOUBLE, man, context,
00483                                   defvalue);
00484     cpl_free(paramname);
00485 
00486     cpl_ensure_code(par != NULL, cpl_error_get_code());
00487     
00488     error = cpl_parameter_set_alias(par, CPL_PARAMETER_MODE_CLI,
00489                                     alias ? alias : parameter);
00490     cpl_ensure_code(!error, error);
00491     
00492     error = cpl_parameter_disable(par, CPL_PARAMETER_MODE_ENV);
00493     cpl_ensure_code(!error, error);
00494 
00495     error = cpl_parameterlist_append(self, par);
00496     cpl_ensure_code(!error, error);
00497     
00498     return CPL_ERROR_NONE;
00499 }
00500 
00501 
00502 /*----------------------------------------------------------------------------*/
00516 /*----------------------------------------------------------------------------*/
00517 int irplib_plugin_test(cpl_pluginlist * self, size_t nstr, const char *astr[]) {
00518 
00519     cpl_plugin     * plugin;
00520     cpl_recipe     * recipe;
00521     int            (*recipe_create) (cpl_plugin *);
00522     int            (*recipe_exec  ) (cpl_plugin *);
00523     int            (*recipe_deinit) (cpl_plugin *);
00524     const cpl_msg_severity msg_level = cpl_msg_get_level();
00525     cpl_error_code error;
00526     FILE         * stream;
00527     cpl_boolean    is_debug;
00528 
00529 
00530     /* Unless the CPL_MSG_LEVEL has been explicitly set, turn off
00531        terminal messaging completely while inside this function */
00532     if (getenv("CPL_MSG_LEVEL") == NULL) cpl_msg_set_level(CPL_MSG_OFF);
00533 
00534     is_debug = cpl_msg_get_level() <= CPL_MSG_DEBUG ? CPL_TRUE : CPL_FALSE;
00535 
00536     /* Modified from CPL unit tests */
00537     stream = is_debug ? stdout : fopen("/dev/null", "a");
00538 
00539     inistate = cpl_errorstate_get();
00540 
00541     assert( nstr == 0 || astr != NULL );
00542 
00543     plugin = cpl_pluginlist_get_first(self);
00544 
00545     if (plugin == NULL) {
00546         cpl_msg_warning(cpl_func, "With an empty pluginlist, "
00547                         "no tests can be made");
00548         cpl_msg_set_level(msg_level);
00549         return 0;
00550     }
00551 
00552     cpl_plugin_dump(plugin, stream);
00553 
00554     recipe_create = cpl_plugin_get_init(plugin);
00555     cpl_test( recipe_create != NULL);
00556 
00557     recipe_exec   = cpl_plugin_get_exec(plugin);
00558     cpl_test( recipe_exec != NULL);
00559 
00560     recipe_deinit = cpl_plugin_get_deinit(plugin);
00561     cpl_test( recipe_deinit != NULL);
00562 
00563     /* Only plugins of type recipe are tested (further)  */
00564     if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) {
00565         cpl_msg_warning(cpl_func, "This plugin is not of type recipe, "
00566                       "cannot test further");
00567         cpl_msg_set_level(msg_level);
00568         return 0;
00569     }
00570 
00571     cpl_test_zero(recipe_create(plugin));
00572 
00573     recipe = (cpl_recipe *) plugin;
00574 
00575     cpl_test_nonnull( recipe->parameters );
00576 
00577     recipe_parameterlist_set(recipe->parameters);
00578 
00579     cpl_parameterlist_dump(recipe->parameters, stream);
00580 
00581     recipe->frames = cpl_frameset_new();
00582 
00583     cpl_msg_info(cpl_func,"Checking handling of pre-existing CPL error state - "
00584                  "may produce warning(s)/error(s):");
00585     cpl_error_set(cpl_func, CPL_ERROR_EOL);
00586     /* Call recipe and expect non-zero return code */
00587     cpl_test( recipe_exec(plugin) );
00588     /* Expect also the CPL error code to be preserved */
00589     cpl_test_error( CPL_ERROR_EOL );
00590 
00591     cpl_msg_info(cpl_func,"Checking handling of empty frameset - "
00592                  "may produce warning(s)/error(s):");
00593     /* Call recipe and expect non-zero return code */
00594     cpl_test( recipe_exec(plugin) );
00595     error = cpl_error_get_code();
00596     /* Expect also the CPL error code to be set */
00597     cpl_test_error( error );
00598     cpl_test( error );
00599 
00600     cpl_msg_info(cpl_func,"Checking handling of dummy frameset - "
00601                  "may produce warning(s)/error(s):");
00602     do {
00603         cpl_frame * f = cpl_frame_new();
00604         error = cpl_frame_set_filename(f, "/dev/null");
00605         cpl_test_error(error);
00606         cpl_test_zero(error);
00607         error = cpl_frame_set_tag(f, "RECIPE_DUMMY_TAG");
00608         cpl_test_error(error);
00609         cpl_test_zero(error);
00610         error = cpl_frameset_insert(recipe->frames, f);
00611         cpl_test_error(error);
00612         cpl_test_zero(error);
00613 
00614         /* Call recipe and expect non-zero return code */
00615         cpl_test( recipe_exec(plugin) );
00616         error = cpl_error_get_code();
00617         /* Expect also the CPL error code to be set */
00618         cpl_test_error( error );
00619         cpl_test( error );
00620 
00621         error = cpl_frameset_erase_frame(recipe->frames, f);
00622         cpl_test_error(error);
00623         cpl_test_zero(error);
00624 
00625     } while (0);
00626 
00627 #ifdef IRPLIB_TEST_RANDOM_SOF
00628     recipe_sof_test_devfile(plugin, DEV_RANDOM, nstr, astr);
00629 #endif
00630 
00631     recipe_sof_test_devfile(plugin, "/dev/null", nstr, astr);
00632 
00633     recipe_sof_test_devfile(plugin, ".", nstr, astr);
00634 
00635     recipe_sof_test_image_empty(plugin, nstr, astr);
00636 
00637     recipe_sof_test_local(plugin);
00638 
00639     recipe_sof_test_from_env(plugin);
00640 
00641     cpl_frameset_delete(recipe->frames);
00642 
00643     error = recipe_deinit(plugin);
00644     cpl_test_error(error);
00645     cpl_test_zero(error);
00646 
00647     cpl_msg_set_level(msg_level);
00648 
00649     if (stream != stdout) fclose(stream);
00650 
00651     return 0;
00652 }
00653 
00656 /*----------------------------------------------------------------------------*/
00666 /*----------------------------------------------------------------------------*/
00667 static void recipe_parameterlist_set(cpl_parameterlist * self)
00668 {
00669 
00670     cpl_parameter * p = cpl_parameterlist_get_first(self);
00671 
00672     for (; p != NULL; p = cpl_parameterlist_get_next(self)) {
00673 
00674         const char * envvar;
00675         const char * svalue;
00676 
00677         /* FIXME: Needed ? */
00678         if (cpl_parameter_get_default_flag(p)) continue;
00679 
00680         cpl_msg_debug(cpl_func, __FILE__ " line %u: OK", __LINE__);
00681 
00682         envvar = cpl_parameter_get_alias(p, CPL_PARAMETER_MODE_ENV);
00683         svalue = envvar ? getenv(envvar) : NULL;
00684 
00685         switch (cpl_parameter_get_type(p)) {
00686         case CPL_TYPE_BOOL: {
00687             const int value
00688                 = svalue ? atoi(svalue) : cpl_parameter_get_default_bool(p);
00689             cpl_parameter_set_bool(p, value);
00690             break;
00691         }
00692         case CPL_TYPE_INT: {
00693             const int value
00694                 = svalue ? atoi(svalue) : cpl_parameter_get_default_int(p);
00695             cpl_parameter_set_int(p, value);
00696             break;
00697         }
00698         case CPL_TYPE_DOUBLE: {
00699             const double value
00700                 = svalue ? atof(svalue) : cpl_parameter_get_default_double(p);
00701             cpl_parameter_set_double(p, value);
00702             break;
00703         }
00704         case CPL_TYPE_STRING:
00705             {
00706                 const char * s_default = cpl_parameter_get_default_string(p);
00707                 /* Replace NULL with "" */
00708                 const char * value
00709                     = svalue ? svalue : (s_default ? s_default : "");
00710                 cpl_parameter_set_string(p, value);
00711                 break;
00712             }
00713 
00714         default:
00715             assert( 0 ); /* It is a testing error to reach this point */
00716         }
00717     }
00718 }
00719 
00720 
00721 /*----------------------------------------------------------------------------*/
00731 /*----------------------------------------------------------------------------*/
00732 static void recipe_sof_test_devfile(cpl_plugin * plugin, const char * filename,
00733                                     size_t nstr, const char *astr[])
00734 {
00735     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00736     int       (*recipe_exec) (cpl_plugin *);
00737     cpl_frameset * copy;
00738     cpl_error_code error;
00739     size_t i;
00740 
00741 
00742     if (nstr < 1) return;
00743     if (filename == NULL) return;
00744 
00745     cpl_msg_info(cpl_func, "Testing recipe with %u %s as input ",
00746                  (unsigned)nstr, filename);
00747 
00748     for (i = 0; i < nstr; i++) {
00749         cpl_frame * f = cpl_frame_new();
00750 
00751         error = cpl_frame_set_filename(f, filename);
00752         cpl_test_error(error);
00753         cpl_test_zero(error);
00754 
00755         error = cpl_frame_set_tag(f, astr[i]);
00756         cpl_test_error(error);
00757         cpl_test_zero(error);
00758 
00759         error = cpl_frameset_insert(recipe->frames, f);
00760         cpl_test_error(error);
00761         cpl_test_zero(error);
00762     }
00763 
00764     copy = cpl_frameset_duplicate(recipe->frames);
00765 
00766     recipe_exec = cpl_plugin_get_exec(plugin);
00767     cpl_test( recipe_exec != NULL);
00768 
00769     /* Call recipe and expect non-zero return code */
00770     cpl_test( recipe_exec(plugin) );
00771     error = cpl_error_get_code();
00772     /* Expect also the CPL error code to be set */
00773     cpl_test_error( error );
00774     cpl_test( error );
00775 
00776     recipe_frameset_test_frameset_diff(recipe->frames, copy);
00777 
00778     recipe_frameset_empty(recipe->frames);
00779 
00780     cpl_frameset_delete(copy);
00781 
00782     return;
00783 }
00784 
00785 /*----------------------------------------------------------------------------*/
00792 /*----------------------------------------------------------------------------*/
00793 static void recipe_sof_test_image_empty(cpl_plugin * plugin, size_t nstr,
00794                                         const char *astr[])
00795 {
00796     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00797     int       (*recipe_exec) (cpl_plugin *);
00798     cpl_frameset * copy;
00799     cpl_error_code error;
00800     size_t i;
00801     cpl_frame * frame;
00802     cpl_image * iempty;
00803 
00804 
00805     if (nstr < 1) return;
00806 
00807     cpl_msg_info(cpl_func, "Testing recipe with %u empty images as input ",
00808                  (unsigned)nstr);
00809 
00810     iempty = cpl_image_new(13, 17, CPL_TYPE_FLOAT);
00811     cpl_test_nonnull(iempty);
00812 
00813     for (i = 0; i < nstr; i++) {
00814         cpl_frame * f = cpl_frame_new();
00815         char * rawname = cpl_sprintf("raw%05u.fits", (unsigned)(i+1));
00816 
00817         error = cpl_image_save(iempty, rawname,CPL_BPP_IEEE_FLOAT, NULL,
00818                                CPL_IO_DEFAULT);
00819         cpl_test_error(error);
00820         cpl_test_zero(error);
00821 
00822         error = cpl_frame_set_filename(f, rawname);
00823         cpl_test_error(error);
00824         cpl_test_zero(error);
00825 
00826         error = cpl_frame_set_tag(f, astr[i]);
00827         cpl_test_error(error);
00828         cpl_test_zero(error);
00829 
00830         error = cpl_frameset_insert(recipe->frames, f);
00831         cpl_test_error(error);
00832         cpl_test_zero(error);
00833 
00834         cpl_free(rawname);
00835     }
00836     cpl_image_delete(iempty);
00837 
00838     copy = cpl_frameset_duplicate(recipe->frames);
00839 
00840     recipe_exec = cpl_plugin_get_exec(plugin);
00841     cpl_test(recipe_exec != NULL);
00842 
00843     /* Call recipe and expect non-zero return code */
00844     cpl_test( recipe_exec(plugin) );
00845     error = cpl_error_get_code();
00846     /* Expect also the CPL error code to be set */
00847     cpl_test_error( error );
00848     cpl_test( error );
00849 
00850     for (frame = cpl_frameset_get_first(recipe->frames); frame != NULL;
00851          frame = cpl_frameset_get_next(recipe->frames))
00852         {
00853             cpl_test_zero( remove(cpl_frame_get_filename(frame)) );
00854         }
00855 
00856     recipe_frameset_test_frameset_diff(recipe->frames, copy);
00857 
00858     recipe_frameset_empty(recipe->frames);
00859 
00860     cpl_frameset_delete(copy);
00861 
00862     return;
00863 }
00864 
00865 
00866 /*----------------------------------------------------------------------------*/
00873 /*----------------------------------------------------------------------------*/
00874 static void recipe_sof_test_from_env(cpl_plugin * plugin)
00875 {
00876     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00877     const char * recipename = cpl_plugin_get_name(plugin);
00878     const char * var_name = "RECIPE_SOF_PATH";
00879     const char * sof_path = getenv(var_name);
00880     cpl_error_code error;
00881 
00882     char * sof_name;
00883 
00884     if (sof_path == NULL) {
00885         cpl_msg_warning(cpl_func, "Environment variable %s is unset: "
00886                         "No SOFs to check", var_name);
00887         return;
00888     }
00889 
00890     cpl_msg_debug(cpl_func, "Checking for SOFs in %s", sof_path);
00891 
00892     cpl_test_nonnull( recipename );
00893     if (recipename == NULL) return;
00894 
00895     sof_name = cpl_sprintf("%s/%s.sof", sof_path, recipename);
00896 
00897     cpl_msg_debug(cpl_func, "Checking for SOF %s", sof_name);
00898     
00899     recipe_frameset_load(recipe->frames, sof_name);
00900 
00901     if (!cpl_frameset_is_empty(recipe->frames)) {
00902 
00903         int          (*recipe_exec  ) (cpl_plugin *);
00904         cpl_frameset * copy = cpl_frameset_duplicate(recipe->frames);
00905 
00906         recipe_exec   = cpl_plugin_get_exec(plugin);
00907         cpl_test(recipe_exec != NULL);
00908 
00909         cpl_msg_info(cpl_func,"Checking handling of SOF: %s", sof_name);
00910 
00911         /* Call recipe and expect zero return code */
00912         cpl_test_zero( recipe_exec(plugin) );
00913         error = cpl_error_get_code();
00914         /* Expect also the CPL error code to be clear */
00915         cpl_test_error( error );
00916         cpl_test_zero( error );
00917 
00918         error = cpl_dfs_update_product_header(recipe->frames);
00919         cpl_test_error( error );
00920         cpl_test_zero( error );
00921 
00922         recipe_frameset_test_frameset_diff(recipe->frames, copy);
00923 
00924         recipe_frameset_empty(recipe->frames);
00925 
00926         cpl_frameset_delete(copy);
00927 
00928     }
00929 
00930     cpl_free(sof_name);
00931 
00932     return;
00933 }
00934 
00935 
00936 
00937 /*----------------------------------------------------------------------------*/
00944 /*----------------------------------------------------------------------------*/
00945 static void recipe_sof_test_local(cpl_plugin * plugin)
00946 {
00947     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00948     const char * recipename = cpl_plugin_get_name(plugin);
00949     cpl_error_code error;
00950     char * sof_name = cpl_sprintf("%s.sof", recipename);
00951 
00952     cpl_msg_debug(cpl_func, "Checking for SOF %s", sof_name);
00953     
00954     recipe_frameset_load(recipe->frames, sof_name);
00955 
00956     if (!cpl_frameset_is_empty(recipe->frames)) {
00957 
00958         int          (*recipe_exec  ) (cpl_plugin *);
00959         cpl_frameset * copy = cpl_frameset_duplicate(recipe->frames);
00960 
00961         recipe_exec   = cpl_plugin_get_exec(plugin);
00962         cpl_test(recipe_exec != NULL);
00963 
00964         cpl_msg_info(cpl_func,"Checking handling of SOF: %s", sof_name);
00965 
00966         /* Call recipe and expect zero return code */
00967         cpl_test_zero( recipe_exec(plugin) );
00968         error = cpl_error_get_code();
00969         /* Expect also the CPL error code to be clear */
00970         cpl_test_error( error );
00971         cpl_test_zero( error );
00972 
00973         error = cpl_dfs_update_product_header(recipe->frames);
00974         cpl_test_error( error );
00975         cpl_test_zero( error );
00976 
00977         recipe_frameset_test_frameset_diff(recipe->frames, copy);
00978 
00979         recipe_frameset_empty(recipe->frames);
00980 
00981         cpl_frameset_delete(copy);
00982     }
00983 
00984     cpl_free(sof_name);
00985 
00986     return;
00987 }
00988 
00989 
00990 
00991 
00992 /**********************************************************************/
01006 /**********************************************************************/
01007 
01008 static void recipe_frameset_load(cpl_frameset * set, const char *name)
01009 {
01010 
01011     FILE *fp;
01012     char line[LINE_LEN_MAX];
01013     char path[LINE_LEN_MAX], group[LINE_LEN_MAX], tag[LINE_LEN_MAX];
01014     int line_number;
01015 
01016     assert( set != NULL );
01017     assert( name != NULL );
01018 
01019     fp = fopen(name, "r");
01020     if (fp == NULL) {
01021         cpl_msg_debug(cpl_func, "Unable to open SOF file '%s'", name);
01022         return;
01023     }
01024 
01025     /* Loop over all the lines in the set-of-frames file */
01026     for (line_number = 0; fgets(line, LINE_LEN_MAX - 1, fp); line_number++) {
01027 
01028         cpl_frame_group grp;
01029         cpl_frame * frame;
01030         int n;
01031 
01032         if (line[0] == '#') continue;
01033 
01034         n = sscanf(line, "%s %s %s", path, tag, group);
01035 
01036         if (n < 1) {
01037             cpl_msg_warning(cpl_func, "Spurious line no. %d in %s: %s",
01038                             line_number, name, line);
01039             break;
01040         }
01041 
01042         /* Allocate a new frame */
01043         frame = cpl_frame_new();
01044 
01045         /* Set the filename component of the frame */
01046         cpl_frame_set_filename(frame, path);
01047 
01048         /* Set the tag component of the frame (or set a default) */
01049         cpl_frame_set_tag(frame, n == 1 ? "" : tag);
01050 
01051         cpl_frameset_insert(set, frame);
01052 
01053         /* Set the group component of the frame (or set a default) */
01054         if (n < 3) continue;
01055 
01056         if (!strcmp(group, CPL_FRAME_GROUP_RAW_ID))
01057             grp = CPL_FRAME_GROUP_RAW;
01058         else if (!strcmp(group, CPL_FRAME_GROUP_CALIB_ID))
01059             grp = CPL_FRAME_GROUP_CALIB;
01060         else if (!strcmp(group, CPL_FRAME_GROUP_PRODUCT_ID))
01061             grp = CPL_FRAME_GROUP_PRODUCT;
01062         else
01063             grp = CPL_FRAME_GROUP_NONE;
01064 
01065         cpl_frame_set_group(frame, grp);
01066     }
01067 
01068     fclose(fp);
01069 
01070     return;
01071 
01072 }
01073 
01074 
01075 /*----------------------------------------------------------------------------*/
01085 /*----------------------------------------------------------------------------*/
01086 static const cpl_parameter * irplib_parameterlist_get(const cpl_parameterlist
01087                                                       * self,
01088                                                       const char * instrume,
01089                                                       const char * recipe,
01090                                                       const char * parameter)
01091 {
01092 
01093     const cpl_parameter * par;
01094     char                * paramname;
01095 
01096 
01097     cpl_ensure(self      != NULL, CPL_ERROR_NULL_INPUT, NULL);
01098     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, NULL);
01099     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, NULL);
01100     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, NULL);
01101 
01102     paramname = cpl_sprintf("%s.%s.%s", instrume, recipe, parameter);
01103 
01104     cpl_ensure(paramname != NULL, cpl_error_get_code(), NULL);
01105     
01106     par = cpl_parameterlist_find_const(self, paramname);
01107 
01108     cpl_free(paramname);
01109 
01110     return par;
01111 
01112 }
01113 
01114 
01115 /*----------------------------------------------------------------------------*/
01141 /*----------------------------------------------------------------------------*/
01142 static void recipe_frameset_empty(cpl_frameset * self)
01143 {
01144     cpl_frame * f;
01145 
01146     if (self == NULL) {
01147         cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
01148         return;
01149     }
01150 
01151     for (f = cpl_frameset_get_first(self); f != NULL;
01152          f = cpl_frameset_get_first(self))
01153         {
01154             cpl_frameset_erase_frame(self, f);
01155         }
01156 }
01157 
01158 
01159 /*----------------------------------------------------------------------------*/
01179 /*----------------------------------------------------------------------------*/
01180 static void recipe_frameset_test_frame(const cpl_frame * self)
01181 {
01182 
01183     cpl_msg_info(cpl_func, "Validating new frame: %s",
01184                  cpl_frame_get_filename(self));
01185 
01186     cpl_test_nonnull(self);
01187 
01188     /* Frame must be tagged */
01189     cpl_test_nonnull(cpl_frame_get_tag(self));
01190 
01191     /* New frames must be products */
01192     cpl_test_eq(cpl_frame_get_group(self), CPL_FRAME_GROUP_PRODUCT);
01193 
01194     if (cpl_frame_get_type(self) != CPL_FRAME_TYPE_PAF) {
01195         /* All but PAF (?) must be FITS */
01196         cpl_test_fits(cpl_frame_get_filename(self));
01197     } else {
01198         /* Frame must at least have a filename */
01199         cpl_test_nonnull(cpl_frame_get_filename(self));
01200     }
01201 }
01202 
01203 /*----------------------------------------------------------------------------*/
01224 /*----------------------------------------------------------------------------*/
01225 static void recipe_frameset_test_frameset_diff(const cpl_frameset * self,
01226                                                const cpl_frameset * other)
01227 {
01228 
01229     const cpl_frame * frame = cpl_frameset_get_first_const(other);
01230 
01231     /* First verify that filenames in other are non-NULL */
01232     for (;frame != NULL; frame = cpl_frameset_get_next_const(other)) {
01233         const char * file = cpl_frame_get_filename(frame);
01234 
01235         if (file == NULL) {
01236             cpl_test_nonnull(cpl_frame_get_filename(frame));
01237             break;
01238         }
01239     }
01240     if (frame != NULL) return;
01241 
01242     frame = cpl_frameset_get_first_const(self);
01243 
01244     for (;frame != NULL; frame = cpl_frameset_get_next_const(self)) {
01245         const cpl_frame * cmp  = cpl_frameset_get_first_const(other);
01246         const char * file = cpl_frame_get_filename(frame);
01247 
01248         if (file == NULL) {
01249             cpl_test_nonnull(cpl_frame_get_filename(frame));
01250             continue;
01251         }
01252 
01253         for (;cmp != NULL; cmp = cpl_frameset_get_next_const(other)) {
01254             const char * cfile = cpl_frame_get_filename(cmp);
01255 
01256             if (!strcmp(file, cfile)) break;
01257 
01258         }
01259         if (cmp == NULL) {
01260             /* frame is new */
01261             recipe_frameset_test_frame(frame);
01262         }
01263     }
01264 }

Generated on Tue Jun 29 12:20:51 2010 for VISIR Pipeline Reference Manual by  doxygen 1.4.7