DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T g

⟦3247332a1⟧ TextFile

    Length: 19123 (0x4ab3)
    Types: TextFile
    Names: »gftype.c«

Derivation

└─⟦060c9c824⟧ Bits:30007080 DKUUG TeX 2/12/89
    └─⟦this⟧ »./tex82/mfware/CMFware/gftype.c« 

TextFile

#include "mf.h"
#include "mf_vars.h"
FILE *output;

void initialize()
{
    integer i;

    output = fopen("gftype.out", "w");
    if (!output)
	perror("gftype.out"), exit(1);

    fprintf(output, "%s\n", "This is GFtype, C Version 2.2");
    for (i = 0; i <= 31; i++) 
	xchr[i] = '?';
    xchr[32] = ' ';
    xchr[33] = '!';
    xchr[34] = '"';
    xchr[35] = '#';
    xchr[36] = '$';
    xchr[37] = '%';
    xchr[38] = '&';
    xchr[39] = '\'';
    xchr[40] = '(';
    xchr[41] = ')';
    xchr[42] = '*';
    xchr[43] = '+';
    xchr[44] = ',';
    xchr[45] = '-';
    xchr[46] = '.';
    xchr[47] = '/';
    xchr[48] = '0';
    xchr[49] = '1';
    xchr[50] = '2';
    xchr[51] = '3';
    xchr[52] = '4';
    xchr[53] = '5';
    xchr[54] = '6';
    xchr[55] = '7';
    xchr[56] = '8';
    xchr[57] = '9';
    xchr[58] = ':';
    xchr[59] = ';';
    xchr[60] = '<';
    xchr[61] = '=';
    xchr[62] = '>';
    xchr[63] = '?';
    xchr[64] = '@';
    xchr[65] = 'A';
    xchr[66] = 'B';
    xchr[67] = 'C';
    xchr[68] = 'D';
    xchr[69] = 'E';
    xchr[70] = 'F';
    xchr[71] = 'G';
    xchr[72] = 'H';
    xchr[73] = 'I';
    xchr[74] = 'J';
    xchr[75] = 'K';
    xchr[76] = 'L';
    xchr[77] = 'M';
    xchr[78] = 'N';
    xchr[79] = 'O';
    xchr[80] = 'P';
    xchr[81] = 'Q';
    xchr[82] = 'R';
    xchr[83] = 'S';
    xchr[84] = 'T';
    xchr[85] = 'U';
    xchr[86] = 'V';
    xchr[87] = 'W';
    xchr[88] = 'X';
    xchr[89] = 'Y';
    xchr[90] = 'Z';
    xchr[91] = '[';
    xchr[92] = '\\';
    xchr[93] = ']';
    xchr[94] = '^';
    xchr[95] = '_';
    xchr[96] = '`';
    xchr[97] = 'a';
    xchr[98] = 'b';
    xchr[99] = 'c';
    xchr[100] = 'd';
    xchr[101] = 'e';
    xchr[102] = 'f';
    xchr[103] = 'g';
    xchr[104] = 'h';
    xchr[105] = 'i';
    xchr[106] = 'j';
    xchr[107] = 'k';
    xchr[108] = 'l';
    xchr[109] = 'm';
    xchr[110] = 'n';
    xchr[111] = 'o';
    xchr[112] = 'p';
    xchr[113] = 'q';
    xchr[114] = 'r';
    xchr[115] = 's';
    xchr[116] = 't';
    xchr[117] = 'u';
    xchr[118] = 'v';
    xchr[119] = 'w';
    xchr[120] = 'x';
    xchr[121] = 'y';
    xchr[122] = 'z';
    xchr[123] = '{';
    xchr[124] = '|';
    xchr[125] = '}';
    xchr[126] = '~';
    for (i = 127; i <= 255; i++) 
	xchr[i] = '?';
    for (i = 0; i <= 127; i++) 
	xord[chr(i)] = 32;
    for (i = 32; i <= 126; i++) 
	xord[xchr[i]] = i;
    wantsmnemonics = true;
    wantspixels = true;
    for (i = 0; i <= 255; i++) 
	charptr[i] = -1;
    totalchars = 0;
    minmoverall = maxint;
    maxmoverall = -maxint;
    minnoverall = maxint;
    maxnoverall = -maxint;
}
void jumpout()
{
    cexit(0);
}
integer getbyte()
{
    register integer _result;
    eightbits b;
    if (eof(gffile))
	_result = 0;
    else {
	read(gffile, b);
	curloc = curloc + 1;
	_result = b;
    }
    return(_result);
}
integer gettwobytes()
{
    register integer _result;
    eightbits a, b;
    read(gffile, a);
    read(gffile, b);
    curloc = curloc + 2;
    _result = (a * 256) + b;
    return(_result);
}
integer getthreebytes()
{
    register integer _result;
    eightbits a, b, c;
    read(gffile, a);
    read(gffile, b);
    read(gffile, c);
    curloc = curloc + 3;
    _result = (((a * 256) + b) * 256) + c;
    return(_result);
}
integer signedquad()
{
    register integer _result;
    eightbits a, b, c, d;
    read(gffile, a);
    read(gffile, b);
    read(gffile, c);
    read(gffile, d);
    curloc = curloc + 4;
    if (a < 128)
	_result = (((((a * 256) + b) * 256) + c) * 256) + d;
    else
	_result = ((((((a - 256) * 256) + b) * 256) + c) * 256) + d;
    return(_result);
}
ASCIIcode lowercasify(c)
ASCIIcode c;
{
    register ASCIIcode _result;
    if ((c >= 65) && (c <= 90))
	_result = c + 32;
    else
	_result = c;
    return(_result);
}
void dialog()
{
L1:
    printf("%s", "Mnemonic output? (default=yes, ? for help): ");
    inputln;
    buffer[0] = lowercasify(buffer[0]);
    if (buffer[0] != 63)
	wantsmnemonics = (((buffer[0] == 121) || (buffer[0] == 49)) || (buffer[0] == 116)) || (buffer[0] == 32);
    else {
	printf("%s", "Type Y for complete listing,");
	printf("%s\n", " N for errors/images only.");
	goto L1;
    }
L2:
    printf("%s", "Pixel output? (default=yes, ? for help): ");
    inputln;
    buffer[0] = lowercasify(buffer[0]);
    if (buffer[0] != 63)
	wantspixels = (((buffer[0] == 121) || (buffer[0] == 49)) || (buffer[0] == 116)) || (buffer[0] == 32);
    else {
	printf("%s", "Type Y to list characters pictorially");
	printf("%s\n", " with *\'s, N to omit this option.");
	goto L2;
    }
    fprintf(output, "%s", "Options selected: Mnemonic output = ");
    if (wantsmnemonics)
	fprintf(output, "%s", "true");
    else
	fprintf(output, "%s", "false");
    fprintf(output, "%s", "; pixel output = ");
    if (wantspixels)
	fprintf(output, "%s", "true");
    else
	fprintf(output, "%s", "false");
    fprintf(output, "%c\n", '.');
}
void printscaled(s)
integer s;
{
    integer delta;
    if (s < 0) {
	fprintf(output, "%c", '-');
	s = -s;
    }
    fprintf(output, "%d", s / 65536);
    s = (10 * (s%65536)) + 5;
    if (s != 5) {
	delta = 10;
	fprintf(output, "%c", '.');
	do {
	    if (delta > 65536)
		s = (s + 32768) - (delta/2);
	    fprintf(output, "%c", chr(ord('0') + (s / 65536)));
	    s = 10 * (s%65536);
	    delta = delta * 10;
	} while (! (s <= delta));
    }
}
extern integer firstpar();
boolean dochar()
{
    register boolean _result;
    eightbits o;
    integer p, q;
    boolean aok;
    aok = true;
    while (true){
	a = curloc;
	o = getbyte();
	p = firstpar(o);
	if (eof(gffile)) {
	    fprintf(output, "%c%s%s%c", ' ', "Bad GF file: ", "the file ended prematurely", '!');
	    jumpout();
	}
	if (o <= 67) {
	    if (wantsmnemonics)
		fprintf(output, "%s", " paint ");
	    do {
		if (wantsmnemonics)
		    if (paintswitch == 0)
			fprintf(output, "%c%d%c", '(', p, ')');
		    else
			fprintf(output, "%d", p);
		m = m + p;
		if (m > maxmobserved)
		    maxmobserved = m - 1;
		if (wantspixels)
		    if (paintswitch == 1)
			if (n <= maxsubrow) {
			    l = m - p;
			    r = m - 1;
			    if (r > maxsubcol)
				r = maxsubcol;
			    m = l;
			    while (m <= r){
				imagearray[m][n] = 1;
				m = m + 1;
			    }
			    m = l + p;
			}
		paintswitch = 1 - paintswitch;
		a = curloc;
		o = getbyte();
		p = firstpar(o);
		if (eof(gffile)) {
		    fprintf(output, "%c%s%s%c", ' ', "Bad GF file: ", "the file ended prematurely", '!');
		    jumpout();
		}
	    } while (! (o > 67));
	}
	if (o >= 70 && o <= 73) {
		{
		    if (wantsmnemonics) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%d%c%d", a, ": ", "skip", (o - 70) % 4, ' ', p);
		    }
		    n = (n + p) + 1;
		    m = 0;
		    paintswitch = 0;
		    if (wantsmnemonics)
			fprintf(output, "%s%d%c", " (n=", maxnstated - n, ')');
		}
	} else if (o >= 74 && o <= 238) {
		{
		    if (wantsmnemonics) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%d", a, ": ", "newrow ", p);
		    }
		    n = n + 1;
		    m = p;
		    paintswitch = 1;
		    if (wantsmnemonics)
			fprintf(output, "%s%d%c", " (n=", maxnstated - n, ')');
		}
	} else if (o == 244) {
		if (wantsmnemonics) {
		    fprintf(output, "\n");
		    fprintf(output, "%d%s%s", a, ": ", "no op");
		}
	} else if (o == 247) {
		{
		    {
			fprintf(output, "%d%s%s%s", a, ": ", "! ", "preamble command within a character!");
			fprintf(output, "\n");
		    }
		    goto L9998;
		}
	} else if (o == 248 || o == 249) {
		{
		    {
			fprintf(output, "%d%s%s%s", a, ": ", "! ", "postamble command within a character!");
			fprintf(output, "\n");
		    }
		    goto L9998;
		}
	        break;
	} else if (o == 67 || o == 68) {
		{
		    {
			fprintf(output, "%d%s%s%s", a, ": ", "! ", "boc occurred before eoc!");
			fprintf(output, "\n");
		    }
		    goto L9998;
		}
	} else if (o == 69) {
		{
		    if (wantsmnemonics) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s", a, ": ", "eoc");
		    }
		    fprintf(output, "\n");
		    goto L9999;
		}
	} else if (o >= 239 && o <= 242) {
		{
		    if (wantsmnemonics) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s", a, ": ", "xxx \'");
		    }
		    badchar = false;
		    b = 16;
		    if (p < 0) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%s", a, ": ", "! ", "string of negative length!");
			fprintf(output, "\n");
		    }
		    while (p > 0){
			q = getbyte();
			if ((q < 32) || (q > 126))
			    badchar = true;
			if (wantsmnemonics) {
			    fprintf(output, "%c", xchr[q]);
			    if (b < linelength)
				b = b + 1;
			    else {
				fprintf(output, "\n");
				b = 2;
			    }
			}
			p = p - 1;
		    }
		    if (wantsmnemonics)
			fprintf(output, "%c", '\'');
		    if (badchar) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%s", a, ": ", "! ", "non-ASCII character in xxx command!");
			fprintf(output, "\n");
		    }
		}
	} else if (o == 243) {
		{
		    if (wantsmnemonics) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%d%s", a, ": ", "yyy ", p, " (");
		    }
		    if (wantsmnemonics) {
			printscaled(p);
			fprintf(output, "%c", ')');
		    }
		}
	        break;
	} else {
		{
		    fprintf(output, "%d%s%s%s%d%c", a, ": ", "! ", "undefined command ", o, '!');
		    fprintf(output, "\n");
		}
	}
    }
