home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume24 / psroff3.0 / part07 / utils.c < prev   
Encoding:
C/C++ Source or Header  |  1991-10-09  |  12.5 KB  |  570 lines

  1. /*
  2.     Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991 Chris Lewis
  3.         All Rights Reserved
  4.  
  5.     See the LICENSE file for a full description of restrictions under which
  6.     this software is provided.
  7.  
  8.     Function:        Utility functions (font loads, prologs etc.)
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. #ifndef    lint
  14. static char SCCSid[] =
  15.     "@(#)utils.c: 2.14 Copyright 91/04/05 01:21:20 Chris Lewis";
  16. #endif
  17.  
  18. #ifndef    HEADERSIZE
  19. #    ifdef COFF
  20. #        include <aouthdr.h>
  21. #        include <filehdr.h>
  22. #        include <scnhdr.h>
  23. #        include <ldfcn.h>
  24. #        include <reloc.h>
  25. #        define H1 (sizeof (struct filehdr) + sizeof (struct aouthdr))
  26. #        define H2 (sizeof (struct scnhdr) + sizeof (struct reloc))
  27. #        define HEADERSIZE (H1 + H2)
  28. #    else
  29. #        include <a.out.h>
  30. #        define HEADERSIZE (sizeof (struct exec))
  31. #    endif
  32. #endif
  33.  
  34. extern struct cattab tabN[], tabS[];
  35.  
  36. int lastFont, lastPoints;
  37. int lastYPos, lastXPos;
  38.  
  39. int symidx = 3;        /* Default on otroff, otroff doesn't necessarily
  40.                emit loads either */
  41.  
  42. int extcount = 0;
  43. struct troff2befont *extchars;
  44. struct cattab *extidx;
  45.  
  46. extern char *malloc();
  47.  
  48. char *skipblanks(p)
  49. register char *p; {
  50.     while (*p && isspace(*p)) p++;
  51.     return(p);
  52. }
  53.  
  54. char *gettok(p, bp)
  55. register char *p, *bp; {
  56.     p = skipblanks(p);
  57.     while(*p && !isspace(*p)) *bp++ = *p++;
  58.     *bp = '\0';
  59.     return(p);
  60. }
  61.  
  62. interp(buf, xlator, suf)
  63. char *buf, *suf; FUNC xlator; {
  64.     register char *p;
  65.     char token[512];
  66.     p = gettok(buf, token);
  67.     if (0 == strcmp(token, "include") || 0 == strcmp(token, "binclude")) {
  68.     int binary;
  69.     FILE *inc;
  70.     binary = (token[0] == 'b') ? 1: 0;
  71.     p = gettok(p, token);
  72.     DBP((D_SPEC, "Trying to include %s\n", token));
  73.     if (!(inc = fopen(token, "r"))) {
  74.         strcat(token, ".");
  75.         strcat(token, suf);
  76.         DBP((D_SPEC, "Trying to include %s\n", token));
  77.         if (!(inc = fopen(token, "r"))) {
  78.         char nbuf[512];
  79.         if (token[0] != '/') {
  80.             sprintf(nbuf, "%s/%s", LIBDIR, token);
  81.             DBP((D_SPEC, "Trying to include %s\n", nbuf));
  82.             inc = fopen(nbuf, "r");
  83.         }
  84.         }
  85.     }
  86.     if (!inc) {
  87.         fprintf(stderr, "%s: cannot open file %s\n", progname, token);
  88.         exit(1);
  89.     } else {
  90.         DBP((D_SPEC, "Successfull include\n"));
  91.         if (binary || !xlator)
  92.         while ((binary = fread(token, 1, sizeof(token), inc)) > 0)
  93.             fwrite(token, 1, binary, stdout);
  94.         else
  95.         (*xlator)(inc);
  96.         fclose(inc);
  97.     }
  98.     }
  99.  
  100.     else {
  101.     fprintf(stderr, "%s: unknown directive: %s\n", progname, token);
  102.     exit(1);
  103.     }
  104. }
  105.  
  106. char nodename[25];
  107. getnodename() {
  108.     FILE *popen();
  109.     FILE *uuname;
  110.     if ((uuname = popen(NODECMD, "r")) == NULL)
  111.     strcpy(nodename, "<noname>");
  112.     else {
  113.     fscanf(uuname, "%s", nodename);
  114.     if (pclose(uuname))
  115.         strcpy(nodename, "<noname>");
  116.     }
  117. }
  118.  
  119. struct fonttable fonttable[MAXFONTS+1];
  120. struct fonttable *xlatetable[INTFONTS];
  121.  
  122. #define    READFONT    0
  123. #define    READNORM    1
  124. #define    READSYMB    2
  125. #define    READEXT        3
  126.  
  127. loadfont(normfont, symfont)
  128. struct troff2befont *normfont, *symfont; {
  129.  
  130.     char buffer[BUFSIZ];
  131.     char *buf[6];
  132.     int tableindex;
  133.     int state, i, count;
  134.     register char *first;
  135.     extern int atoi();
  136.     struct cattab *tab;
  137.     struct troff2befont *otab;
  138.     int done;
  139.  
  140.     FILE *fontfile;
  141.  
  142.     for (i = 0; i < 6; i++)
  143.     buf[i] = mustmalloc(64, "loadfont");
  144.  
  145.     for (tableindex = 0; tableindex < INTFONTS; tableindex++) {
  146.     xlatetable[tableindex] = &fonttable[tableindex];
  147.     }
  148.  
  149.     fontfile = libopen(printer, "fonts");
  150.  
  151.     tableindex = 0;
  152.  
  153.     state = READFONT;
  154.  
  155.     while(fgets(buffer, sizeof(buffer), fontfile)) {
  156.  
  157.     first = buffer;
  158.  
  159.     for(;*first && isspace(*first); first++);
  160.  
  161.     if (!*first || *first == '#')
  162.         continue;
  163.  
  164.     switch(count = sscanf(first, "%s%s%s%s%s%s",
  165.         buf[0], buf[1], buf[2], buf[3], buf[4], buf[5])) {
  166.         case 1: buf[1][0] = '\0';
  167.         case 2: buf[2][0] = '\0';
  168.         case 3: buf[3][0] = '\0';
  169.         case 4: buf[4][0] = '\0';
  170.         case 5: buf[5][0] = '\0';
  171.         case 6:
  172.         if        (strcmp(buf[0], "normal") == 0) {
  173.             state = READNORM;
  174.             break;
  175.         } else if (strcmp(buf[0], "symbol") == 0) {
  176.             state = READSYMB;
  177.             break;
  178.         } else if (strcmp(buf[0], "extensions") == 0) {
  179.             state = READEXT;
  180.             break;
  181.         }
  182.         switch(state) {
  183.             case READFONT:
  184.             if (tableindex == MAXFONTS) {
  185.                 fprintf(stderr, "%s: Too many fonts for %s!\n",
  186.                 progname, printer);
  187.                 exit(1);
  188.             }
  189.             for(i = 0; i < 4; i++) {
  190.                 first = mustmalloc(strlen(buf[i])+1,
  191.                 "fonttable");
  192.                 strcpy(first, buf[i]);
  193.                 fonttable[tableindex].tab[i] = first;
  194.             }
  195. #ifdef    OPT
  196.             fonttable[tableindex].widthtable = (char *) NULL;
  197. #endif
  198.             tableindex++;
  199.             break;
  200.             case READNORM: case READSYMB: case READEXT:
  201.             done = 0;
  202.             if (count <= 1) {
  203.                 fprintf(stderr, "%s: bad %s.fonts line: %s\n",
  204.                 progname, printer, buffer);
  205.                 exit(1);
  206.             }
  207.  
  208.             if (state == READEXT) {
  209.                 if (!(extcount % EXTCHUNK)) {
  210.                 if (!extchars) {
  211.                     extchars = (struct troff2befont *)
  212.                     mustmalloc(EXTCHUNK *
  213.                     sizeof(struct troff2befont), "extchars");
  214.                     extidx = (struct cattab *)
  215.                     mustmalloc((1 + EXTCHUNK) *
  216.                     sizeof(struct cattab), "extidx");
  217.                 } else {
  218.                     extchars = (struct troff2befont *)
  219.                     realloc((char *) extchars,
  220.                         (extcount + EXTCHUNK + 1) *
  221.                         sizeof(struct troff2befont));
  222.                     extidx = (struct cattab *)
  223.                     realloc((char *) extidx,
  224.                         (extcount + EXTCHUNK + 1) *
  225.                         sizeof(struct cattab));
  226.                     clrarray(&extchars[extcount],
  227.                     EXTCHUNK * sizeof(struct troff2befont));
  228.                     clrarray(&extidx[extcount],
  229.                     EXTCHUNK * sizeof(struct cattab));
  230.                 }
  231.                 }
  232.  
  233.                 extidx[extcount].ch_name = mustmalloc(strlen(buf[0])
  234.                 + 1, "extend");
  235.                 strcpy(extidx[extcount].ch_name, buf[0]);
  236.  
  237.                 extidx[extcount].ch_catidx = extcount;
  238.                 addchar(&extchars[extcount], buf, count, buffer);
  239.                 extidx[extcount].ch_set = extchars[extcount].t2b_font;
  240.                 extidx[extcount].ch_wididx = NTC;
  241.                 extidx[extcount].ch_desc = "Ext";
  242.  
  243.                 extcount++;
  244.                 extidx[extcount].ch_name = NOC;
  245.                 done = 1;
  246.             } else {
  247.                 if (state == READNORM) {
  248.                 tab = tabN;
  249.                 otab = normfont;
  250.                 } else {
  251.                 tab = tabS;
  252.                 otab = symfont;
  253.                 }
  254.  
  255.                 for (i = 0; tab[i].ch_name; i++) {
  256.                 if (strcmp(tab[i].ch_name, buf[0]) == 0) {
  257.                     addchar(&otab[i], buf, count, buffer);
  258.                     done = 1;
  259.                     break;
  260.                 }
  261.                 }
  262.             }
  263.             if (!done) {
  264.                 fprintf(stderr, "%s: couldn't apply %s.fonts: %s\n",
  265.                 progname, printer, buffer);
  266.                 exit(1);
  267.             }
  268.         }
  269.     }
  270.     }
  271.     fclose(fontfile);
  272. #ifdef    OPT
  273.     loadwidth(xlatetable[0]);
  274.     loadwidth(xlatetable[1]);
  275.     loadwidth(xlatetable[2]);
  276.     loadwidth(xlatetable[3]);
  277. #endif
  278.     for (i = 0; i < 6; i++)
  279.     free(buf[i]);
  280. }
  281.  
  282. addchar(p, fontentry, count, buffer)
  283. register struct troff2befont *p;
  284. char *fontentry[];
  285. char *buffer;
  286. int count; {
  287.     register char *first;
  288.     switch(fontentry[1][0]) {
  289.     case 'N':
  290.         p->t2b_font = N; break;
  291.     case 'S':
  292.         p->t2b_font = S; break;
  293.     case 'D':
  294.         p->t2b_font = D; break;
  295.     case '0':
  296.     case '1':
  297.     case '2':
  298.     case '3':
  299.     case '4':
  300.     case '5':
  301.     case '6':
  302.     case '7':
  303.     case '8':
  304.     case '9':
  305.         p->t2b_font = atoi(fontentry[1]);
  306.         break;
  307.     default:
  308.         fprintf(stderr, "%s: bad font in %s\n",
  309.         progname, buffer);
  310.         exit(1);
  311.     }
  312.     switch(count) {
  313.     case 6:
  314.         p->t2b_scale = atoi(fontentry[5]);
  315.     case 5:
  316.         p->t2b_yc = atoi(fontentry[4]);
  317.     case 4:
  318.         p->t2b_xc = atoi(fontentry[3]);
  319.     case 3:
  320.         octdecode(fontentry[2]);
  321.         first = mustmalloc(strlen(fontentry[2]) + 1,
  322.         "fonttable");
  323.         strcpy(first, fontentry[2]);
  324.         p->t2b_charseq = first;
  325.     }
  326. }
  327.  
  328. /*    Translate any octal escapes *inplace* */
  329. octdecode(str)
  330. register char *str; {
  331.     register char *from, *to;
  332.     int tmp, i;
  333.     from = to = str;
  334.     while(*from) {
  335.     if (*from != '\\')
  336.         *to++ = *from++;
  337.     else {
  338.         tmp = 0;
  339.         from++;
  340.         i = 3;
  341.         while(i-- > 0 && *from && *from >= '0' && *from <= '7')
  342.         tmp = (tmp << 3) + *from++ - '0';
  343.         *to++ = tmp&0xff;
  344.     }
  345.     }
  346.     *to++ = '\0';
  347. }
  348.  
  349.  
  350. dumpsequence(sequence)
  351. register char *sequence; {
  352.     printf("\t");
  353.     for(;*sequence;sequence++)
  354.     if (isascii(*sequence) && isprint(*sequence))
  355.         printf("%c", *sequence);
  356.     else
  357.         printf("\\%03o", (*sequence)&0xff);
  358. }
  359.  
  360. dumpline(name, tp)
  361. register char *name;
  362. register struct troff2befont *tp; {
  363.     if (name != NOC) {
  364.     printf("%s\t", name);
  365.     switch(tp->t2b_font) {
  366.         case N: printf("N"); break;
  367.         case S: printf("S"); break;
  368.         case D: printf("D"); break;
  369.         default: printf("%d", tp->t2b_font); break;
  370.     }
  371.     dumpsequence(tp->t2b_charseq);
  372.     printf("\t%d\t%d\t%d", tp->t2b_xc, tp->t2b_yc, tp->t2b_scale);
  373.     printf("\n");
  374.     }
  375. }
  376.  
  377. dumplist(namelist, tp)
  378. register struct cattab *namelist;
  379. register struct troff2befont *tp; {
  380.     register int i;
  381.     for (i = 0; namelist[i].ch_name && namelist[i].ch_catidx != NTC;
  382.     i++, tp++) {
  383.     if (strlen(namelist[i].ch_name) == 0)
  384.         continue;
  385.     if (strcmp(namelist[i].ch_name, "hy") == 0)
  386.         dumpline("-", tp);
  387.     dumpline(namelist[i].ch_name, tp);
  388.     }
  389. }
  390.  
  391. dumptables(bep)
  392. struct backend *bep; {
  393.     if (!bep) {
  394.     fprintf(stderr, "%s: no backend selected for table dump\n", progname);
  395.     exit(1);
  396.     }
  397.     printf("normal\n");
  398.     dumplist(tabN, bep->bestdfont);
  399.     printf("symbol\n");
  400.     dumplist(tabS, bep->besymfont);
  401.     if (extchars) {
  402.     printf("extensions\n");
  403.     dumplist(extidx, extchars);
  404.     }
  405. }
  406.  
  407. FontSel(from, to)
  408. char from, *to; {
  409. #ifdef    DEBUG
  410.     register int i;
  411. #endif
  412.     register struct fonttable *p;
  413.     int intfont;
  414.     DBP((D_SPEC, "FontSel: %c -> %s\n", from, to));
  415.     if (from < (ditroff? '0' : '1') || from > '9') {
  416.     fprintf(stderr, "Bad arguments to FontSel: %c %s\n", from, to);
  417.     return;
  418.     }
  419.     intfont = from - '1';
  420.     if (intfont < 0)
  421.     intfont = INTFONTS - 1;
  422.     if (strcmp(to, "S") == 0) {
  423.     symidx = intfont;
  424.     DBP((D_CAT, "Special font is: %d\n", symidx));
  425.     }
  426.  
  427.     for (p = fonttable; p->troffName; p++)
  428.     if (strcmp(p->troffName, to) == 0) {
  429.         xlatetable[intfont] = p;
  430.         break;
  431.     }
  432.     if (!p->troffName) {
  433.     fprintf(stderr, "Could not translate font %c (%s)\n", from, to);
  434.     }
  435. #ifdef    OPT
  436.     if (p->troffName && !p->widthtable)
  437.     loadwidth(p);
  438. #endif
  439.  
  440. #ifdef    DEBUG
  441.     for (i = 0; i < INTFONTS; i++)
  442.     if (xlatetable[i])
  443.         DBP((D_SPEC, "Font %d->%s\n", i+1, xlatetable[i]->fontName));
  444. #endif
  445. }
  446.  
  447. FILE *libopen(pref, suf)
  448. register char *pref, *suf; {
  449.  
  450.     register char *buffer = mustmalloc(strlen(LIBDIR) + 50, "libopen");
  451.     register FILE *library;
  452.  
  453.     sprintf(buffer, "%s.%s", pref, suf);
  454.     if ((library = fopen(buffer, "r")) == NULL) {
  455.     sprintf(buffer, "lib/%s.%s", pref, suf);
  456.     if ((library = fopen(buffer, "r")) == NULL) {
  457.         sprintf(buffer, "%s/%s.%s", LIBDIR, pref, suf);
  458.         if ((library = fopen(buffer, "r")) == NULL) {
  459.         fprintf(stderr, "Cannot find %s.%s in . or lib or %s\n", pref, suf,
  460.             LIBDIR);
  461.         exit(1);
  462.         }
  463.     }
  464.     }
  465.     free(buffer);
  466.     return(library);
  467. }
  468.  
  469. resetState() {
  470.     lastFont = -1;
  471.     lastPoints = -1;
  472.     lastYPos = -1;
  473.     lastXPos = -1;
  474. }
  475.  
  476. doprologs() {
  477.     if (!prologs)
  478.     return;
  479.     while(*prologs)
  480.     dospecial(*prologs++);
  481. }
  482.  
  483. #ifdef    OPT
  484. loadwidth(p)
  485. struct fonttable *p; {
  486.     FILE *f;
  487.     int c;
  488.     if ((int) p->widthtable == 1)
  489.     return;
  490.     p->widthtable = mustmalloc(224, "widthtable");
  491.     strcpy(widthptr, "ft");
  492.     strcat(widthptr, p->troffName);
  493.     DBP((D_SPEC, "Attempting to read font file %s\n", widthtables));
  494.     if (f = fopen(widthtables, "r")) {
  495.     for (c = 0; c < HEADERSIZE; c++) getc(f);
  496. #ifdef    ASCIIWIDTHS
  497.     if (widread(p->widthtable, f)) {
  498. #else
  499.     if (224 != fread(p->widthtable, 1, 224, f)) {
  500. #endif
  501.         fprintf(stderr, "%s: badly formed width table %s\n",
  502.         progname, widthtables);
  503.         free(p->widthtable);
  504.         p->widthtable = (char *) 1;
  505.         DBP((D_SPEC, "Load of %s failed\n", widthtables));
  506.     } else {
  507.         for (c = 0; c < 224; c++)
  508.         p->widthtable[c] &= 0x3f;
  509.         DBP((D_SPEC, "Load of %s succeeded\n", widthtables));
  510.     }
  511.     } else {
  512.     DBP((D_SPEC, "Failed to open widthtable %s\n", widthtables));
  513.     free(p->widthtable);
  514.     p->widthtable = (char *) 1;
  515.     }
  516. }
  517.  
  518. #ifdef    ASCIIWIDTHS
  519. widread(widths, f)
  520. char *widths;
  521. FILE *f; {
  522.     int v, i;
  523.     for (i = 0; i < 224; i++)
  524.     if (fscanf(f, "%d", &v) != 1)
  525.         return(1);
  526.     else
  527.         widths[i] = v;
  528.     return(0);
  529. }
  530. #endif
  531.  
  532. #endif
  533.  
  534. #ifdef    NULLCHECK
  535. mab() {
  536.     fprintf(stderr, "KABOOM\n");
  537.     abort();
  538. }
  539. #endif
  540.  
  541. drawparse(ct, values, str)
  542. int *ct;
  543. short *values;
  544. char *str; {
  545.     int opcode, neg, temp;
  546.  
  547.     *ct = 0;
  548.     while(*str && isspace(*str)) str++;
  549.     opcode = *str;
  550.     neg = 1;
  551.     for (;*str;str++) {
  552.     if (isspace(*str))
  553.         continue;
  554.     else if (*str == '\\')
  555.         str += 3;
  556.     else if (*str == '-')
  557.         neg = -1;
  558.     else if (!isdigit(*str))
  559.         continue;
  560.     else {
  561.         temp = *str - '0';
  562.         while(isdigit(*(str+1)))
  563.         temp = temp * 10 + (*++str - '0');
  564.         values[(*ct)++] = neg * temp;
  565.         neg = 1;
  566.     }
  567.     }
  568.     return(opcode);
  569. }
  570.