| 64 | 
  | 
                        "SOFTWARE", | 
| 65 | 
  | 
                        "CAPDATE", | 
| 66 | 
  | 
                        "GMT", | 
| 67 | 
+ | 
                        "FRAME", | 
| 68 | 
  | 
                        NULL    /* terminator */ | 
| 69 | 
  | 
                }; | 
| 70 | 
  | 
                                /* header variable settings */ | 
| 75 | 
  | 
#define adv_linecnt(htp)        (lin1cnt += (htp == &hdr1), \ | 
| 76 | 
  | 
                                        lin2cnt += (htp == &hdr2)) | 
| 77 | 
  | 
 | 
| 78 | 
+ | 
typedef struct {                /* dynamic line buffer */ | 
| 79 | 
+ | 
        char    *str; | 
| 80 | 
+ | 
        int     len; | 
| 81 | 
+ | 
        int     siz; | 
| 82 | 
+ | 
} LINEBUF; | 
| 83 | 
+ | 
 | 
| 84 | 
+ | 
#define init_line(bp)   ((bp)->str = NULL, (bp)->siz = 0) | 
| 85 | 
+ | 
                                /* 100 MByte limit on line buffer */ | 
| 86 | 
+ | 
#define MAXBUF          (100L<<20) | 
| 87 | 
+ | 
 | 
| 88 | 
  | 
                                /* input files */ | 
| 89 | 
  | 
char            *progname = NULL; | 
| 90 | 
  | 
const char      stdin_name[] = "<stdin>"; | 
| 106 | 
  | 
        exit(2); | 
| 107 | 
  | 
} | 
| 108 | 
  | 
 | 
| 109 | 
+ | 
/* Read a text line, increasing buffer size as necessary */ | 
| 110 | 
+ | 
static int | 
| 111 | 
+ | 
read_line(LINEBUF *bp, FILE *fp) | 
| 112 | 
+ | 
{ | 
| 113 | 
+ | 
        static int      doneWarn = 0; | 
| 114 | 
+ | 
 | 
| 115 | 
+ | 
        bp->len = 0; | 
| 116 | 
+ | 
        if (!bp->str) { | 
| 117 | 
+ | 
                bp->str = (char *)malloc(bp->siz = 512); | 
| 118 | 
+ | 
                if (!bp->str) | 
| 119 | 
+ | 
                        goto memerr; | 
| 120 | 
+ | 
        } | 
| 121 | 
+ | 
        while (fgets(bp->str + bp->len, bp->siz - bp->len, fp)) { | 
| 122 | 
+ | 
                bp->len += strlen(bp->str + bp->len); | 
| 123 | 
+ | 
                if (bp->str[bp->len-1] == '\n') | 
| 124 | 
+ | 
                        break;          /* found EOL */ | 
| 125 | 
+ | 
                if (bp->len < bp->siz - 4) | 
| 126 | 
+ | 
                        continue;       /* at EOF? */ | 
| 127 | 
+ | 
                if (bp->siz >= MAXBUF) { | 
| 128 | 
+ | 
                        if ((report >= REP_WARN) & !doneWarn) { | 
| 129 | 
+ | 
                                fprintf(stderr, | 
| 130 | 
+ | 
                        "%s: warning - input line(s) past %ld MByte limit\n", | 
| 131 | 
+ | 
                                        progname, MAXBUF>>20); | 
| 132 | 
+ | 
                                doneWarn++; | 
| 133 | 
+ | 
                        } | 
| 134 | 
+ | 
                        break;          /* return MAXBUF partial line */ | 
| 135 | 
+ | 
                } | 
| 136 | 
+ | 
                if ((bp->siz += bp->siz/2) > MAXBUF) | 
| 137 | 
+ | 
                        bp->siz = MAXBUF; | 
| 138 | 
+ | 
                bp->str = (char *)realloc(bp->str, bp->siz); | 
| 139 | 
+ | 
                if (!bp->str) | 
| 140 | 
+ | 
                        goto memerr; | 
| 141 | 
+ | 
        } | 
| 142 | 
+ | 
        return(bp->len); | 
| 143 | 
+ | 
memerr: | 
| 144 | 
+ | 
        fprintf(stderr, | 
| 145 | 
+ | 
                "%s: out of memory in read_line() allocating %d byte buffer\n", | 
| 146 | 
+ | 
                        progname, bp->siz); | 
| 147 | 
+ | 
        exit(2); | 
| 148 | 
+ | 
} | 
| 149 | 
+ | 
 | 
