UVES Pipeline Reference Manual  5.4.6
uves_propertylist-test.c
1 /* $Id: uves_propertylist-test.c,v 1.3 2009-06-05 05:49:02 amodigli Exp $
2  *
3  * This file is part of the ESO Common Pipeline Library
4  * Copyright (C) 2001-2005 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  */
20 
21 /*
22  * $Author: amodigli $
23  * $Date: 2009-06-05 05:49:02 $
24  * $Revision: 1.3 $
25  * $Name: not supported by cvs2svn $
26  */
27 #ifdef HAVE_CONFIG_H
28 # include <config.h>
29 #endif
30 
31 #undef CX_DISABLE_ASSERT
32 #undef CX_LOG_DOMAIN
33 
34 
35 #include <uves_propertylist.h>
36 
37 #include <cpl_test.h>
38 //#include "cpl_init.h"
39 //#include "cpl_error.h"
40 //#include "uves_propertylist_impl.h"
41 
42 #include <cpl.h>
43 #include <cxmemory.h>
44 #include <cxmessages.h>
45 #include <qfits.h>
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <string.h>
50 #include <math.h>
51 
52 #define FLT_EPS 1.0e-6
53 #define DBL_EPS 1.0e-14
54 
55 
56 static void
57 test_property_dump(cpl_property *property)
58 {
59 
60  const cxchar *name = cpl_property_get_name(property);
61  const cxchar *comment = cpl_property_get_comment(property);
62 
63  cxchar c;
64 
65  long size = cpl_property_get_size(property);
66 
67  cpl_type type = cpl_property_get_type(property);
68 
69 
70  fprintf(stderr, "Property at address %p\n", (void *)property);
71  fprintf(stderr, "\tname : %p '%s'\n", (void *)name, name);
72  fprintf(stderr, "\tcomment: %p '%s'\n", (void *)comment, comment);
73  fprintf(stderr, "\ttype : %#09x\n", type);
74  fprintf(stderr, "\tsize : %ld\n", size);
75  fprintf(stderr, "\tvalue : ");
76 
77 
78  switch (type) {
79  case CPL_TYPE_CHAR:
80  c = cpl_property_get_char(property);
81  if (!c)
82  fprintf(stderr, "''");
83  else
84  fprintf(stderr, "'%c'", c);
85  break;
86 
87  case CPL_TYPE_BOOL:
88  fprintf(stderr, "%d", cpl_property_get_bool(property));
89  break;
90 
91  case CPL_TYPE_INT:
92  fprintf(stderr, "%d", cpl_property_get_int(property));
93  break;
94 
95  case CPL_TYPE_LONG:
96  fprintf(stderr, "%ld", cpl_property_get_long(property));
97  break;
98 
99  case CPL_TYPE_FLOAT:
100  fprintf(stderr, "%.7g", cpl_property_get_float(property));
101  break;
102 
103  case CPL_TYPE_DOUBLE:
104  fprintf(stderr, "%.15g", cpl_property_get_double(property));
105  break;
106 
107  case CPL_TYPE_STRING:
108  fprintf(stderr, "'%s'", cpl_property_get_string(property));
109  break;
110 
111  default:
112  fprintf(stderr, "unknown.");
113  break;
114 
115  }
116 
117  fprintf(stderr, "\n");
118 
119  return;
120 
121 }
122 
123 
124 static void
125 test_plist_dump(uves_propertylist *plist)
126 {
127 
128  cxlong i;
129  cxlong sz = uves_propertylist_get_size(plist);
130 
131 
132  fprintf(stderr, "Property list at address %p:\n", (void *) plist);
133 
134  for (i = 0; i < sz; i++) {
135  cpl_property *p = uves_propertylist_get(plist, i);
136  test_property_dump(p);
137  }
138 
139  return;
140 
141 }
142 
143 static int test_main(void)
144 {
145 
146  const cxchar *keys[] = {
147  "a", "b", "c", "d", "e", "f", "g",
148  "A", "B", "C", "D", "E", "F", "G"
149  };
150 
151  const cxchar *comments[] = {
152  "A character value",
153  "A boolean value",
154  "A integer value",
155  "A long integer value",
156  "A floating point number",
157  "A double precision number",
158  "A string value",
159  };
160 
161  cpl_type types[] = {
162  CPL_TYPE_CHAR,
163  CPL_TYPE_BOOL,
164  CPL_TYPE_INT,
165  CPL_TYPE_LONG,
166  CPL_TYPE_FLOAT,
167  CPL_TYPE_DOUBLE,
168  CPL_TYPE_STRING
169  };
170 
171  cxlong i;
172 
173  cxfloat fval[] = {-1.23456789, 0.};
174  cxdouble dval[] = {-1.23456789, 0.};
175 
176  uves_propertylist *plist, *_plist;
177 
178  qfits_header *header, *_header;
179 
180  struct fcard {
181  const cxchar *key;
182  const cxchar *val;
183  const cxchar *com;
184  cpl_type type;
185  };
186 
187  struct fcard hdr[] = {
188  {"SIMPLE", "T",
189  "Standard FITS format (NOST-100.0)",
190  CPL_TYPE_BOOL},
191  {"BITPIX", "16",
192  "# of bits storing pix values",
193  CPL_TYPE_INT},
194  {"NAXIS", "2",
195  "# of axes in frame",
196  CPL_TYPE_INT},
197  {"NAXIS1", "2148",
198  "# pixels/axis",
199  CPL_TYPE_INT},
200  {"NAXIS2", "2340",
201  "# pixels/axis",
202  CPL_TYPE_INT},
203  {"ORIGIN", "ESO",
204  "European Southern Observatory",
205  CPL_TYPE_STRING},
206  {"DATE", "2002-03-08T04:27:21.420",
207  "Date this file was written (dd/mm/yyyy)",
208  CPL_TYPE_STRING},
209  {"MJD-OBS", "52341.17813019",
210  "Obs start 2002-03-08T04:16:30.448",
211  CPL_TYPE_DOUBLE},
212  {"DATE-OBS", "2002-03-08T04:16:30.448",
213  "Date of observation",
214  CPL_TYPE_STRING},
215  {"EXPTIME", "600.000",
216  "Total integration time. 00:10:00.000",
217  CPL_TYPE_DOUBLE},
218  {"TELESCOP", "VLT",
219  "ESO <TEL>",
220  CPL_TYPE_STRING},
221  {"RA", "181.41734",
222  "12:05:40.1 RA (J2000) pointing",
223  CPL_TYPE_DOUBLE},
224  {"DEC", "-7.65555",
225  "-07:39:19.9 DEC (J2000) pointing",
226  CPL_TYPE_DOUBLE},
227  {"EQUINOX", "2000.",
228  "Standard FK5 (years)",
229  CPL_TYPE_DOUBLE},
230  {"RADECSYS", "FK5",
231  "Coordinate reference frame",
232  CPL_TYPE_STRING},
233  {"LST", "38309.370",
234  "10:38:29.370 LST at start",
235  CPL_TYPE_DOUBLE},
236  {"UTC", "15438.000",
237  "04:17:18.000 UT at start",
238  CPL_TYPE_DOUBLE},
239  {"OBSERVER", "UNKNOWN",
240  "Name of observer",
241  CPL_TYPE_STRING},
242  {"INSTRUME", "UNKNOWN",
243  "Instrument used",
244  CPL_TYPE_STRING},
245  {"PI-COI", "'555555555'",
246  "Name of PI and COI",
247  CPL_TYPE_STRING},
248  {"OBJECT", "None",
249  "Original target",
250  CPL_TYPE_STRING},
251  {"PCOUNT", "0",
252  "Number of parameters per group",
253  CPL_TYPE_INT},
254  {"GCOUNT", "1",
255  "Number of groups",
256  CPL_TYPE_INT},
257  {"CRVAL1", "181.41734",
258  "12:05:40.1, RA at ref pixel",
259  CPL_TYPE_DOUBLE},
260  {"CRPIX1", "2341.8585366",
261  "Reference pixel in X",
262  CPL_TYPE_DOUBLE},
263  {"CDELT1", "0.20500000",
264  "SS arcsec per pixel in RA",
265  CPL_TYPE_DOUBLE},
266  {"CTYPE1", "RA---TAN",
267  "pixel coordinate system",
268  CPL_TYPE_STRING},
269  {"CRVAL2", "-7.65555",
270  "-07:39:19.9, DEC at ref pixel",
271  CPL_TYPE_DOUBLE},
272  {"CRPIX2", "2487.8585366",
273  "Reference pixel in Y",
274  CPL_TYPE_DOUBLE},
275  {"CDELT2", "0.20500000",
276  "SS arcsec per pixel in DEC",
277  CPL_TYPE_DOUBLE},
278  {"CTYPE2", "DEC--TAN",
279  "pixel coordinate system",
280  CPL_TYPE_STRING},
281  {"BSCALE", "1.0",
282  "pixel=FITS*BSCALE+BZERO",
283  CPL_TYPE_DOUBLE},
284  {"BZERO", "32768.0",
285  "pixel=FITS*BSCALE+BZERO",
286  CPL_TYPE_DOUBLE},
287  {"CD1_1", "0.000057",
288  "Translation matrix element",
289  CPL_TYPE_DOUBLE},
290  {"CD1_2", "0.000000",
291  "Translation matrix element",
292  CPL_TYPE_DOUBLE},
293  {"CD2_1", "0.000000",
294  "Translation matrix element",
295  CPL_TYPE_DOUBLE},
296  {"CD2_2", "0.000057",
297  "Translation matrix element",
298  CPL_TYPE_DOUBLE},
299  {"HIERARCH ESO OBS DID", "ESO-VLT-DIC.OBS-1.7",
300  "OBS Dictionary",
301  CPL_TYPE_STRING},
302  {"HIERARCH ESO OBS OBSERVER", "UNKNOWN",
303  "Observer Name",
304  CPL_TYPE_STRING},
305  {"HIERARCH ESO OBS PI-COI NAME", "UNKNOWN",
306  "PI-COI name",
307  CPL_TYPE_STRING},
308  {"HIERARCH ESO INS GRAT NAME", "HR",
309  "Grating name",
310  CPL_TYPE_STRING},
311  {"HIERARCH ESO PRO CATG", "X",
312  "Product category",
313  CPL_TYPE_STRING},
314  {"HIERARCH ESO TPL NEXP", "5",
315  "Number of exposures",
316  CPL_TYPE_INT},
317  {"HISTORY", "1st history record", NULL, CPL_TYPE_STRING},
318  {"COMMENT", "1st comment record", NULL, CPL_TYPE_STRING},
319  {"HISTORY", "2st history record", NULL, CPL_TYPE_STRING},
320  {"COMMENT", "2st comment record", NULL, CPL_TYPE_STRING},
321  {"COMMENT", "3st comment record", NULL, CPL_TYPE_STRING},
322  {"HISTORY", "3st history record", NULL, CPL_TYPE_STRING},
323  {"END", NULL, NULL, CPL_TYPE_STRING}
324  };
325 
326  FILE *file;
327 
328  const cxchar *longname = "0123456789012345678901234567890123456789"
329  "0123456789012345678901234567890123456789";
330 
331 
332  /*
333  * Test 1: Create a property list and check its validity.
334  */
335 
336  plist = uves_propertylist_new();
337 
338  cx_assert(plist != NULL);
339  cx_assert(uves_propertylist_is_empty(plist));
340  cx_assert(uves_propertylist_get_size(plist) == 0);
341 
342 
343  /*
344  * Test 2: Append properties to the list created in the previous test
345  * and verify the data.
346  */
347 
348  uves_propertylist_append_char(plist, keys[0], 'a');
349  uves_propertylist_set_comment(plist, keys[0], comments[0]);
350 
351  uves_propertylist_append_bool(plist, keys[1], 1);
352  uves_propertylist_set_comment(plist, keys[1], comments[1]);
353 
354  uves_propertylist_append_int(plist, keys[2], -1);
355  uves_propertylist_set_comment(plist, keys[2], comments[2]);
356 
357  uves_propertylist_append_long(plist, keys[3], 32768);
358  uves_propertylist_set_comment(plist, keys[3], comments[3]);
359 
360  uves_propertylist_append_float(plist, keys[4], fval[0]);
361  uves_propertylist_set_comment(plist, keys[4], comments[4]);
362 
363  uves_propertylist_append_double(plist, keys[5], dval[0]);
364  uves_propertylist_set_comment(plist, keys[5], comments[5]);
365 
366  uves_propertylist_append_string(plist, keys[6], comments[6]);
367  uves_propertylist_set_comment(plist, keys[6], comments[6]);
368 
369  cx_assert(!uves_propertylist_is_empty(plist));
370  cx_assert(uves_propertylist_get_size(plist) == 7);
371 
372 
373  for (i = 0; i < uves_propertylist_get_size(plist); i++) {
374  cpl_property *p = uves_propertylist_get(plist, i);
375 
376  cx_assert(!strcmp(cpl_property_get_name(p), keys[i]));
377  cx_assert(!strcmp(cpl_property_get_comment(p), comments[i]));
378  cx_assert(cpl_property_get_type(p) == types[i]);
379 
380  cx_assert(uves_propertylist_contains(plist, keys[i]));
381  cx_assert(!strcmp(uves_propertylist_get_comment(plist, keys[i]),
382  comments[i]));
383  cx_assert(uves_propertylist_get_type(plist, keys[i]) == types[i]);
384  }
385 
386  cx_assert(uves_propertylist_get_char(plist, keys[0]) == 'a');
387  cx_assert(uves_propertylist_get_bool(plist, keys[1]) == 1);
388  cx_assert(uves_propertylist_get_int(plist, keys[2]) == -1);
389  cx_assert(uves_propertylist_get_long(plist, keys[3]) == 32768);
390 
391  fval[1] = uves_propertylist_get_float(plist, keys[4]);
392  cx_assert(!memcmp(&fval[0], &fval[1], sizeof(float)));
393 
394  dval[1] = uves_propertylist_get_double(plist, keys[5]);
395  cx_assert(!memcmp(&dval[0], &dval[1], sizeof(double)));
396 
397  cx_assert(!strcmp(uves_propertylist_get_string(plist, keys[6]),
398  comments[6]));
399 
400 
401  /*
402  * Test 3: Modify the values of the property list entries
403  * and verify the data.
404  */
405 
406  cx_assert(uves_propertylist_set_char(plist, keys[0], 'b') == 0);
407  cx_assert(uves_propertylist_get_char(plist, keys[0]) == 'b');
408 
409  cx_assert(uves_propertylist_set_bool(plist, keys[1], 0) == 0);
410  cx_assert(uves_propertylist_get_bool(plist, keys[1]) == 0);
411 
412  cx_assert(uves_propertylist_set_int(plist, keys[2], -1) == 0);
413  cx_assert(uves_propertylist_get_int(plist, keys[2]) == -1);
414 
415  cx_assert(uves_propertylist_set_long(plist, keys[3], 1) == 0);
416  cx_assert(uves_propertylist_get_long(plist, keys[3]) == 1);
417 
418  fval[0] = 9.87654321;
419  cx_assert(uves_propertylist_set_float(plist, keys[4], fval[0]) == 0);
420  fval[1] = uves_propertylist_get_float(plist, keys[4]);
421  cx_assert(!memcmp(&fval[0], &fval[1], sizeof(float)));
422 
423  dval[0] = -9.87654321;
424  cx_assert(uves_propertylist_set_double(plist, keys[5], dval[0]) == 0);
425  dval[1] = uves_propertylist_get_double(plist, keys[5]);
426  cx_assert(!memcmp(&dval[0], &dval[1], sizeof(double)));
427 
428  cx_assert(uves_propertylist_set_string(plist, keys[6], comments[0]) == 0);
429  cx_assert(!strcmp(uves_propertylist_get_string(plist, keys[6]),
430  comments[0]));
431 
432  /*
433  * Test 4: Check that trying to modify an entry with a different
434  * type is properly failing.
435  */
436 
437  if (0) test_plist_dump(plist);
438 
439  cx_assert(uves_propertylist_set_char(plist, keys[1], 'a') ==
440  CPL_ERROR_TYPE_MISMATCH);
441  if (0) test_plist_dump(plist);
442 
443 
444  cx_assert(uves_propertylist_set_bool(plist, keys[2], 1) ==
445  CPL_ERROR_TYPE_MISMATCH);
446 
447  cx_assert(uves_propertylist_set_int(plist, keys[3], 1) ==
448  CPL_ERROR_TYPE_MISMATCH);
449  cx_assert(uves_propertylist_set_long(plist, keys[4], 1) ==
450  CPL_ERROR_TYPE_MISMATCH);
451  cx_assert(uves_propertylist_set_float(plist, keys[5], 1.) ==
452  CPL_ERROR_TYPE_MISMATCH);
453  cx_assert(uves_propertylist_set_double(plist, keys[6], 1.) ==
454  CPL_ERROR_TYPE_MISMATCH);
455 
456  cx_assert(uves_propertylist_set_string(plist, keys[0], comments[0]) ==
457  CPL_ERROR_TYPE_MISMATCH);
458 
459  /*
460  * Test 5: Verify that values are inserted correctly into the property
461  * list.
462  */
463 
464  cx_assert(uves_propertylist_insert_char(plist, keys[0],
465  keys[7], 'a') == 0);
466  cx_assert(uves_propertylist_insert_after_char(plist, keys[0],
467  keys[7], 'c') == 0);
468 
469  cx_assert(uves_propertylist_insert_bool(plist, keys[1],
470  keys[8], 0) == 0);
471  cx_assert(uves_propertylist_insert_after_bool(plist, keys[1],
472  keys[8], 1) == 0);
473 
474  cx_assert(uves_propertylist_insert_int(plist, keys[2],
475  keys[9], 0) == 0);
476  cx_assert(uves_propertylist_insert_after_int(plist, keys[2],
477  keys[9], 1) == 0);
478 
479  cx_assert(uves_propertylist_insert_long(plist, keys[3], keys[10],
480  123456789) == 0);
481  cx_assert(uves_propertylist_insert_after_long(plist, keys[3], keys[10],
482  123456789) == 0);
483 
484  cx_assert(uves_propertylist_insert_float(plist, keys[4], keys[11],
485  fval[0]) == 0);
486  cx_assert(uves_propertylist_insert_after_float(plist, keys[4], keys[11],
487  -fval[0]) == 0);
488 
489  cx_assert(uves_propertylist_insert_double(plist, keys[5], keys[12],
490  dval[0]) == 0);
491  cx_assert(uves_propertylist_insert_after_double(plist, keys[5], keys[12],
492  -dval[0]) == 0);
493 
494  cx_assert(uves_propertylist_insert_string(plist, keys[6],
495  keys[13], "") == 0);
496  cx_assert(uves_propertylist_insert_after_string(plist, keys[6],
497  keys[13], "") == 0);
498  for (i = 0; i < 7; i++) {
499  cpl_property *p0 = uves_propertylist_get(plist, 3 * i);
500  cpl_property *p1 = uves_propertylist_get(plist, 3 * i + 1);
501  cpl_property *p2 = uves_propertylist_get(plist, 3 * i + 2);
502 
503  cx_assert(!strcmp(cpl_property_get_name(p0), keys[i + 7]));
504  cx_assert(!strcmp(cpl_property_get_name(p1), keys[i]));
505  cx_assert(!strcmp(cpl_property_get_name(p2), keys[i + 7]));
506 
507  switch (cpl_property_get_type(p0)) {
508  case CPL_TYPE_CHAR:
509  cx_assert(cpl_property_get_char(p0) == 'a');
510  cx_assert(cpl_property_get_char(p2) == 'c');
511  break;
512 
513  case CPL_TYPE_BOOL:
514  cx_assert(cpl_property_get_bool(p0) == 0);
515  cx_assert(cpl_property_get_bool(p2) == 1);
516  break;
517 
518  case CPL_TYPE_INT:
519  cx_assert(cpl_property_get_int(p0) == 0);
520  cx_assert(cpl_property_get_int(p2) == 1);
521  break;
522 
523  case CPL_TYPE_LONG:
524  cx_assert(cpl_property_get_long(p0) == 123456789);
525  cx_assert(cpl_property_get_long(p2) == 123456789);
526  break;
527 
528  case CPL_TYPE_FLOAT:
529  fval[1] = cpl_property_get_float(p0);
530  cx_assert(!memcmp(&fval[0], &fval[1], sizeof(float)));
531 
532  fval[1] = -cpl_property_get_float(p2);
533  cx_assert(!memcmp(&fval[0], &fval[1], sizeof(float)));
534  break;
535 
536  case CPL_TYPE_DOUBLE:
537  dval[1] = cpl_property_get_double(p0);
538  cx_assert(!memcmp(&dval[0], &dval[1], sizeof(double)));
539 
540  dval[1] = -cpl_property_get_double(p2);
541  cx_assert(!memcmp(&dval[0], &dval[1], sizeof(double)));
542  break;
543 
544  case CPL_TYPE_STRING:
545  cx_assert(!strcmp(cpl_property_get_string(p0), ""));
546  cx_assert(!strcmp(cpl_property_get_string(p2), ""));
547  break;
548 
549  default:
550  /* This point should never be reached */
551  cx_log("uves_propertylist-test", CX_LOG_LEVEL_ERROR, "file %s: "
552  "line %d: Invalid value type encountered", __FILE__,
553  __LINE__);
554  break;
555  }
556  }
557 
558 
559  /*
560  * Test 6: Verify that modification of or insertion at/after a non
561  * existing elements is reported correctly.
562  */
563  cx_assert(uves_propertylist_contains(plist, "Non-existing key") == 0);
564 
565  cx_assert(uves_propertylist_set_char(plist, "Non-existing key", 'a') ==
566  CPL_ERROR_DATA_NOT_FOUND);
567  cx_assert(uves_propertylist_set_bool(plist, "Non-existing key", 1) ==
568  CPL_ERROR_DATA_NOT_FOUND);
569  cx_assert(uves_propertylist_set_int(plist, "Non-existing key", 1) ==
570  CPL_ERROR_DATA_NOT_FOUND);
571  cx_assert(uves_propertylist_set_long(plist, "Non-existing key", 1) ==
572  CPL_ERROR_DATA_NOT_FOUND);
573  cx_assert(uves_propertylist_set_float(plist, "Non-existing key", 1) ==
574  CPL_ERROR_DATA_NOT_FOUND);
575  cx_assert(uves_propertylist_set_double(plist, "Non-existing key", 1) ==
576  CPL_ERROR_DATA_NOT_FOUND);
577  cx_assert(uves_propertylist_set_string(plist, "Non-existing key", "") ==
578  CPL_ERROR_DATA_NOT_FOUND);
579 
580  cx_assert(uves_propertylist_insert_char(plist, "Non-existing key",
581  "h", 'a') == 1);
582  cx_assert(uves_propertylist_insert_bool(plist, "Non-existing key",
583  "h", 1) == 1);
584  cx_assert(uves_propertylist_insert_int(plist, "Non-existing key",
585  "h", 1) == 1);
586  cx_assert(uves_propertylist_insert_long(plist, "Non-existing key",
587  "h", 1) == 1);
588  cx_assert(uves_propertylist_insert_float(plist, "Non-existing key",
589  "h", 1) == 1);
590  cx_assert(uves_propertylist_insert_double(plist, "Non-existing key",
591  "h", 1) == 1);
592  cx_assert(uves_propertylist_insert_string(plist, "Non-existing key",
593  "h", "") == 1);
594 
595  cx_assert(uves_propertylist_insert_after_char(plist, "Non-existing key",
596  "h", 'a') == 1);
597  cx_assert(uves_propertylist_insert_after_bool(plist, "Non-existing key",
598  "h", 1) == 1);
599  cx_assert(uves_propertylist_insert_after_int(plist, "Non-existing key",
600  "h", 1) == 1);
601  cx_assert(uves_propertylist_insert_after_long(plist, "Non-existing key",
602  "h", 1) == 1);
603  cx_assert(uves_propertylist_insert_after_float(plist, "Non-existing key",
604  "h", 1) == 1);
605  cx_assert(uves_propertylist_insert_after_double(plist, "Non-existing key",
606  "h", 1) == 1);
607  cx_assert(uves_propertylist_insert_after_string(plist, "Non-existing key",
608  "h", "") == 1);
609 
610 
611  /*
612  * Test 7: Create a copy of the property list and verify that original
613  * and copy are identical but do not share any resources.
614  */
615 
616  _plist = uves_propertylist_duplicate(plist);
617  cx_assert(_plist != NULL);
618  cx_assert(_plist != plist);
619 
620  for (i = 0; i < uves_propertylist_get_size(plist); i++) {
621  cpl_property *p = uves_propertylist_get(plist, i);
622  cpl_property *_p = uves_propertylist_get(_plist, i);
623 
624  cx_assert(cpl_property_get_name(p) != cpl_property_get_name(_p));
625  cx_assert(!strcmp(cpl_property_get_name(p),
626  cpl_property_get_name(_p)));
627  cx_assert(cpl_property_get_comment(p) == NULL ||
628  (cpl_property_get_comment(p) !=
629  cpl_property_get_comment(_p)));
630  cx_assert(cpl_property_get_comment(p) == NULL ||
631  !strcmp(cpl_property_get_comment(p),
632  cpl_property_get_comment(_p)));
633 
634  switch (cpl_property_get_type(p)) {
635  case CPL_TYPE_CHAR:
636  cx_assert(cpl_property_get_char(p) ==
637  cpl_property_get_char(_p));
638  break;
639 
640  case CPL_TYPE_BOOL:
641  cx_assert(cpl_property_get_bool(p) ==
642  cpl_property_get_bool(_p));
643  break;
644 
645  case CPL_TYPE_INT:
646  cx_assert(cpl_property_get_int(p) ==
647  cpl_property_get_int(_p));
648  break;
649 
650  case CPL_TYPE_LONG:
651  cx_assert(cpl_property_get_long(p) ==
652  cpl_property_get_long(_p));
653  break;
654 
655  case CPL_TYPE_FLOAT:
656  fval[0] = cpl_property_get_float(p);
657  fval[1] = cpl_property_get_float(_p);
658  cx_assert(!memcmp(&fval[0], &fval[1], sizeof(float)));
659  break;
660 
661  case CPL_TYPE_DOUBLE:
662  dval[0] = cpl_property_get_double(p);
663  dval[1] = cpl_property_get_double(_p);
664  cx_assert(!memcmp(&dval[0], &dval[1], sizeof(double)));
665  break;
666 
667  case CPL_TYPE_STRING:
668  cx_assert(!strcmp(cpl_property_get_string(p),
669  cpl_property_get_string(_p)));
670  break;
671 
672  default:
673  /* This point should never be reached */
674  cx_log("uves_propertylist-test", CX_LOG_LEVEL_ERROR, "file %s: "
675  "line %d: Invalid value type encountered", __FILE__,
676  __LINE__);
677  break;
678  }
679  }
680 
681  uves_propertylist_delete(_plist);
682 
683  /*
684  * Test 8: Erase elements from the property list and verify the list
685  * structure and the data.
686  */
687 
688  for (i = 0; i < 7; i++) {
689  uves_propertylist_erase(plist, keys[i + 7]);
690  cx_assert(uves_propertylist_contains(plist, keys[i + 7]) == 1);
691 
692  uves_propertylist_erase(plist, keys[i + 7]);
693  cx_assert(uves_propertylist_contains(plist, keys[i + 7]) == 0);
694  }
695  cx_assert(uves_propertylist_get_size(plist) == 7);
696 
697  for (i = 0; i < 7; i++) {
698  cpl_property *p = uves_propertylist_get(plist, i);
699  cx_assert(!strcmp(cpl_property_get_name(p), keys[i]));
700  }
701 
702  if (0) test_plist_dump(plist);
703 
704  cx_assert(uves_propertylist_get_char(plist, keys[0]) == 'b');
705  cx_assert(uves_propertylist_get_bool(plist, keys[1]) == 0);
706  cx_assert(uves_propertylist_get_int(plist, keys[2]) == -1);
707  cx_assert(uves_propertylist_get_long(plist, keys[3]) == 1);
708 
709  fval[0] = 9.87654321;
710  fval[1] = uves_propertylist_get_float(plist, keys[4]);
711  cx_assert(!memcmp(&fval[0], &fval[1], sizeof(float)));
712 
713  dval[0] = -9.87654321;
714  dval[1] = uves_propertylist_get_double(plist, keys[5]);
715  cx_assert(!memcmp(&dval[0], &dval[1], sizeof(double)));
716 
717  cx_assert(!strcmp(uves_propertylist_get_string(plist, keys[6]),
718  comments[0]));
719 
720  /*
721  * Test 9: Erase all elements from the property list and verify that
722  * the list is empty.
723  */
724 
726 
727  cx_assert(uves_propertylist_is_empty(plist));
728  cx_assert(uves_propertylist_get_size(plist) == 0);
729 
731 
732 
733  /*
734  * Test 10: Create a property list from an input (FITS) file. Verify the
735  * loaded data.
736  */
737 
738  /* Create a sample FITS header and save it to a file */
739 
740  header = qfits_header_new();
741 
742  for (i = 0; (cxsize)i < sizeof hdr / sizeof(struct fcard); i++)
743  qfits_header_append(header, hdr[i].key, hdr[i].val, hdr[i].com, NULL);
744 
745  file = fopen("cpltest1.fits", "w");
746  qfits_header_dump(header, file);
747  fclose(file);
748 
749  /* Load the 1st FITS header into a property list */
750 
751  plist = uves_propertylist_load("cpltest1.fits", 0);
752  cx_assert(plist != NULL);
753 
754  cx_assert(uves_propertylist_contains(plist, "END") == 0);
755  cx_assert(uves_propertylist_get_size(plist) ==
756  (sizeof hdr / sizeof(struct fcard) - 1));
757 
758  for (i = 0; i < uves_propertylist_get_size(plist); i++) {
759  const cxchar *s = hdr[i].key;
760  cpl_property *p = uves_propertylist_get(plist, i);
761 
762  /*
763  * Strip HIERARCH from the keyword if it is present. HIERARCH
764  * is not carried over to the property name.
765  */
766 
767  if (strstr(hdr[i].key, "HIERARCH"))
768  s = hdr[i].key + strlen("HIERARCH") + 1;
769 
770  cx_assert(!strcmp(cpl_property_get_name(p), s));
771  cx_assert(hdr[i].com == NULL ||
772  !strcmp(cpl_property_get_comment(p), hdr[i].com));
773  cx_assert(cpl_property_get_type(p) == hdr[i].type);
774 
775  switch (hdr[i].type) {
776  case CPL_TYPE_BOOL:
777  cx_assert(cpl_property_get_bool(p) ==
778  (*hdr[i].val == 'T' ? 1 : 0));
779  break;
780 
781  case CPL_TYPE_INT:
782  cx_assert(cpl_property_get_int(p) == atoi(hdr[i].val));
783  break;
784 
785  case CPL_TYPE_DOUBLE:
786  dval[0] = cpl_property_get_double(p);
787  dval[1] = atof(hdr[i].val);
788  cx_assert(!memcmp(&dval[0], &dval[1], sizeof(double)));
789  break;
790 
791  case CPL_TYPE_STRING:
792  cx_assert(!strcmp(cpl_property_get_string(p),
793  qfits_pretty_string(hdr[i].val)));
794  break;
795 
796  default:
797  cx_log("uves_propertylist-test", CX_LOG_LEVEL_ERROR, "file %s: "
798  "line %d: Invalid value type encountered", __FILE__,
799  __LINE__);
800  break;
801  }
802  }
803 
804 
805  /*
806  * Test 11: Convert the qfits FITS header back into a property list and
807  * verify that the original property list and the one created
808  * from the FITS header are identical.
809  */
810 
811  _plist = uves_propertylist_from_fits(header) ;
812  cx_assert(_plist != NULL);
813  cx_assert(uves_propertylist_get_size(plist) ==
815 
816  for (i = 0; i < uves_propertylist_get_size(plist); i++) {
817  cpl_property *p = uves_propertylist_get(plist, i);
818  cpl_property *_p = uves_propertylist_get(_plist, i);
819 
820  cx_assert(strcmp(cpl_property_get_name(p),
821  cpl_property_get_name(_p)) == 0);
822  cx_assert(strcmp(cpl_property_get_comment(p),
823  cpl_property_get_comment(_p)) == 0);
824  cx_assert(cpl_property_get_type(p) == cpl_property_get_type(_p));
825 
826  switch (cpl_property_get_type(p)) {
827  case CPL_TYPE_BOOL:
828  cx_assert(cpl_property_get_bool(p) == cpl_property_get_bool(_p));
829  break;
830 
831  case CPL_TYPE_INT:
832  cx_assert(cpl_property_get_int(p) == cpl_property_get_int(_p));
833  break;
834 
835  case CPL_TYPE_DOUBLE:
836  cx_assert(cpl_property_get_double(p) ==
837  cpl_property_get_double(_p));
838  break;
839 
840  case CPL_TYPE_STRING:
841  cx_assert(strcmp(cpl_property_get_string(p),
842  cpl_property_get_string(_p)) == 0);
843  break;
844 
845  default:
846  cx_log("uves_propertylist-test", CX_LOG_LEVEL_ERROR,
847  "file %s: line %d: Invalid value type encountered",
848  __FILE__, __LINE__);
849  break;
850  }
851  }
852 
853  uves_propertylist_delete(_plist);
854 
855 
856  /*
857  * Test 12: Create a qfits header from the property list and verify
858  * the header data. Note that uves_propertylist_to_fits establishes
859  * the DICB sorting order.
860  */
861 
862  qfits_header_sort(&header);
863 
864  file = fopen("cpltest1.fits", "w");
865  qfits_header_dump(header, file);
866  fclose(file);
867 
868 
869  _header = uves_propertylist_to_fits(plist);
870  cx_assert(_header != NULL);
871 
872  file = fopen("cpltest2.fits", "w");
873  qfits_header_dump(_header, file);
874  fclose(file);
875 
876 
877  for (i = 0; i < header->n; i++) {
878  cxchar key[FITS_LINESZ + 1];
879  cxchar val[FITS_LINESZ + 1];
880  cxchar com[FITS_LINESZ + 1];
881 
882  cxchar _key[FITS_LINESZ + 1];
883  cxchar _val[FITS_LINESZ + 1];
884  cxchar _com[FITS_LINESZ + 1];
885 
886 
887  qfits_header_getitem(header, i, key, val, com, NULL);
888  cx_assert(qfits_header_getitem(_header, i, _key, _val,
889  _com, NULL) == 0);
890 
891  cx_assert(!strcmp(key, _key));
892  cx_assert(_com == NULL || !strcmp(com, _com));
893 
894  switch (qfits_get_type(val)) {
895  case QFITS_FLOAT:
896  fval[0] = atof(val);
897  fval[1] = atof(_val);
898 
899  cx_assert(fabs(fval[0] - fval[1]) < FLT_EPS);
900  break;
901 
902  default:
903  cx_assert(strlen(val) == 0 ||
904  !strcmp(qfits_pretty_string(val),
905  qfits_pretty_string(_val)));
906  break;
907  }
908 
909  }
910 
911  qfits_header_destroy(header);
912  qfits_header_destroy(_header);
913 
914 
915  /*
916  * Test 13: Copy all propertys matching a given pattern from one
917  * property list to another.
918  */
919 
920  _plist = uves_propertylist_new();
921 
922  uves_propertylist_copy_property_regexp(_plist, plist, "^ESO .*", 0);
923  cx_assert(uves_propertylist_get_size(_plist) == 6);
924  cx_assert(uves_propertylist_contains(_plist, "ESO OBS DID") != 0);
925  cx_assert(uves_propertylist_contains(_plist, "ESO OBS OBSERVER") != 0);
926  cx_assert(uves_propertylist_contains(_plist, "ESO OBS PI-COI NAME") != 0);
927  cx_assert(uves_propertylist_contains(_plist, "ESO INS GRAT NAME") != 0);
928  cx_assert(uves_propertylist_contains(_plist, "ESO PRO CATG") != 0);
929  cx_assert(uves_propertylist_contains(_plist, "ESO TPL NEXP") != 0);
930 
931  uves_propertylist_empty(_plist);
932  cx_assert(uves_propertylist_is_empty(_plist) != 0);
933 
934  uves_propertylist_copy_property_regexp(_plist, plist, "^ESO .*", 1);
935  cx_assert(uves_propertylist_get_size(_plist) ==
936  (uves_propertylist_get_size(plist) - 6));
937 
938 
939  /*
940  * Test 14: Erase all properties matching the given pattern from the
941  * property list.
942  */
943 
944  uves_propertylist_empty(_plist);
945  cx_assert(uves_propertylist_is_empty(_plist) != 0);
946 
947  uves_propertylist_copy_property_regexp(_plist, plist, "^ESO .*", 0);
948  cx_assert(uves_propertylist_get_size(_plist) == 6);
949 
950  uves_propertylist_erase_regexp(_plist, "^ESO OBS .*", 0);
951  cx_assert(uves_propertylist_get_size(_plist) == 3);
952 
953  uves_propertylist_erase_regexp(_plist, "ESO TPL NEXP", 0);
954  cx_assert(uves_propertylist_get_size(_plist) == 2);
955 
956  uves_propertylist_delete(_plist);
958 
959 
960  /*
961  * Test 15: Create a property list from a file. Only properties matching
962  * the given pattern are loaded.
963  */
964 
965  plist = NULL;
966 
967  plist = uves_propertylist_load_regexp("cpltest1.fits", 0,
968  "^ESO .*", 0);
969  cx_assert(plist != NULL);
970  cx_assert(uves_propertylist_is_empty(plist) == 0);
971  cx_assert(uves_propertylist_get_size(plist) == 6);
972  cx_assert(uves_propertylist_contains(plist, "ESO OBS DID") != 0);
973  cx_assert(uves_propertylist_contains(plist, "ESO OBS OBSERVER") != 0);
974  cx_assert(uves_propertylist_contains(plist, "ESO OBS PI-COI NAME") != 0);
975  cx_assert(uves_propertylist_contains(plist, "ESO INS GRAT NAME") != 0);
976  cx_assert(uves_propertylist_contains(plist, "ESO PRO CATG") != 0);
977  cx_assert(uves_propertylist_contains(plist, "ESO TPL NEXP") != 0);
978 
980 
981 
982  /*
983  * Test 16: Append a property list to another.
984  */
985 
986  plist = uves_propertylist_new();
987  _plist = uves_propertylist_new();
988 
989  uves_propertylist_append_char(plist, keys[0], 'a');
990  uves_propertylist_set_comment(plist, keys[0], comments[0]);
991 
992  uves_propertylist_append_bool(plist, keys[1], 1);
993  uves_propertylist_set_comment(plist, keys[1], comments[1]);
994 
995  uves_propertylist_append_int(plist, keys[2], -1);
996  uves_propertylist_set_comment(plist, keys[2], comments[2]);
997 
998  uves_propertylist_append_long(plist, keys[3], 32768);
999  uves_propertylist_set_comment(plist, keys[3], comments[3]);
1000 
1001  uves_propertylist_append_float(_plist, keys[4], fval[0]);
1002  uves_propertylist_set_comment(_plist, keys[4], comments[4]);
1003 
1004  uves_propertylist_append_double(_plist, keys[5], dval[0]);
1005  uves_propertylist_set_comment(_plist, keys[5], comments[5]);
1006 
1007  uves_propertylist_append_string(_plist, keys[6], comments[6]);
1008  uves_propertylist_set_comment(_plist, keys[6], comments[6]);
1009 
1010  cx_assert(!uves_propertylist_is_empty(plist));
1011  cx_assert(uves_propertylist_get_size(plist) == 4);
1012 
1013  cx_assert(!uves_propertylist_is_empty(_plist));
1014  cx_assert(uves_propertylist_get_size(_plist) == 3);
1015 
1016  uves_propertylist_append(plist, _plist);
1017 
1018  cx_assert(!uves_propertylist_is_empty(plist));
1019  cx_assert(uves_propertylist_get_size(plist) == 7);
1020 
1021  cx_assert(!uves_propertylist_is_empty(_plist));
1022  cx_assert(uves_propertylist_get_size(_plist) == 3);
1023 
1024  for (i = 0; i < uves_propertylist_get_size(plist); i++) {
1025  cpl_property *p = uves_propertylist_get(plist, i);
1026 
1027  cx_assert(!strcmp(cpl_property_get_name(p), keys[i]));
1028  cx_assert(!strcmp(cpl_property_get_comment(p), comments[i]));
1029  cx_assert(cpl_property_get_type(p) == types[i]);
1030 
1031  cx_assert(uves_propertylist_contains(plist, keys[i]));
1032  cx_assert(!strcmp(uves_propertylist_get_comment(plist, keys[i]),
1033  comments[i]));
1034  cx_assert(uves_propertylist_get_type(plist, keys[i]) == types[i]);
1035  }
1036 
1037 
1038  /*
1039  * Test 17: Create a FITS header using a list containing a property with
1040  * a name of length 80 characters (the length of a FITS card)
1041  */
1042 
1043  uves_propertylist_empty(plist);
1044 
1045  uves_propertylist_append_string(plist, longname, comments[6]);
1046 
1047  qfits_header_destroy(uves_propertylist_to_fits(plist));
1048 
1049 
1050  uves_propertylist_delete(_plist);
1051  _plist = NULL;
1052 
1053  uves_propertylist_delete(plist);
1054  plist = NULL;
1055 
1056  cx_assert( cpl_error_get_code() == CPL_ERROR_UNSPECIFIED );
1057  cpl_error_reset();
1058 
1059  /*
1060  * All tests succeeded
1061  */
1062 
1063  return 0;
1064 
1065 }
1066 
1067 int main(void)
1068 {
1069  cpl_test_init(PACKAGE_BUGREPORT, CPL_MSG_WARNING);
1070 
1071  //cpl_msg_set_level(CPL_MSG_DEBUG);
1072  test_main();
1073 
1074  return cpl_test_end(0);
1075 }
cpl_error_code uves_propertylist_insert_after_double(uves_propertylist *self, const char *after, const char *name, double value)
Insert a double value into a property list after the given position.
int uves_propertylist_get_bool(const uves_propertylist *self, const char *name)
Get the boolean value of the given property list entry.
const char * uves_propertylist_get_comment(const uves_propertylist *self, const char *name)
Get the comment of the given property list entry.
cpl_error_code uves_propertylist_insert_int(uves_propertylist *self, const char *here, const char *name, int value)
Insert a integer value into a property list at the given position.
void uves_propertylist_empty(uves_propertylist *self)
Remove all properties from a property list.
int uves_propertylist_erase(uves_propertylist *self, const char *name)
Erase the given property from a property list.
cpl_error_code uves_propertylist_insert_after_char(uves_propertylist *self, const char *after, const char *name, char value)
Insert a character value into a property list after the given position.
int uves_propertylist_is_empty(const uves_propertylist *self)
Check whether a property list is empty.
double uves_propertylist_get_double(const uves_propertylist *self, const char *name)
Get the double value of the given property list entry.
cpl_error_code uves_propertylist_insert_float(uves_propertylist *self, const char *here, const char *name, float value)
Insert a float value into a property list at the given position.
cpl_error_code uves_propertylist_set_double(uves_propertylist *self, const char *name, double value)
Set the value of the given double property list entry.
cpl_error_code uves_propertylist_insert_bool(uves_propertylist *self, const char *here, const char *name, int value)
Insert a boolean value into a property list at the given position.
cpl_error_code uves_propertylist_insert_after_long(uves_propertylist *self, const char *after, const char *name, long value)
Insert a long value into a property list after the given position.
cpl_error_code uves_propertylist_insert_long(uves_propertylist *self, const char *here, const char *name, long value)
Insert a long value into a property list at the given position.
long uves_propertylist_get_long(const uves_propertylist *self, const char *name)
Get the long value of the given property list entry.
cpl_type uves_propertylist_get_type(const uves_propertylist *self, const char *name)
Get the the type of a property list entry.
uves_propertylist * uves_propertylist_new(void)
Create an empty property list.
long uves_propertylist_get_size(const uves_propertylist *self)
Get the current size of a property list.
cpl_error_code uves_propertylist_set_comment(uves_propertylist *self, const char *name, const char *comment)
Modify the comment field of the given property list entry.
const char * uves_propertylist_get_string(const uves_propertylist *self, const char *name)
Get the string value of the given property list entry.
uves_propertylist * uves_propertylist_load(const char *name, int position)
Create a property list from a file.
cpl_error_code uves_propertylist_set_string(uves_propertylist *self, const char *name, const char *value)
Set the value of the given string property list entry.
cpl_error_code uves_propertylist_set_int(uves_propertylist *self, const char *name, int value)
Set the value of the given integer property list entry.
cpl_error_code uves_propertylist_copy_property_regexp(uves_propertylist *self, const uves_propertylist *other, const char *regexp, int invert)
Copy matching properties from another property list.
char uves_propertylist_get_char(const uves_propertylist *self, const char *name)
Get the character value of the given property list entry.
cpl_error_code uves_propertylist_insert_char(uves_propertylist *self, const char *here, const char *name, char value)
Insert a character value into a property list at the given position.
cpl_error_code uves_propertylist_set_float(uves_propertylist *self, const char *name, float value)
Set the value of the given float property list entry.
int uves_propertylist_get_int(const uves_propertylist *self, const char *name)
Get the integer value of the given property list entry.
cpl_error_code uves_propertylist_set_char(uves_propertylist *self, const char *name, char value)
Set the value of the given character property list entry.
int uves_propertylist_erase_regexp(uves_propertylist *self, const char *regexp, int invert)
Erase all properties with name matching a given regular expression.
cpl_error_code uves_propertylist_insert_double(uves_propertylist *self, const char *here, const char *name, double value)
Insert a double value into a property list at the given position.
cpl_error_code uves_propertylist_insert_after_string(uves_propertylist *self, const char *after, const char *name, const char *value)
Insert a string value into a property list after the given position.
cpl_error_code uves_propertylist_insert_after_bool(uves_propertylist *self, const char *after, const char *name, int value)
Insert a boolean value into a property list after the given position.
cpl_error_code uves_propertylist_insert_after_int(uves_propertylist *self, const char *after, const char *name, int value)
Insert a integer value into a property list after the given position.
cpl_error_code uves_propertylist_set_long(uves_propertylist *self, const char *name, long value)
Set the value of the given long property list entry.
uves_propertylist * uves_propertylist_duplicate(const uves_propertylist *self)
Create a copy of the given property list.
int uves_propertylist_contains(const uves_propertylist *self, const char *name)
Check whether a property is present in a property list.
void uves_propertylist_delete(const uves_propertylist *self)
Destroy a property list.
float uves_propertylist_get_float(const uves_propertylist *self, const char *name)
Get the float value of the given property list entry.
cpl_error_code uves_propertylist_insert_after_float(uves_propertylist *self, const char *after, const char *name, float value)
Insert a float value into a property list after the given position.
cpl_error_code uves_propertylist_set_bool(uves_propertylist *self, const char *name, int value)
Set the value of the given boolean property list entry.
cpl_error_code uves_propertylist_insert_string(uves_propertylist *self, const char *here, const char *name, const char *value)
Insert a string value into a property list at the given position.
int main(void)
Various tests of low-level library functions.
Definition: uves-test.c:393
uves_propertylist * uves_propertylist_load_regexp(const char *name, int position, const char *regexp, int invert)
Create a filtered property list from a file.
cpl_error_code uves_propertylist_append(uves_propertylist *self, const uves_propertylist *other)
Append a property list..