irplib_plugin.c

00001 /* $Id: irplib_plugin.c,v 1.40 2013-08-22 17:44:56 cgarcia 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: cgarcia $
00023  * $Date: 2013-08-22 17:44:56 $
00024  * $Revision: 1.40 $
00025  * $Name: not supported by cvs2svn $
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     if (recipe_create != NULL && recipe_exec != NULL && recipe_deinit != NULL) {
00514 
00515         cpl_test_zero(recipe_create(plugin));
00516 
00517         recipe = (cpl_recipe *) plugin;
00518 
00519         cpl_test_nonnull( recipe->parameters );
00520 
00521         recipe_parameterlist_set(recipe->parameters);
00522 
00523         cpl_parameterlist_dump(recipe->parameters, stream);
00524 
00525         recipe->frames = cpl_frameset_new();
00526 
00527         if (irplib_plugin_has_sof_from_env(plugin, "RECIPE_SOF_PATH")) {
00528 
00529             recipe_sof_test_from_env(plugin);
00530 
00531         } else {
00532 
00533             const cpl_msg_severity msg_level = cpl_msg_get_level();
00534 
00535             /* Unless the CPL_MSG_LEVEL has been explicitly set, turn off
00536                terminal messaging completely while inside this function */
00537             if (getenv("CPL_MSG_LEVEL") == NULL) cpl_msg_set_level(CPL_MSG_OFF);
00538 
00539             cpl_msg_info(cpl_func,"Checking handling of pre-existing CPL error "
00540                          "state - may produce warning(s)/error(s):");
00541             cpl_error_set(cpl_func, CPL_ERROR_EOL);
00542             /* Call recipe and expect non-zero return code */
00543             cpl_test( recipe_exec(plugin) );
00544             /* Expect also the CPL error code to be preserved */
00545             cpl_test_error( CPL_ERROR_EOL );
00546 
00547             cpl_msg_info(cpl_func,"Checking handling of empty frameset - "
00548                          "may produce warning(s)/error(s):");
00549             /* Call recipe and expect non-zero return code */
00550             cpl_test( recipe_exec(plugin) );
00551             error = cpl_error_get_code();
00552             /* Expect also the CPL error code to be set */
00553             cpl_test_error( error );
00554             cpl_test( error );
00555 
00556             cpl_msg_info(cpl_func,"Checking handling of dummy frameset - "
00557                          "may produce warning(s)/error(s):");
00558             do {
00559                 cpl_frame * f = cpl_frame_new();
00560                 error = cpl_frame_set_filename(f, "/dev/null");
00561                 cpl_test_eq_error(error, CPL_ERROR_NONE);
00562                 error = cpl_frame_set_tag(f, "RECIPE_DUMMY_TAG");
00563                 cpl_test_eq_error(error, CPL_ERROR_NONE);
00564                 error = cpl_frameset_insert(recipe->frames, f);
00565                 cpl_test_eq_error(error, CPL_ERROR_NONE);
00566 
00567                 /* Call recipe and expect non-zero return code */
00568                 cpl_test( recipe_exec(plugin) );
00569                 error = cpl_error_get_code();
00570                 /* Expect also the CPL error code to be set */
00571                 cpl_test_error( error );
00572                 cpl_test( error );
00573 
00574                 error = cpl_frameset_erase_frame(recipe->frames, f);
00575                 cpl_test_eq_error(error, CPL_ERROR_NONE);
00576 
00577             } while (0);
00578 
00579 #ifdef IRPLIB_TEST_RANDOM_SOF
00580             recipe_sof_test_devfile(plugin, DEV_RANDOM, nstr, astr);
00581 #endif
00582 
00583             recipe_sof_test_devfile(plugin, "/dev/null", nstr, astr);
00584 
00585             recipe_sof_test_devfile(plugin, ".", nstr, astr);
00586 
00587             recipe_sof_test_image_empty(plugin, nstr, astr);
00588 
00589             recipe_sof_test_local(plugin);
00590 
00591             cpl_msg_set_level(msg_level);
00592 
00593         }
00594 
00595         cpl_frameset_delete(recipe->frames);
00596 
00597         error = recipe_deinit(plugin);
00598         cpl_test_eq_error(error, CPL_ERROR_NONE);
00599     }
00600 
00601     if (stream != stdout) fclose(stream);
00602 
00603     return 0;
00604 }
00605 
00608 /*----------------------------------------------------------------------------*/
00618 /*----------------------------------------------------------------------------*/
00619 static void recipe_parameterlist_set(cpl_parameterlist * self)
00620 {
00621 
00622     cpl_parameter * p = cpl_parameterlist_get_first(self);
00623 
00624     for (; p != NULL; p = cpl_parameterlist_get_next(self)) {
00625 
00626         const char * envvar;
00627         const char * svalue;
00628 
00629         /* FIXME: Needed ? */
00630         if (cpl_parameter_get_default_flag(p)) continue;
00631 
00632         cpl_msg_debug(cpl_func, __FILE__ " line %u: OK", __LINE__);
00633 
00634         envvar = cpl_parameter_get_alias(p, CPL_PARAMETER_MODE_ENV);
00635         svalue = envvar ? getenv(envvar) : NULL;
00636 
00637         switch (cpl_parameter_get_type(p)) {
00638         case CPL_TYPE_BOOL: {
00639             const int value
00640                 = svalue ? atoi(svalue) : cpl_parameter_get_default_bool(p);
00641             cpl_parameter_set_bool(p, value);
00642             break;
00643         }
00644         case CPL_TYPE_INT: {
00645             const int value
00646                 = svalue ? atoi(svalue) : cpl_parameter_get_default_int(p);
00647             cpl_parameter_set_int(p, value);
00648             break;
00649         }
00650         case CPL_TYPE_DOUBLE: {
00651             const double value
00652                 = svalue ? atof(svalue) : cpl_parameter_get_default_double(p);
00653             cpl_parameter_set_double(p, value);
00654             break;
00655         }
00656         case CPL_TYPE_STRING:
00657             {
00658                 const char * s_default = cpl_parameter_get_default_string(p);
00659                 /* Replace NULL with "" */
00660                 const char * value
00661                     = svalue ? svalue : (s_default ? s_default : "");
00662                 cpl_parameter_set_string(p, value);
00663                 break;
00664             }
00665 
00666         default:
00667             assert( 0 ); /* It is a testing error to reach this point */
00668         }
00669     }
00670 }
00671 
00672 
00673 /*----------------------------------------------------------------------------*/
00683 /*----------------------------------------------------------------------------*/
00684 static void recipe_sof_test_devfile(cpl_plugin * plugin, const char * filename,
00685                                     size_t nstr, const char *astr[])
00686 {
00687     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00688     int       (*recipe_exec) (cpl_plugin *);
00689     cpl_frameset * copy;
00690     cpl_error_code error;
00691     size_t i;
00692 
00693 
00694     if (nstr < 1) return;
00695     if (filename == NULL) return;
00696 
00697     cpl_msg_info(cpl_func, "Testing recipe with %u %s as input ",
00698                  (unsigned)nstr, filename);
00699 
00700     for (i = 0; i < nstr; i++) {
00701         cpl_frame * f = cpl_frame_new();
00702 
00703         error = cpl_frame_set_filename(f, filename);
00704         cpl_test_eq_error(error, CPL_ERROR_NONE);
00705 
00706         error = cpl_frame_set_tag(f, astr[i]);
00707         cpl_test_eq_error(error, CPL_ERROR_NONE);
00708 
00709         error = cpl_frameset_insert(recipe->frames, f);
00710         cpl_test_eq_error(error, CPL_ERROR_NONE);
00711     }
00712 
00713     copy = cpl_frameset_duplicate(recipe->frames);
00714 
00715     recipe_exec = cpl_plugin_get_exec(plugin);
00716     cpl_test( recipe_exec != NULL);
00717 
00718     if (recipe_exec != NULL) {
00719 
00720         /* Call recipe and expect non-zero return code */
00721         cpl_test( recipe_exec(plugin) );
00722         error = cpl_error_get_code();
00723         /* Expect also the CPL error code to be set */
00724         cpl_test_error( error );
00725         cpl_test( error );
00726 
00727         recipe_frameset_test_frameset_diff(recipe->frames, copy);
00728 
00729         recipe_frameset_empty(recipe->frames);
00730     }
00731 
00732     cpl_frameset_delete(copy);
00733 
00734     return;
00735 }
00736 
00737 /*----------------------------------------------------------------------------*/
00744 /*----------------------------------------------------------------------------*/
00745 static void recipe_sof_test_image_empty(cpl_plugin * plugin, size_t nstr,
00746                                         const char *astr[])
00747 {
00748     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00749     int       (*recipe_exec) (cpl_plugin *);
00750     cpl_frameset * copy;
00751     cpl_error_code error;
00752     size_t i;
00753     cpl_frame * frame;
00754     cpl_image * iempty;
00755     int retstat;
00756 
00757 
00758     if (nstr < 1) return;
00759 
00760     cpl_msg_info(cpl_func, "Testing recipe with %u empty images as input ",
00761                  (unsigned)nstr);
00762 
00763     iempty = cpl_image_new(13, 17, CPL_TYPE_FLOAT);
00764     cpl_test_nonnull(iempty);
00765 
00766     for (i = 0; i < nstr; i++) {
00767         cpl_frame * f = cpl_frame_new();
00768         char * rawname = cpl_sprintf("%s-raw%05u.fits",
00769                                      cpl_plugin_get_name(plugin),
00770                                      (unsigned)(i+1));
00771 
00772         error = cpl_image_save(iempty, rawname,CPL_BPP_IEEE_FLOAT, NULL,
00773                                CPL_IO_DEFAULT);
00774         cpl_test_eq_error(error, CPL_ERROR_NONE);
00775 
00776         error = cpl_frame_set_filename(f, rawname);
00777         cpl_test_eq_error(error, CPL_ERROR_NONE);
00778 
00779         error = cpl_frame_set_tag(f, astr[i]);
00780         cpl_test_eq_error(error, CPL_ERROR_NONE);
00781 
00782         error = cpl_frameset_insert(recipe->frames, f);
00783         cpl_test_eq_error(error, CPL_ERROR_NONE);
00784 
00785         cpl_free(rawname);
00786     }
00787     cpl_image_delete(iempty);
00788 
00789     copy = cpl_frameset_duplicate(recipe->frames);
00790 
00791     recipe_exec = cpl_plugin_get_exec(plugin);
00792     cpl_test(recipe_exec != NULL);
00793 
00794     if (recipe_exec != NULL) {
00795 
00796         /* Call recipe and expect consistency between return code and
00797            CPL error */
00798 
00799         retstat = recipe_exec(plugin);
00800         error = cpl_error_get_code();
00801         /* Expect also the CPL error code to be set */
00802         if (error == 0) {
00803             cpl_test_zero(retstat);
00804         } else {
00805             cpl_test(retstat);
00806         }
00807         cpl_test_error( error );
00808 
00809         recipe_frameset_test_frameset_diff(recipe->frames, copy);
00810 
00811         for (frame = cpl_frameset_get_first(recipe->frames); frame != NULL;
00812              frame = cpl_frameset_get_next(recipe->frames))
00813             {
00814                 cpl_test_zero( remove(cpl_frame_get_filename(frame)) );
00815             }
00816 
00817         recipe_frameset_empty(recipe->frames);
00818     }
00819 
00820     cpl_frameset_delete(copy);
00821 
00822     return;
00823 }
00824 
00825 
00826 /*----------------------------------------------------------------------------*/
00834 /*----------------------------------------------------------------------------*/
00835 cpl_boolean irplib_plugin_has_sof_from_env(const cpl_plugin * plugin,
00836                                            const char * envname)
00837 {
00838     const char      * recipename = cpl_plugin_get_name(plugin);
00839     const char      * sof_path   = envname ? getenv(envname) : NULL;
00840     cpl_frameset    * frames;
00841     char            * sof_name;
00842     const cpl_frame * ffirst;
00843 
00844     cpl_ensure(plugin  != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
00845     cpl_ensure(envname != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
00846     cpl_ensure(recipename != NULL, CPL_ERROR_DATA_NOT_FOUND, CPL_FALSE);
00847     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), CPL_FALSE);
00848 
00849     if (sof_path == NULL) return CPL_FALSE;
00850 
00851     sof_name = cpl_sprintf("%s/%s.sof", sof_path, recipename);
00852 
00853     frames = cpl_frameset_new();
00854     recipe_frameset_load(frames, sof_name);
00855 
00856     ffirst = cpl_frameset_get_position_const(frames, 0);
00857 
00858     cpl_free(sof_name);
00859     cpl_frameset_delete(frames);
00860 
00861     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), CPL_FALSE);
00862 
00863     return ffirst ? CPL_TRUE : CPL_FALSE;
00864 
00865 }
00866 
00867 /*----------------------------------------------------------------------------*/
00874 /*----------------------------------------------------------------------------*/
00875 static void recipe_sof_test_from_env(cpl_plugin * plugin)
00876 {
00877     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00878     const char * recipename = cpl_plugin_get_name(plugin);
00879     const char * var_name = "RECIPE_SOF_PATH";
00880     const char * sof_path = getenv(var_name);
00881     cpl_error_code error;
00882 
00883     char * sof_name;
00884 
00885     if (sof_path == NULL) {
00886         cpl_msg_warning(cpl_func, "Environment variable %s is unset: "
00887                         "No SOFs to check", var_name);
00888         return;
00889     }
00890 
00891     cpl_msg_debug(cpl_func, "Checking for SOFs in %s", sof_path);
00892 
00893     cpl_test_nonnull( recipename );
00894     if (recipename == NULL) return;
00895 
00896     sof_name = cpl_sprintf("%s/%s.sof", sof_path, recipename);
00897 
00898     cpl_msg_debug(cpl_func, "Checking for SOF %s", sof_name);
00899     
00900     recipe_frameset_load(recipe->frames, sof_name);
00901 
00902     if (!cpl_frameset_is_empty(recipe->frames)) {
00903 
00904         int          (*recipe_exec  ) (cpl_plugin *);
00905         cpl_frameset * copy = cpl_frameset_duplicate(recipe->frames);
00906 
00907         recipe_exec   = cpl_plugin_get_exec(plugin);
00908         cpl_test(recipe_exec != NULL);
00909 
00910         if (recipe_exec != NULL) {
00911             cpl_msg_info(cpl_func,"Checking handling of SOF: %s", sof_name);
00912 
00913             /* Call recipe and expect zero return code */
00914             cpl_test_zero( recipe_exec(plugin) );
00915             /* Expect also the CPL error code to be clear */
00916             cpl_test_error(CPL_ERROR_NONE);
00917 
00918             error = cpl_dfs_update_product_header(recipe->frames);
00919             cpl_test_eq_error(error, CPL_ERROR_NONE);
00920 
00921             recipe_frameset_test_frameset_diff(recipe->frames, copy);
00922 
00923             recipe_frameset_empty(recipe->frames);
00924         }
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         if (recipe_exec != NULL) {
00965 
00966             cpl_msg_info(cpl_func,"Checking handling of SOF: %s", sof_name);
00967 
00968             /* Call recipe and expect zero return code */
00969             cpl_test_zero( recipe_exec(plugin) );
00970             /* Expect also the CPL error code to be clear */
00971             cpl_test_error(CPL_ERROR_NONE);
00972 
00973             error = cpl_dfs_update_product_header(recipe->frames);
00974             cpl_test_eq_error( error, CPL_ERROR_NONE );
00975 
00976             recipe_frameset_test_frameset_diff(recipe->frames, copy);
00977 
00978             recipe_frameset_empty(recipe->frames);
00979         }
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         char scan_fmt[50];
01029         cpl_frame_group grp;
01030         cpl_frame * frame;
01031         int n;
01032 
01033         if (line[0] == '#') continue;
01034 
01035         snprintf(scan_fmt, 49, "%%%ds %%%ds %%%ds", LINE_LEN_MAX - 1,
01036                  LINE_LEN_MAX - 1, LINE_LEN_MAX - 1); 
01037         n = sscanf(line, scan_fmt, path, tag, group);
01038 
01039         if (n < 1) {
01040             cpl_msg_warning(cpl_func, "Spurious line no. %d in %s: %s",
01041                             line_number, name, line);
01042             break;
01043         }
01044 
01045         /* Allocate a new frame */
01046         frame = cpl_frame_new();
01047 
01048         /* Set the filename component of the frame */
01049         cpl_frame_set_filename(frame, path);
01050 
01051         /* Set the tag component of the frame (or set a default) */
01052         cpl_frame_set_tag(frame, n == 1 ? "" : tag);
01053 
01054         cpl_frameset_insert(set, frame);
01055 
01056         /* Set the group component of the frame (or set a default) */
01057         if (n < 3) continue;
01058 
01059         if (!strcmp(group, CPL_FRAME_GROUP_RAW_ID))
01060             grp = CPL_FRAME_GROUP_RAW;
01061         else if (!strcmp(group, CPL_FRAME_GROUP_CALIB_ID))
01062             grp = CPL_FRAME_GROUP_CALIB;
01063         else if (!strcmp(group, CPL_FRAME_GROUP_PRODUCT_ID))
01064             grp = CPL_FRAME_GROUP_PRODUCT;
01065         else
01066             grp = CPL_FRAME_GROUP_NONE;
01067 
01068         cpl_frame_set_group(frame, grp);
01069     }
01070 
01071     fclose(fp);
01072 
01073     return;
01074 
01075 }
01076 
01077 
01078 /*----------------------------------------------------------------------------*/
01088 /*----------------------------------------------------------------------------*/
01089 static
01090 const cpl_parameter * irplib_parameterlist_get(const cpl_parameterlist * self,
01091                                                const char * instrume,
01092                                                const char * recipe,
01093                                                const char * parameter)
01094 {
01095 
01096     char                * paramname;
01097     const cpl_parameter * par;
01098 
01099 
01100     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, NULL);
01101     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, NULL);
01102     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, NULL);
01103 
01104     paramname = cpl_sprintf("%s.%s.%s", instrume, recipe, parameter);
01105 
01106     par = cpl_parameterlist_find_const(self, paramname);
01107 
01108     if (par == NULL) (void)cpl_error_set_message(cpl_func,
01109                                                  cpl_error_get_code()
01110                                                  ? cpl_error_get_code()
01111                                                  : CPL_ERROR_DATA_NOT_FOUND,
01112                                                  "%s", paramname);
01113 
01114     cpl_free(paramname);
01115     
01116     return par;
01117 
01118 }
01119 
01120 
01121 /*----------------------------------------------------------------------------*/
01147 /*----------------------------------------------------------------------------*/
01148 static void recipe_frameset_empty(cpl_frameset * self)
01149 {
01150     cpl_frame * f;
01151 
01152     if (self == NULL) {
01153         cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
01154         return;
01155     }
01156 
01157     for (f = cpl_frameset_get_first(self); f != NULL;
01158          f = cpl_frameset_get_first(self))
01159         {
01160             cpl_frameset_erase_frame(self, f);
01161         }
01162 }
01163 
01164 
01165 /*----------------------------------------------------------------------------*/
01185 /*----------------------------------------------------------------------------*/
01186 static void recipe_frameset_test_frame(const cpl_frame * self)
01187 {
01188 
01189     cpl_msg_info(cpl_func, "Validating new frame: %s",
01190                  cpl_frame_get_filename(self));
01191 
01192     cpl_test_nonnull(self);
01193 
01194     /* Frame must be tagged */
01195     cpl_test_nonnull(cpl_frame_get_tag(self));
01196 
01197     /* New frames must be products */
01198     cpl_test_eq(cpl_frame_get_group(self), CPL_FRAME_GROUP_PRODUCT);
01199 
01200     if (cpl_frame_get_type(self) != CPL_FRAME_TYPE_PAF) {
01201         /* All but PAF (?) must be FITS */
01202         cpl_test_fits(cpl_frame_get_filename(self));
01203     } else {
01204         /* Frame must at least have a filename */
01205         cpl_test_nonnull(cpl_frame_get_filename(self));
01206     }
01207 }
01208 
01209 /*----------------------------------------------------------------------------*/
01230 /*----------------------------------------------------------------------------*/
01231 static void recipe_frameset_test_frameset_diff(const cpl_frameset * self,
01232                                                const cpl_frameset * other)
01233 {
01234 
01235     const cpl_frame * frame = cpl_frameset_get_first_const(other);
01236 
01237     /* First verify that filenames in other are non-NULL */
01238     for (;frame != NULL; frame = cpl_frameset_get_next_const(other)) {
01239         const char * file = cpl_frame_get_filename(frame);
01240 
01241         if (file == NULL) {
01242             cpl_test_nonnull(cpl_frame_get_filename(frame));
01243             break;
01244         }
01245     }
01246     if (frame != NULL) return;
01247 
01248     frame = cpl_frameset_get_first_const(self);
01249 
01250     for (;frame != NULL; frame = cpl_frameset_get_next_const(self)) {
01251         const cpl_frame * cmp  = cpl_frameset_get_first_const(other);
01252         const char * file = cpl_frame_get_filename(frame);
01253 
01254         if (file == NULL) {
01255             cpl_test_nonnull(cpl_frame_get_filename(frame));
01256             continue;
01257         }
01258 
01259         for (;cmp != NULL; cmp = cpl_frameset_get_next_const(other)) {
01260             const char * cfile = cpl_frame_get_filename(cmp);
01261 
01262             if (!strcmp(file, cfile)) break;
01263 
01264         }
01265         if (cmp == NULL) {
01266             /* frame is new */
01267 
01268             cpl_test_eq(cpl_frame_get_group(frame), CPL_FRAME_GROUP_PRODUCT);
01269             recipe_frameset_test_frame(frame);
01270         }
01271     }
01272 }
Generated on Mon Feb 17 15:01:44 2014 for NACO Pipeline Reference Manual by  doxygen 1.6.3