[net.sources] A program to de-compile nroff drive tables

matt@oddjob.UChicago.UUCP (Matt Crawford) (05/11/84)

><

Below is a program which will take the filename of an nroff drive table
as its only argument and produce a C program on its standard output
which, when compiled and stripped, produces exactly the original drive
table.  (Unless the original was unstripped or in old format or pure
or...)  The header file "tw.h" from the troff source directory must be
in the current directory when this program is run.

___________________________________________________
Matt			Arpa: Crawford@ANL-MCS.ARPA
Crawford		UUCP: ihnp4!oddjob!matt


------------------------dumptab.c--------------------------------
/* dumptab:  a program to de-compile nroff drive tables so they can
**		be fiddled with.
**
** usage:	dumptab tab300 > Tab300.c
**
** Matt Crawford, University of Chicago, 10 May 1984
** ihnp4!oddjob!matt		   matt@anl-mcs.arpa
*/

#include <stdio.h>
#include <sys/file.h>
#include <ctype.h>
#include "tw.h"

void	loadtab(), vprint();
char	*codelabel[] = {
	"space",	"!",	"\"",	"#",	"$",	"%",	"&",
	"' close",	"(",	")",	"*",	"+",	",",	"- hyphen",
	".",	"/",	"0",	"1",	"2",	"3",	"4",	"5",
	"6",	"7",	"8",	"9",	":",	";",	"<",	"=",
	">",	"?",	"@",	"A",	"B",	"C",	"D",	"E",
	"F",	"G",	"H",	"I",	"J",	"K",	"L",	"M",
	"N",	"O",	"P",	"Q",	"R",	"S",	"T",	"U",
	"V",	"W",	"X",	"Y",	"Z",	"[",	"\\",	"]",
	"^",	"_ dash",	"` open",	"a",	"b",	"c",
	"d",	"e",	"f",	"g",	"h",	"i",	"j",	"k",
	"l",	"m",	"n",	"o",	"p",	"q",	"r",	"s",
	"t",	"u",	"v",	"w",	"x",	"y",	"z",	"{",
	"|",	"}",	"~",	"narrow sp",	"hyphen",	"bullet",
	"square",	"3/4 em",	"rule",	"1/4",	"1/2",	"3/4",
	"minus",	"fi",	"fl",	"ff",	"ffi",	"ffl",	"degree",
	"dagger",	"section",	"foot mark",	"acute accent",
	"grave accent",	"underrule",	"slash (longer)",
	"half narrow space",	"unpaddable space",	"alpha",
	"beta",	"gamma",	"delta",	"epsilon",	"zeta",
	"eta",	"theta",	"iota",	"kappa",	"lambda",
	"mu",	"nu",	"xi",	"omicron",	"pi",	"rho",	"sigma",
	"tau",	"upsilon",	"phi",	"chi",	"psi",	"omega",
	"Gamma",	"Delta",	"Theta",	"Lambda",
	"Xi",	"Pi",	"Sigma",	"Tau",	"Upsilon",	"Phi",
	"Psi",	"Omega",	"square root",	"terminal sigma",
	"root en",	">=",	"<=",	"identically equal",
	"equation minus",	"approx =",	"approximates",
	"not equal",	"right arrow",	"left arrow",	"up arrow",
	"down arrow",	"eqn equals",	"multiply",	"divide",
	"plus-minus",	"cup (union)",	"cap (intersection)",	"subset of",
	"superset of",	"improper subset",	" improper superset",
	"infinity",	"pt deriv",	"gradient",	"not",	"integral",
	"proportional to",	"empty set",	"member of",
	"equation plus",	"registration mk",	"copyright mk",
	"box rule",	"cent sign",	"dbl dagger",	"right hand",
	"left hand",	"math * ",	"bell system sign",
	"or (was star)",	"circle",	"left top of big curly",
	"left bottom of big curly",	"right top of big curly",
	"right bottom of big curly",	"left center of big curly",
	"right center of big curly",	"bold vertical rule",
	"left bottom of big bracket",	"right bottom of big bracket",
	"left top of big bracket",	"right top of big bracket",
	"???",	"???",	"???",	"???",	"???",	"???",	"???",	"???",
	"???",	"???",	"???",	"???",	"???",	/* No idea what these are */
};

