1*364Sceastha /* 2*364Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3*364Sceastha * Use is subject to license terms. 4*364Sceastha */ 5*364Sceastha 60Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 70Sstevel@tonic-gate /* All Rights Reserved */ 80Sstevel@tonic-gate 90Sstevel@tonic-gate /* 100Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California. 110Sstevel@tonic-gate * All rights reserved. The Berkeley software License Agreement 120Sstevel@tonic-gate * specifies the terms and conditions for redistribution. 130Sstevel@tonic-gate */ 14*364Sceastha 15*364Sceastha #pragma ident "%Z%%M% %I% %E% SMI" 160Sstevel@tonic-gate 17*364Sceastha #include "e.h" 18*364Sceastha #include <stdlib.h> 19*364Sceastha #include <locale.h> 200Sstevel@tonic-gate 210Sstevel@tonic-gate #define MAXLINE 8192 /* maximum input line */ 220Sstevel@tonic-gate 23*364Sceastha char in[MAXLINE+1]; /* input buffer */ 240Sstevel@tonic-gate int noeqn; 250Sstevel@tonic-gate 26*364Sceastha void error(int, char *, char *); 270Sstevel@tonic-gate 28*364Sceastha static void do_inline(void); 29*364Sceastha int eqn(int, char *[]); 30*364Sceastha static int getline(char *); 31*364Sceastha static void init(void); 32*364Sceastha void nrwid(int, int, int); 33*364Sceastha int oalloc(void); 34*364Sceastha void ofree(int); 35*364Sceastha static void setfile(int, char *[]); 36*364Sceastha void setps(int); 37*364Sceastha 38*364Sceastha int 39*364Sceastha main(int argc, char *argv[]) 40*364Sceastha { 410Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 420Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 430Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 440Sstevel@tonic-gate #endif 450Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 46*364Sceastha return (eqn(argc, argv)); 470Sstevel@tonic-gate } 480Sstevel@tonic-gate 49*364Sceastha int 50*364Sceastha eqn(int argc, char *argv[]) 51*364Sceastha { 520Sstevel@tonic-gate int i, type; 530Sstevel@tonic-gate 54*364Sceastha setfile(argc, argv); 550Sstevel@tonic-gate init_tbl(); /* install keywords in tables */ 56*364Sceastha while ((type = getline(in)) != EOF) { 570Sstevel@tonic-gate eqline = linect; 58*364Sceastha if (in[0] == '.' && in[1] == 'E' && in[2] == 'Q') { 59*364Sceastha for (i = 11; i < 100; used[i++] = 0) 60*364Sceastha ; 61*364Sceastha printf("%s", in); 620Sstevel@tonic-gate printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); 630Sstevel@tonic-gate markline = 0; 640Sstevel@tonic-gate init(); 650Sstevel@tonic-gate yyparse(); 66*364Sceastha if (eqnreg > 0) { 670Sstevel@tonic-gate printf(".nr %d \\w'\\*(%d'\n", eqnreg, eqnreg); 68*364Sceastha /* 69*364Sceastha * printf(".if \\n(%d>\\n(.l .tm too-long eqn, 70*364Sceastha * file %s, between lines %d-%d\n", 71*364Sceastha * eqnreg, svargv[ifile], eqline, linect); 72*364Sceastha */ 73*364Sceastha 74*364Sceastha /* for -ms macros */ 75*364Sceastha printf(".nr MK %d\n", markline); 76*364Sceastha 770Sstevel@tonic-gate printf(".if %d>\\n(.v .ne %du\n", eqnht, eqnht); 780Sstevel@tonic-gate printf(".rn %d 10\n", eqnreg); 79*364Sceastha if (!noeqn) printf("\\*(10\n"); 800Sstevel@tonic-gate } 810Sstevel@tonic-gate printf(".ps \\n(99\n.ft \\n(98\n"); 820Sstevel@tonic-gate printf(".EN"); 830Sstevel@tonic-gate if (lastchar == EOF) { 840Sstevel@tonic-gate putchar('\n'); 850Sstevel@tonic-gate break; 860Sstevel@tonic-gate } 870Sstevel@tonic-gate if (putchar(lastchar) != '\n') 88*364Sceastha while (putchar(gtc()) != '\n') 89*364Sceastha ; 90*364Sceastha } else if (type == lefteq) 910Sstevel@tonic-gate do_inline(); 920Sstevel@tonic-gate else 93*364Sceastha printf("%s", in); 940Sstevel@tonic-gate } 95*364Sceastha return (0); 960Sstevel@tonic-gate } 970Sstevel@tonic-gate 98*364Sceastha static int 99*364Sceastha getline(char *s) 100*364Sceastha { 101*364Sceastha int c; 102*364Sceastha while ((*s++ = c = gtc()) != '\n' && c != EOF && c != lefteq) 1030Sstevel@tonic-gate if (s >= in+MAXLINE) { 104*364Sceastha error(!FATAL, gettext( 105*364Sceastha "input line too long: %.20s\n"), in); 1060Sstevel@tonic-gate in[MAXLINE] = '\0'; 1070Sstevel@tonic-gate break; 1080Sstevel@tonic-gate } 109*364Sceastha if (c == lefteq) 1100Sstevel@tonic-gate s--; 1110Sstevel@tonic-gate *s++ = '\0'; 112*364Sceastha return (c); 1130Sstevel@tonic-gate } 1140Sstevel@tonic-gate 115*364Sceastha static void 116*364Sceastha do_inline(void) 117*364Sceastha { 1180Sstevel@tonic-gate int ds; 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate printf(".nr 99 \\n(.s\n.nr 98 \\n(.f\n"); 1210Sstevel@tonic-gate ds = oalloc(); 1220Sstevel@tonic-gate printf(".rm %d \n", ds); 123*364Sceastha do { 1240Sstevel@tonic-gate if (*in) 1250Sstevel@tonic-gate printf(".as %d \"%s\n", ds, in); 1260Sstevel@tonic-gate init(); 1270Sstevel@tonic-gate yyparse(); 1280Sstevel@tonic-gate if (eqnreg > 0) { 1290Sstevel@tonic-gate printf(".as %d \\*(%d\n", ds, eqnreg); 1300Sstevel@tonic-gate ofree(eqnreg); 1310Sstevel@tonic-gate } 1320Sstevel@tonic-gate printf(".ps \\n(99\n.ft \\n(98\n"); 1330Sstevel@tonic-gate } while (getline(in) == lefteq); 1340Sstevel@tonic-gate if (*in) 1350Sstevel@tonic-gate printf(".as %d \"%s", ds, in); 1360Sstevel@tonic-gate printf(".ps \\n(99\n.ft \\n(98\n"); 1370Sstevel@tonic-gate printf("\\*(%d\n", ds); 1380Sstevel@tonic-gate ofree(ds); 1390Sstevel@tonic-gate } 1400Sstevel@tonic-gate 141*364Sceastha void 142*364Sceastha putout(int p1) 143*364Sceastha { 1440Sstevel@tonic-gate extern int gsize, gfont; 1450Sstevel@tonic-gate int before, after; 146*364Sceastha if (dbg) 147*364Sceastha printf(".\tanswer <- S%d, h=%d,b=%d\n", p1, eht[p1], ebase[p1]); 1480Sstevel@tonic-gate eqnht = eht[p1]; 1490Sstevel@tonic-gate printf(".ds %d \\x'0'", p1); 1500Sstevel@tonic-gate /* suppposed to leave room for a subscript or superscript */ 1510Sstevel@tonic-gate #ifndef NEQN 1520Sstevel@tonic-gate before = eht[p1] - ebase[p1] - VERT(EM(1.2, ps)); 153*364Sceastha #else /* NEQN */ 1540Sstevel@tonic-gate before = eht[p1] - ebase[p1] - VERT(3); /* 3 = 1.5 lines */ 155*364Sceastha #endif /* NEQN */ 1560Sstevel@tonic-gate if (spaceval != NULL) 1570Sstevel@tonic-gate printf("\\x'0-%s'", spaceval); 1580Sstevel@tonic-gate else if (before > 0) 1590Sstevel@tonic-gate printf("\\x'0-%du'", before); 1600Sstevel@tonic-gate printf("\\f%c\\s%d\\*(%d%s\\s\\n(99\\f\\n(98", 161*364Sceastha gfont, gsize, p1, rfont[p1] == ITAL ? "\\|" : ""); 1620Sstevel@tonic-gate #ifndef NEQN 1630Sstevel@tonic-gate after = ebase[p1] - VERT(EM(0.2, ps)); 164*364Sceastha #else /* NEQN */ 1650Sstevel@tonic-gate after = ebase[p1] - VERT(1); 166*364Sceastha #endif /* NEQN */ 1670Sstevel@tonic-gate if (spaceval == NULL && after > 0) 1680Sstevel@tonic-gate printf("\\x'%du'", after); 1690Sstevel@tonic-gate putchar('\n'); 1700Sstevel@tonic-gate eqnreg = p1; 1710Sstevel@tonic-gate if (spaceval != NULL) { 1720Sstevel@tonic-gate free(spaceval); 1730Sstevel@tonic-gate spaceval = NULL; 1740Sstevel@tonic-gate } 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate } 1770Sstevel@tonic-gate 178*364Sceastha int 179*364Sceastha max(int i, int j) 180*364Sceastha { 181*364Sceastha return (i > j ? i : j); 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate 184*364Sceastha int 185*364Sceastha oalloc(void) 186*364Sceastha { 1870Sstevel@tonic-gate int i; 188*364Sceastha char ebuf[3]; 189*364Sceastha 190*364Sceastha for (i = 11; i < 100; i++) 191*364Sceastha if (used[i]++ == 0) 192*364Sceastha return (i); 193*364Sceastha (void) snprintf(ebuf, sizeof (ebuf), "%d", i); 194*364Sceastha error(FATAL, gettext("no eqn strings left"), ebuf); 195*364Sceastha return (0); 1960Sstevel@tonic-gate } 1970Sstevel@tonic-gate 198*364Sceastha void 199*364Sceastha ofree(int n) 200*364Sceastha { 2010Sstevel@tonic-gate used[n] = 0; 2020Sstevel@tonic-gate } 2030Sstevel@tonic-gate 204*364Sceastha void 205*364Sceastha setps(int p) 206*364Sceastha { 2070Sstevel@tonic-gate printf(".ps %d\n", EFFPS(p)); 2080Sstevel@tonic-gate } 2090Sstevel@tonic-gate 210*364Sceastha void 211*364Sceastha nrwid(int n1, int p, int n2) 212*364Sceastha { 2130Sstevel@tonic-gate printf(".nr %d \\w'\\s%d\\*(%d'\n", n1, EFFPS(p), n2); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate 216*364Sceastha static void 217*364Sceastha setfile(int argc, char *argv[]) 218*364Sceastha { 2190Sstevel@tonic-gate static char *nullstr = "-"; 2200Sstevel@tonic-gate 2210Sstevel@tonic-gate svargc = --argc; 2220Sstevel@tonic-gate svargv = argv; 2230Sstevel@tonic-gate while (svargc > 0 && svargv[1][0] == '-') { 2240Sstevel@tonic-gate switch (svargv[1][1]) { 2250Sstevel@tonic-gate 226*364Sceastha case 'd': lefteq = svargv[1][2]; righteq = svargv[1][3]; break; 2270Sstevel@tonic-gate case 's': gsize = atoi(&svargv[1][2]); break; 2280Sstevel@tonic-gate case 'p': deltaps = atoi(&svargv[1][2]); break; 2290Sstevel@tonic-gate case 'f': gfont = svargv[1][2]; break; 2300Sstevel@tonic-gate case 'e': noeqn++; break; 231*364Sceastha case 0: goto endargs; 2320Sstevel@tonic-gate default: dbg = 1; 2330Sstevel@tonic-gate } 2340Sstevel@tonic-gate svargc--; 2350Sstevel@tonic-gate svargv++; 2360Sstevel@tonic-gate } 237*364Sceastha endargs: 2380Sstevel@tonic-gate ifile = 1; 2390Sstevel@tonic-gate linect = 1; 2400Sstevel@tonic-gate if (svargc <= 0) { 2410Sstevel@tonic-gate curfile = stdin; 2420Sstevel@tonic-gate svargv[1] = nullstr; 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate else 2450Sstevel@tonic-gate openinfile(); /* opens up the first input file */ 2460Sstevel@tonic-gate } 2470Sstevel@tonic-gate 248*364Sceastha void 249*364Sceastha yyerror(void) 250*364Sceastha { 251*364Sceastha } 2520Sstevel@tonic-gate 253*364Sceastha static void 254*364Sceastha init(void) 255*364Sceastha { 2560Sstevel@tonic-gate ct = 0; 2570Sstevel@tonic-gate ps = gsize; 2580Sstevel@tonic-gate ft = gfont; 2590Sstevel@tonic-gate setps(ps); 2600Sstevel@tonic-gate printf(".ft %c\n", ft); 2610Sstevel@tonic-gate } 2620Sstevel@tonic-gate 263*364Sceastha void 264*364Sceastha error(int fatal, char *s1, char *s2) 265*364Sceastha { 266*364Sceastha if (fatal > 0) 2670Sstevel@tonic-gate printf(gettext("eqn fatal error: ")); 2680Sstevel@tonic-gate printf(s1, s2); 2690Sstevel@tonic-gate printf(gettext("\nfile %s, between lines %d and %d\n"), 270*364Sceastha svargv[ifile], eqline, linect); 2710Sstevel@tonic-gate fprintf(stderr, gettext("eqn: ")); 272*364Sceastha if (fatal > 0) 2730Sstevel@tonic-gate fprintf(stderr, gettext("fatal error: ")); 2740Sstevel@tonic-gate fprintf(stderr, s1, s2); 2750Sstevel@tonic-gate fprintf(stderr, gettext("\nfile %s, between lines %d and %d\n"), 276*364Sceastha svargv[ifile], eqline, linect); 2770Sstevel@tonic-gate if (fatal > 0) 278*364Sceastha exit(1); 2790Sstevel@tonic-gate } 280