plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

main.c (7182B)


      1 #include "e.h"
      2 
      3 #define getline p9getline
      4 #undef inline
      5 #define inline _einline
      6 
      7 #define	MAXLINE	3600	/* maximum input line */
      8 
      9 char *version = "version Oct 24, 1991";
     10 
     11 char	in[MAXLINE+1];	/* input buffer */
     12 int	noeqn;
     13 char	*cmdname;
     14 
     15 int	yyparse(void);
     16 void	settype(char *);
     17 int	getdata(void);
     18 int	getline(char *);
     19 void	inline(void);
     20 void	init(void);
     21 void	init_tbl(void);
     22 
     23 int
     24 main(int argc, char *argv[])
     25 {
     26 	char *p, buf[20];
     27 
     28 	cmdname = argv[0];
     29 	if ((p = getenv("TYPESETTER")))
     30 		typesetter = p;
     31 	while (argc > 1 && argv[1][0] == '-') {
     32 		switch (argv[1][1]) {
     33 
     34 		case 'd':
     35 			if (argv[1][2] == '\0') {
     36 				dbg++;
     37 				printf("...\teqn %s\n", version);
     38 			} else {
     39 				lefteq = argv[1][2];
     40 				righteq = argv[1][3];
     41 			}
     42 			break;
     43 		case 's': szstack[0] = gsize = atoi(&argv[1][2]); break;
     44 		case 'p': deltaps = atoi(&argv[1][2]); dps_set = 1; break;
     45 		case 'm': minsize = atoi(&argv[1][2]); break;
     46 		case 'f': strcpy(ftstack[0].name,&argv[1][2]); break;
     47 		case 'e': noeqn++; break;
     48 		case 'T': typesetter = &argv[1][2]; break;
     49 		default:
     50 			fprintf(stderr, "%s: unknown option %s\n", cmdname, argv[1]);
     51 			break;
     52 		}
     53 		argc--;
     54 		argv++;
     55 	}
     56 	settype(typesetter);
     57 	sprintf(buf, "\"%s\"", typesetter);
     58 	install(deftbl, strsave(typesetter), strsave(buf), 0);
     59 	init_tbl();	/* install other keywords in tables */
     60 	curfile = infile;
     61 	pushsrc(File, curfile->fname);
     62 	if (argc <= 1) {
     63 		curfile->fin = stdin;
     64 		curfile->fname = strsave("-");
     65 		getdata();
     66 	} else
     67 		while (argc-- > 1) {
     68 			if (strcmp(*++argv, "-") == 0)
     69 				curfile->fin = stdin;
     70 			else if ((curfile->fin = fopen(*argv, "r")) == NULL)
     71 				ERROR "can't open file %s", *argv FATAL;
     72 			curfile->fname = strsave(*argv);
     73 			getdata();
     74 			if (curfile->fin != stdin)
     75 				fclose(curfile->fin);
     76 		}
     77 	return 0;
     78 }
     79 
     80 void settype(char *s)	/* initialize data for particular typesetter */
     81 			/* the minsize could profitably come from the */
     82 {			/* troff description file /usr/lib/font/dev.../DESC.out */
     83 	if (strcmp(s, "202") == 0)
     84 		{ minsize = 5; ttype = DEV202; }
     85 	else if (strcmp(s, "aps") == 0)
     86 		{ minsize = 5; ttype = DEVAPS; }
     87 	else if (strcmp(s, "cat") == 0)
     88 		{ minsize = 6; ttype = DEVCAT; }
     89 	else if (strcmp(s, "post") == 0)
     90 		{ minsize = 4; ttype = DEVPOST; }
     91 	else
     92 		{ minsize = 5; ttype = DEV202; }
     93 }
     94 
     95 int
     96 getdata(void)
     97 {
     98 	int i, type, ln;
     99 	char fname[100];
    100 
    101 	errno = 0;
    102 	curfile->lineno = 0;
    103 	printf(".lf 1 %s\n", curfile->fname);
    104 	while ((type = getline(in)) != EOF) {
    105 		if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') {
    106 			for (i = 11; i < 100; i++)
    107 				used[i] = 0;
    108 			printf("%s", in);
    109 			if (markline) {	/* turn off from last time */
    110 				printf(".nr MK 0\n");
    111 				markline = 0;
    112 			}
    113 			display = 1;
    114 			init();
    115 			yyparse();
    116 			if (eqnreg > 0) {
    117 				if (markline)
    118 					printf(".nr MK %d\n", markline); /* for -ms macros */
    119 				printf(".if %gm>\\n(.v .ne %gm\n", eqnht, eqnht);
    120 				printf(".rn %d 10\n", eqnreg);
    121 				if (!noeqn)
    122 					printf("\\&\\*(10\n");
    123 			}
    124 			printf(".EN");
    125 			while (putchar(input()) != '\n')
    126 				;
    127 			printf(".lf %d\n", curfile->lineno+1);
    128 		}
    129 		else if (type == lefteq)
    130 			inline();
    131 		else if (in[0] == '.' && in[1] == 'l' && in[2] == 'f') {
    132 			if (sscanf(in+3, "%d %s", &ln, fname) == 2) {
    133 				free(curfile->fname);
    134 				printf(".lf %d %s\n", curfile->lineno = ln, curfile->fname = strsave(fname));
    135 			} else
    136 				printf(".lf %d\n", curfile->lineno = ln);
    137 		} else
    138 			printf("%s", in);
    139 	}
    140 	return(0);
    141 }
    142 
    143 int
    144 getline(char *s)
    145 {
    146 	register int c;
    147 
    148 	while ((c=input()) != '\n' && c != EOF && c != lefteq) {
    149 		if (s >= in+MAXLINE) {
    150 			ERROR "input line too long: %.20s\n", in WARNING;
    151 			in[MAXLINE] = '\0';
    152 			break;
    153 		}
    154 		*s++ = c;
    155 	}
    156 	if (c != lefteq)
    157 		*s++ = c;
    158 	*s = '\0';
    159 	return(c);
    160 }
    161 
    162 void inline(void)
    163 {
    164 	int ds, n, sz1 = 0;
    165 
    166 	n = curfile->lineno;
    167 	if (szstack[0] != 0)
    168 		printf(".nr %d \\n(.s\n", sz1 = salloc());
    169 	ds = salloc();
    170 	printf(".rm %d \n", ds);
    171 	display = 0;
    172 	do {
    173 		if (*in)
    174 			printf(".as %d \"%s\n", ds, in);
    175 		init();
    176 		yyparse();
    177 		if (eqnreg > 0) {
    178 			printf(".as %d \\*(%d\n", ds, eqnreg);
    179 			sfree(eqnreg);
    180 			printf(".lf %d\n", curfile->lineno+1);
    181 		}
    182 	} while (getline(in) == lefteq);
    183 	if (*in)
    184 		printf(".as %d \"%s", ds, in);
    185 	if (sz1)
    186 		printf("\\s\\n(%d", sz1);
    187 	printf("\\*(%d\n", ds);
    188 	printf(".lf %d\n", curfile->lineno+1);
    189 	if (curfile->lineno > n+3)
    190 		fprintf(stderr, "eqn warning: multi-line %c...%c, file %s:%d,%d\n",
    191 			lefteq, righteq, curfile->fname, n, curfile->lineno);
    192 	sfree(ds);
    193 	if (sz1) sfree(sz1);
    194 }
    195 
    196 void putout(int p1)
    197 {
    198 	double before, after;
    199 	extern double BeforeSub, AfterSub;
    200 
    201 	dprintf(".\tanswer <- S%d, h=%g,b=%g\n",p1, eht[p1], ebase[p1]);
    202 	eqnht = eht[p1];
    203 	before = eht[p1] - ebase[p1] - BeforeSub;	/* leave room for sub or superscript */
    204 	after = ebase[p1] - AfterSub;
    205 	if (spaceval || before > 0.01 || after > 0.01) {
    206 		printf(".ds %d ", p1);	/* used to be \\x'0' here:  why? */
    207 		if (spaceval != NULL)
    208 			printf("\\x'0-%s'", spaceval);
    209 		else if (before > 0.01)
    210 			printf("\\x'0-%gm'", before);
    211 		printf("\\*(%d", p1);
    212 		if (spaceval == NULL && after > 0.01)
    213 			printf("\\x'%gm'", after);
    214 		putchar('\n');
    215 	}
    216 	if (szstack[0] != 0)
    217 		printf(".ds %d %s\\*(%d\\s\\n(99\n", p1, DPS(gsize,gsize), p1);
    218 	eqnreg = p1;
    219 	if (spaceval != NULL) {
    220 		free(spaceval);
    221 		spaceval = NULL;
    222 	}
    223 }
    224 
    225 void init(void)
    226 {
    227 	synerr = 0;
    228 	ct = 0;
    229 	ps = gsize;
    230 	ftp = ftstack;
    231 	ft = ftp->ft;
    232 	nszstack = 0;
    233 	if (szstack[0] != 0)	/* absolute gsize in effect */
    234 		printf(".nr 99 \\n(.s\n");
    235 }
    236 
    237 int
    238 salloc(void)
    239 {
    240 	int i;
    241 
    242 	for (i = 11; i < 100; i++)
    243 		if (used[i] == 0) {
    244 			used[i]++;
    245 			return(i);
    246 		}
    247 	ERROR "no eqn strings left (%d)", i FATAL;
    248 	return(0);
    249 }
    250 
    251 void sfree(int n)
    252 {
    253 	used[n] = 0;
    254 }
    255 
    256 void nrwid(int n1, int p, int n2)
    257 {
    258 	printf(".nr %d 0\\w'%s\\*(%d'\n", n1, DPS(gsize,p), n2);	/* 0 defends against - width */
    259 }
    260 
    261 char *ABSPS(int dn)	/* absolute size dn in printable form \sd or \s(dd (dd >= 40) */
    262 {
    263 	static char buf[100], *lb = buf;
    264 	char *p;
    265 
    266 	if (lb > buf + sizeof(buf) - 10)
    267 		lb = buf;
    268 	p = lb;
    269 	*lb++ = '\\';
    270 	*lb++ = 's';
    271 	if (dn >= 10) {		/* \s(dd only works in new troff */
    272 		if (dn >= 40)
    273 			*lb++ = '(';
    274 		*lb++ = dn/10 + '0';
    275 		*lb++ = dn%10 + '0';
    276 	} else {
    277 		*lb++ = dn + '0';
    278 	}
    279 	*lb++ = '\0';
    280 	return p;
    281 }
    282 
    283 char *DPS(int f, int t)	/* delta ps (t-f) in printable form \s+d or \s-d or \s+-(dd */
    284 {
    285 	static char buf[100], *lb = buf;
    286 	char *p;
    287 	int dn;
    288 
    289 	if (lb > buf + sizeof(buf) - 10)
    290 		lb = buf;
    291 	p = lb;
    292 	*lb++ = '\\';
    293 	*lb++ = 's';
    294 	dn = EFFPS(t) - EFFPS(f);
    295 	if (szstack[nszstack] != 0)	/* absolute */
    296 		dn = EFFPS(t);		/* should do proper \s(dd */
    297 	else if (dn >= 0)
    298 		*lb++ = '+';
    299 	else {
    300 		*lb++ = '-';
    301 		dn = -dn;
    302 	}
    303 	if (dn >= 10) {		/* \s+(dd only works in new troff */
    304 		*lb++ = '(';
    305 		*lb++ = dn/10 + '0';
    306 		*lb++ = dn%10 + '0';
    307 	} else {
    308 		*lb++ = dn + '0';
    309 	}
    310 	*lb++ = '\0';
    311 	return p;
    312 }
    313 
    314 int
    315 EFFPS(int n)	/* effective value of n */
    316 {
    317 	if (n >= minsize)
    318 		return n;
    319 	else
    320 		return minsize;
    321 }
    322 
    323 double EM(double m, int ps)	/* convert m to ems in gsize */
    324 {
    325 	m *= (double) EFFPS(ps) / gsize;
    326 	if (m <= 0.001 && m >= -0.001)
    327 		return 0;
    328 	else
    329 		return m;
    330 }
    331 
    332 double REL(double m, int ps)	/* convert m to ems in ps */
    333 {
    334 	m *= (double) gsize / EFFPS(ps);
    335 	if (m <= 0.001 && m >= -0.001)
    336 		return 0;
    337 	else
    338 		return m;
    339 }