irplib_plugin.c

00001 /* $Id: irplib_plugin.c,v 1.39 2012/02/03 14:19:06 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: 2012/02/03 14:19:06 $
00024  * $Revision: 1.39 $
00025  * $Name: uves-5_0_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     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("raw%05u.fits", (unsigned)(i+1));
00769 
00770         error = cpl_image_save(iempty, rawname,CPL_BPP_IEEE_FLOAT, NULL,
00771                                CPL_IO_DEFAULT);
00772         cpl_test_eq_error(error, CPL_ERROR_NONE);
00773 
00774         error = cpl_frame_set_filename(f, rawname);
00775         cpl_test_eq_error(error, CPL_ERROR_NONE);
00776 
00777         error = cpl_frame_set_tag(f, astr[i]);
00778         cpl_test_eq_error(error, CPL_ERROR_NONE);
00779 
00780         error = cpl_frameset_insert(recipe->frames, f);
00781         cpl_test_eq_error(error, CPL_ERROR_NONE);
00782 
00783         cpl_free(rawname);
00784     }
00785     cpl_image_delete(iempty);
00786 
00787     copy = cpl_frameset_duplicate(recipe->frames);
00788 
00789     recipe_exec = cpl_plugin_get_exec(plugin);
00790     cpl_test(recipe_exec != NULL);
00791 
00792     if (recipe_exec != NULL) {
00793 
00794         /* Call recipe and expect consistency between return code and
00795            CPL error */
00796 
00797         retstat = recipe_exec(plugin);
00798         error = cpl_error_get_code();
00799         /* Expect also the CPL error code to be set */
00800         if (error == 0) {
00801             cpl_test_zero(retstat);
00802         } else {
00803             cpl_test(retstat);
00804         }
00805         cpl_test_error( error );
00806 
00807         recipe_frameset_test_frameset_diff(recipe->frames, copy);
00808 
00809         for (frame = cpl_frameset_get_first(recipe->frames); frame != NULL;
00810              frame = cpl_frameset_get_next(recipe->frames))
00811             {
00812                 cpl_test_zero( remove(cpl_frame_get_filename(frame)) );
00813             }
00814 
00815         recipe_frameset_empty(recipe->frames);
00816     }
00817 
00818     cpl_frameset_delete(copy);
00819 
00820     return;
00821 }
00822 
00823 
00824 /*----------------------------------------------------------------------------*/
00832 /*----------------------------------------------------------------------------*/
00833 cpl_boolean irplib_plugin_has_sof_from_env(const cpl_plugin * plugin,
00834                                            const char * envname)
00835 {
00836     const char      * recipename = cpl_plugin_get_name(plugin);
00837     const char      * sof_path   = envname ? getenv(envname) : NULL;
00838     cpl_frameset    * frames;
00839     char            * sof_name;
00840     const cpl_frame * ffirst;
00841 
00842     cpl_ensure(plugin  != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
00843     cpl_ensure(envname != NULL, CPL_ERROR_NULL_INPUT, CPL_FALSE);
00844     cpl_ensure(recipename != NULL, CPL_ERROR_DATA_NOT_FOUND, CPL_FALSE);
00845     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), CPL_FALSE);
00846 
00847     if (sof_path == NULL) return CPL_FALSE;
00848 
00849     sof_name = cpl_sprintf("%s/%s.sof", sof_path, recipename);
00850 
00851     frames = cpl_frameset_new();
00852     recipe_frameset_load(frames, sof_name);
00853 
00854     ffirst = cpl_frameset_get_first_const(frames);
00855 
00856     cpl_free(sof_name);
00857     cpl_frameset_delete(frames);
00858 
00859     cpl_ensure(!cpl_error_get_code(), cpl_error_get_code(), CPL_FALSE);
00860 
00861     return ffirst ? CPL_TRUE : CPL_FALSE;
00862 
00863 }
00864 
00865 /*----------------------------------------------------------------------------*/
00872 /*----------------------------------------------------------------------------*/
00873 static void recipe_sof_test_from_env(cpl_plugin * plugin)
00874 {
00875     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00876     const char * recipename = cpl_plugin_get_name(plugin);
00877     const char * var_name = "RECIPE_SOF_PATH";
00878     const char * sof_path = getenv(var_name);
00879     cpl_error_code error;
00880 
00881     char * sof_name;
00882 
00883     if (sof_path == NULL) {
00884         cpl_msg_warning(cpl_func, "Environment variable %s is unset: "
00885                         "No SOFs to check", var_name);
00886         return;
00887     }
00888 
00889     cpl_msg_debug(cpl_func, "Checking for SOFs in %s", sof_path);
00890 
00891     cpl_test_nonnull( recipename );
00892     if (recipename == NULL) return;
00893 
00894     sof_name = cpl_sprintf("%s/%s.sof", sof_path, recipename);
00895 
00896     cpl_msg_debug(cpl_func, "Checking for SOF %s", sof_name);
00897     
00898     recipe_frameset_load(recipe->frames, sof_name);
00899 
00900     if (!cpl_frameset_is_empty(recipe->frames)) {
00901 
00902         int          (*recipe_exec  ) (cpl_plugin *);
00903         cpl_frameset * copy = cpl_frameset_duplicate(recipe->frames);
00904 
00905         recipe_exec   = cpl_plugin_get_exec(plugin);
00906         cpl_test(recipe_exec != NULL);
00907 
00908         if (recipe_exec != NULL) {
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             /* Expect also the CPL error code to be clear */
00914             cpl_test_error(CPL_ERROR_NONE);
00915 
00916             error = cpl_dfs_update_product_header(recipe->frames);
00917             cpl_test_eq_error(error, CPL_ERROR_NONE);
00918 
00919             recipe_frameset_test_frameset_diff(recipe->frames, copy);
00920 
00921             recipe_frameset_empty(recipe->frames);
00922         }
00923 
00924         cpl_frameset_delete(copy);
00925 
00926     }
00927 
00928     cpl_free(sof_name);
00929 
00930     return;
00931 }
00932 
00933 
00934 
00935 /*----------------------------------------------------------------------------*/
00942 /*----------------------------------------------------------------------------*/
00943 static void recipe_sof_test_local(cpl_plugin * plugin)
00944 {
00945     cpl_recipe * recipe  = (cpl_recipe*)plugin;
00946     const char * recipename = cpl_plugin_get_name(plugin);
00947     cpl_error_code error;
00948     char * sof_name = cpl_sprintf("%s.sof", recipename);
00949 
00950     cpl_msg_debug(cpl_func, "Checking for SOF %s", sof_name);
00951     
00952     recipe_frameset_load(recipe->frames, sof_name);
00953 
00954     if (!cpl_frameset_is_empty(recipe->frames)) {
00955 
00956         int          (*recipe_exec  ) (cpl_plugin *);
00957         cpl_frameset * copy = cpl_frameset_duplicate(recipe->frames);
00958 
00959         recipe_exec   = cpl_plugin_get_exec(plugin);
00960         cpl_test(recipe_exec != NULL);
00961 
00962         if (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             /* Expect also the CPL error code to be clear */
00969             cpl_test_error(CPL_ERROR_NONE);
00970 
00971             error = cpl_dfs_update_product_header(recipe->frames);
00972             cpl_test_eq_error( error, CPL_ERROR_NONE );
00973 
00974             recipe_frameset_test_frameset_diff(recipe->frames, copy);
00975 
00976             recipe_frameset_empty(recipe->frames);
00977         }
00978 
00979         cpl_frameset_delete(copy);
00980     }
00981 
00982     cpl_free(sof_name);
00983 
00984     return;
00985 }
00986 
00987 
00988 
00989 
00990 /**********************************************************************/
01004 /**********************************************************************/
01005 
01006 static void recipe_frameset_load(cpl_frameset * set, const char *name)
01007 {
01008 
01009     FILE *fp;
01010     char line[LINE_LEN_MAX];
01011     char path[LINE_LEN_MAX], group[LINE_LEN_MAX], tag[LINE_LEN_MAX];
01012     int line_number;
01013 
01014     assert( set != NULL );
01015     assert( name != NULL );
01016 
01017     fp = fopen(name, "r");
01018     if (fp == NULL) {
01019         cpl_msg_debug(cpl_func, "Unable to open SOF file '%s'", name);
01020         return;
01021     }
01022 
01023     /* Loop over all the lines in the set-of-frames file */
01024     for (line_number = 0; fgets(line, LINE_LEN_MAX - 1, fp); line_number++) {
01025 
01026         cpl_frame_group grp;
01027         cpl_frame * frame;
01028         int n;
01029 
01030         if (line[0] == '#') continue;
01031 
01032         n = sscanf(line, "%s %s %s", path, tag, group);
01033 
01034         if (n < 1) {
01035             cpl_msg_warning(cpl_func, "Spurious line no. %d in %s: %s",
01036                             line_number, name, line);
01037             break;
01038         }
01039 
01040         /* Allocate a new frame */
01041         frame = cpl_frame_new();
01042 
01043         /* Set the filename component of the frame */
01044         cpl_frame_set_filename(frame, path);
01045 
01046         /* Set the tag component of the frame (or set a default) */
01047         cpl_frame_set_tag(frame, n == 1 ? "" : tag);
01048 
01049         cpl_frameset_insert(set, frame);
01050 
01051         /* Set the group component of the frame (or set a default) */
01052         if (n < 3) continue;
01053 
01054         if (!strcmp(group, CPL_FRAME_GROUP_RAW_ID))
01055             grp = CPL_FRAME_GROUP_RAW;
01056         else if (!strcmp(group, CPL_FRAME_GROUP_CALIB_ID))
01057             grp = CPL_FRAME_GROUP_CALIB;
01058         else if (!strcmp(group, CPL_FRAME_GROUP_PRODUCT_ID))
01059             grp = CPL_FRAME_GROUP_PRODUCT;
01060         else
01061             grp = CPL_FRAME_GROUP_NONE;
01062 
01063         cpl_frame_set_group(frame, grp);
01064     }
01065 
01066     fclose(fp);
01067 
01068     return;
01069 
01070 }
01071 
01072 
01073 /*----------------------------------------------------------------------------*/
01083 /*----------------------------------------------------------------------------*/
01084 static
01085 const cpl_parameter * irplib_parameterlist_get(const cpl_parameterlist * self,
01086                                                const char * instrume,
01087                                                const char * recipe,
01088                                                const char * parameter)
01089 {
01090 
01091     char                * paramname;
01092     const cpl_parameter * par;
01093 
01094 
01095     cpl_ensure(instrume  != NULL, CPL_ERROR_NULL_INPUT, NULL);
01096     cpl_ensure(recipe    != NULL, CPL_ERROR_NULL_INPUT, NULL);
01097     cpl_ensure(parameter != NULL, CPL_ERROR_NULL_INPUT, NULL);
01098 
01099     paramname = cpl_sprintf("%s.%s.%s", instrume, recipe, parameter);
01100 
01101     par = cpl_parameterlist_find_const(self, paramname);
01102 
01103     if (par == NULL) (void)cpl_error_set_message(cpl_func,
01104                                                  cpl_error_get_code()
01105                                                  ? cpl_error_get_code()
01106                                                  : CPL_ERROR_DATA_NOT_FOUND,
01107                                                  "%s", paramname);
01108 
01109     cpl_free(paramname);
01110     
01111     return par;
01112 
01113 }
01114 
01115 
01116 /*----------------------------------------------------------------------------*/
01142 /*----------------------------------------------------------------------------*/
01143 static void recipe_frameset_empty(cpl_frameset * self)
01144 {
01145     cpl_frame * f;
01146 
01147     if (self == NULL) {
01148         cpl_error_set(cpl_func, CPL_ERROR_NULL_INPUT);
01149         return;
01150     }
01151 
01152     for (f = cpl_frameset_get_first(self); f != NULL;
01153          f = cpl_frameset_get_first(self))
01154         {
01155             cpl_frameset_erase_frame(self, f);
01156         }
01157 }
01158 
01159 
01160 /*----------------------------------------------------------------------------*/
01180 /*----------------------------------------------------------------------------*/
01181 static void recipe_frameset_test_frame(const cpl_frame * self)
01182 {
01183 
01184     cpl_msg_info(cpl_func, "Validating new frame: %s",
01185                  cpl_frame_get_filename(self));
01186 
01187     cpl_test_nonnull(self);
01188 
01189     /* Frame must be tagged */
01190     cpl_test_nonnull(cpl_frame_get_tag(self));
01191 
01192     /* New frames must be products */
01193     cpl_test_eq(cpl_frame_get_group(self), CPL_FRAME_GROUP_PRODUCT);
01194 
01195     if (cpl_frame_get_type(self) != CPL_FRAME_TYPE_PAF) {
01196         /* All but PAF (?) must be FITS */
01197         cpl_test_fits(cpl_frame_get_filename(self));
01198     } else {
01199         /* Frame must at least have a filename */
01200         cpl_test_nonnull(cpl_frame_get_filename(self));
01201     }
01202 }
01203 
01204 /*----------------------------------------------------------------------------*/
01225 /*----------------------------------------------------------------------------*/
01226 static void recipe_frameset_test_frameset_diff(const cpl_frameset * self,
01227                                                const cpl_frameset * other)
01228 {
01229 
01230     const cpl_frame * frame = cpl_frameset_get_first_const(other);
01231 
01232     /* First verify that filenames in other are non-NULL */
01233     for (;frame != NULL; frame = cpl_frameset_get_next_const(other)) {
01234         const char * file = cpl_frame_get_filename(frame);
01235 
01236         if (file == NULL) {
01237             cpl_test_nonnull(cpl_frame_get_filename(frame));
01238             break;
01239         }
01240     }
01241     if (frame != NULL) return;
01242 
01243     frame = cpl_frameset_get_first_const(self);
01244 
01245     for (;frame != NULL; frame = cpl_frameset_get_next_const(self)) {
01246         const cpl_frame * cmp  = cpl_frameset_get_first_const(other);
01247         const char * file = cpl_frame_get_filename(frame);
01248 
01249         if (file == NULL) {
01250             cpl_test_nonnull(cpl_frame_get_filename(frame));
01251             continue;
01252         }
01253 
01254         for (;cmp != NULL; cmp = cpl_frameset_get_next_const(other)) {
01255             const char * cfile = cpl_frame_get_filename(cmp);
01256 
01257             if (!strcmp(file, cfile)) break;
01258 
01259         }
01260         if (cmp == NULL) {
01261             /* frame is new */
01262 
01263             cpl_test_eq(cpl_frame_get_group(frame), CPL_FRAME_GROUP_PRODUCT);
01264             recipe_frameset_test_frame(frame);
01265         }
01266     }
01267 }

Generated on 9 Mar 2012 for UVES Pipeline Reference Manual by  doxygen 1.6.1