URI:
       tmain.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tmain.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 }