main(argc, argv)
char	**argv;
{
	register int	c;
	register char	**endptr = &t.zzz;
	register FILE	*twfp;
	char		labelbuf[64];

	loadtab(argv[1]);
	if ( (twfp = fopen("tw.h", "r")) == NULL ) {
		perror("tw.h");
		exit(1);
	}
	
	while ( (c = getc(twfp)) != EOF && c != /*{*/ '}')
		putc(c, stdout);
	fclose(twfp);
	printf(/*{*/ "} t = {\n" /*}*/);	/* Stupid emacs! */
	printf("/*bset    */\t\t0%o,\n", t.bset);
	printf("/*breset  */\t\t0%o,\n", t.breset);
#define intshow(memb) \
		printf("/*%-8s*/\t\t%d,\n", "memb", t.memb)
	intshow(Hor);
	intshow(Vert);
	intshow(Newline);
	intshow(Char);
	intshow(Em);
	intshow(Halfline);
	intshow(Adj);
#define show(memb) \
		printf("/*%-8s*/\t\t\"", "memb");\
		vprint(t.memb);\
		printf("\",\n")
	show(twinit);
	show(twrest);
	show(twnl);
	show(hlr);
	show(hlf);
	show(flr);
	show(bdon);
	show(bdoff);
	show(ploton);
	show(plotoff);
	show(up);
	show(down);
	show(right);
	show(left);
	while ( **--endptr == '\0' )
		;
	for ( c = 0; c < 256-32		/* Not all 256-32 chars are in use */
		&& &t.codetab[c] <= endptr; c++ ) {
		printf("%-20s\t\"", sprintf(labelbuf, "/* %s */",
						codelabel[c]));
		if ( t.codetab[c][0] )
			vprint(t.codetab[c]);
		else
			printf("\\000\\0");
		printf("\",\n");
	}
	printf(/*{*/ "};\n");
	exit(0);
}

void
vprint(str)
register char	*str;
{
	while ( str && *str ) {
		char	c[5];

		if ( isascii(*str) && isprint(*str)
				&& *str != '\\' && *str != '"' ) {
			c[0] = *str;
			c[1] = '\0';
		} else
			switch ( *str ) {
			case '\\':
			case '"':
				c[0] = '\\';
				c[1] = *str;
				c[2] = '\0';
			        break;
			case '\b':
			        strcpy(c, "\\b");
			        break;
			case '\t':
			        strcpy(c, "\\t");
			        break;
			case '\n':
			        strcpy(c, "\\n");
			        break;
/*
			case '\f':
			        strcpy(c, "\\f");
			        break;
*/
			case '\r':
			        strcpy(c, "\\r");
			        break;
			default:
				sprintf(c, "\\%03.3o", (int)*str & 0377);
			        break;
			}
		fputs(c, stdout);
		str++;
	}
}

void
loadtab( tname )
char	*tname;
{
	register int	n, tfd;
	int		head[8];
	register char	**pp, *mptr;
	extern char	*sbrk();

	if( (tfd=open(tname, O_RDONLY)) < 0 ) {
		perror( tname );
		exit(1);
	}
	read(tfd, (char *)head, 8*sizeof(int));
	n = sizeof(int) * ((int *)&t.zzz - &t.bset);
	read(tfd, (char *)&t.bset, n);
	head[2] -= n;
	mptr = sbrk(head[2]);
	lseek(tfd, (long)t.twinit+8*sizeof(int), 0);
	tfd = read(tfd, mptr, head[2]);
	n = mptr - t.twinit;
	for ( pp = &t.twinit; pp < &t.zzz; pp++ )
		if ( *pp )
			*pp += n;
		else
			*pp = "";
}