1 /*
2 This file is part of "fitsverify" and was imported from:
3 http://heasarc.gsfc.nasa.gov/docs/software/ftools/fitsverify/
4 */
5 #include "fverify.h"
6
fits_parse_card(FILE * out,int kpos,char * card,char * kname,kwdtyp * ktype,char * kvalue,char * kcomm)7 int fits_parse_card(FILE *out, /* output file pointer */
8 int kpos, /* keyposition starting from 1 */
9 char *card, /* key card */
10 char *kname, /* key name */
11 kwdtyp *ktype, /* key type */
12 char *kvalue, /* key value */
13 char *kcomm /* comment */
14 )
15 /* Ref: Defininition of the Flexible Image Transport System(FITS),
16 Sec. 5.1 and 5.2.
17 */
18 {
19 char vind[3];
20 char *p;
21 char **pt;
22 int i;
23 char temp1[FLEN_CARD];
24 unsigned long stat = 0;
25
26 *kname = '\0';
27 *kvalue = '\0';
28 *kcomm = '\0';
29 *ktype = UNKNOWN;
30
31 if(strlen(card) > FLEN_CARD-1 ) {
32 strncpy(temp1,card,20);
33 temp1[21]='\0';
34 sprintf(errmes,"card %s is > 80.",card);
35 wrterr(out,errmes,1);
36 return 1;
37 }
38 card[FLEN_CARD-1] = '\0';
39
40 /* get the kname */
41 strncpy(kname, card, 8);
42 kname[8] = '\0';
43
44 /* take out the trailing space */
45 i = 7;
46 p = &kname[7];
47 while(isspace((int)*p) && i >= 0) {*p = '\0'; p--; i--;}
48
49 /* Whether the keyword name is left justified */
50 i = 0;
51 p = &kname[0];
52 while(isspace((int)*p) && *p != '\0' ) { p++; i++;}
53 if( i < 8 && i > 0) {
54 sprintf(errmes,"Keyword #%d: Name %s is not left justified.",
55 kpos,kname);
56 wrterr(out,errmes,1);
57 }
58 /* Whether the characters in keyword name are valid */
59 while(*p != '\0' ){
60 if((*p < 'A' || *p > 'Z')&&
61 (*p < '0' || *p > '9')&&
62 (*p != '-' && *p != '_') ) {
63 sprintf(errmes,
64 "Keyword #%d: Name \"%s\" contains char \"%c\" which is not letter, digit, \"-\", and \"_\".",kpos,kname,*p);
65 wrterr(out,errmes,1);
66 break;
67 }
68 p++; i++;
69 }
70
71 /* COMMENT, HISTORY, HIERARCH and "" keywords */
72 if( !strcmp(kname,"COMMENT") ||
73 !strcmp(kname,"HISTORY") ||
74 !strcmp(kname,"HIERARCH") ||
75 !strcmp(kname,"CONTINUE") ||
76 !strcmp(kname,"") ){
77
78 *ktype = COM_KEY;
79
80 p = &card[8];
81 strcpy(kcomm, p);
82 kcomm[FLEN_COMMENT-1] = '\0';
83 for( ; *p != '\0'; p++) {
84 if(!isprint((int)*p)) {
85 sprintf(errmes,
86 "Keyword #%d, %s: String contains non-text characters.",
87 kpos,kname);
88 wrterr(out,errmes,1);
89 return 1;
90 }
91 }
92 p = kname;
93 while(!isspace((int)*p)&& *p != '\0')p++;
94 *p = '\0';
95 return 0;
96 }
97
98 /* End Keyword: 9-80 shall be filled with ASCII blanks \x20 */
99 if( !strcmp(kname,"END") ){
100 *ktype = COM_KEY;
101 if(card[3] == '\0') return 0;
102 for( p = &card[8]; *p != '\0'; p++) {
103 if(*p != '\x20' ){
104 wrterr(out,"END keyword contains non-blank characters.",1);
105 return 1;
106 }
107 }
108 kname[3] = '\0';
109 return 0;
110 }
111
112
113 /* check for value indicator */
114 p = &card[8];
115 strncpy(vind,p,2);
116 vind[2] = '\0';
117 if(strcmp(vind,"= ") && strcmp(vind,"=") ){
118 /* no value indicator, so this is a commentary keyword */
119 *ktype = COM_KEY;
120 strcpy(kcomm, p);
121 kcomm[FLEN_COMMENT-1] = '\0';
122 for( ; *p != '\0'; p++) {
123 if(!isprint((int)*p)) {
124 sprintf(errmes,
125 "Keyword #%d, %s: String contains non-text characters.",
126 kpos,kname);
127 wrterr(out,errmes,1);
128 return 1;
129 }
130 }
131 p = kname;
132 while(!isspace((int)*p)&& *p != '\0')p++;
133 *p = '\0';
134 return 0;
135 }
136
137 p = &card[10];
138 while (isspace((int)*p) && *p != '\0') p++;
139 pt = &p;
140 switch (*p) {
141 case '\'': /* string */
142 get_str(pt, kvalue,&stat);
143 *ktype = STR_KEY;
144 p = *pt;
145 if(*p != '\0') get_comm(pt,kcomm,&stat);
146 break;
147 case 'T': case 'F': /*logical */
148 get_log(pt, kvalue, &stat);
149 *ktype = LOG_KEY;
150 p = *pt;
151 if(*p != '\0') get_comm(pt,kcomm,&stat);
152 break;
153 case '+': case '-': case '.': /* number */
154 case '0': case '1': case '2':
155 case '3': case '4': case '5':
156 case '6': case '7': case '8':
157 case '9':
158 get_num(pt, kvalue, ktype, &stat);
159 p = *pt;
160 if(*p != '\0') get_comm(pt,kcomm,&stat);
161 break;
162 case '(': /* complex number */
163 get_cmp(pt, kvalue, ktype, &stat);
164 p = *pt;
165 if(*p != '\0') get_comm(pt,kcomm,&stat);
166 break;
167 case '/': /* comment */
168 if(*p != '\0') get_comm(pt,kcomm,&stat);
169 *ktype = UNKNOWN;
170 break;
171 default:
172 get_unknown(pt,kvalue,ktype,&stat);
173 p = *pt;
174 if(*p != '\0') get_comm(pt,kcomm,&stat);
175 }
176 /* take out the trailing blanks for non-string keys */
177 if(*ktype != STR_KEY) {
178 i = strlen(kvalue);
179 p = &kvalue[i-1];
180 while(isspace((int)*p) && i >0) {
181 *p = '\0';
182 p--; i--;
183 }
184 if(i == 0 && isspace((int)*p))*p = '\0';
185 }
186 pr_kval_err(out,kpos,kname,kvalue,stat);
187 if(stat != 0) return 1;
188 return 0;
189 }
190
191 /* parse And test the string keys */
get_str(char ** pt,char * kvalue,unsigned long * stat)192 void get_str(char **pt, /* card string from character 11*/
193 char *kvalue, /* key value string */
194 unsigned long *stat /* error number */
195 )
196 {
197 char *pi;
198 char prev; /* previous char */
199 int nchar = 0;
200 char *p;
201
202 p = *pt;
203 pi = p;
204 p++;
205 prev = 'a';
206 while(*p != '\0') {
207 if( !isprint((int)*p) )*stat |= BAD_STR;
208 if(prev == '\'' && *p != '\'') break;
209 if(prev == '\'' && *p == '\'') { /* skip the '' */
210 p++;
211 prev = 'a';
212 }
213 else {
214 prev = *p;
215 p++;
216 }
217 }
218 p--;
219 if(*p != '\'') *stat |= NO_TRAIL_QUOTE;
220 pi++;
221 nchar = p - pi ; /* excluding the ' */
222 strncpy(kvalue,pi,nchar);
223 *(kvalue+nchar) = '\0';
224 pi = kvalue + (nchar -1) ;
225 while(isspace((int)*pi)){ *pi = '\0'; pi--;} /* delete the trailing space */
226 p++; /* skip the ' */
227 while(isspace((int)*p) && *p != '\0') p++;
228 *pt = p;
229 return;
230 }
231
232 /* parse and test the logical keys */
get_log(char ** pt,char * kvalue,unsigned long * stat)233 void get_log(char **pt, /* card string */
234 char *kvalue, /* key value string */
235 unsigned long *stat /* error number */
236 )
237 {
238 char *p;
239
240 p = *pt;
241 *kvalue = *p;
242 kvalue[1] = '\0';
243 p++;
244 while(isspace((int)*p)) p++;
245 if(*p != '/' && *p != '\0') *stat |= BAD_LOGICAL;
246 *pt = p;
247 return;
248 }
249
250 /* parse and test the numerical keys */
get_num(char ** pt,char * kvalue,kwdtyp * ktype,unsigned long * stat)251 void get_num(char **pt, /* card string */
252 char *kvalue, /* comment string */
253 kwdtyp *ktype,
254 unsigned long *stat /* error number */
255 )
256 {
257 char *pi;
258 int set_deci = 0;
259 int set_expo = 0;
260 int set_sign = 0;
261 int nchar;
262 char *p;
263
264 p = *pt;
265 pi = p;
266 *ktype = INT_KEY;
267
268 if( *p != '+' && *p != '-' && !isdigit((int)*p) &&*p != '.') {
269 *stat |= BAD_NUM;
270 return;
271 }
272 if(*p == '.') {
273 *ktype = FLT_KEY;
274 set_deci = 1;
275 }
276 if(*p == '+'|| *p == '-') {
277 set_sign = 1;
278 }
279 p++;
280 while(!isspace((int)*p) && *p != '\0' && *p != '/') {
281 if( *p == '.' && !set_deci ){
282 set_deci = 1;
283 *ktype = FLT_KEY;
284 p++;
285 continue;
286 }
287 if( (*p == 'd'|| *p == 'e') && !set_expo) {
288 set_expo = 1;
289 *ktype = FLT_KEY;
290 p++;
291 if(*p == '+' || *p == '-') p++;
292 *stat |= LOWCASE_EXPO;
293 continue;
294 }
295 if( (*p == 'D'|| *p == 'E') && !set_expo) {
296 set_expo = 1;
297 *ktype = FLT_KEY;
298 p++;
299 if(*p == '+' || *p == '-') p++;
300 continue;
301 }
302 if(!isdigit((int)*p)) *stat |= BAD_NUM;
303 p++;
304 }
305 nchar = p - pi;
306 strncpy(kvalue,pi,nchar);
307 *(kvalue+nchar) = '\0';
308 while(isspace((int)*p) && *p != '\0') p++;
309 *pt = p;
310 return;
311 }
312
313 /* parse and test the complex keys */
get_cmp(char ** pt,char * kvalue,kwdtyp * ktype,unsigned long * stat)314 void get_cmp(char **pt, /* card string */
315 char *kvalue, /* comment string */
316 kwdtyp *ktype,
317 unsigned long *stat /* error number */
318 )
319 {
320 char *p;
321 char **pp;
322 char *pr_beg; /* end of real part */
323 char *pr_end=0; /* end of real part */
324 char *pi_beg; /* beginning of the imaginay part */
325 char *pi_end=0; /* end of real part */
326 int nchar;
327 int set_comm = 0;
328 int set_paren = 0;
329
330 unsigned long tr = 0;
331 unsigned long ti = 0;
332 kwdtyp rtype, itype;
333 char temp[FLEN_CARD];
334 char card[FLEN_CARD];
335
336
337 strcpy(card,*pt); /* save the original */
338 card[FLEN_CARD-1] = '\0';
339
340 *ktype = CMI_KEY; /* default: integer complex */
341 p = card + 1;
342 pr_beg = p;
343
344 temp[0] = '\0';
345 while(*p != '\0' && *p != '/') {
346 if(*p == ')') {
347 set_paren = 1;
348 pi_end = p;
349 p++;
350 break;
351 }
352 if(!set_comm && *p == ',') {
353 set_comm = 1;
354 pr_end = p;
355 pi_beg = p+1;
356 }
357 else if(*p == ',') {
358 *stat |= TOO_MANY_COMMA;
359 }
360 p++;
361 }
362 if(!set_comm) *stat |= NO_COMMA;
363 if(!set_paren) {
364 *stat |= NO_TRAIL_PAREN;
365 pi_end = p;
366 pi_end--;
367 while(isspace((int)*pi_end))pi_end--;
368 pi_end++;
369 }
370
371 nchar = pi_end - card ;
372 strncpy(kvalue,card,nchar);
373 *(kvalue+nchar) = '\0';
374 while(isspace((int)*p)&& *p != '\0') p++;
375 *pt = *pt + (p - card);
376
377 /* analyse the real and imagine part */
378 *pr_end = '\0';
379 *pi_end = '\0';
380 while(isspace((int)*pr_beg) && *pr_beg != '\0') pr_beg++;
381 while(isspace((int)*pi_beg) && *pi_beg != '\0') pi_beg++;
382 temp[0] = '\0';
383 pp = &pr_beg;
384 get_num(pp, temp, &rtype, &tr);
385 if(tr)*stat |= BAD_REAL;
386 temp[0] = '\0';
387 pp = &pi_beg;
388 get_num(pp, temp, &itype, &ti);
389 if(ti)*stat |= BAD_IMG;
390 if(rtype == FLT_KEY || itype == FLT_KEY) *ktype = CMF_KEY;
391 return;
392 }
393
394 /* parse and test the comment keys */
get_comm(char ** pt,char * kcomm,unsigned long * stat)395 void get_comm(char **pt, /* card string */
396 char *kcomm, /* comment string */
397 unsigned long *stat /* error number */
398 )
399 {
400 char *pi;
401 int nchar = 0;
402 char *p;
403
404 p = *pt;
405 pi = p;
406 if(*p != '/') {
407 *stat |= NO_START_SLASH;
408 }
409 p++;
410 while(*p != '\0') {
411 if(!isprint((int)*p) ) *stat |= BAD_COMMENT;
412 p++;
413 }
414 nchar = p - pi;
415 strncpy(kcomm,pi,nchar);
416 *(kcomm+nchar) = '\0';
417 return;
418 }
419
420 /* parsing the unknown keyword */
get_unknown(char ** pt,char * kvalue,kwdtyp * ktype,unsigned long * stat)421 void get_unknown(char **pt, /* card string */
422 char *kvalue, /* comment string */
423 kwdtyp *ktype,
424 unsigned long *stat /* error number */
425 )
426 {
427 char *p;
428 char *p1;
429 char temp[FLEN_CARD];
430
431 p = *pt;
432 strcpy(temp,*pt);
433 p1 = temp;
434 while(*p != '\0' && *p != '/') { p++; p1++;}
435 *p1 = '\0';
436 p1 = temp;
437 *pt = p;
438
439 strcpy(kvalue, p1);
440 *ktype = UNKNOWN;
441 *stat |= UNKNOWN_TYPE;
442 return ;
443 }
444 /* routine to print out the error of keyword value/comment */
pr_kval_err(FILE * out,int kpos,char * kname,char * kval,unsigned long errnum)445 void pr_kval_err(FILE *out, /* output FILE */
446 int kpos, /* keyposition starting from 1 */
447 char *kname, /* keyword name */
448 char *kval, /* keyword value */
449 unsigned long errnum /* error number */
450 )
451 {
452 if(errnum == 0) return;
453 if(errnum & BAD_STR) {
454 sprintf(errmes,
455 "Keyword #%d, %s: String \"%s\" contains non-text characters.",
456 kpos,kname,kval);
457 wrterr(out,errmes,1);
458 }
459 if(errnum & NO_TRAIL_QUOTE) {
460 sprintf(errmes,
461 "Keyword #%d, %s: The closing \"\'\" is missing in the string." ,
462 kpos,kname);
463 wrterr(out,errmes,1);
464 }
465 if(errnum & BAD_LOGICAL) {
466 sprintf(errmes,"Keyword #%d, %s: Bad logical value \"%s\".",
467 kpos,kname,kval);
468 wrterr(out,errmes,1);
469 }
470 if(errnum & BAD_NUM) {
471 sprintf(errmes,"Keyword #%d, %s: Bad numerical value \"%s\".",
472 kpos,kname,kval);
473 wrterr(out,errmes,1);
474 }
475 if(errnum & LOWCASE_EXPO) {
476 sprintf(errmes,
477 "Keyword #%d, %s: lower-case exponent d or e is illegal in value %s.",
478 kpos,kname,kval);
479 wrterr(out,errmes,1);
480 }
481 if(errnum & NO_TRAIL_PAREN) {
482 sprintf(errmes,
483 "Keyword #%d, %s: Complex value \"%s\" misses closing \")\".",
484 kpos,kname, kval);
485 wrterr(out,errmes,1);
486 }
487 if(errnum & NO_COMMA) {
488 sprintf(errmes,
489 "keyword #%d, %s : Complex value \"%s\" misses \",\".",
490 kpos,kname,kval);
491 wrterr(out,errmes,1);
492 }
493 if(errnum & TOO_MANY_COMMA) {
494 sprintf(errmes,
495 "Keyword #%d, %s: Too many \",\" are in the complex value \"%s\".",
496 kpos,kname,kval);
497 wrterr(out,errmes,1);
498 }
499 if(errnum & BAD_REAL) {
500 sprintf(errmes,
501 "Keyword #%d, %s: Real part of complex value \"%s\" is bad.",
502 kpos,kname,kval);
503 wrterr(out,errmes,1);
504 }
505 if(errnum & BAD_IMG) {
506 sprintf(errmes,
507 "Keyword #%d, %s: Imagine part of complex value \"%s\" is bad.",
508 kpos,kname,kval);
509 wrterr(out,errmes,1);
510 }
511 if(errnum & NO_START_SLASH) {
512 sprintf(errmes,
513 "Keyword #%d, %s: Value and Comment not separated by a \"/\".",
514 kpos,kname);
515 wrterr(out,errmes,1);
516 }
517 if(errnum & BAD_COMMENT) {
518 sprintf(errmes,
519 "Keyword #%d, %s: Comment contains non-text characters.",
520 kpos,kname);
521 wrterr(out,errmes,1);
522 }
523
524 if(errnum & UNKNOWN_TYPE) {
525 if (*kval != 0) { /* don't report null keywords as an error */
526 sprintf(errmes,
527 "Keyword #%d, %s: Type of value \"%s\" is unknown.",
528 kpos,kname,kval);
529 wrterr(out,errmes,1);
530 }
531 }
532 return ;
533 }
534
check_str(FitsKey * pkey,FILE * out)535 int check_str(FitsKey* pkey, FILE *out)
536 {
537 if(pkey->ktype == UNKNOWN && *(pkey->kvalue) == 0) {
538 sprintf(errmes,"Keyword #%d, %s has a null value; expected a string.",
539 pkey->kindex,pkey->kname);
540 wrterr(out,errmes,1);
541 return 0;
542 } else if(pkey->ktype != STR_KEY) {
543 sprintf(errmes,"Keyword #%d, %s: \"%s\" is not a string.",
544 pkey->kindex,pkey->kname, pkey->kvalue);
545 wrterr(out,errmes,1);
546 return 0;
547 }
548 return 1;
549 }
550
check_int(FitsKey * pkey,FILE * out)551 int check_int(FitsKey* pkey, FILE *out)
552 {
553 if(pkey->ktype == UNKNOWN && *(pkey->kvalue) == 0) {
554 sprintf(errmes,"Keyword #%d, %s has a null value; expected an integer.",
555 pkey->kindex,pkey->kname);
556 wrterr(out,errmes,1);
557 return 0;
558 } else if(pkey->ktype != INT_KEY) {
559 sprintf(errmes,"Keyword #%d, %s: value = %s is not an integer.",
560 pkey->kindex,pkey->kname, pkey->kvalue);
561 if(pkey->ktype == STR_KEY)
562 strcat(errmes," The value is entered as a string. ");
563 wrterr(out,errmes,1);
564 return 0;
565 }
566 return 1;
567 }
check_flt(FitsKey * pkey,FILE * out)568 int check_flt(FitsKey* pkey, FILE *out)
569 {
570 if(pkey->ktype == UNKNOWN && *(pkey->kvalue) == 0) {
571 sprintf(errmes,"Keyword #%d, %s has a null value; expected a float.",
572 pkey->kindex,pkey->kname);
573 wrterr(out,errmes,1);
574 return 0;
575 } else if(pkey->ktype != INT_KEY && pkey->ktype != FLT_KEY) {
576 sprintf(errmes,
577 "Keyword #%d, %s: value = %s is not a floating point number.",
578 pkey->kindex,pkey->kname, pkey->kvalue);
579 if(pkey->ktype == STR_KEY)
580 strcat(errmes," The value is entered as a string. ");
581 wrterr(out,errmes,1);
582 return 0;
583 }
584 return 1;
585 }
586
check_cmi(FitsKey * pkey,FILE * out)587 int check_cmi(FitsKey* pkey, FILE *out)
588 {
589 if(pkey->ktype != CMI_KEY ) {
590 sprintf(errmes,
591 "Keyword #%d, %s: value = %s is not a integer complex number.",
592 pkey->kindex,pkey->kname, pkey->kvalue);
593 if(pkey->ktype == STR_KEY)
594 strcat(errmes," The value is entered as a string. ");
595 wrterr(out,errmes,1);
596 return 0;
597 }
598 return 1;
599 }
600
check_cmf(FitsKey * pkey,FILE * out)601 int check_cmf(FitsKey* pkey, FILE *out)
602 {
603 if(pkey->ktype != CMI_KEY && pkey->ktype != CMF_KEY) {
604 sprintf(errmes,
605 "Keyword #%d, %s: value = %s is not a floating point complex number.",
606 pkey->kindex,pkey->kname, pkey->kvalue);
607 if(pkey->ktype == STR_KEY)
608 strcat(errmes," The value is entered as a string. ");
609 wrterr(out,errmes,1);
610 return 0;
611 }
612 return 1;
613 }
check_log(FitsKey * pkey,FILE * out)614 int check_log(FitsKey* pkey, FILE *out)
615 {
616 if(pkey->ktype != LOG_KEY ) {
617 sprintf(errmes,
618 "Keyword #%d, %s: value = %s is not a logical constant.",
619 pkey->kindex,pkey->kname, pkey->kvalue);
620 if(pkey->ktype == STR_KEY)
621 strcat(errmes," The value is entered as a string. ");
622 wrterr(out,errmes,1);
623 return 0;
624 }
625 return 1;
626 }
check_fixed_int(char * card,FILE * out)627 int check_fixed_int(char* card, FILE *out)
628 {
629 char *cptr;
630
631 /* fixed format integer must be right justified in columns 11-30 */
632
633 cptr = &card[10];
634
635 while (*cptr == ' ')cptr++; /* skip leading spaces */
636
637 if (*cptr == '-')
638 cptr++; /* skip leading minus sign */
639 else if (*cptr == '+')
640 cptr++; /* skip leading plus sign */
641
642 while (isdigit((int) *cptr))cptr++; /* skip digits */
643
644 /* should be pointing to column 31 of the card */
645
646 if ((cptr - card) != 30) {
647 sprintf(errmes,
648 "%.8s mandatory keyword is not in integer fixed format:",
649 card);
650 wrterr(out,errmes,1);
651 print_fmt(out,card,13);
652 print_fmt(out," -------------------^",13);
653
654 return 0;
655 }
656 return 1;
657 }
check_fixed_log(char * card,FILE * out)658 int check_fixed_log(char* card, FILE *out)
659 {
660 char *cptr;
661
662 /* fixed format logical must have T or F in column 30 */
663
664 cptr = &card[10];
665
666 while (*cptr == ' ')cptr++; /* skip leading spaces */
667
668 if (*cptr != 'T' && *cptr != 'F') {
669 sprintf(errmes,
670 "%.8s mandatory keyword does not have T or F logical value.",
671 card);
672 wrterr(out,errmes,1);
673 return 0;
674 }
675
676 /* should be pointing to column 31 of the card */
677
678 if ((cptr - card) != 29) {
679 sprintf(errmes,
680 "%.8s mandatory keyword is not in logical fixed format:",
681 card);
682 wrterr(out,errmes,1);
683 print_fmt(out,card,13);
684 print_fmt(out," -------------------^",13);
685
686 return 0;
687 }
688 return 1;
689 }
check_fixed_str(char * card,FILE * out)690 int check_fixed_str(char* card, FILE *out)
691 {
692 char *cptr;
693
694 /* fixed format string must have quotes in columns 11 and >= 20 */
695 /* This only applys to the XTENSION and TFORMn keywords. */
696
697 cptr = &card[10];
698
699 if (*cptr != '\'' ) {
700 sprintf(errmes,
701 "%.8s mandatory string keyword does not start in col 11.",
702 card);
703 wrterr(out,errmes,1);
704 print_fmt(out,card,13);
705 print_fmt(out," ^--------^",13);
706 return 0;
707 }
708
709 cptr++;
710
711 while (*cptr != '\'') {
712
713 if (*cptr == '\0') {
714 sprintf(errmes,
715 "%.8s mandatory string keyword missing closing quote character:",
716 card);
717 wrterr(out,errmes,1);
718 print_fmt(out,card,13);
719 return 0;
720 }
721 cptr++;
722 }
723
724 if ((cptr - card) < 19) {
725 sprintf(errmes,
726 "%.8s mandatory string keyword ends before column 20.",
727 card);
728 wrterr(out,errmes,1);
729 print_fmt(out,card,13);
730 print_fmt(out," ^--------^",13);
731
732 return 0;
733 }
734
735 return 1;
736 }
737