L9998:
    fprintf(output, "%c\n", '!');
    aok = false;
L9999:
    _result = aok;
    return(_result);
}
void readpostamble()
{
    integer k;
    integer p, q, m, u, v, w, c;
    postloc = curloc - 1;
    fprintf(output, "%s%d", "Postamble starts at byte ", postloc);
    if (postloc == gfprevptr)
	fprintf(output, "%c\n", '.');
    else
	fprintf(output, "%s%d%c\n", ", after special info at byte ", gfprevptr, '.');
    p = signedquad();
    if (p != gfprevptr) {
	fprintf(output, "%d%s%s%s%d%s%d%s%d%c", a, ": ", "! ", "backpointer in byte ", curloc - 4, " should be ", gfprevptr, " not ", p, '!');
	fprintf(output, "\n");
    }
    designsize = signedquad();
    checksum = signedquad();
    fprintf(output, "%s%d%s", "design size = ", designsize, " (");
    printscaled(designsize / 16);
    fprintf(output, "%s\n", "pt)");
    fprintf(output, "%s%d\n", "check sum = ", checksum);
    hppp = signedquad();
    vppp = signedquad();
    fprintf(output, "%s%d%s", "hppp = ", hppp, " (");
    printscaled(hppp);
    fprintf(output, "%c\n", ')');
    fprintf(output, "%s%d%s", "vppp = ", vppp, " (");
    printscaled(vppp);
    fprintf(output, "%c\n", ')');
    pixratio = (designsize / 1048576.0) * (hppp / 1048576.0);
    minmstated = signedquad();
    maxmstated = signedquad();
    minnstated = signedquad();
    maxnstated = signedquad();
    fprintf(output, "%s%d%s%d\n", "min m = ", minmstated, ", max m = ", maxmstated);
    if (minmstated > minmoverall) {
	fprintf(output, "%d%s%s%s%d%c", a, ": ", "! ", "min m should be <=", minmoverall, '!');
	fprintf(output, "\n");
    }
    if (maxmstated < maxmoverall) {
	fprintf(output, "%d%s%s%s%d%c", a, ": ", "! ", "max m should be >=", maxmoverall, '!');
	fprintf(output, "\n");
    }
    fprintf(output, "%s%d%s%d\n", "min n = ", minnstated, ", max n = ", maxnstated);
    if (minnstated > minnoverall) {
	fprintf(output, "%d%s%s%s%d%c", a, ": ", "! ", "min n should be <=", minnoverall, '!');
	fprintf(output, "\n");
    }
    if (maxnstated < maxnoverall) {
	fprintf(output, "%d%s%s%s%d%c", a, ": ", "! ", "max n should be >=", maxnoverall, '!');
	fprintf(output, "\n");
    }
    do {
	a = curloc;
	k = getbyte();
	if ((k == 245) || (k == 246)) {
	    c = firstpar(k);
	    if (k == 245) {
		u = signedquad();
		v = signedquad();
	    }
	    else {
		u = getbyte() * 65536;
		v = 0;
	    }
	    w = signedquad();
	    p = signedquad();
	    fprintf(output, "%s%d%s%d%s", "Character ", c, ": dx ", u, " (");
	    printscaled(u);
	    if (v != 0) {
		fprintf(output, "%s%d%s", "), dy ", v, " (");
		printscaled(v);
	    }
	    fprintf(output, "%s%d%s", "), width ", w, " (");
	    w = round(w * pixratio);
	    printscaled(w);
	    fprintf(output, "%s%d\n", "), loc ", p);
	    if (p != charptr[c]) {
		fprintf(output, "%d%s%s%s%d%c", a, ": ", "! ", "character location should be ", charptr[c], '!');
		fprintf(output, "\n");
	    }
	    k = 244;
	}
    } while (! (k != 244));
    if (k != 249) {
	fprintf(output, "%d%s%s%s", a, ": ", "! ", "should be postpost!");
	fprintf(output, "\n");
    }
    q = signedquad();
    if (q != postloc) {
	fprintf(output, "%d%s%s%s%d%s%d", a, ": ", "! ", "postamble pointer should be ", postloc, " not ", q);
	fprintf(output, "\n");
    }
    m = getbyte();
    if (m != 131) {
	fprintf(output, "%d%s%s%s%d%s%d", a, ": ", "! ", "identification byte should be ", 131, ", not ", m);
	fprintf(output, "\n");
    }
    k = curloc;
    m = 223;
    while ((m == 223) && (! eof(gffile)))
	m = getbyte();
    if (! eof(gffile)) {
	fprintf(output, "%c%s%s%d%s%c", ' ', "Bad GF file: ", "signature in byte ", curloc - 1, " should be 223", '!');
	jumpout();
    }
    else if (curloc < (k + 4)) {
	fprintf(output, "%d%s%s%s", a, ": ", "! ", "not enough signature bytes at end of file!");
	fprintf(output, "\n");
    }
}
mf()
{
    initialize();
    dialog();
    opengffile();
    o = getbyte();
    if (o != 247) {
	fprintf(output, "%c%s%s%c", ' ', "Bad GF file: ", "First byte isn\'t start of preamble!", '!');
	jumpout();
    }
    o = getbyte();
    if (o != 131) {
	fprintf(output, "%c%s%s%d%s%d%c", ' ', "Bad GF file: ", "identification byte should be ", 131, " not ", o, '!');
	jumpout();
    }
    o = getbyte();
    fprintf(output, "%c", '\'');
    while (o > 0){
	o = o - 1;
	fprintf(output, "%c", xchr[getbyte()]);
    }
    fprintf(output, "%c\n", '\'');
    do {
	gfprevptr = curloc;
	do {
	    a = curloc;
	    o = getbyte();
	    p = firstpar(o);
	    if (eof(gffile)) {
		fprintf(output, "%c%s%s%c", ' ', "Bad GF file: ", "the file ended prematurely", '!');
		jumpout();
	    }
	    if (o == 243) {
		{
		    if (wantsmnemonics) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%d%s", a, ": ", "yyy ", p, " (");
		    }
		    if (wantsmnemonics) {
			printscaled(p);
			fprintf(output, "%c", ')');
		    }
		}
		o = 244;
	    }
	    else if ((o >= 239) && (o <= 242)) {
		{
		    if (wantsmnemonics) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s", a, ": ", "xxx \'");
		    }
		    badchar = false;
		    b = 16;
		    if (p < 0) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%s", a, ": ", "! ", "string of negative length!");
			fprintf(output, "\n");
		    }
		    while (p > 0){
			q = getbyte();
			if ((q < 32) || (q > 126))
			    badchar = true;
			if (wantsmnemonics) {
			    fprintf(output, "%c", xchr[q]);
			    if (b < linelength)
				b = b + 1;
			    else {
				fprintf(output, "\n");
				b = 2;
			    }
			}
			p = p - 1;
		    }
		    if (wantsmnemonics)
			fprintf(output, "%c", '\'');
		    if (badchar) {
			fprintf(output, "\n");
			fprintf(output, "%d%s%s%s", a, ": ", "! ", "non-ASCII character in xxx command!");
			fprintf(output, "\n");
		    }
		}
		o = 244;
	    }
	    else if (o == 244)
		if (wantsmnemonics) {
		    fprintf(output, "\n");
		    fprintf(output, "%d%s%s", a, ": ", "no op");
		}
	} while (! (o != 244));
	if (o != 248) {
	    if (o != 67)
		if (o != 68) {
		    fprintf(output, "%c%s%s%d%s%d%c%c", ' ', "Bad GF file: ", "byte ", curloc - 1, " is not boc (", o, ')', '!');
		    jumpout();
		}
	    fprintf(output, "\n");
	    fprintf(output, "%d%s", curloc - 1, ": beginning of char ");
	    a = curloc - 1;
	    totalchars = totalchars + 1;
	    if (o == 67) {
		charactercode = signedquad();
		p = signedquad();
		c = charactercode%256;
		if (c < 0)
		    c = c + 256;
		minmstated = signedquad();
		maxmstated = signedquad();
		minnstated = signedquad();
		maxnstated = signedquad();
	    }
	    else {
		charactercode = getbyte();
		p = -1;
		c = charactercode;
		q = getbyte();
		maxmstated = getbyte();
		minmstated = maxmstated - q;
		q = getbyte();
		maxnstated = getbyte();
		minnstated = maxnstated - q;
	    }
	    fprintf(output, "%d", c);
	    if (charactercode != c)
		fprintf(output, "%s%d", " with extension ", (charactercode - c) / 256);
	    if (wantsmnemonics)
		fprintf(output, "%s%d%s%d%c%d%s%d\n", ": ", minmstated, "<=m<=", maxmstated, ' ', minnstated, "<=n<=", maxnstated);
	    maxmobserved = -1;
	    if (charptr[c] != p) {
		fprintf(output, "%d%s%s%s%d%s%d%c", a, ": ", "! ", "previous character pointer should be ", charptr[c], ", not ", p, '!');
		fprintf(output, "\n");
	    }
	    else if (p > 0)
		if (wantsmnemonics)
		    fprintf(output, "%s%d%c\n", "(previous character with the same code started at byte ", p, ')');
	    charptr[c] = gfprevptr;
	    if (wantsmnemonics)
		fprintf(output, "%s%d%c", "(initially n=", maxnstated, ')');
	    if (wantspixels) {
		maxsubcol = (maxmstated - minmstated) - 1;
		if (maxsubcol > maxcol)
		    maxsubcol = maxcol;
		maxsubrow = maxnstated - minnstated;
		if (maxsubrow > maxrow)
		    maxsubrow = maxrow;
		n = 0;
		while (n <= maxsubrow){
		    m = 0;
		    while (m <= maxsubcol){
			imagearray[m][n] = 0;
			m = m + 1;
		    }
		    n = n + 1;
		}
	    }
	    m = 0;
	    n = 0;
	    paintswitch = 0;
	    if (! dochar()) {
		fprintf(output, "%c%s%s%c", ' ', "Bad GF file: ", "char ended unexpectedly", '!');
		jumpout();
	    }
	    maxnobserved = n;
	    if (wantspixels) {
		if ((maxmobserved > maxcol) || (maxnobserved > maxrow))
		    fprintf(output, "%s\n", "(The character is too large to be displayed in full.)");
		if (maxsubcol > maxmobserved)
		    maxsubcol = maxmobserved;
		if (maxsubrow > maxnobserved)
		    maxsubrow = maxnobserved;
		if (maxsubcol >= 0) {
		    fprintf(output, "%s%d%c%d%s\n", ".<--This pixel\'s lower left corner is at (", minmstated, ',', maxnstated + 1, ") in METAFONT coordinates");
		    n = 0;
		    while (n <= maxsubrow){
			m = 0;
			b = 0;
			while (m <= maxsubcol){
			    if (imagearray[m][n] == 0)
				b = b + 1;
			    else {
				while (b > 0){
				    fprintf(output, "%c", ' ');
				    b = b - 1;
				}
				fprintf(output, "%c", '*');
			    }
			    m = m + 1;
			}
			fprintf(output, "\n");
			n = n + 1;
		    }
		    fprintf(output, "%s%d%c%d%s\n", ".<--This pixel\'s upper left corner is at (", minmstated, ',', maxnstated - maxsubrow, ") in METAFONT coordinates");
		}
		else
		    fprintf(output, "%s\n", "(The character is entirely blank.)");
	    }
	    maxmobserved = (minmstated + maxmobserved) + 1;
	    n = maxnstated - maxnobserved;
	    if (minmstated < minmoverall)
		minmoverall = minmstated;
	    if (maxmobserved > maxmoverall)
		maxmoverall = maxmobserved;
	    if (n < minnoverall)
		minnoverall = n;
	    if (maxnstated > maxnoverall)
		maxnoverall = maxnstated;
	    if (maxmobserved > maxmstated)
		fprintf(output, "%s%d\n", "The previous character should have had max m >= ", maxmobserved);
	    if (n < minnstated)
		fprintf(output, "%s%d\n", "The previous character should have had min n <= ", n);
	}
    } while (! (o == 248));
    fprintf(output, "\n");
    readpostamble();
    fprintf(output, "%s%d%s", "The file had ", totalchars, " character");
    if (totalchars != 1)
	fprintf(output, "%c", 's');
    fprintf(output, "%s", " altogether.\n");
L9999:
    null;
}