1 /* This file, modkey.c, contains routines that modify, insert, or update */
2 /* keywords in a FITS header. */
3
4 /* The FITSIO software was written by William Pence at the High Energy */
5 /* Astrophysic Science Archive Research Center (HEASARC) at the NASA */
6 /* Goddard Space Flight Center. */
7
8 #include <string.h>
9 /* stddef.h is apparently needed to define size_t */
10 #include <ctype.h>
11 #include <stddef.h>
12 #include <stdlib.h>
13 #include "fitsio2.h"
14 /*--------------------------------------------------------------------------*/
ffuky(fitsfile * fptr,int datatype,const char * keyname,void * value,const char * comm,int * status)15 int ffuky( fitsfile *fptr, /* I - FITS file pointer */
16 int datatype, /* I - datatype of the value */
17 const char *keyname,/* I - name of keyword to write */
18 void *value, /* I - keyword value */
19 const char *comm, /* I - keyword comment */
20 int *status) /* IO - error status */
21 /*
22 Update the keyword, value and comment in the FITS header.
23 The datatype is specified by the 2nd argument.
24 */
25 {
26 if (*status > 0) /* inherit input status value if > 0 */
27 return(*status);
28
29 if (datatype == TSTRING)
30 {
31 ffukys(fptr, keyname, (char *) value, comm, status);
32 }
33 else if (datatype == TBYTE)
34 {
35 ffukyj(fptr, keyname, (LONGLONG) *(unsigned char *) value, comm, status);
36 }
37 else if (datatype == TSBYTE)
38 {
39 ffukyj(fptr, keyname, (LONGLONG) *(signed char *) value, comm, status);
40 }
41 else if (datatype == TUSHORT)
42 {
43 ffukyj(fptr, keyname, (LONGLONG) *(unsigned short *) value, comm, status);
44 }
45 else if (datatype == TSHORT)
46 {
47 ffukyj(fptr, keyname, (LONGLONG) *(short *) value, comm, status);
48 }
49 else if (datatype == TINT)
50 {
51 ffukyj(fptr, keyname, (LONGLONG) *(int *) value, comm, status);
52 }
53 else if (datatype == TUINT)
54 {
55 ffukyg(fptr, keyname, (double) *(unsigned int *) value, 0,
56 comm, status);
57 }
58 else if (datatype == TLOGICAL)
59 {
60 ffukyl(fptr, keyname, *(int *) value, comm, status);
61 }
62 else if (datatype == TULONG)
63 {
64 ffukyg(fptr, keyname, (double) *(unsigned long *) value, 0,
65 comm, status);
66 }
67 else if (datatype == TLONG)
68 {
69 ffukyj(fptr, keyname, (LONGLONG) *(long *) value, comm, status);
70 }
71 else if (datatype == TLONGLONG)
72 {
73 ffukyj(fptr, keyname, *(LONGLONG *) value, comm, status);
74 }
75 else if (datatype == TFLOAT)
76 {
77 ffukye(fptr, keyname, *(float *) value, -7, comm, status);
78 }
79 else if (datatype == TDOUBLE)
80 {
81 ffukyd(fptr, keyname, *(double *) value, -15, comm, status);
82 }
83 else if (datatype == TCOMPLEX)
84 {
85 ffukyc(fptr, keyname, (float *) value, -7, comm, status);
86 }
87 else if (datatype == TDBLCOMPLEX)
88 {
89 ffukym(fptr, keyname, (double *) value, -15, comm, status);
90 }
91 else
92 *status = BAD_DATATYPE;
93
94 return(*status);
95 }
96 /*--------------------------------------------------------------------------*/
ffukyu(fitsfile * fptr,const char * keyname,const char * comm,int * status)97 int ffukyu(fitsfile *fptr, /* I - FITS file pointer */
98 const char *keyname, /* I - keyword name */
99 const char *comm, /* I - keyword comment */
100 int *status) /* IO - error status */
101 {
102 int tstatus;
103
104 if (*status > 0) /* inherit input status value if > 0 */
105 return(*status);
106
107 tstatus = *status;
108
109 if (ffmkyu(fptr, keyname, comm, status) == KEY_NO_EXIST)
110 {
111 *status = tstatus;
112 ffpkyu(fptr, keyname, comm, status);
113 }
114 return(*status);
115 }
116 /*--------------------------------------------------------------------------*/
ffukys(fitsfile * fptr,const char * keyname,const char * value,const char * comm,int * status)117 int ffukys(fitsfile *fptr, /* I - FITS file pointer */
118 const char *keyname, /* I - keyword name */
119 const char *value, /* I - keyword value */
120 const char *comm, /* I - keyword comment */
121 int *status) /* IO - error status */
122 {
123 int tstatus;
124
125 if (*status > 0) /* inherit input status value if > 0 */
126 return(*status);
127
128 tstatus = *status;
129
130 if (ffmkys(fptr, keyname, value, comm, status) == KEY_NO_EXIST)
131 {
132 *status = tstatus;
133 ffpkys(fptr, keyname, value, comm, status);
134 }
135 return(*status);
136 }
137 /*--------------------------------------------------------------------------*/
ffukls(fitsfile * fptr,const char * keyname,const char * value,const char * comm,int * status)138 int ffukls(fitsfile *fptr, /* I - FITS file pointer */
139 const char *keyname, /* I - keyword name */
140 const char *value, /* I - keyword value */
141 const char *comm, /* I - keyword comment */
142 int *status) /* IO - error status */
143 {
144 /* update a long string keyword */
145
146 int tstatus;
147 char junk[FLEN_ERRMSG];
148
149 if (*status > 0) /* inherit input status value if > 0 */
150 return(*status);
151
152 tstatus = *status;
153
154 if (ffmkls(fptr, keyname, value, comm, status) == KEY_NO_EXIST)
155 {
156 /* since the ffmkls call failed, it wrote a bogus error message */
157 fits_read_errmsg(junk); /* clear the error message */
158
159 *status = tstatus;
160 ffpkls(fptr, keyname, value, comm, status);
161 }
162 return(*status);
163 }/*--------------------------------------------------------------------------*/
ffukyl(fitsfile * fptr,const char * keyname,int value,const char * comm,int * status)164 int ffukyl(fitsfile *fptr, /* I - FITS file pointer */
165 const char *keyname,/* I - keyword name */
166 int value, /* I - keyword value */
167 const char *comm, /* I - keyword comment */
168 int *status) /* IO - error status */
169 {
170 int tstatus;
171
172 if (*status > 0) /* inherit input status value if > 0 */
173 return(*status);
174
175 tstatus = *status;
176
177 if (ffmkyl(fptr, keyname, value, comm, status) == KEY_NO_EXIST)
178 {
179 *status = tstatus;
180 ffpkyl(fptr, keyname, value, comm, status);
181 }
182 return(*status);
183 }
184 /*--------------------------------------------------------------------------*/
ffukyj(fitsfile * fptr,const char * keyname,LONGLONG value,const char * comm,int * status)185 int ffukyj(fitsfile *fptr, /* I - FITS file pointer */
186 const char *keyname,/* I - keyword name */
187 LONGLONG value, /* I - keyword value */
188 const char *comm, /* I - keyword comment */
189 int *status) /* IO - error status */
190 {
191 int tstatus;
192
193 if (*status > 0) /* inherit input status value if > 0 */
194 return(*status);
195
196 tstatus = *status;
197
198 if (ffmkyj(fptr, keyname, value, comm, status) == KEY_NO_EXIST)
199 {
200 *status = tstatus;
201 ffpkyj(fptr, keyname, value, comm, status);
202 }
203 return(*status);
204 }
205 /*--------------------------------------------------------------------------*/
ffukyf(fitsfile * fptr,const char * keyname,float value,int decim,const char * comm,int * status)206 int ffukyf(fitsfile *fptr, /* I - FITS file pointer */
207 const char *keyname,/* I - keyword name */
208 float value, /* I - keyword value */
209 int decim, /* I - no of decimals */
210 const char *comm, /* I - keyword comment */
211 int *status) /* IO - error status */
212 {
213 int tstatus;
214
215 if (*status > 0) /* inherit input status value if > 0 */
216 return(*status);
217
218 tstatus = *status;
219
220 if (ffmkyf(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
221 {
222 *status = tstatus;
223 ffpkyf(fptr, keyname, value, decim, comm, status);
224 }
225 return(*status);
226 }
227 /*--------------------------------------------------------------------------*/
ffukye(fitsfile * fptr,const char * keyname,float value,int decim,const char * comm,int * status)228 int ffukye(fitsfile *fptr, /* I - FITS file pointer */
229 const char *keyname,/* I - keyword name */
230 float value, /* I - keyword value */
231 int decim, /* I - no of decimals */
232 const char *comm, /* I - keyword comment */
233 int *status) /* IO - error status */
234 {
235 int tstatus;
236
237 if (*status > 0) /* inherit input status value if > 0 */
238 return(*status);
239
240 tstatus = *status;
241
242 if (ffmkye(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
243 {
244 *status = tstatus;
245 ffpkye(fptr, keyname, value, decim, comm, status);
246 }
247 return(*status);
248 }
249 /*--------------------------------------------------------------------------*/
ffukyg(fitsfile * fptr,const char * keyname,double value,int decim,const char * comm,int * status)250 int ffukyg(fitsfile *fptr, /* I - FITS file pointer */
251 const char *keyname,/* I - keyword name */
252 double value, /* I - keyword value */
253 int decim, /* I - no of decimals */
254 const char *comm, /* I - keyword comment */
255 int *status) /* IO - error status */
256 {
257 int tstatus;
258
259 if (*status > 0) /* inherit input status value if > 0 */
260 return(*status);
261
262 tstatus = *status;
263
264 if (ffmkyg(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
265 {
266 *status = tstatus;
267 ffpkyg(fptr, keyname, value, decim, comm, status);
268 }
269 return(*status);
270 }
271 /*--------------------------------------------------------------------------*/
ffukyd(fitsfile * fptr,const char * keyname,double value,int decim,const char * comm,int * status)272 int ffukyd(fitsfile *fptr, /* I - FITS file pointer */
273 const char *keyname,/* I - keyword name */
274 double value, /* I - keyword value */
275 int decim, /* I - no of decimals */
276 const char *comm, /* I - keyword comment */
277 int *status) /* IO - error status */
278 {
279 int tstatus;
280
281 if (*status > 0) /* inherit input status value if > 0 */
282 return(*status);
283
284 tstatus = *status;
285
286 if (ffmkyd(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
287 {
288 *status = tstatus;
289 ffpkyd(fptr, keyname, value, decim, comm, status);
290 }
291 return(*status);
292 }
293 /*--------------------------------------------------------------------------*/
ffukfc(fitsfile * fptr,const char * keyname,float * value,int decim,const char * comm,int * status)294 int ffukfc(fitsfile *fptr, /* I - FITS file pointer */
295 const char *keyname,/* I - keyword name */
296 float *value, /* I - keyword value */
297 int decim, /* I - no of decimals */
298 const char *comm, /* I - keyword comment */
299 int *status) /* IO - error status */
300 {
301 int tstatus;
302
303 if (*status > 0) /* inherit input status value if > 0 */
304 return(*status);
305
306 tstatus = *status;
307
308 if (ffmkfc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
309 {
310 *status = tstatus;
311 ffpkfc(fptr, keyname, value, decim, comm, status);
312 }
313 return(*status);
314 }
315 /*--------------------------------------------------------------------------*/
ffukyc(fitsfile * fptr,const char * keyname,float * value,int decim,const char * comm,int * status)316 int ffukyc(fitsfile *fptr, /* I - FITS file pointer */
317 const char *keyname,/* I - keyword name */
318 float *value, /* I - keyword value */
319 int decim, /* I - no of decimals */
320 const char *comm, /* I - keyword comment */
321 int *status) /* IO - error status */
322 {
323 int tstatus;
324
325 if (*status > 0) /* inherit input status value if > 0 */
326 return(*status);
327
328 tstatus = *status;
329
330 if (ffmkyc(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
331 {
332 *status = tstatus;
333 ffpkyc(fptr, keyname, value, decim, comm, status);
334 }
335 return(*status);
336 }
337 /*--------------------------------------------------------------------------*/
ffukfm(fitsfile * fptr,const char * keyname,double * value,int decim,const char * comm,int * status)338 int ffukfm(fitsfile *fptr, /* I - FITS file pointer */
339 const char *keyname,/* I - keyword name */
340 double *value, /* I - keyword value */
341 int decim, /* I - no of decimals */
342 const char *comm, /* I - keyword comment */
343 int *status) /* IO - error status */
344 {
345 int tstatus;
346
347 if (*status > 0) /* inherit input status value if > 0 */
348 return(*status);
349
350 tstatus = *status;
351
352 if (ffmkfm(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
353 {
354 *status = tstatus;
355 ffpkfm(fptr, keyname, value, decim, comm, status);
356 }
357 return(*status);
358 }
359 /*--------------------------------------------------------------------------*/
ffukym(fitsfile * fptr,const char * keyname,double * value,int decim,const char * comm,int * status)360 int ffukym(fitsfile *fptr, /* I - FITS file pointer */
361 const char *keyname,/* I - keyword name */
362 double *value, /* I - keyword value */
363 int decim, /* I - no of decimals */
364 const char *comm, /* I - keyword comment */
365 int *status) /* IO - error status */
366 {
367 int tstatus;
368
369 if (*status > 0) /* inherit input status value if > 0 */
370 return(*status);
371
372 tstatus = *status;
373
374 if (ffmkym(fptr, keyname, value, decim, comm, status) == KEY_NO_EXIST)
375 {
376 *status = tstatus;
377 ffpkym(fptr, keyname, value, decim, comm, status);
378 }
379 return(*status);
380 }
381 /*--------------------------------------------------------------------------*/
ffucrd(fitsfile * fptr,const char * keyname,const char * card,int * status)382 int ffucrd(fitsfile *fptr, /* I - FITS file pointer */
383 const char *keyname,/* I - keyword name */
384 const char *card, /* I - card string value */
385 int *status) /* IO - error status */
386 {
387 int tstatus;
388
389 if (*status > 0) /* inherit input status value if > 0 */
390 return(*status);
391
392 tstatus = *status;
393
394 if (ffmcrd(fptr, keyname, card, status) == KEY_NO_EXIST)
395 {
396 *status = tstatus;
397 ffprec(fptr, card, status);
398 }
399 return(*status);
400 }
401 /*--------------------------------------------------------------------------*/
ffmrec(fitsfile * fptr,int nkey,const char * card,int * status)402 int ffmrec(fitsfile *fptr, /* I - FITS file pointer */
403 int nkey, /* I - number of the keyword to modify */
404 const char *card, /* I - card string value */
405 int *status) /* IO - error status */
406 {
407 if (*status > 0) /* inherit input status value if > 0 */
408 return(*status);
409
410 ffmaky(fptr, nkey+1, status);
411 ffmkey(fptr, card, status);
412 return(*status);
413 }
414 /*--------------------------------------------------------------------------*/
ffmcrd(fitsfile * fptr,const char * keyname,const char * card,int * status)415 int ffmcrd(fitsfile *fptr, /* I - FITS file pointer */
416 const char *keyname, /* I - keyword name */
417 const char *card, /* I - card string value */
418 int *status) /* IO - error status */
419 {
420 char tcard[FLEN_CARD], valstring[FLEN_CARD], comm[FLEN_CARD], value[FLEN_CARD];
421 char nextcomm[FLEN_COMMENT];
422 int keypos, len;
423
424 if (*status > 0) /* inherit input status value if > 0 */
425 return(*status);
426
427 if (ffgcrd(fptr, keyname, tcard, status) > 0)
428 return(*status);
429
430 ffmkey(fptr, card, status);
431
432 /* calc position of keyword in header */
433 keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80) + 1;
434
435 ffpsvc(tcard, valstring, comm, status);
436
437 if (*status > 0) /* inherit input status value if > 0 */
438 return(*status);
439
440 /* check for string value which may be continued over multiple keywords */
441 ffpmrk(); /* put mark on message stack; erase any messages after this */
442 ffc2s(valstring, value, status); /* remove quotes and trailing spaces */
443
444 if (*status == VALUE_UNDEFINED) {
445 ffcmrk(); /* clear any spurious error messages, back to the mark */
446 *status = 0;
447 } else {
448
449 len = strlen(value);
450
451 while (len && value[len - 1] == '&') /* ampersand used as continuation char */
452 {
453 ffgcnt(fptr, value, nextcomm, status);
454 if (*value)
455 {
456 ffdrec(fptr, keypos, status); /* delete the keyword */
457 len = strlen(value);
458 }
459 else /* a null valstring indicates no continuation */
460 len = 0;
461 }
462 }
463
464 return(*status);
465 }
466 /*--------------------------------------------------------------------------*/
ffmnam(fitsfile * fptr,const char * oldname,const char * newname,int * status)467 int ffmnam(fitsfile *fptr, /* I - FITS file pointer */
468 const char *oldname,/* I - existing keyword name */
469 const char *newname,/* I - new name for keyword */
470 int *status) /* IO - error status */
471 {
472 char comm[FLEN_COMMENT];
473 char value[FLEN_VALUE];
474 char card[FLEN_CARD];
475
476 if (*status > 0) /* inherit input status value if > 0 */
477 return(*status);
478
479 if (ffgkey(fptr, oldname, value, comm, status) > 0)
480 return(*status);
481
482 ffmkky(newname, value, comm, card, status); /* construct the card */
483 ffmkey(fptr, card, status); /* rewrite with new name */
484
485 return(*status);
486 }
487 /*--------------------------------------------------------------------------*/
ffmcom(fitsfile * fptr,const char * keyname,const char * comm,int * status)488 int ffmcom(fitsfile *fptr, /* I - FITS file pointer */
489 const char *keyname,/* I - keyword name */
490 const char *comm, /* I - keyword comment */
491 int *status) /* IO - error status */
492 {
493 char oldcomm[FLEN_COMMENT];
494 char value[FLEN_VALUE];
495 char card[FLEN_CARD];
496
497 if (*status > 0) /* inherit input status value if > 0 */
498 return(*status);
499
500 if (ffgkey(fptr, keyname, value, oldcomm, status) > 0)
501 return(*status);
502
503 ffmkky(keyname, value, comm, card, status); /* construct the card */
504 ffmkey(fptr, card, status); /* rewrite with new comment */
505
506 return(*status);
507 }
508 /*--------------------------------------------------------------------------*/
ffpunt(fitsfile * fptr,const char * keyname,const char * unit,int * status)509 int ffpunt(fitsfile *fptr, /* I - FITS file pointer */
510 const char *keyname,/* I - keyword name */
511 const char *unit, /* I - keyword unit string */
512 int *status) /* IO - error status */
513 /*
514 Write (put) the units string into the comment field of the existing keyword.
515 This routine uses a FITS convention in which the units are enclosed in
516 square brackets following the '/' comment field delimiter, e.g.:
517
518 KEYWORD = 12 / [kpc] comment string goes here
519 */
520 {
521 char oldcomm[FLEN_COMMENT];
522 char newcomm[FLEN_COMMENT];
523 char value[FLEN_VALUE];
524 char card[FLEN_CARD];
525 char *loc;
526 size_t len;
527
528 if (*status > 0) /* inherit input status value if > 0 */
529 return(*status);
530
531 if (ffgkey(fptr, keyname, value, oldcomm, status) > 0)
532 return(*status);
533
534 /* copy the units string to the new comment string if not null */
535 if (*unit)
536 {
537 strcpy(newcomm, "[");
538 strncat(newcomm, unit, 45); /* max allowed length is about 45 chars */
539 strcat(newcomm, "] ");
540 len = strlen(newcomm);
541 len = FLEN_COMMENT - len - 1; /* amount of space left in the field */
542 }
543 else
544 {
545 newcomm[0] = '\0';
546 len = FLEN_COMMENT - 1;
547 }
548
549 if (oldcomm[0] == '[') /* check for existing units field */
550 {
551 loc = strchr(oldcomm, ']'); /* look for the closing bracket */
552 if (loc)
553 {
554 loc++;
555 while (*loc == ' ') /* skip any blank spaces */
556 loc++;
557
558 strncat(newcomm, loc, len); /* concat remainder of comment */
559 }
560 else
561 {
562 strncat(newcomm, oldcomm, len); /* append old comment onto new */
563 }
564 }
565 else
566 {
567 strncat(newcomm, oldcomm, len);
568 }
569
570 ffmkky(keyname, value, newcomm, card, status); /* construct the card */
571 ffmkey(fptr, card, status); /* rewrite with new units string */
572
573 return(*status);
574 }
575 /*--------------------------------------------------------------------------*/
ffmkyu(fitsfile * fptr,const char * keyname,const char * comm,int * status)576 int ffmkyu(fitsfile *fptr, /* I - FITS file pointer */
577 const char *keyname,/* I - keyword name */
578 const char *comm, /* I - keyword comment */
579 int *status) /* IO - error status */
580 {
581 char valstring[FLEN_VALUE];
582 char oldcomm[FLEN_COMMENT];
583 char card[FLEN_CARD];
584
585 if (*status > 0) /* inherit input status value if > 0 */
586 return(*status);
587
588 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
589 return(*status); /* get old comment */
590
591 strcpy(valstring," "); /* create a dummy value string */
592
593 if (!comm || comm[0] == '&') /* preserve the current comment string */
594 ffmkky(keyname, valstring, oldcomm, card, status);
595 else
596 ffmkky(keyname, valstring, comm, card, status);
597
598 ffmkey(fptr, card, status);
599
600 return(*status);
601 }
602 /*--------------------------------------------------------------------------*/
ffmkys(fitsfile * fptr,const char * keyname,const char * value,const char * comm,int * status)603 int ffmkys(fitsfile *fptr, /* I - FITS file pointer */
604 const char *keyname, /* I - keyword name */
605 const char *value, /* I - keyword value */
606 const char *comm, /* I - keyword comment */
607 int *status) /* IO - error status */
608 {
609 /* NOTE: This routine does not support long continued strings */
610 /* It will correctly overwrite an existing long continued string, */
611 /* but it will not write a new long string. */
612
613 char oldval[FLEN_VALUE], valstring[FLEN_VALUE];
614 char oldcomm[FLEN_COMMENT];
615 char card[FLEN_CARD], nextcomm[FLEN_COMMENT];
616 int len, keypos;
617
618 if (*status > 0) /* inherit input status value if > 0 */
619 return(*status);
620
621 if (ffgkey(fptr, keyname, oldval, oldcomm, status) > 0)
622 return(*status); /* get old comment */
623
624 ffs2c(value, valstring, status); /* convert value to a string */
625
626 if (!comm || comm[0] == '&') /* preserve the current comment string */
627 ffmkky(keyname, valstring, oldcomm, card, status);
628 else
629 ffmkky(keyname, valstring, comm, card, status);
630
631 ffmkey(fptr, card, status); /* overwrite the previous keyword */
632
633 keypos = (int) (((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80) + 1);
634
635 if (*status > 0)
636 return(*status);
637
638 /* check if old string value was continued over multiple keywords */
639 ffpmrk(); /* put mark on message stack; erase any messages after this */
640 ffc2s(oldval, valstring, status); /* remove quotes and trailing spaces */
641
642 if (*status == VALUE_UNDEFINED) {
643 ffcmrk(); /* clear any spurious error messages, back to the mark */
644 *status = 0;
645 } else {
646
647 len = strlen(valstring);
648
649 while (len && valstring[len - 1] == '&') /* ampersand is continuation char */
650 {
651 ffgcnt(fptr, valstring, nextcomm, status);
652 if (*valstring)
653 {
654 ffdrec(fptr, keypos, status); /* delete the continuation */
655 len = strlen(valstring);
656 }
657 else /* a null valstring indicates no continuation */
658 len = 0;
659 }
660 }
661
662 return(*status);
663 }
664 /*--------------------------------------------------------------------------*/
ffmkls(fitsfile * fptr,const char * keyname,const char * value,const char * incomm,int * status)665 int ffmkls( fitsfile *fptr, /* I - FITS file pointer */
666 const char *keyname, /* I - name of keyword to write */
667 const char *value, /* I - keyword value */
668 const char *incomm, /* I - keyword comment */
669 int *status) /* IO - error status */
670 /*
671 Modify the value and optionally the comment of a long string keyword.
672 This routine supports the
673 HEASARC long string convention and can modify arbitrarily long string
674 keyword values. The value is continued over multiple keywords that
675 have the name COMTINUE without an equal sign in column 9 of the card.
676 This routine also supports simple string keywords which are less than
677 69 characters in length.
678
679 This routine is not very efficient, so it should be used sparingly.
680 */
681 {
682 char valstring[FLEN_VALUE];
683 char card[FLEN_CARD], tmpkeyname[FLEN_CARD];
684 char comm[FLEN_COMMENT];
685 char tstring[FLEN_VALUE], *cptr;
686 char *longval;
687 int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1;
688 int nkeys, keypos;
689
690 if (*status > 0) /* inherit input status value if > 0 */
691 return(*status);
692
693 if (!incomm || incomm[0] == '&') /* preserve the old comment string */
694 {
695 ffghps(fptr, &nkeys, &keypos, status); /* save current position */
696
697 if (ffgkls(fptr, keyname, &longval, comm, status) > 0)
698 return(*status); /* keyword doesn't exist */
699
700 free(longval); /* don't need the old value */
701
702 /* move back to previous position to ensure that we delete */
703 /* the right keyword in case there are more than one keyword */
704 /* with this same name. */
705 ffgrec(fptr, keypos - 1, card, status);
706 } else {
707 /* copy the input comment string */
708 strncpy(comm, incomm, FLEN_COMMENT-1);
709 comm[FLEN_COMMENT-1] = '\0';
710 }
711
712 /* delete the old keyword */
713 if (ffdkey(fptr, keyname, status) > 0)
714 return(*status); /* keyword doesn't exist */
715
716 ffghps(fptr, &nkeys, &keypos, status); /* save current position */
717
718 /* now construct the new keyword, and insert into header */
719 remain = strlen(value); /* number of characters to write out */
720 next = 0; /* pointer to next character to write */
721
722 /* count the number of single quote characters in the string */
723 nquote = 0;
724 cptr = strchr(value, '\''); /* search for quote character */
725
726 while (cptr) /* search for quote character */
727 {
728 nquote++; /* increment no. of quote characters */
729 cptr++; /* increment pointer to next character */
730 cptr = strchr(cptr, '\''); /* search for another quote char */
731 }
732
733 strncpy(tmpkeyname, keyname, 80);
734 tmpkeyname[80] = '\0';
735
736 cptr = tmpkeyname;
737 while(*cptr == ' ') /* skip over leading spaces in name */
738 cptr++;
739
740 /* determine the number of characters that will fit on the line */
741 /* Note: each quote character is expanded to 2 quotes */
742
743 namelen = strlen(cptr);
744 if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) )
745 {
746 /* This a normal 8-character FITS keyword */
747 nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */
748 }
749 else
750 {
751 nchar = 80 - nquote - namelen - 5;
752 }
753
754 contin = 0;
755 while (remain > 0)
756 {
757 if (nchar > FLEN_VALUE-1)
758 {
759 ffpmsg("longstr keyword value is too long (ffmkls)");
760 return (*status=BAD_KEYCHAR);
761 }
762 strncpy(tstring, &value[next], nchar); /* copy string to temp buff */
763 tstring[nchar] = '\0';
764 ffs2c(tstring, valstring, status); /* put quotes around the string */
765
766 if (remain > nchar) /* if string is continued, put & as last char */
767 {
768 vlen = strlen(valstring);
769 nchar -= 1; /* outputting one less character now */
770
771 if (valstring[vlen-2] != '\'')
772 valstring[vlen-2] = '&'; /* over write last char with & */
773 else
774 { /* last char was a pair of single quotes, so over write both */
775 valstring[vlen-3] = '&';
776 valstring[vlen-1] = '\0';
777 }
778 }
779
780 if (contin) /* This is a CONTINUEd keyword */
781 {
782 ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */
783 strncpy(&card[8], " ", 2); /* overwrite the '=' */
784 }
785 else
786 {
787 ffmkky(keyname, valstring, comm, card, status); /* make keyword */
788 }
789
790 ffirec(fptr, keypos, card, status); /* insert the keyword */
791
792 keypos++; /* next insert position */
793 contin = 1;
794 remain -= nchar;
795 next += nchar;
796 nchar = 68 - nquote;
797 }
798 return(*status);
799 }
800 /*--------------------------------------------------------------------------*/
ffmkyl(fitsfile * fptr,const char * keyname,int value,const char * comm,int * status)801 int ffmkyl(fitsfile *fptr, /* I - FITS file pointer */
802 const char *keyname, /* I - keyword name */
803 int value, /* I - keyword value */
804 const char *comm, /* I - keyword comment */
805 int *status) /* IO - error status */
806 {
807 char valstring[FLEN_VALUE];
808 char oldcomm[FLEN_COMMENT];
809 char card[FLEN_CARD];
810
811 if (*status > 0) /* inherit input status value if > 0 */
812 return(*status);
813
814 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
815 return(*status); /* get old comment */
816
817 ffl2c(value, valstring, status); /* convert value to a string */
818
819 if (!comm || comm[0] == '&') /* preserve the current comment string */
820 ffmkky(keyname, valstring, oldcomm, card, status);
821 else
822 ffmkky(keyname, valstring, comm, card, status);
823
824 ffmkey(fptr, card, status);
825
826 return(*status);
827 }
828 /*--------------------------------------------------------------------------*/
ffmkyj(fitsfile * fptr,const char * keyname,LONGLONG value,const char * comm,int * status)829 int ffmkyj(fitsfile *fptr, /* I - FITS file pointer */
830 const char *keyname, /* I - keyword name */
831 LONGLONG value, /* I - keyword value */
832 const char *comm, /* I - keyword comment */
833 int *status) /* IO - error status */
834 {
835 char valstring[FLEN_VALUE];
836 char oldcomm[FLEN_COMMENT];
837 char card[FLEN_CARD];
838
839 if (*status > 0) /* inherit input status value if > 0 */
840 return(*status);
841
842 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
843 return(*status); /* get old comment */
844
845 ffi2c(value, valstring, status); /* convert value to a string */
846
847 if (!comm || comm[0] == '&') /* preserve the current comment string */
848 ffmkky(keyname, valstring, oldcomm, card, status);
849 else
850 ffmkky(keyname, valstring, comm, card, status);
851
852 ffmkey(fptr, card, status);
853
854 return(*status);
855 }
856 /*--------------------------------------------------------------------------*/
ffmkyf(fitsfile * fptr,const char * keyname,float value,int decim,const char * comm,int * status)857 int ffmkyf(fitsfile *fptr, /* I - FITS file pointer */
858 const char *keyname, /* I - keyword name */
859 float value, /* I - keyword value */
860 int decim, /* I - no of decimals */
861 const char *comm, /* I - keyword comment */
862 int *status) /* IO - error status */
863 {
864 char valstring[FLEN_VALUE];
865 char oldcomm[FLEN_COMMENT];
866 char card[FLEN_CARD];
867
868 if (*status > 0) /* inherit input status value if > 0 */
869 return(*status);
870
871 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
872 return(*status); /* get old comment */
873
874 ffr2f(value, decim, valstring, status); /* convert value to a string */
875
876 if (!comm || comm[0] == '&') /* preserve the current comment string */
877 ffmkky(keyname, valstring, oldcomm, card, status);
878 else
879 ffmkky(keyname, valstring, comm, card, status);
880
881 ffmkey(fptr, card, status);
882
883 return(*status);
884 }
885 /*--------------------------------------------------------------------------*/
ffmkye(fitsfile * fptr,const char * keyname,float value,int decim,const char * comm,int * status)886 int ffmkye(fitsfile *fptr, /* I - FITS file pointer */
887 const char *keyname, /* I - keyword name */
888 float value, /* I - keyword value */
889 int decim, /* I - no of decimals */
890 const char *comm, /* I - keyword comment */
891 int *status) /* IO - error status */
892 {
893 char valstring[FLEN_VALUE];
894 char oldcomm[FLEN_COMMENT];
895 char card[FLEN_CARD];
896
897 if (*status > 0) /* inherit input status value if > 0 */
898 return(*status);
899
900 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
901 return(*status); /* get old comment */
902
903 ffr2e(value, decim, valstring, status); /* convert value to a string */
904
905 if (!comm || comm[0] == '&') /* preserve the current comment string */
906 ffmkky(keyname, valstring, oldcomm, card, status);
907 else
908 ffmkky(keyname, valstring, comm, card, status);
909
910 ffmkey(fptr, card, status);
911
912 return(*status);
913 }
914 /*--------------------------------------------------------------------------*/
ffmkyg(fitsfile * fptr,const char * keyname,double value,int decim,const char * comm,int * status)915 int ffmkyg(fitsfile *fptr, /* I - FITS file pointer */
916 const char *keyname, /* I - keyword name */
917 double value, /* I - keyword value */
918 int decim, /* I - no of decimals */
919 const char *comm, /* I - keyword comment */
920 int *status) /* IO - error status */
921 {
922 char valstring[FLEN_VALUE];
923 char oldcomm[FLEN_COMMENT];
924 char card[FLEN_CARD];
925
926 if (*status > 0) /* inherit input status value if > 0 */
927 return(*status);
928
929 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
930 return(*status); /* get old comment */
931
932 ffd2f(value, decim, valstring, status); /* convert value to a string */
933
934 if (!comm || comm[0] == '&') /* preserve the current comment string */
935 ffmkky(keyname, valstring, oldcomm, card, status);
936 else
937 ffmkky(keyname, valstring, comm, card, status);
938
939 ffmkey(fptr, card, status);
940
941 return(*status);
942 }
943 /*--------------------------------------------------------------------------*/
ffmkyd(fitsfile * fptr,const char * keyname,double value,int decim,const char * comm,int * status)944 int ffmkyd(fitsfile *fptr, /* I - FITS file pointer */
945 const char *keyname, /* I - keyword name */
946 double value, /* I - keyword value */
947 int decim, /* I - no of decimals */
948 const char *comm, /* I - keyword comment */
949 int *status) /* IO - error status */
950 {
951 char valstring[FLEN_VALUE];
952 char oldcomm[FLEN_COMMENT];
953 char card[FLEN_CARD];
954
955 if (*status > 0) /* inherit input status value if > 0 */
956 return(*status);
957
958 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
959 return(*status); /* get old comment */
960
961 ffd2e(value, decim, valstring, status); /* convert value to a string */
962
963 if (!comm || comm[0] == '&') /* preserve the current comment string */
964 ffmkky(keyname, valstring, oldcomm, card, status);
965 else
966 ffmkky(keyname, valstring, comm, card, status);
967
968 ffmkey(fptr, card, status);
969
970 return(*status);
971 }
972 /*--------------------------------------------------------------------------*/
ffmkfc(fitsfile * fptr,const char * keyname,float * value,int decim,const char * comm,int * status)973 int ffmkfc(fitsfile *fptr, /* I - FITS file pointer */
974 const char *keyname, /* I - keyword name */
975 float *value, /* I - keyword value */
976 int decim, /* I - no of decimals */
977 const char *comm, /* I - keyword comment */
978 int *status) /* IO - error status */
979 {
980 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
981 char oldcomm[FLEN_COMMENT];
982 char card[FLEN_CARD];
983
984 if (*status > 0) /* inherit input status value if > 0 */
985 return(*status);
986
987 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
988 return(*status); /* get old comment */
989
990 strcpy(valstring, "(" );
991 ffr2f(value[0], decim, tmpstring, status); /* convert to string */
992 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
993 {
994 ffpmsg("complex key value too long (ffmkfc)");
995 return(*status=BAD_F2C);
996 }
997 strcat(valstring, tmpstring);
998 strcat(valstring, ", ");
999 ffr2f(value[1], decim, tmpstring, status); /* convert to string */
1000 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1001 {
1002 ffpmsg("complex key value too long (ffmkfc)");
1003 return(*status=BAD_F2C);
1004 }
1005 strcat(valstring, tmpstring);
1006 strcat(valstring, ")");
1007
1008 if (!comm || comm[0] == '&') /* preserve the current comment string */
1009 ffmkky(keyname, valstring, oldcomm, card, status);
1010 else
1011 ffmkky(keyname, valstring, comm, card, status);
1012
1013 ffmkey(fptr, card, status);
1014
1015 return(*status);
1016 }
1017 /*--------------------------------------------------------------------------*/
ffmkyc(fitsfile * fptr,const char * keyname,float * value,int decim,const char * comm,int * status)1018 int ffmkyc(fitsfile *fptr, /* I - FITS file pointer */
1019 const char *keyname, /* I - keyword name */
1020 float *value, /* I - keyword value */
1021 int decim, /* I - no of decimals */
1022 const char *comm, /* I - keyword comment */
1023 int *status) /* IO - error status */
1024 {
1025 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
1026 char oldcomm[FLEN_COMMENT];
1027 char card[FLEN_CARD];
1028
1029 if (*status > 0) /* inherit input status value if > 0 */
1030 return(*status);
1031
1032 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
1033 return(*status); /* get old comment */
1034
1035 strcpy(valstring, "(" );
1036 ffr2e(value[0], decim, tmpstring, status); /* convert to string */
1037 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
1038 {
1039 ffpmsg("complex key value too long (ffmkyc)");
1040 return(*status=BAD_F2C);
1041 }
1042 strcat(valstring, tmpstring);
1043 strcat(valstring, ", ");
1044 ffr2e(value[1], decim, tmpstring, status); /* convert to string */
1045 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1046 {
1047 ffpmsg("complex key value too long (ffmkyc)");
1048 return(*status=BAD_F2C);
1049 }
1050 strcat(valstring, tmpstring);
1051 strcat(valstring, ")");
1052
1053 if (!comm || comm[0] == '&') /* preserve the current comment string */
1054 ffmkky(keyname, valstring, oldcomm, card, status);
1055 else
1056 ffmkky(keyname, valstring, comm, card, status);
1057
1058 ffmkey(fptr, card, status);
1059
1060 return(*status);
1061 }
1062 /*--------------------------------------------------------------------------*/
ffmkfm(fitsfile * fptr,const char * keyname,double * value,int decim,const char * comm,int * status)1063 int ffmkfm(fitsfile *fptr, /* I - FITS file pointer */
1064 const char *keyname, /* I - keyword name */
1065 double *value, /* I - keyword value */
1066 int decim, /* I - no of decimals */
1067 const char *comm, /* I - keyword comment */
1068 int *status) /* IO - error status */
1069 {
1070 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
1071 char oldcomm[FLEN_COMMENT];
1072 char card[FLEN_CARD];
1073
1074 if (*status > 0) /* inherit input status value if > 0 */
1075 return(*status);
1076
1077 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
1078 return(*status); /* get old comment */
1079
1080 strcpy(valstring, "(" );
1081 ffd2f(value[0], decim, tmpstring, status); /* convert to string */
1082 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
1083 {
1084 ffpmsg("complex key value too long (ffmkfm)");
1085 return(*status=BAD_F2C);
1086 }
1087 strcat(valstring, tmpstring);
1088 strcat(valstring, ", ");
1089 ffd2f(value[1], decim, tmpstring, status); /* convert to string */
1090 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1091 {
1092 ffpmsg("complex key value too long (ffmkfm)");
1093 return(*status=BAD_F2C);
1094 }
1095 strcat(valstring, tmpstring);
1096 strcat(valstring, ")");
1097
1098 if (!comm || comm[0] == '&') /* preserve the current comment string */
1099 ffmkky(keyname, valstring, oldcomm, card, status);
1100 else
1101 ffmkky(keyname, valstring, comm, card, status);
1102
1103 ffmkey(fptr, card, status);
1104
1105 return(*status);
1106 }
1107 /*--------------------------------------------------------------------------*/
ffmkym(fitsfile * fptr,const char * keyname,double * value,int decim,const char * comm,int * status)1108 int ffmkym(fitsfile *fptr, /* I - FITS file pointer */
1109 const char *keyname, /* I - keyword name */
1110 double *value, /* I - keyword value */
1111 int decim, /* I - no of decimals */
1112 const char *comm, /* I - keyword comment */
1113 int *status) /* IO - error status */
1114 {
1115 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
1116 char oldcomm[FLEN_COMMENT];
1117 char card[FLEN_CARD];
1118
1119 if (*status > 0) /* inherit input status value if > 0 */
1120 return(*status);
1121
1122 if (ffgkey(fptr, keyname, valstring, oldcomm, status) > 0)
1123 return(*status); /* get old comment */
1124
1125 strcpy(valstring, "(" );
1126 ffd2e(value[0], decim, tmpstring, status); /* convert to string */
1127 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
1128 {
1129 ffpmsg("complex key value too long (ffmkym)");
1130 return(*status=BAD_F2C);
1131 }
1132 strcat(valstring, tmpstring);
1133 strcat(valstring, ", ");
1134 ffd2e(value[1], decim, tmpstring, status); /* convert to string */
1135 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1136 {
1137 ffpmsg("complex key value too long (ffmkym)");
1138 return(*status=BAD_F2C);
1139 }
1140 strcat(valstring, tmpstring);
1141 strcat(valstring, ")");
1142
1143 if (!comm || comm[0] == '&') /* preserve the current comment string */
1144 ffmkky(keyname, valstring, oldcomm, card, status);
1145 else
1146 ffmkky(keyname, valstring, comm, card, status);
1147
1148 ffmkey(fptr, card, status);
1149
1150 return(*status);
1151 }
1152 /*--------------------------------------------------------------------------*/
ffikyu(fitsfile * fptr,const char * keyname,const char * comm,int * status)1153 int ffikyu(fitsfile *fptr, /* I - FITS file pointer */
1154 const char *keyname, /* I - keyword name */
1155 const char *comm, /* I - keyword comment */
1156 int *status) /* IO - error status */
1157 /*
1158 Insert a null-valued keyword and comment into the FITS header.
1159 */
1160 {
1161 char valstring[FLEN_VALUE];
1162 char card[FLEN_CARD];
1163
1164 if (*status > 0) /* inherit input status value if > 0 */
1165 return(*status);
1166
1167 strcpy(valstring," "); /* create a dummy value string */
1168 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1169 ffikey(fptr, card, status);
1170
1171 return(*status);
1172 }
1173 /*--------------------------------------------------------------------------*/
ffikys(fitsfile * fptr,const char * keyname,const char * value,const char * comm,int * status)1174 int ffikys(fitsfile *fptr, /* I - FITS file pointer */
1175 const char *keyname, /* I - keyword name */
1176 const char *value, /* I - keyword value */
1177 const char *comm, /* I - keyword comment */
1178 int *status) /* IO - error status */
1179 {
1180 char valstring[FLEN_VALUE];
1181 char card[FLEN_CARD];
1182
1183 if (*status > 0) /* inherit input status value if > 0 */
1184 return(*status);
1185
1186 ffs2c(value, valstring, status); /* put quotes around the string */
1187
1188 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1189 ffikey(fptr, card, status);
1190
1191 return(*status);
1192 }
1193 /*--------------------------------------------------------------------------*/
ffikls(fitsfile * fptr,const char * keyname,const char * value,const char * comm,int * status)1194 int ffikls( fitsfile *fptr, /* I - FITS file pointer */
1195 const char *keyname, /* I - name of keyword to write */
1196 const char *value, /* I - keyword value */
1197 const char *comm, /* I - keyword comment */
1198 int *status) /* IO - error status */
1199 /*
1200 Insert a long string keyword. This routine supports the
1201 HEASARC long string convention and can insert arbitrarily long string
1202 keyword values. The value is continued over multiple keywords that
1203 have the name COMTINUE without an equal sign in column 9 of the card.
1204 This routine also supports simple string keywords which are less than
1205 69 characters in length.
1206 */
1207 {
1208 char valstring[FLEN_VALUE];
1209 char card[FLEN_CARD], tmpkeyname[FLEN_CARD];
1210 char tstring[FLEN_VALUE], *cptr;
1211 int next, remain, vlen, nquote, nchar, namelen, contin, tstatus = -1;
1212
1213 if (*status > 0) /* inherit input status value if > 0 */
1214 return(*status);
1215
1216 /* construct the new keyword, and insert into header */
1217 remain = strlen(value); /* number of characters to write out */
1218 next = 0; /* pointer to next character to write */
1219
1220 /* count the number of single quote characters in the string */
1221 nquote = 0;
1222 cptr = strchr(value, '\''); /* search for quote character */
1223
1224 while (cptr) /* search for quote character */
1225 {
1226 nquote++; /* increment no. of quote characters */
1227 cptr++; /* increment pointer to next character */
1228 cptr = strchr(cptr, '\''); /* search for another quote char */
1229 }
1230
1231
1232 strncpy(tmpkeyname, keyname, 80);
1233 tmpkeyname[80] = '\0';
1234
1235 cptr = tmpkeyname;
1236 while(*cptr == ' ') /* skip over leading spaces in name */
1237 cptr++;
1238
1239 /* determine the number of characters that will fit on the line */
1240 /* Note: each quote character is expanded to 2 quotes */
1241
1242 namelen = strlen(cptr);
1243 if (namelen <= 8 && (fftkey(cptr, &tstatus) <= 0) )
1244 {
1245 /* This a normal 8-character FITS keyword */
1246 nchar = 68 - nquote; /* max of 68 chars fit in a FITS string value */
1247 }
1248 else
1249 {
1250 nchar = 80 - nquote - namelen - 5;
1251 }
1252
1253 contin = 0;
1254 while (remain > 0)
1255 {
1256 if (nchar > FLEN_VALUE-1)
1257 {
1258 ffpmsg("longstr keyword value is too long (ffikls)");
1259 return (*status=BAD_KEYCHAR);
1260 }
1261 strncpy(tstring, &value[next], nchar); /* copy string to temp buff */
1262 tstring[nchar] = '\0';
1263 ffs2c(tstring, valstring, status); /* put quotes around the string */
1264
1265 if (remain > nchar) /* if string is continued, put & as last char */
1266 {
1267 vlen = strlen(valstring);
1268 nchar -= 1; /* outputting one less character now */
1269
1270 if (valstring[vlen-2] != '\'')
1271 valstring[vlen-2] = '&'; /* over write last char with & */
1272 else
1273 { /* last char was a pair of single quotes, so over write both */
1274 valstring[vlen-3] = '&';
1275 valstring[vlen-1] = '\0';
1276 }
1277 }
1278
1279 if (contin) /* This is a CONTINUEd keyword */
1280 {
1281 ffmkky("CONTINUE", valstring, comm, card, status); /* make keyword */
1282 strncpy(&card[8], " ", 2); /* overwrite the '=' */
1283 }
1284 else
1285 {
1286 ffmkky(keyname, valstring, comm, card, status); /* make keyword */
1287 }
1288
1289 ffikey(fptr, card, status); /* insert the keyword */
1290
1291 contin = 1;
1292 remain -= nchar;
1293 next += nchar;
1294 nchar = 68 - nquote;
1295 }
1296 return(*status);
1297 }
1298 /*--------------------------------------------------------------------------*/
ffikyl(fitsfile * fptr,const char * keyname,int value,const char * comm,int * status)1299 int ffikyl(fitsfile *fptr, /* I - FITS file pointer */
1300 const char *keyname, /* I - keyword name */
1301 int value, /* I - keyword value */
1302 const char *comm, /* I - keyword comment */
1303 int *status) /* IO - error status */
1304 {
1305 char valstring[FLEN_VALUE];
1306 char card[FLEN_CARD];
1307
1308 if (*status > 0) /* inherit input status value if > 0 */
1309 return(*status);
1310
1311 ffl2c(value, valstring, status); /* convert logical to 'T' or 'F' */
1312 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1313 ffikey(fptr, card, status); /* write the keyword*/
1314
1315 return(*status);
1316 }
1317 /*--------------------------------------------------------------------------*/
ffikyj(fitsfile * fptr,const char * keyname,LONGLONG value,const char * comm,int * status)1318 int ffikyj(fitsfile *fptr, /* I - FITS file pointer */
1319 const char *keyname, /* I - keyword name */
1320 LONGLONG value, /* I - keyword value */
1321 const char *comm, /* I - keyword comment */
1322 int *status) /* IO - error status */
1323 {
1324 char valstring[FLEN_VALUE];
1325 char card[FLEN_CARD];
1326
1327 if (*status > 0) /* inherit input status value if > 0 */
1328 return(*status);
1329
1330 ffi2c(value, valstring, status); /* convert to formatted string */
1331 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1332 ffikey(fptr, card, status); /* write the keyword*/
1333
1334 return(*status);
1335 }
1336 /*--------------------------------------------------------------------------*/
ffikyf(fitsfile * fptr,const char * keyname,float value,int decim,const char * comm,int * status)1337 int ffikyf(fitsfile *fptr, /* I - FITS file pointer */
1338 const char *keyname, /* I - keyword name */
1339 float value, /* I - keyword value */
1340 int decim, /* I - no of decimals */
1341 const char *comm, /* I - keyword comment */
1342 int *status) /* IO - error status */
1343 {
1344 char valstring[FLEN_VALUE];
1345 char card[FLEN_CARD];
1346
1347 if (*status > 0) /* inherit input status value if > 0 */
1348 return(*status);
1349
1350 ffr2f(value, decim, valstring, status); /* convert to formatted string */
1351 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1352 ffikey(fptr, card, status); /* write the keyword*/
1353
1354 return(*status);
1355 }
1356 /*--------------------------------------------------------------------------*/
ffikye(fitsfile * fptr,const char * keyname,float value,int decim,const char * comm,int * status)1357 int ffikye(fitsfile *fptr, /* I - FITS file pointer */
1358 const char *keyname, /* I - keyword name */
1359 float value, /* I - keyword value */
1360 int decim, /* I - no of decimals */
1361 const char *comm, /* I - keyword comment */
1362 int *status) /* IO - error status */
1363 {
1364 char valstring[FLEN_VALUE];
1365 char card[FLEN_CARD];
1366
1367 if (*status > 0) /* inherit input status value if > 0 */
1368 return(*status);
1369
1370 ffr2e(value, decim, valstring, status); /* convert to formatted string */
1371 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1372 ffikey(fptr, card, status); /* write the keyword*/
1373
1374 return(*status);
1375 }
1376 /*--------------------------------------------------------------------------*/
ffikyg(fitsfile * fptr,const char * keyname,double value,int decim,const char * comm,int * status)1377 int ffikyg(fitsfile *fptr, /* I - FITS file pointer */
1378 const char *keyname, /* I - keyword name */
1379 double value, /* I - keyword value */
1380 int decim, /* I - no of decimals */
1381 const char *comm, /* I - keyword comment */
1382 int *status) /* IO - error status */
1383 {
1384 char valstring[FLEN_VALUE];
1385 char card[FLEN_CARD];
1386
1387 if (*status > 0) /* inherit input status value if > 0 */
1388 return(*status);
1389
1390 ffd2f(value, decim, valstring, status); /* convert to formatted string */
1391 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1392 ffikey(fptr, card, status); /* write the keyword*/
1393
1394 return(*status);
1395 }
1396 /*--------------------------------------------------------------------------*/
ffikyd(fitsfile * fptr,const char * keyname,double value,int decim,const char * comm,int * status)1397 int ffikyd(fitsfile *fptr, /* I - FITS file pointer */
1398 const char *keyname, /* I - keyword name */
1399 double value, /* I - keyword value */
1400 int decim, /* I - no of decimals */
1401 const char *comm, /* I - keyword comment */
1402 int *status) /* IO - error status */
1403 {
1404 char valstring[FLEN_VALUE];
1405 char card[FLEN_CARD];
1406
1407 if (*status > 0) /* inherit input status value if > 0 */
1408 return(*status);
1409
1410 ffd2e(value, decim, valstring, status); /* convert to formatted string */
1411 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1412 ffikey(fptr, card, status); /* write the keyword*/
1413
1414 return(*status);
1415 }
1416 /*--------------------------------------------------------------------------*/
ffikfc(fitsfile * fptr,const char * keyname,float * value,int decim,const char * comm,int * status)1417 int ffikfc(fitsfile *fptr, /* I - FITS file pointer */
1418 const char *keyname, /* I - keyword name */
1419 float *value, /* I - keyword value */
1420 int decim, /* I - no of decimals */
1421 const char *comm, /* I - keyword comment */
1422 int *status) /* IO - error status */
1423 {
1424 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
1425 char card[FLEN_CARD];
1426
1427 if (*status > 0) /* inherit input status value if > 0 */
1428 return(*status);
1429
1430 strcpy(valstring, "(" );
1431 ffr2f(value[0], decim, tmpstring, status); /* convert to string */
1432 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
1433 {
1434 ffpmsg("complex key value too long (ffikfc)");
1435 return(*status=BAD_F2C);
1436 }
1437 strcat(valstring, tmpstring);
1438 strcat(valstring, ", ");
1439 ffr2f(value[1], decim, tmpstring, status); /* convert to string */
1440 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1441 {
1442 ffpmsg("complex key value too long (ffikfc)");
1443 return(*status=BAD_F2C);
1444 }
1445 strcat(valstring, tmpstring);
1446 strcat(valstring, ")");
1447
1448 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1449 ffikey(fptr, card, status); /* write the keyword*/
1450
1451 return(*status);
1452 }
1453 /*--------------------------------------------------------------------------*/
ffikyc(fitsfile * fptr,const char * keyname,float * value,int decim,const char * comm,int * status)1454 int ffikyc(fitsfile *fptr, /* I - FITS file pointer */
1455 const char *keyname, /* I - keyword name */
1456 float *value, /* I - keyword value */
1457 int decim, /* I - no of decimals */
1458 const char *comm, /* I - keyword comment */
1459 int *status) /* IO - error status */
1460 {
1461 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
1462 char card[FLEN_CARD];
1463
1464 if (*status > 0) /* inherit input status value if > 0 */
1465 return(*status);
1466
1467 strcpy(valstring, "(" );
1468 ffr2e(value[0], decim, tmpstring, status); /* convert to string */
1469 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
1470 {
1471 ffpmsg("complex key value too long (ffikyc)");
1472 return(*status=BAD_F2C);
1473 }
1474 strcat(valstring, tmpstring);
1475 strcat(valstring, ", ");
1476 ffr2e(value[1], decim, tmpstring, status); /* convert to string */
1477 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1478 {
1479 ffpmsg("complex key value too long (ffikyc)");
1480 return(*status=BAD_F2C);
1481 }
1482 strcat(valstring, tmpstring);
1483 strcat(valstring, ")");
1484
1485 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1486 ffikey(fptr, card, status); /* write the keyword*/
1487
1488 return(*status);
1489 }
1490 /*--------------------------------------------------------------------------*/
ffikfm(fitsfile * fptr,const char * keyname,double * value,int decim,const char * comm,int * status)1491 int ffikfm(fitsfile *fptr, /* I - FITS file pointer */
1492 const char *keyname, /* I - keyword name */
1493 double *value, /* I - keyword value */
1494 int decim, /* I - no of decimals */
1495 const char *comm, /* I - keyword comment */
1496 int *status) /* IO - error status */
1497 {
1498 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
1499 char card[FLEN_CARD];
1500
1501 if (*status > 0) /* inherit input status value if > 0 */
1502 return(*status);
1503
1504
1505 strcpy(valstring, "(" );
1506 ffd2f(value[0], decim, tmpstring, status); /* convert to string */
1507 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
1508 {
1509 ffpmsg("complex key value too long (ffikfm)");
1510 return(*status=BAD_F2C);
1511 }
1512 strcat(valstring, tmpstring);
1513 strcat(valstring, ", ");
1514 ffd2f(value[1], decim, tmpstring, status); /* convert to string */
1515 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1516 {
1517 ffpmsg("complex key value too long (ffikfm)");
1518 return(*status=BAD_F2C);
1519 }
1520 strcat(valstring, tmpstring);
1521 strcat(valstring, ")");
1522
1523 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1524 ffikey(fptr, card, status); /* write the keyword*/
1525
1526 return(*status);
1527 }
1528 /*--------------------------------------------------------------------------*/
ffikym(fitsfile * fptr,const char * keyname,double * value,int decim,const char * comm,int * status)1529 int ffikym(fitsfile *fptr, /* I - FITS file pointer */
1530 const char *keyname, /* I - keyword name */
1531 double *value, /* I - keyword value */
1532 int decim, /* I - no of decimals */
1533 const char *comm, /* I - keyword comment */
1534 int *status) /* IO - error status */
1535 {
1536 char valstring[FLEN_VALUE], tmpstring[FLEN_VALUE];
1537 char card[FLEN_CARD];
1538
1539 if (*status > 0) /* inherit input status value if > 0 */
1540 return(*status);
1541
1542 strcpy(valstring, "(" );
1543 ffd2e(value[0], decim, tmpstring, status); /* convert to string */
1544 if (strlen(tmpstring)+3 > FLEN_VALUE-1)
1545 {
1546 ffpmsg("complex key value too long (ffikym)");
1547 return(*status=BAD_F2C);
1548 }
1549 strcat(valstring, tmpstring);
1550 strcat(valstring, ", ");
1551 ffd2e(value[1], decim, tmpstring, status); /* convert to string */
1552 if (strlen(valstring) + strlen(tmpstring)+1 > FLEN_VALUE-1)
1553 {
1554 ffpmsg("complex key value too long (ffikym)");
1555 return(*status=BAD_F2C);
1556 }
1557 strcat(valstring, tmpstring);
1558 strcat(valstring, ")");
1559
1560 ffmkky(keyname, valstring, comm, card, status); /* construct the keyword*/
1561 ffikey(fptr, card, status); /* write the keyword*/
1562
1563 return(*status);
1564 }
1565 /*--------------------------------------------------------------------------*/
ffirec(fitsfile * fptr,int nkey,const char * card,int * status)1566 int ffirec(fitsfile *fptr, /* I - FITS file pointer */
1567 int nkey, /* I - position to insert new keyword */
1568 const char *card, /* I - card string value */
1569 int *status) /* IO - error status */
1570 {
1571 if (*status > 0) /* inherit input status value if > 0 */
1572 return(*status);
1573
1574 ffmaky(fptr, nkey, status); /* move to insert position */
1575 ffikey(fptr, card, status); /* insert the keyword card */
1576
1577 return(*status);
1578 }
1579 /*--------------------------------------------------------------------------*/
ffikey(fitsfile * fptr,const char * card,int * status)1580 int ffikey(fitsfile *fptr, /* I - FITS file pointer */
1581 const char *card, /* I - card string value */
1582 int *status) /* IO - error status */
1583 /*
1584 insert a keyword at the position of (fptr->Fptr)->nextkey
1585 */
1586 {
1587 int ii, len, nshift, keylength;
1588 long nblocks;
1589 LONGLONG bytepos;
1590 char *inbuff, *outbuff, *tmpbuff, buff1[FLEN_CARD], buff2[FLEN_CARD];
1591
1592 if (*status > 0) /* inherit input status value if > 0 */
1593 return(*status);
1594
1595 /* reset position to the correct HDU if necessary */
1596 if (fptr->HDUposition != (fptr->Fptr)->curhdu)
1597 ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
1598
1599 if ( ((fptr->Fptr)->datastart - (fptr->Fptr)->headend) == 80) /* only room for END card */
1600 {
1601 nblocks = 1;
1602 if (ffiblk(fptr, nblocks, 0, status) > 0) /* add new 2880-byte block*/
1603 return(*status);
1604 }
1605
1606 /* no. keywords to shift */
1607 nshift= (int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80);
1608
1609 strncpy(buff2, card, 80); /* copy card to output buffer */
1610 buff2[80] = '\0';
1611
1612 len = strlen(buff2);
1613
1614 /* silently replace any illegal characters with a space */
1615 for (ii=0; ii < len; ii++)
1616 if (buff2[ii] < ' ' || buff2[ii] > 126) buff2[ii] = ' ';
1617
1618 for (ii=len; ii < 80; ii++) /* fill buffer with spaces if necessary */
1619 buff2[ii] = ' ';
1620
1621 keylength = strcspn(buff2, "=");
1622 if (keylength == 80) keylength = 8;
1623
1624 /* test for the common commentary keywords which by definition have 8-char names */
1625 if ( !fits_strncasecmp( "COMMENT ", buff2, 8) || !fits_strncasecmp( "HISTORY ", buff2, 8) ||
1626 !fits_strncasecmp( " ", buff2, 8) || !fits_strncasecmp( "CONTINUE", buff2, 8) )
1627 keylength = 8;
1628
1629 for (ii=0; ii < keylength; ii++) /* make sure keyword name is uppercase */
1630 buff2[ii] = toupper(buff2[ii]);
1631
1632 fftkey(buff2, status); /* test keyword name contains legal chars */
1633
1634 /* no need to do this any more, since any illegal characters have been removed
1635 fftrec(buff2, status); */ /* test rest of keyword for legal chars */
1636
1637 inbuff = buff1;
1638 outbuff = buff2;
1639
1640 bytepos = (fptr->Fptr)->nextkey; /* pointer to next keyword in header */
1641 ffmbyt(fptr, bytepos, REPORT_EOF, status);
1642
1643 for (ii = 0; ii < nshift; ii++) /* shift each keyword down one position */
1644 {
1645 ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */
1646
1647 ffmbyt(fptr, bytepos, REPORT_EOF, status); /* move back */
1648 ffpbyt(fptr, 80, outbuff, status); /* overwrite with other buffer */
1649
1650 tmpbuff = inbuff; /* swap input and output buffers */
1651 inbuff = outbuff;
1652 outbuff = tmpbuff;
1653
1654 bytepos += 80;
1655 }
1656
1657 ffpbyt(fptr, 80, outbuff, status); /* write the final keyword */
1658
1659 (fptr->Fptr)->headend += 80; /* increment the position of the END keyword */
1660 (fptr->Fptr)->nextkey += 80; /* increment the pointer to next keyword */
1661
1662 return(*status);
1663 }
1664 /*--------------------------------------------------------------------------*/
ffdkey(fitsfile * fptr,const char * keyname,int * status)1665 int ffdkey(fitsfile *fptr, /* I - FITS file pointer */
1666 const char *keyname, /* I - keyword name */
1667 int *status) /* IO - error status */
1668 /*
1669 delete a specified header keyword
1670 */
1671 {
1672 int keypos, len;
1673 char valstring[FLEN_VALUE], comm[FLEN_COMMENT], value[FLEN_VALUE];
1674 char message[FLEN_ERRMSG], nextcomm[FLEN_COMMENT];
1675
1676 if (*status > 0) /* inherit input status value if > 0 */
1677 return(*status);
1678
1679 if (ffgkey(fptr, keyname, valstring, comm, status) > 0) /* read keyword */
1680 {
1681 snprintf(message, FLEN_ERRMSG,"Could not find the %s keyword to delete (ffdkey)",
1682 keyname);
1683 ffpmsg(message);
1684 return(*status);
1685 }
1686
1687 /* calc position of keyword in header */
1688 keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80);
1689
1690 ffdrec(fptr, keypos, status); /* delete the keyword */
1691
1692 if (*status > 0) /* inherit input status value if > 0 */
1693 return(*status);
1694
1695 /* check for string value which may be continued over multiple keywords */
1696 ffpmrk(); /* put mark on message stack; erase any messages after this */
1697 ffc2s(valstring, value, status); /* remove quotes and trailing spaces */
1698
1699 if (*status == VALUE_UNDEFINED) {
1700 ffcmrk(); /* clear any spurious error messages, back to the mark */
1701 *status = 0;
1702 } else {
1703
1704 len = strlen(value);
1705
1706 while (len && value[len - 1] == '&') /* ampersand used as continuation char */
1707 {
1708 ffgcnt(fptr, value, nextcomm, status);
1709 if (*value)
1710 {
1711 ffdrec(fptr, keypos, status); /* delete the keyword */
1712 len = strlen(value);
1713 }
1714 else /* a null valstring indicates no continuation */
1715 len = 0;
1716 }
1717 }
1718
1719 return(*status);
1720 }
1721 /*--------------------------------------------------------------------------*/
ffdstr(fitsfile * fptr,const char * string,int * status)1722 int ffdstr(fitsfile *fptr, /* I - FITS file pointer */
1723 const char *string, /* I - keyword name */
1724 int *status) /* IO - error status */
1725 /*
1726 delete a specified header keyword containing the input string
1727 */
1728 {
1729 int keypos, len;
1730 char valstring[FLEN_VALUE], comm[FLEN_COMMENT], value[FLEN_VALUE];
1731 char card[FLEN_CARD], message[FLEN_ERRMSG], nextcomm[FLEN_COMMENT];
1732
1733 if (*status > 0) /* inherit input status value if > 0 */
1734 return(*status);
1735
1736 if (ffgstr(fptr, string, card, status) > 0) /* read keyword */
1737 {
1738 snprintf(message, FLEN_ERRMSG,"Could not find the %s keyword to delete (ffdkey)",
1739 string);
1740 ffpmsg(message);
1741 return(*status);
1742 }
1743
1744 /* calc position of keyword in header */
1745 keypos = (int) ((((fptr->Fptr)->nextkey) - ((fptr->Fptr)->headstart[(fptr->Fptr)->curhdu])) / 80);
1746
1747 ffdrec(fptr, keypos, status); /* delete the keyword */
1748
1749 /* check for string value which may be continued over multiple keywords */
1750 ffpsvc(card, valstring, comm, status);
1751
1752 if (*status > 0) /* inherit input status value if > 0 */
1753 return(*status);
1754
1755 /* check for string value which may be continued over multiple keywords */
1756 ffpmrk(); /* put mark on message stack; erase any messages after this */
1757 ffc2s(valstring, value, status); /* remove quotes and trailing spaces */
1758
1759 if (*status == VALUE_UNDEFINED) {
1760 ffcmrk(); /* clear any spurious error messages, back to the mark */
1761 *status = 0;
1762 } else {
1763
1764 len = strlen(value);
1765
1766 while (len && value[len - 1] == '&') /* ampersand used as continuation char */
1767 {
1768 ffgcnt(fptr, value, nextcomm, status);
1769 if (*value)
1770 {
1771 ffdrec(fptr, keypos, status); /* delete the keyword */
1772 len = strlen(value);
1773 }
1774 else /* a null valstring indicates no continuation */
1775 len = 0;
1776 }
1777 }
1778
1779 return(*status);
1780 }/*--------------------------------------------------------------------------*/
ffdrec(fitsfile * fptr,int keypos,int * status)1781 int ffdrec(fitsfile *fptr, /* I - FITS file pointer */
1782 int keypos, /* I - position in header of keyword to delete */
1783 int *status) /* IO - error status */
1784 /*
1785 Delete a header keyword at position keypos. The 1st keyword is at keypos=1.
1786 */
1787 {
1788 int ii, nshift;
1789 LONGLONG bytepos;
1790 char *inbuff, *outbuff, *tmpbuff, buff1[81], buff2[81];
1791 char message[FLEN_ERRMSG];
1792
1793 if (*status > 0) /* inherit input status value if > 0 */
1794 return(*status);
1795
1796 /* reset position to the correct HDU if necessary */
1797 if (fptr->HDUposition != (fptr->Fptr)->curhdu)
1798 ffmahd(fptr, (fptr->HDUposition) + 1, NULL, status);
1799
1800 if (keypos < 1 ||
1801 keypos > (fptr->Fptr)->headend - (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] / 80 )
1802 return(*status = KEY_OUT_BOUNDS);
1803
1804 (fptr->Fptr)->nextkey = (fptr->Fptr)->headstart[(fptr->Fptr)->curhdu] + (keypos - 1) * 80;
1805
1806 nshift=(int) (( (fptr->Fptr)->headend - (fptr->Fptr)->nextkey ) / 80); /* no. keywords to shift */
1807
1808 if (nshift <= 0)
1809 {
1810 snprintf(message, FLEN_ERRMSG,"Cannot delete keyword number %d. It does not exist.",
1811 keypos);
1812 ffpmsg(message);
1813 return(*status = KEY_OUT_BOUNDS);
1814 }
1815
1816 bytepos = (fptr->Fptr)->headend - 80; /* last keyword in header */
1817
1818 /* construct a blank keyword */
1819 strcpy(buff2, " ");
1820 strcat(buff2, " ");
1821 inbuff = buff1;
1822 outbuff = buff2;
1823 for (ii = 0; ii < nshift; ii++) /* shift each keyword up one position */
1824 {
1825
1826 ffmbyt(fptr, bytepos, REPORT_EOF, status);
1827 ffgbyt(fptr, 80, inbuff, status); /* read the current keyword */
1828
1829 ffmbyt(fptr, bytepos, REPORT_EOF, status);
1830 ffpbyt(fptr, 80, outbuff, status); /* overwrite with next keyword */
1831
1832 tmpbuff = inbuff; /* swap input and output buffers */
1833 inbuff = outbuff;
1834 outbuff = tmpbuff;
1835
1836 bytepos -= 80;
1837 }
1838
1839 (fptr->Fptr)->headend -= 80; /* decrement the position of the END keyword */
1840 return(*status);
1841 }
1842
1843