| 150 | 
+ | 
/* Free line buffer */ | 
| 151 | 
+ | 
static void | 
| 152 | 
+ | 
free_line(LINEBUF *bp) | 
| 153 | 
+ | 
{ | 
| 154 | 
+ | 
        if (bp->str) free(bp->str); | 
| 155 | 
+ | 
        init_line(bp); | 
| 156 | 
+ | 
} | 
| 157 | 
+ | 
 | 
| 158 | 
  | 
/* Get type ID from name (or 0 if not found) */ | 
| 159 | 
  | 
static int | 
| 160 | 
  | 
xlate_type(const char *nm) | 
| 200 | 
  | 
{ | 
| 201 | 
  | 
        int     p; | 
| 202 | 
  | 
 | 
| 203 | 
< | 
        if (!real_check(colval(c1,RED)+colval(c1,GRN)+colval(c1,BLU)*(1./3.), | 
| 204 | 
< | 
                        colval(c2,RED)+colval(c2,GRN)+colval(c2,BLU))*(1./3.)) | 
| 203 | 
> | 
        if (!real_check((colval(c1,RED)+colval(c1,GRN)+colval(c1,BLU))*(1./3.), | 
| 204 | 
> | 
                        (colval(c2,RED)+colval(c2,GRN)+colval(c2,BLU))*(1./3.))) | 
| 205 | 
  | 
                return(0); | 
| 206 | 
  | 
 | 
| 207 | 
  | 
        p = (colval(c1,GRN) > colval(c1,RED)) ? GRN : RED; | 
| 505 | 
  | 
static int | 
| 506 | 
  | 
compare_text() | 
| 507 | 
  | 
{ | 
| 508 | 
< | 
        char    l1buf[4096], l2buf[4096]; | 
| 508 | 
> | 
        LINEBUF l1buf, l2buf; | 
| 509 | 
  | 
 | 
| 510 | 
  | 
        if (report >= REP_VERBOSE) { | 
| 511 | 
  | 
                fputs(progname, stdout); | 
| 512 | 
  | 
                fputs(": comparing inputs as ASCII text\n", stdout); | 
| 513 | 
  | 
        } | 
| 514 | 
< | 
                                                /* compare a line at a time */ | 
| 515 | 
< | 
        while (fgets(l1buf, sizeof(l1buf), f1in)) { | 
| 514 | 
> | 
        init_line(&l1buf); init_line(&l2buf);   /* compare a line at a time */ | 
| 515 | 
> | 
        while (read_line(&l1buf, f1in)) { | 
| 516 | 
  | 
                lin1cnt++; | 
| 517 | 
< | 
                if (!*sskip2(l1buf,0)) | 
| 517 | 
> | 
                if (!*sskip2(l1buf.str,0)) | 
| 518 | 
  | 
                        continue;               /* ignore empty lines */ | 
| 519 | 
< | 
                while (fgets(l2buf, sizeof(l2buf), f2in)) { | 
| 519 | 
> | 
 | 
| 520 | 
> | 
                while (read_line(&l2buf, f2in)) { | 
| 521 | 
  | 
                        lin2cnt++; | 
| 522 | 
< | 
                        if (*sskip2(l2buf,0)) | 
| 522 | 
> | 
                        if (*sskip2(l2buf.str,0)) | 
| 523 | 
  | 
                                break;          /* found other non-empty line */ | 
| 524 | 
  | 
                } | 
| 525 | 
< | 
                if (feof(f2in)) { | 
| 525 | 
> | 
                if (!l2buf.len) {               /* input 2 EOF? */ | 
| 526 | 
  | 
                        if (report != REP_QUIET) { | 
| 527 | 
  | 
                                fputs(f2name, stdout); | 
| 528 | 
  | 
                                fputs(": unexpected end-of-file\n", stdout); | 
| 529 | 
  | 
                        } | 
| 530 | 
+ | 
                        free_line(&l1buf); free_line(&l2buf); | 
| 531 | 
  | 
                        return(0); | 
| 532 | 
  | 
                } | 
| 533 | 
  | 
                                                /* compare non-empty lines */ | 
| 534 | 
< | 
                if (!equiv_string(l1buf, l2buf)) { | 
| 534 | 
> | 
                if (!equiv_string(l1buf.str, l2buf.str)) { | 
| 535 | 
  | 
                        if (report != REP_QUIET) { | 
| 536 | 
  | 
                                printf("%s: inputs '%s' and '%s' differ at line %d|%d\n", | 
| 537 | 
  | 
                                                progname, f1name, f2name, | 
| 538 | 
  | 
                                                lin1cnt, lin2cnt); | 
| 539 | 
< | 
                                if (report >= REP_VERBOSE) { | 
| 539 | 
> | 
                                if ( report >= REP_VERBOSE && | 
| 540 | 
> | 
                                                (l1buf.len < 256) & | 
| 541 | 
> | 
                                                (l2buf.len < 256) ) { | 
| 542 | 
  | 
                                        fputs("------------- Mismatch -------------\n", stdout); | 
| 543 | 
  | 
                                        printf("%s@%d:\t%s", f1name, | 
| 544 | 
< | 
                                                        lin1cnt, l1buf); | 
| 544 | 
> | 
                                                        lin1cnt, l1buf.str); | 
| 545 | 
  | 
                                        printf("%s@%d:\t%s", f2name, | 
| 546 | 
< | 
                                                        lin2cnt, l2buf); | 
| 546 | 
> | 
                                                        lin2cnt, l2buf.str); | 
| 547 | 
  | 
                                } | 
| 548 | 
  | 
                        } | 
| 549 | 
+ | 
                        free_line(&l1buf); free_line(&l2buf); | 
| 550 | 
  | 
                        return(0); | 
| 551 | 
  | 
                } | 
| 552 | 
  | 
        } | 
| 553 | 
< | 
                                                /* check for EOF on input 2 */ | 
| 554 | 
< | 
        while (fgets(l2buf, sizeof(l2buf), f2in)) { | 
| 555 | 
< | 
                if (!*sskip2(l2buf,0)) | 
| 553 | 
> | 
        free_line(&l1buf);                      /* check for EOF on input 2 */ | 
| 554 | 
> | 
        while (read_line(&l2buf, f2in)) { | 
| 555 | 
> | 
                if (!*sskip2(l2buf.str,0)) | 
| 556 | 
  | 
                        continue; | 
| 557 | 
  | 
                if (report != REP_QUIET) { | 
| 558 | 
  | 
                        fputs(f1name, stdout); | 
| 559 | 
  | 
                        fputs(": unexpected end-of-file\n", stdout); | 
| 560 | 
  | 
                } | 
| 561 | 
+ | 
                free_line(&l2buf); | 
| 562 | 
  | 
                return(0); | 
| 563 | 
  | 
        } | 
| 564 | 
+ | 
        free_line(&l2buf); | 
| 565 | 
  | 
        return(good_RMS());                     /* final check for reals */ | 
| 566 | 
  | 
} | 
| 567 | 
  | 
 | 
| 778 | 
  | 
        ign_header |= !has_header(typ1);        /* check headers if indicated */ | 
| 779 | 
  | 
        if (!ign_header && !headers_match()) | 
| 780 | 
  | 
                return(1); | 
| 781 | 
< | 
        lu_done(&hdr1); lu_done(&hdr2); | 
| 781 | 
> | 
        lu_done(&hdr1); lu_done(&hdr2);         /* done with header info. */ | 
| 782 | 
  | 
        if (!ign_header & (report >= REP_WARN)) { | 
| 716 | 
– | 
                if (typ1 == TYP_UNKNOWN) | 
| 717 | 
– | 
                        printf("%s: warning - unrecognized format, comparing as binary\n", | 
| 718 | 
– | 
                                        progname); | 
| 783 | 
  | 
                if (lin1cnt != lin2cnt) | 
| 784 | 
  | 
                        printf("%s: warning - headers are different lengths\n", | 
| 785 | 
+ | 
                                        progname); | 
| 786 | 
+ | 
                if (typ1 == TYP_UNKNOWN) | 
| 787 | 
+ | 
                        printf("%s: warning - unrecognized format\n", | 
| 788 | 
  | 
                                        progname); | 
| 789 | 
  | 
        } | 
| 790 | 
  | 
        if (report >= REP_VERBOSE) |