UVES Pipeline Reference Manual  5.4.6
uves_plugin.h
1 /* $Id: uves_plugin.h,v 1.1 2008-03-28 08:56:45 amodigli Exp $
2  *
3  * This file is part of the UVES package
4  * Copyright (C) 2002,2003 European Southern Observatory
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: amodigli $
23  * $Date: 2008-03-28 08:56:45 $
24  * $Revision: 1.1 $
25  * $Name: not supported by cvs2svn $
26  */
27 
28 #ifndef UVES_PLUGIN_H
29 #define UVES_PLUGIN_H
30 
31 /*-----------------------------------------------------------------------------
32  Includes
33  -----------------------------------------------------------------------------*/
34 
35 #include <irplib_utils.h> /* irplib_reset() */
36 
37 #include <cpl.h>
38 
39 /*-----------------------------------------------------------------------------
40  Define
41  -----------------------------------------------------------------------------*/
42 
43 /* Needed to concatenate two macro arguments */
44 #define UVES_CONCAT(a,b) a ## _ ## b
45 #define UVES_CONCAT2X(a,b) UVES_CONCAT(a,b)
46 
47 /* A macro to generate the pipeline copyright and license */
48 #ifdef cpl_get_license
49 #define uves_irplib_get_license cpl_get_license
50 #else
51 /* FIXME: Drop once CPL 4.0 is no longer supported */
52 #define uves_irplib_get_license(PACKAGE_NAME, YEAR) \
53  "This file is part of the " PACKAGE_NAME "\n" \
54  "Copyright (C) " YEAR " European Southern Observatory\n" \
55  "\n" \
56  "This program is free software; you can redistribute it and/or modify\n" \
57  "it under the terms of the GNU General Public License as published by\n" \
58  "the Free Software Foundation; either version 2 of the License, or\n" \
59  "(at your option) any later version.\n" \
60  "\n" \
61  "This program is distributed in the hope that it will be useful,\n" \
62  "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
63  "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" \
64  "GNU General Public License for more details.\n" \
65  "\n" \
66  "You should have received a copy of the GNU General Public License\n" \
67  "along with this program; if not, write to the Free Software\n" \
68  "Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, \n" \
69  "MA 02111-1307 USA"
70 #endif
71 
72 #ifdef CPL_RECIPE_DEFINE
73 #define UVES_IRPLIB_RECIPE_DEFINE CPL_RECIPE_DEFINE
74 #else
75 /* FIXME: Drop once CPL 4.0 is no longer supported */
76 /*----------------------------------------------------------------------------*/
128 /*----------------------------------------------------------------------------*/
129 
130 #define UVES_IRPLIB_RECIPE_DEFINE(RECIPE_NAME, RECIPE_VERSION, RECIPE_FILL_PARAMS, \
131  RECIPE_AUTHOR, RECIPE_AUTHOR_EMAIL, RECIPE_YEAR, \
132  RECIPE_SYNOPSIS, RECIPE_DESCRIPTION) \
133  \
134  /* The prototypes of the recipe create, exec and destroy functions */ \
135 static int UVES_CONCAT2X(RECIPE_NAME,create) (cpl_plugin * plugin); \
136 static int UVES_CONCAT2X(RECIPE_NAME,exec) (cpl_plugin * plugin); \
137 static int UVES_CONCAT2X(RECIPE_NAME,destroy)(cpl_plugin * plugin); \
138  \
139  /* The prototype of the function called by the recipe exec function */ \
140 static int RECIPE_NAME(cpl_frameset *, const cpl_parameterlist *); \
141  \
142 int cpl_plugin_get_info(cpl_pluginlist * list) \
143 { \
144  cpl_recipe * recipe; \
145  cpl_plugin * plugin; \
146  /* Verify that the compile-time and run-time versions of CPL match */ \
147  /* - this will work for run-time versions going back to CPL 3.0 */ \
148  /* - earlier versions will cause an exit with an unresolved symbol */ \
149  const unsigned vruntime = CPL_VERSION(cpl_version_get_major(), \
150  cpl_version_get_minor(), \
151  cpl_version_get_micro()); \
152  /* The version number of the first major version */ \
153  const unsigned vmruntime = CPL_VERSION(cpl_version_get_major(), 0, 0); \
154  \
155  \
156  if (vruntime < CPL_VERSION_CODE) { \
157  cpl_msg_warning(cpl_func, "Run-time version %s of CPL is lower than " \
158  "the compile-time version", cpl_version_get_version());\
159  } else if (vmruntime > CPL_VERSION_CODE) { \
160  cpl_msg_warning(cpl_func, "Run-time version %s of CPL has a newer " \
161  "major version than the compile-time version", \
162  cpl_version_get_version()); \
163  } else if (vruntime > CPL_VERSION_CODE) { \
164  cpl_msg_info(cpl_func, "Run-time version %s of CPL is higher than " \
165  "the compile-time version", cpl_version_get_version()); \
166  } \
167  \
168  recipe = cpl_calloc(1, sizeof(*recipe)); \
169  if (recipe == NULL) { \
170  cpl_msg_error(cpl_func, "Recipe allocation failed"); \
171  (void)cpl_error_set(cpl_func, CPL_ERROR_ILLEGAL_OUTPUT); \
172  return 1; \
173  } \
174  \
175  plugin = &recipe->interface; \
176  \
177  if (cpl_plugin_init(plugin, \
178  CPL_PLUGIN_API, \
179  RECIPE_VERSION, \
180  CPL_PLUGIN_TYPE_RECIPE, \
181  #RECIPE_NAME, \
182  RECIPE_SYNOPSIS, \
183  RECIPE_DESCRIPTION, \
184  RECIPE_AUTHOR, \
185  RECIPE_AUTHOR_EMAIL, \
186  uves_irplib_get_license(PACKAGE_NAME, RECIPE_YEAR), \
187  UVES_CONCAT2X(RECIPE_NAME,create), \
188  UVES_CONCAT2X(RECIPE_NAME,exec), \
189  UVES_CONCAT2X(RECIPE_NAME,destroy))) { \
190  cpl_msg_error(cpl_func, "Plugin initialization failed"); \
191  (void)cpl_error_set_where(cpl_func); \
192  return 1; \
193  } \
194  \
195  if (cpl_pluginlist_append(list, plugin)) { \
196  cpl_msg_error(cpl_func, "Error adding plugin to list"); \
197  (void)cpl_error_set_where(cpl_func); \
198  return 1; \
199  } \
200  \
201  return 0; \
202 } \
203  \
204  /* The definition of the recipe create function */ \
205 static int UVES_CONCAT2X(RECIPE_NAME,create)(cpl_plugin * plugin) \
206 { \
207  cpl_recipe * recipe; \
208  \
209  /* Do not create the recipe if an error code is already set */ \
210  if (cpl_error_get_code() != CPL_ERROR_NONE) { \
211  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s", \
212  cpl_func, __LINE__, cpl_error_get_where()); \
213  return (int)cpl_error_get_code(); \
214  } \
215  \
216  if (plugin == NULL) { \
217  cpl_msg_error(cpl_func, "Null plugin"); \
218  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); \
219  } \
220  \
221  /* Verify plugin type */ \
222  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) { \
223  cpl_msg_error(cpl_func, "Plugin is not a recipe"); \
224  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH); \
225  } \
226  \
227  /* Get the recipe */ \
228  recipe = (cpl_recipe *)plugin; \
229  \
230  /* Create the parameters list in the cpl_recipe object */ \
231  recipe->parameters = cpl_parameterlist_new(); \
232  if (recipe->parameters == NULL) { \
233  cpl_msg_error(cpl_func, "Parameter list allocation failed"); \
234  cpl_ensure_code(0, (int)CPL_ERROR_ILLEGAL_OUTPUT); \
235  } \
236  \
237  /* Fill the parameters list */ \
238  return(RECIPE_FILL_PARAMS); \
239 } \
240  \
241  /* The definition of the recipe exec function */ \
242 static int UVES_CONCAT2X(RECIPE_NAME,exec)(cpl_plugin * plugin) \
243 { \
244  cpl_recipe * recipe; \
245  int recipe_status; \
246  cpl_errorstate initial_errorstate = cpl_errorstate_get(); \
247  \
248  /* Return immediately if an error code is already set */ \
249  if (cpl_error_get_code() != CPL_ERROR_NONE) { \
250  cpl_msg_error(cpl_func, "%s():%d: An error is already set: %s", \
251  cpl_func, __LINE__, cpl_error_get_where()); \
252  return (int)cpl_error_get_code(); \
253  } \
254  \
255  if (plugin == NULL) { \
256  cpl_msg_error(cpl_func, "Null plugin"); \
257  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); \
258  } \
259  \
260  /* Verify plugin type */ \
261  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) { \
262  cpl_msg_error(cpl_func, "Plugin is not a recipe"); \
263  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH); \
264  } \
265  \
266  /* Get the recipe */ \
267  recipe = (cpl_recipe *)plugin; \
268  \
269  /* Verify parameter and frame lists */ \
270  if (recipe->parameters == NULL) { \
271  cpl_msg_error(cpl_func, "Recipe invoked with NULL parameter list"); \
272  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); \
273  } \
274  if (recipe->frames == NULL) { \
275  cpl_msg_error(cpl_func, "Recipe invoked with NULL frame set"); \
276  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); \
277  } \
278  \
279  /* Reset the UVES internal state before actually starting */ \
280  irplib_reset(); \
281  \
282  /* Invoke the recipe */ \
283  recipe_status = RECIPE_NAME(recipe->frames, recipe->parameters); \
284  \
285  if (!cpl_errorstate_is_equal(initial_errorstate)) { \
286  /* Dump the error history since recipe execution start. \
287  At this point the recipe cannot recover from the error */ \
288  cpl_errorstate_dump(initial_errorstate, CPL_FALSE, NULL); \
289  } \
290  \
291  return recipe_status; \
292 } \
293  \
294  /* The definition of the recipe destroy function */ \
295 static int UVES_CONCAT2X(RECIPE_NAME,destroy)(cpl_plugin * plugin) \
296 { \
297  cpl_recipe * recipe; \
298  \
299  if (plugin == NULL) { \
300  cpl_msg_error(cpl_func, "Null plugin"); \
301  cpl_ensure_code(0, (int)CPL_ERROR_NULL_INPUT); \
302  } \
303  \
304  /* Verify plugin type */ \
305  if (cpl_plugin_get_type(plugin) != CPL_PLUGIN_TYPE_RECIPE) { \
306  cpl_msg_error(cpl_func, "Plugin is not a recipe"); \
307  cpl_ensure_code(0, (int)CPL_ERROR_TYPE_MISMATCH); \
308  } \
309  \
310  /* Get the recipe */ \
311  recipe = (cpl_recipe *)plugin; \
312  \
313  if (recipe->parameters != NULL) \
314  cpl_parameterlist_delete(recipe->parameters); \
315  \
316  return 0; \
317 } \
318  \
319  /* This dummy declaration requires the macro to be invoked as if it was \
320  a kind of function definition, with a terminating ; */ \
321 extern int uves_plugin_end
322 #endif
323 
324 /*-----------------------------------------------------------------------------
325  Function prototypes
326  -----------------------------------------------------------------------------*/
327 
328 
329 #endif