1 /*** File libwcs/iget.c
2 *** January 4, 2007
3 *** By Jessica Mink, jmink@cfa.harvard.edu
4 *** Harvard-Smithsonian Center for Astrophysics
5 *** Copyright (C) 1998-2007
6 *** Smithsonian Astrophysical Observatory, Cambridge, MA, USA
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
22 Correspondence concerning WCSTools should be addressed as follows:
23 Internet email: jmink@cfa.harvard.edu
24 Postal address: Jessica Mink
25 Smithsonian Astrophysical Observatory
26 60 Garden St.
27 Cambridge, MA 02138 USA
28
29 * Module: iget.c (Get IRAF FITS Header parameter values)
30 * Purpose: Extract values for variables from IRAF keyword value string
31 * Subroutine: mgeti4 (hstring,mkey,keyword,ival) returns long integer
32 * Subroutine: mgetr8 (hstring,mkey,keyword,dval) returns double
33 * Subroutine: mgetstr (hstring,mkey,keyword,lstr,str) returns character string
34 * Subroutine: igeti4 (hstring,keyword,ival) returns long integer
35 * Subroutine: igetr4 (hstring,keyword,rval) returns real
36 * Subroutine: igetr8 (hstring,keyword,dval) returns double
37 * Subroutine: igets (hstring,keyword,lstr,str) returns character string
38 * Subroutine: igetc (hstring,keyword) returns character string
39 * Subroutine: isearch (hstring,keyword) returns pointer to header string entry
40 */
41
42 #include <string.h> /* NULL, strlen, strstr, strcpy */
43 #include <stdio.h>
44 #include "fitshead.h" /* FITS header extraction subroutines */
45 #include <stdlib.h>
46 #ifndef VMS
47 #include <limits.h>
48 #else
49 #define INT_MAX 2147483647 /* Biggest number that can fit in long */
50 #define SHRT_MAX 32767
51 #endif
52
53 #define MAX_LVAL 2000
54
55 static char *isearch();
56 static char val[30];
57
58 /* Extract long value for variable from IRAF multiline keyword value */
59
60 int
mgeti4(hstring,mkey,keyword,ival)61 mgeti4 (hstring, mkey, keyword, ival)
62
63 const char *hstring; /* Character string containing FITS or IRAF header information
64 in the format <keyword>= <value> ... */
65 const char *mkey; /* Character string containing the name of the multi-line
66 keyword, the string value of which contains the desired
67 keyword, the value of which is returned. */
68 const char *keyword; /* Character string containing the name of the keyword
69 within the multiline IRAF keyword */
70 int *ival; /* Integer value returned */
71 {
72 char *mstring;
73
74 mstring = malloc (MAX_LVAL);
75
76 if (hgetm (hstring, mkey, MAX_LVAL, mstring)) {
77 if (igeti4 (mstring, keyword, ival)) {
78 free (mstring);
79 return (1);
80 }
81 else {
82 free (mstring);
83 return (0);
84 }
85 }
86 else {
87 free (mstring);
88 return (0);
89 }
90 }
91
92 /* Extract double value for variable from IRAF multiline keyword value */
93
94 int
mgetr8(hstring,mkey,keyword,dval)95 mgetr8 (hstring, mkey, keyword, dval)
96
97 const char *hstring; /* Character string containing FITS or IRAF header information
98 in the format <keyword>= <value> ... */
99 const char *mkey; /* Character string containing the name of the multi-line
100 keyword, the string value of which contains the desired
101 keyword, the value of which is returned. */
102 const char *keyword; /* Character string containing the name of the keyword
103 within the multiline IRAF keyword */
104 double *dval; /* Integer value returned */
105 {
106 char *mstring;
107 mstring = malloc (MAX_LVAL);
108
109 if (hgetm (hstring, mkey, MAX_LVAL, mstring)) {
110 if (igetr8 (mstring, keyword, dval)) {
111 free (mstring);
112 return (1);
113 }
114 else {
115 free (mstring);
116 return (0);
117 }
118 }
119 else {
120 free (mstring);
121 return (0);
122 }
123 }
124
125
126 /* Extract string value for variable from IRAF keyword value string */
127
128 int
mgetstr(hstring,mkey,keyword,lstr,str)129 mgetstr (hstring, mkey, keyword, lstr, str)
130
131 const char *hstring; /* character string containing FITS header information
132 in the format <keyword>= <value> {/ <comment>} */
133 const char *mkey; /* Character string containing the name of the multi-line
134 keyword, the string value of which contains the desired
135 keyword, the value of which is returned. */
136 const char *keyword; /* character string containing the name of the keyword
137 the value of which is returned. hget searches for a
138 line beginning with this string. if "[n]" is present,
139 the n'th token in the value is returned.
140 (the first 8 characters must be unique) */
141 const int lstr; /* Size of str in characters */
142 char *str; /* String (returned) */
143 {
144 char *mstring;
145 mstring = malloc (MAX_LVAL);
146
147 if (hgetm (hstring, mkey, MAX_LVAL, mstring)) {
148 if (igets (mstring, keyword, lstr, str)) {
149 free (mstring);
150 return (1);
151 }
152 else {
153 free (mstring);
154 return (0);
155 }
156 }
157 else {
158 free (mstring);
159 return (0);
160 }
161 }
162
163
164 /* Extract long value for variable from IRAF keyword value string */
165
166 int
igeti4(hstring,keyword,ival)167 igeti4 (hstring, keyword, ival)
168
169 const char *hstring; /* character string containing IRAF header information
170 in the format <keyword>= <value> ... */
171 const char *keyword; /* character string containing the name of the keyword
172 the value of which is returned. hget searches for a
173 line beginning with this string. if "[n]" is present,
174 the n'th token in the value is returned.
175 (the first 8 characters must be unique) */
176 int *ival; /* Integer value returned */
177 {
178 char *value;
179 double dval;
180 int minint;
181
182 /* Get value from header string */
183 value = igetc (hstring,keyword);
184
185 /* Translate value from ASCII to binary */
186 if (value != NULL) {
187 minint = -INT_MAX - 1;
188 strcpy (val, value);
189 dval = atof (val);
190 if (dval+0.001 > INT_MAX)
191 *ival = INT_MAX;
192 else if (dval >= 0)
193 *ival = (int) (dval + 0.001);
194 else if (dval-0.001 < minint)
195 *ival = minint;
196 else
197 *ival = (int) (dval - 0.001);
198 return (1);
199 }
200 else {
201 return (0);
202 }
203 }
204
205
206 /* Extract integer*2 value for variable from IRAF keyword value string */
207
208 int
igeti2(hstring,keyword,ival)209 igeti2 (hstring,keyword,ival)
210
211 const char *hstring; /* character string containing FITS header information
212 in the format <keyword>= <value> {/ <comment>} */
213 const char *keyword; /* character string containing the name of the keyword
214 the value of which is returned. hget searches for a
215 line beginning with this string. if "[n]" is present,
216 the n'th token in the value is returned.
217 (the first 8 characters must be unique) */
218 short *ival;
219 {
220 char *value;
221 double dval;
222 int minshort;
223
224 /* Get value from header string */
225 value = igetc (hstring,keyword);
226
227 /* Translate value from ASCII to binary */
228 if (value != NULL) {
229 strcpy (val, value);
230 dval = atof (val);
231 minshort = -SHRT_MAX - 1;
232 if (dval+0.001 > SHRT_MAX)
233 *ival = SHRT_MAX;
234 else if (dval >= 0)
235 *ival = (short) (dval + 0.001);
236 else if (dval-0.001 < minshort)
237 *ival = minshort;
238 else
239 *ival = (short) (dval - 0.001);
240 return (1);
241 }
242 else {
243 return (0);
244 }
245 }
246
247 /* Extract real value for variable from IRAF keyword value string */
248
249 int
igetr4(hstring,keyword,rval)250 igetr4 (hstring,keyword,rval)
251
252 const char *hstring; /* character string containing FITS header information
253 in the format <keyword>= <value> {/ <comment>} */
254 const char *keyword; /* character string containing the name of the keyword
255 the value of which is returned. hget searches for a
256 line beginning with this string. if "[n]" is present,
257 the n'th token in the value is returned.
258 (the first 8 characters must be unique) */
259 float *rval;
260 {
261 char *value;
262
263 /* Get value from header string */
264 value = igetc (hstring,keyword);
265
266 /* Translate value from ASCII to binary */
267 if (value != NULL) {
268 strcpy (val, value);
269 *rval = (float) atof (val);
270 return (1);
271 }
272 else {
273 return (0);
274 }
275 }
276
277
278 /* Extract real*8 value for variable from IRAF keyword value string */
279
280 int
igetr8(hstring,keyword,dval)281 igetr8 (hstring,keyword,dval)
282
283 const char *hstring; /* character string containing FITS header information
284 in the format <keyword>= <value> {/ <comment>} */
285 const char *keyword; /* character string containing the name of the keyword
286 the value of which is returned. hget searches for a
287 line beginning with this string. if "[n]" is present,
288 the n'th token in the value is returned.
289 (the first 8 characters must be unique) */
290 double *dval;
291 {
292 char *value,val[30];
293
294 /* Get value from header string */
295 value = igetc (hstring,keyword);
296
297 /* Translate value from ASCII to binary */
298 if (value != NULL) {
299 strcpy (val, value);
300 *dval = atof (val);
301 return (1);
302 }
303 else {
304 return (0);
305 }
306 }
307
308
309 /* Extract string value for variable from IRAF keyword value string */
310
311 int
igets(hstring,keyword,lstr,str)312 igets (hstring, keyword, lstr, str)
313
314 const char *hstring; /* character string containing FITS header information
315 in the format <keyword>= <value> {/ <comment>} */
316 const char *keyword; /* character string containing the name of the keyword
317 the value of which is returned. hget searches for a
318 line beginning with this string. if "[n]" is present,
319 the n'th token in the value is returned.
320 (the first 8 characters must be unique) */
321 const int lstr; /* Size of str in characters */
322 char *str; /* String (returned) */
323 {
324 char *value;
325 int lval;
326
327 /* Get value from header string */
328 value = igetc (hstring,keyword);
329
330 if (value != NULL) {
331 lval = strlen (value);
332 if (lval < lstr)
333 strcpy (str, value);
334 else if (lstr > 1)
335 strncpy (str, value, lstr-1);
336 else
337 str[0] = value[0];
338 return (1);
339 }
340 else
341 return (0);
342 }
343
344
345 /* Extract character value for variable from IRAF keyword value string */
346
347 char *
igetc(hstring,keyword0)348 igetc (hstring,keyword0)
349
350 const char *hstring; /* character string containing IRAF keyword value string
351 in the format <keyword>= <value> {/ <comment>} */
352 const char *keyword0; /* character string containing the name of the keyword
353 the value of which is returned. iget searches for a
354 line beginning with this string. if "[n]" is present,
355 the n'th token in the value is returned.
356 (the first 8 characters must be unique) */
357 {
358 static char cval[MAX_LVAL];
359 char *value;
360 char cwhite[8];
361 char lbracket[2],rbracket[2];
362 char keyword[16];
363 char line[MAX_LVAL];
364 char *vpos,*cpar;
365 char *c1, *brack1, *brack2;
366 int ipar, i;
367
368 lbracket[0] = 91;
369 lbracket[1] = 0;
370 rbracket[0] = 93;
371 rbracket[1] = 0;
372
373 /* Find length of variable name */
374 strcpy (keyword,keyword0);
375 brack1 = strsrch (keyword,lbracket);
376 if (brack1 != NULL) *brack1 = '\0';
377
378 /* Search header string for variable name */
379 vpos = isearch (hstring,keyword);
380
381 /* Exit if not found */
382 if (vpos == NULL) {
383 return (NULL);
384 }
385
386 /* Initialize returned value to nulls */
387 for (i = 0; i < MAX_LVAL; i++)
388 line[i] = 0;
389
390 /* If quoted value, copy until second quote is reached */
391 i = 0;
392 if (*vpos == '"') {
393 vpos++;
394 while (*vpos && *vpos != '"' && i < MAX_LVAL)
395 line[i++] = *vpos++;
396 }
397
398 /* Otherwise copy until next space or tab */
399 else {
400 while (*vpos != ' ' && *vpos != (char)9 &&
401 *vpos > 0 && i < MAX_LVAL)
402 line[i++] = *vpos++;
403 }
404
405 /* If keyword has brackets, extract appropriate token from value */
406 if (brack1 != NULL) {
407 c1 = (char *) (brack1 + 1);
408 brack2 = strsrch (c1, rbracket);
409 if (brack2 != NULL) {
410 *brack2 = '\0';
411 ipar = atoi (c1);
412 if (ipar > 0) {
413 cwhite[0] = ' ';
414 cwhite[1] = ',';
415 cwhite[2] = '\0';
416 cpar = strtok (line, cwhite);
417 for (i = 1; i < ipar; i++) {
418 cpar = strtok (NULL, cwhite);
419 }
420 if (cpar != NULL) {
421 strcpy (cval,cpar);
422 }
423 else
424 value = NULL;
425 }
426 }
427 }
428 else
429 strcpy (cval, line);
430
431 value = cval;
432
433 return (value);
434 }
435
436
437 /* Find value for specified IRAF keyword */
438
439 static char *
isearch(hstring,keyword)440 isearch (hstring,keyword)
441
442 /* Find entry for keyword keyword in IRAF keyword value string hstring.
443 NULL is returned if the keyword is not found */
444
445 const char *hstring; /* character string containing fits-style header
446 information in the format <keyword>= <value> {/ <comment>}
447 the default is that each entry is 80 characters long;
448 however, lines may be of arbitrary length terminated by
449 nulls, carriage returns or linefeeds, if packed is true. */
450 const char *keyword; /* character string containing the name of the variable
451 to be returned. isearch searches for a line beginning
452 with this string. The string may be a character
453 literal or a character variable terminated by a null
454 or '$'. it is truncated to 8 characters. */
455 {
456 char *loc, *headnext, *headlast, *pval;
457 int lastchar, nextchar, lkey, nleft, lhstr;
458
459 /* Search header string for variable name */
460 lhstr = 0;
461 while (lhstr < 57600 && hstring[lhstr] != 0)
462 lhstr++;
463 headlast = (char *) hstring + lhstr;
464 headnext = (char *) hstring;
465 pval = NULL;
466 lkey = strlen (keyword);
467 while (headnext < headlast) {
468 nleft = headlast - headnext;
469 loc = strnsrch (headnext, keyword, nleft);
470
471 /* Exit if keyword is not found */
472 if (loc == NULL) {
473 break;
474 }
475
476 nextchar = (int) *(loc + lkey);
477 lastchar = (int) *(loc - 1);
478
479 /* If parameter name in header is longer, keep searching */
480 if (nextchar != 61 && nextchar > 32 && nextchar < 127)
481 headnext = loc + 1;
482
483 /* If start of string, keep it */
484 else if (loc == hstring) {
485 pval = loc;
486 break;
487 }
488
489 /* If preceeded by a blank or tab, keep it */
490 else if (lastchar == 32 || lastchar == 9) {
491 pval = loc;
492 break;
493 }
494
495 else
496 headnext = loc + 1;
497 }
498
499 /* Find start of value string for this keyword */
500 if (pval != NULL) {
501 pval = pval + lkey;
502 while (*pval == ' ' || *pval == '=')
503 pval++;
504 }
505
506 /* Return pointer to calling program */
507 return (pval);
508
509 }
510
511 /* Mar 12 1998 New subroutines
512 * Apr 15 1998 Set IGET() and ISEARCH() static when defined
513 * Apr 24 1998 Add MGETI4(), MGETR8(), and MGETS() for single step IRAF ext.
514 * Jun 1 1998 Add VMS patch from Harry Payne at STScI
515 * Jul 9 1998 Fix bracket token extraction after Paul Sydney
516
517 * May 5 1999 values.h -> POSIX limits.h: MAXINT->INT_MAX, MAXSHORT->SHRT_MAX
518 * Oct 21 1999 Fix declarations after lint
519 *
520 * Feb 11 2000 Stop search for end of quoted keyword if more than 500 chars
521 * Jul 20 2000 Drop unused variables squot, dquot, and slash in igetc()
522 *
523 * Jun 26 2002 Change maximum string length from 600 to 2000; use MAX_LVAL
524 * Jun 26 2002 Stop search for end of quoted keyword if > MAX_LVAL chars
525 *
526 * Sep 23 2003 Change mgets() to mgetstr() to avoid name collision at UCO Lick
527 *
528 * Feb 26 2004 Make igetc() accessible from outside this file
529 *
530 * Jan 4 2007 Declare header, keyword to be const
531 */
532