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