# to unbundle, sh this file (in an empty directory) echo Makefile 1>&2 sed >Makefile <<'//GO.SYSIN DD Makefile' 's/^-//' -.SUFFIXES: .c .o -# unused ascii characters are : and \ . -# fc and fe are (test) programs for compressing and expanding numbers. -# emps.c is a stand-alone program that must be requested separately. -CFLAGS = -O -e = emps.c -fc = fc.o nc.o ne.o trtab.o -fe = fe.o ne.o trtab.o -m = mpc.o nc.o ne.o trtab.o -l = mpc.c nc.c ne.c trtab.c -.c.o: - cc -c $(CFLAGS) $*.c -mpc: $m - cc -o mpc $(CFLAGS) $m -emps: $e - cc -o emps $(CFLAGS) $e -fc: $(fc) - cc $(CFLAGS) -o fc $(fc) -fe: $(fe) - cc $(CFLAGS) -o fe $(fe) -lint: $l - lint $l //GO.SYSIN DD Makefile echo mpc.c 1>&2 sed >mpc.c <<'//GO.SYSIN DD mpc.c' 's/^-//' -/* Convert LP problems from MPS format to the compressed format - * used in the netlib suite of LP problems. - * - * Option -m allows extensions (called "mystery lines") to MPS format. - * Option -? explains usage. Several LP problems may be compressed - * at once. - * - * Written at AT&T Bell Laboratories by David M. Gay to facilitate - * transmitting LP test problems over netlib. Last changed 2 June 1987. - * Please retain this note. - * - * When doing so saves space, floating-point numbers are encoded in - * supersparse format. This program does no rounding (and no floating- - * point computation), so LP problems should be faithfully reproduced. - * Comments in nc.c explain the compressed format for numbers. (The - * compression scheme is ad hoc and carries no claim of optimality. It - * uses only blanks and printing ASCII characters and excludes : and \ , - * as these may cause trouble with some mailers. The initial blank line - * in the compressed format is another attempt to keep certain mailiers - * from interpretting LP data as header information. - * - * Long ints are assumed to have at least 31 bits. - */ - -#define HGULP ((1<<14) - 16) -#define SGULP ((1<<16) - 16) -#include -#include -#include -#include -#include - -struct hrec { - struct hrec *next; - char *v, *tv; - } *hfirst, *hnext, *hlast; - -struct htab { - int canadd, n, nb, nh; - struct hrec **h; - char *null, *what; - } ct, rt, zt; - -extern char *ic(), *nc(); - -char *infile, *progname, **sf, *snext, *slast; -char chkbuf[72], *cs, *cse = chkbuf + 71; -int badrows, checksum = 1, chksum, keepzeros, lenchk = 1, oversized = 1; -int lastc, lastll, line, pass, verbose = 0; -int Mecho, Mecho0, mystcnt, mystkeep, mystkp1, negobj, seekright; -char *badcols; -char curline[84]; -FILE *inf; - -void process(FILE*); - - void -squawk0(const char *fmt, va_list ap) -{ - fprintf(stderr, "%s: ", progname); - vfprintf(stderr, fmt, ap); - if (infile) - fprintf(stderr, - " [line %d of %s (near byte %ld)]\n", line, infile, - (long)(ftell(inf)-lastll)); - else - fprintf(stderr, "\n"); - } - - void -squawk(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - squawk0(fmt, ap); - va_end(ap); - } - - void -scream(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - squawk0(fmt, ap); - va_end(ap); - exit(1); - } - - void -usage(int rc) -{ - char **o; - static char *options[] = { - "C {list undefined cols as seen}", - "M {echo mystery lines on stderr}", - "R {list undefined rows as seen}", - "c# {size of col-name hash table}", - "l {no msg for wide numbers}", - "m {include mystery lines, preceded by :, in stdout}", - "n {negate objective row (if unique)}", - "o {no msg for oversized fields}", - "q {quietly ignore mystery lines}", - "r# {size of row-name hash table}", - "s {omit check sums}", - "v {verbose}", - "z# {size of nonzeros hash table}", - "0 {retain explicit zeros}", - 0}; - - fprintf(stderr, "usage: %s [options] [file1 [file2...]]\nOptions...\n", - progname); - for(o = options; *o; o++) - fprintf(stderr, "\t-%s\n", *o); - exit(rc); - } - - int -main(int argc, char **argv) -{ - char c, *s; - - *curline = ':'; - ct.nh = rt.nh = 2047; - zt.nh = 4095; - ct.null = "col"; - rt.null = "row"; - zt.what = zt.null = "number"; - progname = *argv; - while(s = *++argv) { - if (*s == '-') while(c = *++s) switch(c) { - case 0: - infile = "(stdin)"; - process(stdin); - break; - case 'C': - badcols = "bound on unknown col"; - break; - case 'M': - Mecho0 = seekright = 1; - break; - case 'R': - badrows = 1; - break; - case 'c': - ct.nh = atoi(s+1); - if (ct.nh <= 0) scream("invalid option %s",s); - continue; - case 'l': - lenchk = 0; - break; - case 'm': - mystkp1 = seekright = 1; - break; - case 'n': - negobj = 1; - break; - case 'o': - oversized = 0; - break; - case 'q': - seekright = 1; - break; - case 'r': - rt.nh = atoi(s+1); - if (rt.nh <= 0) scream("invalid option %s",s); - continue; - case 's': - checksum = 0; - break; - case 'v': - verbose = 1; - break; - case 'z': - zt.nh = atoi(s+1); - if (zt.nh <= 0) scream("invalid option %s",s); - continue; - case '0': - keepzeros = 1; - break; - case '?': - usage(0); - default: - fprintf(stderr, - "%s: invalid option %s\n", - progname, s); - usage(1); - } - else { - infile = s; - if (!(inf = fopen(infile, "r"))) - scream("can't open %s",s); - process(inf); - } - } - if (!inf) { - infile = "(stdin)"; - process(stdin); - } - return 0; - } - - char * -m0(int n, const char *who) -{ - char *s; - s = (char*)malloc((size_t)n); - if (!s) - scream("malloc(%d) for %s failed", n, who); - return s; - } - - char * -salloc(char *s) -{ - int n; - char *r, **sp; - - n = strlen(s) + 1; - if (snext + n > slast) { - sp = sf; - sf = (char **)m0(SGULP, "salloc"); - *sf = (char *)sp; - snext = (char *)(sf+1); - slast = ((char *)sf) + SGULP; - } - r = snext; - snext += n; - return strcpy(r, s); - } - - struct hrec * -h0(void) -{ - struct hrec *hp; - - if (hnext >= hlast) { - hp = hfirst; - hfirst = (struct hrec *)m0(HGULP*sizeof(struct hrec), "h0"); - hfirst->next = hp; - hnext = hfirst + 1; - hlast = hfirst + HGULP; - } - return hnext++; - } - -#define Free(x) free((char *)x) - - void -freeall(void) -{ - char **s, **sp; - struct hrec *h, *hp; - - for(sp = sf; s = sp;) { sp = (char **)*s; free((char *)s); } - snext = slast = 0; - sf = 0; - for(hp = hfirst; h = hp;) { hp = h->next; free((char *)h); } - hnext = hlast = 0; - hfirst = 0; - Free(ct.h); - Free(rt.h); - Free(zt.h); - } - - void -htinit(struct htab *ht, int inc) -{ - struct hrec **h, **he; - - ht->n = ht->nb = 0; - ht->canadd = inc; - ht->h = h = (struct hrec **)m0(ht->nh*sizeof(struct hrec *), "htinit"); - he = h + ht->nh; - while(h < he) *h++ = 0; - } - - struct hrec * -hash(struct htab *ht, char *s) -{ - unsigned long x = 0; - /* You can remove the above "unsigned" if below you also change */ - /* "0x80000000" to "0x40000000", but this will change the order */ - /* of things in the hash tables. The resulting compressed files*/ - /* will have the same size, but cmp will find them different. */ - struct hrec *p, *r; - unsigned int c; - char buf[32], *s0 = s; - extern char *ne(); - int ca = ht->canadd; - - if (!(c = *s)) { - if (ca > 0) - squawk("null %s name", ht->null); - return 0; - } - do { - if (x & 1) x = (x>>1) + c + 0x80000000; - else x = (x>>1) + c; - } while(c = *++s); - p = (struct hrec *) &ht->h[x % ht->nh]; - while(r = p->next) { - if (!strcmp(s0,r->v)) { - if (ca >= 2) r->tv++; - return r; - } - p = r; - } - if (ca <= 0) { - if (ht->what) squawk("%s `%s'", ht->what, s0); - ht->nb++; - return 0; - } - p->next = r = h0(); - r->next = 0; - r->tv = 0; - r->v = salloc(s0); - ht->n++; - if (ca == 3 && strlen( (ne(buf,s0), buf) ) > 12) - squawk("number > 12 cols: %s", buf); - return r; - } - -extern char trtab[]; - - void -Flush() -{ - if (lastc) { - putc('\n', stdout); - lastc = 0; - if (checksum) { - *cs++ = trtab[chksum%92]; - chksum = 0; - if (cs >= cse) - printf(" %s\n", cs = chkbuf); - } - } - } - - void -cout(const char *s) -{ - int c, n; - static char invtrtab[256]; - char *tr = invtrtab; - - if (!tr['1']) { - for(n = 0; n < sizeof(invtrtab); n++) tr[n] = 92; - for(n = 0; trtab[n]; n++) tr[trtab[n]] = n; - } - - n = strlen(s); - if (lastc + n > 72) Flush(); - printf("%s", s); - lastc += n; - if (checksum) { - for(c = chksum; n; n--) { - if (c & 1) c = (c>>1) + tr[*s++] + 16384; - else c = (c>>1) + tr[*s++]; - } - chksum = c; - } - } - - int -nzcomp(const void *a, const void *b) -{ - const struct hrec *ap, *bp; - ap = *(const struct hrec **)a; - bp = *(const struct hrec **)b; - return bp->tv - ap->tv; - } - - void -nzsort(void) -{ - unsigned int n = zt.n; - struct hrec **a, **ae, **h, **he, *p; - struct hrec **a0; - char buf[32], *s; - int slen; - unsigned int n0; - - for(h = zt.h, he = h + zt.nh; h < he; h++) - for(p = *h; p; p = p->next) - if (!p->tv) - --n; - - n0 = n; - if (n) { - a = a0 = (struct hrec **) - m0((int)n*sizeof(struct hrec *), "nzsort"); - ae = a + n; - for(h = zt.h; h < he; h++) - for(p = *h; p; p = p->next) - if (p->tv) *a++ = p; - qsort(a0, n, sizeof(struct hrec *), nzcomp); - s = salloc(ic((n = 1), buf)); - slen = strlen(s); - for(a = a0; a < ae; a++) { - p = *a; - if (strlen(p->v) > slen) { - p->tv = s; - s = salloc(ic(++n, buf)); - slen = strlen(s); - } - else p->tv = p->v; - } - printf(" %8u\n", --n); - if (verbose) { - fprintf(stderr, "%u repeated nonzeros", n0); - fprintf(stderr, n == n0 ? ".\n" : - ", %u made supersparse.\n", n); - } - for(a = a0; a < ae; a++) { - p = *a; - if (p->tv != p->v) cout(p->v); - } - free((char *)a0); - Flush(); - } - else printf(" %8d\n", 0); - for(h = zt.h; h < he; h++) - for(p = *h; p; p = p->next) - if (!p->tv) p->tv = p->v; - } - -struct inrec { - char sec[3], - fill1[1], - cname[8], - fill2[2], - rname1[8], - fill1a, - rval1[17], - fill1b, - rname2[8], - fill1c, - rval2[17], - fill9[9]; - } *Ip; - - int -nl(struct inrec *ir, FILE *f, int *fb) -{ - char *buf = (char *)ir, *s; - int b, c, i, j; - -top: - s = curline; - line++; - b = *fb; - for(i = j = 0; i < sizeof(struct inrec) - 1; i++) { - c = getc(f); - if (c == '\n') { - lastll = i; - if (!i || *buf == '*') goto top; - goto eol; - } - if (c == EOF) { -eof: - lastll = i; - scream("premature end of file"); - } - buf[i] = *++s = c; - if (i == b) { i++; j++; b = *++fb; } - } - do { - c = getc(f); - if (c == EOF) goto eof; - } while(c != '\n'); -eol: - buf[i] = *++s = 0; - return i - j; - } - -int *fbp; -FILE *fp; - - void -chk(char *s, const char *t) -{ - char *s0; - const char *t0; - - for(;;) { - for(s0 = s, t0 = t; *t && *s == *t; s++, t++); - if (!*t) return; - if (!seekright) scream("expected `%s', got `%s'", t0, s0); - mystcnt++; - if (Mecho) fprintf(stderr, "%s\n", curline); - if (mystkeep) { Flush(); cout(curline); Flush(); } - nl(Ip, fp, fbp); - s = Ip->sec; - t = t0; - } - } - - char * -trim(char *s, int n) -{ - char *t; - int check = 0; - - if (n < 0) - check = n = -n; - s[n] = 0; - for(t = s; ; t++) - if (!*t) - break; - while(--t >= s && *t == ' '); - t[1] = 0; - if (check && oversized - && (*s != ' ' || s[1] != ' ' || t - s + 3 >= check)) - squawk("oversized field `%s'", s); - return s; - } - - char * -negate(char *s) -{ - char *t; - - negobj++; - for(t = s; *t == ' '; t++); - if (*t == '-') return t+1; - *--s = '-'; - return s; - } - -#define cHash(x) hash(&ct,trim(x,sizeof(x))) -#define rHash(x) hash(&rt,trim(x,sizeof(x))) -#define zHash(x) hash(&zt,nc(trim(x,-sizeof(I.rval1)),buf)) -#define negzHash(x) hash(&zt,nc(negate(trim(x,-sizeof(I.rval1))),buf)) -#define Ic(x) salloc(ic(x,buf)) -#define Chk(x) chk(I.sec,x) -#define Lchk(x) nl(&I,f,fb); chk(I.sec,x) - - void -process(FILE *f) -{ - int bdnz, c, colmx, first, i, line0, ll, nbd, ncol, - ndiff, nec, nfree, nran, nrhs, nz, ranz, rhsnz; - unsigned int n, n0; - struct inrec I; - static char rowchk[128], blanks[] = " "; - char cn00[16], *cn0 = cn00 + 1, objective[12]; - static char tbx[] = "1 \02 \03 \04 \05 \06 "; - static char *bt[] = {"UP", "LO", "FX", "FR", "MI", "PL"}, - *tb[] = {tbx, tbx+2, tbx+4, tbx+6, tbx+8, tbx+10}; - static int fb[] = { 21, 39, 48, 100 }, nfb[] = { -1 }; - char buf[32], *s, zero[4]; - struct hrec *orn, *r, *rn, *z, *zh; - long start = 0; - - inf = f; - Ip = &I; - fp = f; - - for(s = "ENLG"; *s; s++) - rowchk[*s] = 1; - for(n = 1; n <= 6; n++) - ic(n, tb[n-1]); - nc("0", zero); - ic((unsigned int)0, cn00); - if (verbose) - fprintf(stderr, "\n%s:\n", infile); - -top: - Mecho = Mecho0; - mystcnt = mystkeep = 0; - line0 = line; - freeall(); - htinit(&ct, 1); - htinit(&rt, 1); - htinit(&zt, lenchk + 2); - if (keepzeros) zh = 0; - else zh = hash(&zt, nc("0",buf)); - bdnz = c = chksum = colmx = lastc = nbd = ndiff = nec = nfree = - nran = nz = ranz = rhsnz = 0; - pass = 1; - strcpy(cn0, blanks); - cs = chkbuf; - - nl(&I,f,fbp=nfb); - fbp = fb; - chk(I.sec,"NAME"); - - if (verbose) fprintf(stderr, "%s\n", I.sec); - - Lchk("ROWS"); - - for(;;) { - ll = nl(&I,f,fb); - if (*I.sec != ' ') break; - if (ll < 5) continue; - if (!(rowchk[I.sec[1]] ^ rowchk[I.sec[2]])) - squawk("invalid row type %c%c", - I.sec[1], I.sec[2]); - else { - if ((I.sec[1] == 'N' || I.sec[2] == 'N') - && ++nfree == 1) - strcpy(objective, - trim(I.cname,sizeof(I.cname))); - if (I.sec[1] == 'D') - ++ndiff; - } - if (r = rHash(I.cname)) { - if (r->tv) - squawk("duplicate row %s", I.cname); - else - r->tv = (char *) 1; - } - } - if (ndiff) - fprintf(stderr, "%d difference rows (will be mishandled)\n", - ndiff); - if (verbose) { - if (nfree == 1) fprintf(stderr, "%d rows; objective = %s .\n", - rt.n, objective); - else fprintf(stderr, "%d rows (%d of them free).\n", - rt.n, nfree); - } - - orn = negobj && nfree == 1 ? hash(&rt,objective) : 0; - - Chk("COLUMNS"); - rt.canadd = 0; - rt.what = badrows ? "coefficient for unknown row" : 0; - r = 0; - for(n = ncol = 0;;) { - ll = nl(&I,f,fb); - if (strncmp(I.sec,blanks,3)) - break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(cn0,I.cname)) { - if (r && i == nz) /* forget empty column */ - { nec++; n = n0; r->v = blanks; } - i = nz; - r = hash(&ct,I.cname); - n0 = n; - if (r->tv) - squawk("duplicate col %s", I.cname); - else - r->tv = Ic(++n); - ncol++; - strcpy(cn0,I.cname); - if (colmx < c) colmx = c; - c = 0; - } - if (ll < 25) continue; - if ((rn = rHash(I.rname1)) && - (rn == orn ? negzHash(I.rval1) : zHash(I.rval1)) != zh) - { nz++; c++; } - if (ll > 49 && (rn = rHash(I.rname2)) && - (rn == orn ? negzHash(I.rval2) : zHash(I.rval2)) != zh) - { nz++; c++; } - } - if (r && i == nz) /* forget last empty column */ - { nec++; r->v = blanks; } - if (nec) { - ncol -= nec; - if (verbose) fprintf(stderr, - "%d empty columns dropped.\n", nec); - } - ct.canadd = 0; - if (colmx < c) colmx = c; - if (verbose) { - if (negobj) fprintf(stderr, "%d %s coefficients negated.\n", - --negobj, objective); - fprintf(stderr, - "%d columns, %d nonzeros, %d distinct nonzeros in A.\n", - ncol, nz, zh ? zt.n - 1 : zt.n); - } - - Chk("RHS"); - rt.what = badrows ? "rhs value for unknown row" : 0; - for(i = nrhs = 0;;) { - ll = nl(&I,f,fb); - if (strncmp(I.sec,blanks,3)) break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(I.cname,cn0) || !nrhs) { - if (i < rhsnz || !nrhs) { nrhs++; i = rhsnz; } - strcpy(cn0,I.cname); - } - if (ll < 25) continue; - if (rHash(I.rname1) && zHash(I.rval1) != zh) rhsnz++; - if (ll > 49 && rHash(I.rname2) && zHash(I.rval2) != zh) - rhsnz++; - } - if (i == rhsnz && i) nrhs--; - if (verbose) { - fprintf(stderr, "%d RHS nonzeros", rhsnz); - if (nrhs > 1) fprintf(stderr, " (%d right-hand sides)", nrhs); - fprintf(stderr, ".\n"); - if (zh && zh->tv) fprintf(stderr, "%d explicit zeros dropped.\n", - (int)zh->tv); - } - if (zh) zh->tv = 0; - - if (!strncmp(I.sec,"RANGES",6)) { - rt.what = badrows ? "range for unknown row" : 0; - for(i = 0;;) { - ll = nl(&I,f,fb); - if (strncmp(I.sec,blanks,3)) break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(I.cname,cn0) || !nran) { - if (i < ranz || !nran) { nran++; i = ranz; } - strcpy(cn0,I.cname); - } - if (ll < 25) continue; - if (rHash(I.rname1)) { zHash(I.rval1); ranz++; } - if (ll > 49 && rHash(I.rname2)) { - zHash(I.rval2); - ranz++; - } - } - if (i == ranz && i) nran--; - if (verbose) { - fprintf(stderr, "%d ranges", ranz); - if (nran > 1) fprintf(stderr, " (%d sets)", nran); - fprintf(stderr, ".\n"); - } - } - - if (rt.nb && verbose) - fprintf(stderr, "%d references to unknown rows.\n", rt.nb); - - if (!strncmp(I.sec,"BOUNDS",6)) { - ct.what = badcols; - for(i = 0;;) { - ll = nl(&I,f,fb); - if (*I.sec != ' ') break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(I.cname,cn0) || !nbd) { - if (i < bdnz || !nbd) { nbd++; i = bdnz; } - strcpy(cn0,I.cname); - } - if (ll <= 14 || !cHash(I.rname1)) continue; - bdnz++; - if (ll > 24) zHash(I.rval1); - } - if (i == bdnz && i) nbd--; - if (verbose) { - fprintf(stderr, "%d bounds", bdnz); - if (nbd > 1) fprintf(stderr, " (%d bound sets)", nbd); - fprintf(stderr, ".\n"); - if (ct.nb) fprintf(stderr, - "%d references to unknown columns.\n", ct.nb); - } - } - Chk("END"); - if (mystcnt && verbose) fprintf(stderr, mystkp1 ? "(%d%sincluded).\n" - : "%d%signored.\n", mystcnt, - " mystery lines "); - - Mecho = 0; - mystkeep = mystkp1; - fseek(f,start,0); - pass = 2; - line = line0; - zt.canadd = 0; - rt.what = ct.what = 0; - putc('\n', stdout); - nl(&I,f,fbp=nfb); chk(I.sec,"NAME"); - fbp = fb; - cs = chkbuf; - printf("%s\n", trim(I.sec,72)); - printf(" %8d %8d %8d %8d %8d %8d %8d %8d\n %8d %8d", - rt.n, ncol, colmx, nz, nrhs, rhsnz, nran, ranz, - nbd, bdnz); - nzsort(); - -#undef zHash -#undef negzHash -#define zHash(x) hash(&zt,nc(trim(x,sizeof(I.rval1)),buf)) -#define negzHash(x) hash(&zt,nc(negate(trim(x,sizeof(I.rval1))),buf)) - - Lchk("ROWS"); - for(n = 0;;) { - ll = nl(&I,f,fb); - if (*I.sec != ' ') break; - if (ll < 5) continue; - if (!(r = rHash(I.cname))) continue; - if (r->tv == (char *)1) { - *I.fill1 = I.sec[1] == ' ' ? I.sec[2] : I.sec[1]; - cout(I.fill1); - Flush(); - r->tv = Ic(++n); - } - } - - Chk("COLUMNS"); - - for(first = 1;;) { - ll = nl(&I,f,fb); - if (strncmp(I.sec,blanks,3)) break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(I.cname,cn0) || first) { - strncpy(cn0,I.cname,8); - i = 1; - first = 0; - } - if (ll < 25) continue; - if ((r = rHash(I.rname1)) && - (z = r == orn ? negzHash(I.rval1) : zHash(I.rval1)) != zh) { - if (i) { cout(cn00); Flush(); i = 0; } - cout(r->tv); - cout(z->tv); - } - if (ll > 49 && (r = rHash(I.rname2)) && - (z = r == orn ? negzHash(I.rval2) : zHash(I.rval2)) != zh) { - if (i) { cout(cn00); Flush(); i = 0; } - cout(r->tv); - cout(z->tv); - } - } - Flush(); - - Chk("RHS"); - for(first = 1;;) { - ll = nl(&I,f,fb); - if (strncmp(I.sec,blanks,3)) break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(I.cname,cn0) || first) { - strncpy(cn0,I.cname,8); - if (rhsnz) { cout(cn00); Flush(); } - first = 0; - } - if (ll < 25) continue; - if ((r = rHash(I.rname1)) && (z = zHash(I.rval1)) != zh) { - cout(r->tv); - cout(z->tv); - } - if (ll > 49 && (r = rHash(I.rname2)) && - (z = zHash(I.rval2)) != zh) { - cout(r->tv); - cout(z->tv); - } - } - Flush(); - - if (!strncmp(I.sec,"RANGES",6)) { - for(first = 1;;) { - ll = nl(&I,f,fb); - if (strncmp(I.sec,blanks,3)) break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(I.cname,cn0) || first) { - strncpy(cn0,I.cname,8); - if (ranz) { cout(cn00); Flush(); } - first = 0; - } - if (ll < 25) continue; - if (r = rHash(I.rname1)) { - cout(r->tv); - cout(zHash(I.rval1)->tv); - } - if (ll > 49 && (r = rHash(I.rname2))) { - cout(r->tv); - cout(zHash(I.rval2)->tv); - } - } - Flush(); - } - - if (!strncmp(I.sec,"BOUNDS",6)) { /* Bounds */ - for(first = 1;;) { - ll = nl(&I,f,fb); - if (*I.sec != ' ') break; - if (ll < 5) continue; - if (*trim(I.cname,8) && strcmp(I.cname,cn0) || first) { - strncpy(cn0,I.cname,8); - if (bdnz) { cout(cn00); Flush(); } - first = 0; - } - if (ll > 14 && (r = cHash(I.rname1))) { - *I.fill1 = 0; - for(i = 0; i < 6; i++) - if (!strcmp(bt[i], I.sec+1)) break; - if (i == 6) { - squawk("bad bound type %s for col %s", - I.sec+1, I.rname1); - continue; - } - cout(tb[i]); - cout(r->tv); - if (i >= 3) continue; - if (ll > 24) cout(zHash(I.rval1)->tv); - else cout(zero); - } - } - Flush(); - } - Chk("END"); - - /* final check-sum line */ - - if (cs > chkbuf) { *cs = 0; printf(" %s\n", chkbuf); } - - for(c = getc(f); c == '*'; c = getc(f)) { - while((c = getc(f)) != '\n') - if (c == EOF) goto eof; - } - if (c != EOF) { - ungetc(c,f); - start = ftell(f); - goto top; - } -eof: - fclose(f); - line = pass = 0; - } //GO.SYSIN DD mpc.c echo nc.c 1>&2 sed >nc.c <<'//GO.SYSIN DD nc.c' 's/^-//' -/* Base 92 floating-point numbers, signed and unsigned integers - * (to be represented by strings of printing ASCII characters): - * - * First digit indicates type: >= 46 ==> signed #; < 46 ==> unsigned int. - * If >= 46, += 23 for negative; += 11 for integer; for signed integer, - * += 6 if just one digit (|x| < 6). For floating point, first digit - * gives length-1 of fraction digit string. Integer types have a stop - * bit to indicate end of string: >= 46 ==> last character of string - * (for second and subsequent digits). First digit of unsigned integer - * += 23 if that is the only digit. - * - * Written by David M. Gay of AT&T Bell Laboratories to facilitate - * transmitting LP test problems over netlib. - */ - -#include - -extern char trtab[]; -extern void scream(const char*, ...); - -#define tr(x) Tr[x] - - char * -nc(char *s, char *z) -/* compress floating-point number s into z, return z */ -{ - int ea, esign, et, ex = 0, k, nd = 0, sign = 0, tz; - long x = 0, y = 0; - char c, *d, db[32], *s0 = s, *z0 = z; - static char etype[256]; - char *Tr = trtab; - - if (!etype['E']) { - etype['E'] = 1; - etype['e'] = 1; - etype['D'] = 1; - etype['d'] = 1; - etype['+'] = 2; - etype['-'] = 3; - } - - while((c = *s++) == ' ' || c == '0'); - if (c == '-') { sign = 1; c = *s++; } - else if (c == '+') c = *s++; - if (etype[(unsigned char)c] < 2) while(c == ' ') c = *s++; - else while(c == ' ' || c == '0') c = *s++; - tz = 0; - while(c >= '0' && c <= '9') { - if (c == '0') tz++; - else { - for(; tz; --tz) { - if (++nd == 10) { y = x; x = 10; } - else x *= 10; - } - if (++nd == 10) { y = x; x = c + 10 - '0'; } - else x = 10*x + (c - '0'); - } - c = *s++; - } - ea = -tz; - if (c == '.') { - while((c = *s++) >= '0' && c <= '9') { - if (c == '0') tz++; - else { - if (tz) { - ea += tz; - if (x) for(; tz; --tz) { - if (++nd == 10) - { y = x; x = 10; } - else x *= 10; - } - else tz = 0; - } - if (++nd == 10) { y = x; x = c + 10 - '0'; } - else x = 10*x + (c - '0'); - ea++; - } - } - } - if (nd > 18) scream("%d ( > 18) digits in %s", nd, s0); - while(c == ' ') c = *s++; - if (et = etype[(unsigned char)c]) { - esign = et == 3; - c = *s++; - if (et == 1) { - if(etype[(unsigned char)c] > 1) { - if (c == '-') esign = 1; - c = *s++; - } - } - while(c >= '0' && c <= '9') { - ex = 10*ex + (c - '0'); - c = *s++; - } - if (esign) ex = -ex; - } - while(c == ' ') c = *s++; - if (c) scream("invalid char in column %d of `%s'", (int)(s-s0), s0); - - d = db; - if (!x && !y) ex = ea = sign = 0; - if ((ex -= ea) || nd > 9) { /* non-integer */ - if (ex < -50 || ex > 41) - scream("oversize exponent = %d in %s", ex, s0); - do { - *d++ = tr(x%92); - x /= 92; - } while(x); - while(y) { *d++ = tr(y%92); y /= 92; } - k = d - db + 45; /* = 46 + d-db - 1 */ - if (sign) k += 23; - *z++ = tr(k); - *z++ = tr(ex + 50); - } - else { /* integer */ - k = 46 + 11; - if (sign) k += 23; - if (x > 5) { - *d++ = tr(46 + x%46); - x /= 46; - while(x > 5) { - *d++ = tr(x%46); - x /= 46; - } - } - else k += 6; - *z++ = tr(k + x); - } - while(d > db) *z++ = *--d; - *z++ = 0; - return z0; - } - - char * -ic(unsigned int i, char *z) -/* compress i into z, return z */ -{ - char *d, db[16], *z0 = z; - int k; - char *Tr = trtab; - - d = db; - if (i > 22) { - k = 0; - *d++ = tr(46 + i%46); - i /= 46; - while(i > 22) { - *d++ = tr(i%46); - i /= 46; - } - } - else k = 23; - *z++ = tr(k + i); - while(d > db) *z++ = *--d; - *z++ = 0; - return z0; - } //GO.SYSIN DD nc.c echo ne.c 1>&2 sed >ne.c <<'//GO.SYSIN DD ne.c' 's/^-//' -extern char trtab[]; - -#define tr(x) Tr[x] - -char * -ne(s,z) -char *s, *z; -/* invert nc and ic: expand z into s, updated z */ -{ - int ex, k, nd, nelim; - char *d, db[32], *de; - long x, y = 0; - static char invtrtab[256]; - register char *Tr = invtrtab; - - if (!Tr['1']) { - d = invtrtab; - de = invtrtab+sizeof(invtrtab); - while(d < de) *d++ = -1; - for(d = trtab; *d; d++) tr(*d) = d - trtab; - } - d = db; - k = tr(*z++); - if (k < 46) { /* supersparse index */ - if (k >= 23) x = k - 23; - else { - x = k; - for(;;) { - k = tr(*z++); - x = x*46 + k; - if (k >= 46) { x -= 46; break; } - } - } -intout: - if (!x) *d++ = '0'; - else do { - *d++ = '0' + x%10; - x /= 10; - } while(x); - do *s++ = *--d; while(d > db); - } - else { - k -= 46; - if (k >= 23) { *s++ = '-'; k -= 23; nelim = 11; } - else nelim = 12; - if (k >= 11) { /* integer floating-point */ - k -= 11; - *d++ = '.'; - if (k >= 6) x = k - 6; - else { - x = k; - for(;;) { - k = tr(*z++); - x = x*46 + k; - if (k >= 46) { x -= 46; break; } - } - } - goto intout; - } - else { /* general floating-point */ - ex = tr(*z++) - 50; - x = tr(*z++); - while(--k >= 0) { - if (x >= 100000000) { y = x; x = tr(*z++); } - else x = x*92 + tr(*z++); - } - if (y) { - while(x > 1) { *d++ = x%10 + '0'; x /= 10; } - for(;; y /= 10) { - *d++ = y%10 + '0'; - if (y < 10) break; - } - } - else if (x) for(;; x /= 10) { - *d++ = x%10 + '0'; - if (x < 10) break; - } - else *d++ = '0'; - nd = d - db + ex; - if (ex > 0) { - if (nd < nelim || ex < 3) { - while(d > db) *s++ = *--d; - do *s++ = '0'; while(--ex); - *s++ = '.'; - } - else goto Eout; - } - else if (nd >= 0) { - while(--nd >= 0) *s++ = *--d; - *s++ = '.'; - while(d > db) *s++ = *--d; - } - else if (ex > -nelim) { - *s++ = '.'; - while(++nd <= 0) *s++ = '0'; - while(d > db) *s++ = *--d; - } - else { - Eout: - ex += d - db - 1; - if (ex == -10) ex = -9; - else { - if (ex > 9 && ex <= d - db + 8) { - do { *s++ = *--d; - } while (--ex > 9); - } - *s++ = *--d; - } - *s++ = '.'; - while(d > db) *s++ = *--d; - *s++ = 'E'; - if (ex < 0) { *s++ = '-'; ex = -ex; } - while(ex) { *d++ = '0' + ex%10; ex /= 10; } - while(d > db) *s++ = *--d; - } - } - } - *s++ = 0; - return z; - } //GO.SYSIN DD ne.c echo fc.c 1>&2 sed >fc.c <<'//GO.SYSIN DD fc.c' 's/^-//' -/* For debugging, read ASCII numbers on stdin, write them in - * compressed and expanded form on stdout. Numbers without - * a decimal point are taken to be unsigned integers. - */ - -#include -#include -#include - - char * -nonbln(char *s) -{ - int c; - if (s) - for(; c = *s; s++) - if (c > ' ') return s; - return 0; - } - - char * -nextbln(char *s) -{ - while(*s > ' ') s++; - return s; - } - - char * -strchr(const char *s, int c) -{ - do { - if (*s == c) - return (char*)s; - } while(*s++); - return 0; - } - -char *progname; - - void -scream(const char *s, int x, const char *y) /* for nc */ -{ - fprintf(stderr, "%s: ", progname); - fprintf(stderr, s, x, y); - fprintf(stderr, "\n"); - exit(1); - } - - int -main(int argc, char **argv) -{ - char buf[128], c, nb[32], *s, *s1, zbuf[128], *z; - char *ic(), *nc(), *ne(); - unsigned k; - progname = *argv; - - while(s = fgets(buf,sizeof(buf),stdin)) { - while(s = nonbln(s)) { - s1 = nextbln(s); - c = *s1; - *s1 = 0; - if (strchr(s,'.')) { - z = nc(s,zbuf); - ne(nb,zbuf); - printf("%s --> %s (len %d) = %s\n", - s, z, strlen(z), nb); - } - else { - while(*s == '-') s++; - k = atoi(s); - z = ic(k, zbuf); - ne(nb,zbuf); - printf("%u --> %s (len %d) = %s\n", - k, z, strlen(z), nb); - } - *s1 = c; - s = s1; - } - } - return 0; - } //GO.SYSIN DD fc.c echo fe.c 1>&2 sed >fe.c <<'//GO.SYSIN DD fe.c' 's/^-//' -/* For debugging, read compressed numbers on stdin, write them in - * compressed and expanded form on stdout. Numbers written without - * a decimal point are (unsigned) integers (for use as indices in - * a supersparse representation of floating-point numbers). - */ - -#include -#include - - void -fe(char *lines, char *zbuf) -{ - char buf[32], c, *ne(), *s, *zb0, *ze; - - ze = zbuf + strlen(zbuf); - for(s = zb0 = zbuf; s < ze; zbuf = s) { - s = ne(buf,zbuf); - if (s > ze) { - printf("%s\t= \n", zbuf); - return; - } - c = *s; *s = 0; - if (lines) printf(zbuf == zb0 ? "%s" : lines, buf); - else printf("%s\t= %s\n", zbuf, buf); - *s = c; - } - if (lines) - printf("\n"); - } - - int -main(int argc, char **argv) -{ - char buf[256], *s; - char *lines = 0; - int c; - - if (argc > 1 && !strcmp(argv[1], "-l")) { - lines = "\t%s"; - ++argv; - } - - while(s = *++argv) fe(lines, s); - - for(;;){ - do { - c = getchar(); - if (c == EOF) return 0; - } while (c <= ' '); - s = buf; - do { - *s++ = c; - c = getchar(); - } while(c > ' '); - *s++ = 0; - *s++ = 0xff; - fe(lines, buf); - } - } //GO.SYSIN DD fe.c echo trtab.c 1>&2 sed >trtab.c <<'//GO.SYSIN DD trtab.c' 's/^-//' -char trtab[] = "!\"#$%&'()*+,-./0123456789;<=>?@\ -ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwxyz{|}~"; //GO.SYSIN DD trtab.c .