home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume15 / nroffgraphics / part01 / otwrite.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-06-06  |  5.9 KB  |  200 lines

  1. /*
  2.  * otwrite.c -- dump an internal driver-table representation in old-nroff form
  3.  *
  4.  * This code brought to you as a public service by Eric S. Raymond, Feb 1988
  5.  * and is copyrighted (c)1988 by the author. Use, distribute, and mangle
  6.  * freely, but don't try to make money selling it unless you're going to send
  7.  * me a cut. Send bug reports, love letters and death threats to eric@snark
  8.  * aka ...!rutgers!vu-vlsi!snark!eric.
  9.  *
  10.  * This stuff was Bruce Townsend & Ian Darwin's table.c code in a former life,
  11.  * but the data structures are different and cleaner now.
  12.  */
  13. /*LINTLIBRARY*/
  14. #include <stdio.h>
  15. #include "termtab.h"
  16.  
  17. extern char *strcpy();
  18. extern void exit();
  19.  
  20. static void addchar(string, pp)
  21. char    *string;
  22. strtab    *pp;
  23. {
  24.     pp->c_pointer[pp->n_strings] = pp->c_end;
  25.     pp->c_end += (pp->c_length[pp->n_strings] = strlen(string + 2) + 2) + 1;
  26.     if (pp->c_end >= pp->c_data + C_SIZE)
  27.     {
  28.     (void) fprintf(stderr, "Table size too small, increase it!\n");
  29.     exit(1);
  30.     }
  31.     /*
  32.      * copy in the first two bytes without checking for a NUL, this is
  33.      * so we handle the (legal!) case of 0-length characters correctly
  34.      */
  35.     *pp->c_pointer[pp->n_strings] = *string++;
  36.     *(pp->c_pointer[pp->n_strings]+1) = *string++;
  37.  
  38.      /* now copy the rest */
  39.     (void) strcpy(pp->c_pointer[pp->n_strings++] + 2, string);
  40. }
  41.  
  42. static int findchar(string, pp)
  43. strtab    *pp;
  44. char    *string;
  45. {
  46.     int    c_len, s_len, i;
  47.  
  48.     for (i = 0; i < pp->n_strings; i++)
  49.     {
  50.     if ((c_len = pp->c_length[i]) >= (s_len = strlen (string+2) + 2))
  51.     {
  52.         if (!char_comp (string, pp->c_pointer[i] + c_len - s_len, s_len))
  53.         return (pp->c_pointer[i] + c_len - s_len - pp->c_data);
  54.     }
  55.     }
  56.     (void) fprintf(stderr,
  57.            "Serious bug! character %s not found in table\n", string);
  58.     exit(1);
  59.     /* NOTREACHED */
  60. }
  61.  
  62. static void write_err()
  63. {
  64.     (void) fprintf(stderr, "Write to file failed\n");
  65.     exit(1);
  66. }
  67.  
  68. void otwrite(tp, fp)
  69. nrtab_t *tp;
  70. FILE    *fp;
  71. {
  72.     int    i, j, i_len, j_len, ch;
  73.     char    *tail, *start, *char_pointer;
  74.     static nrext_t t_stor;
  75.     static strtab otab;
  76.  
  77.     newstrings(&otab);
  78.  
  79.     /*
  80.      * copy the integer values from the initialized structure
  81.      * to the storage structure
  82.      */
  83.     t_stor.bset = tp->bset;
  84.     t_stor.breset = tp->breset;
  85.     t_stor.Hor = tp->Hor;
  86.     t_stor.Vert = tp->Vert;
  87.     t_stor.Newline = tp->Newline;
  88.     t_stor.Char = tp->Char;
  89.     t_stor.Em = tp->Em;
  90.     t_stor.Halfline = tp->Halfline;
  91.     t_stor.Adj = tp->Adj;
  92.  
  93.     /*
  94.      * force an empty string with a 0-length head character to exist
  95.      * at offset 0 of the otab string table
  96.      */
  97.     (void) addchar("\000\000", &otab);
  98.  
  99.     /*
  100.      * copy control strings out of the in-core form into the otab string table
  101.      */
  102.     (void) addstring(tp->twinit, &otab);
  103.     (void) addstring(tp->twrest, &otab);
  104.     (void) addstring(tp->twnl, &otab);
  105.     (void) addstring(tp->hlr, &otab);
  106.     (void) addstring(tp->hlf, &otab);
  107.     (void) addstring(tp->flr, &otab);
  108.     (void) addstring(tp->bdon, &otab);
  109.     (void) addstring(tp->bdoff, &otab);
  110.     (void) addstring(tp->iton, &otab);
  111.     (void) addstring(tp->itoff, &otab);
  112.     (void) addstring(tp->ploton, &otab);
  113.     (void) addstring(tp->plotoff, &otab);
  114.     (void) addstring(tp->up, &otab);
  115.     (void) addstring(tp->down, &otab);
  116.     (void) addstring(tp->right, &otab);
  117.     (void) addstring(tp->left, &otab);
  118.  
  119.     /* copy character expansions to the new table */
  120.     for (ch = CHARMIN; ch < CHARMAX; ch++)
  121.     if (tp->codetab[ch - CHARMIN] != (char *)NULL)
  122.         addchar(tp->codetab[ch - CHARMIN], &otab);
  123.  
  124.     /* eliminate strings which are tails of other strings */
  125.     for (i = 0; i < otab.n_strings; i++)
  126.     {
  127.     if (!otab.c_pointer[i])
  128.         continue;    /* String cleared out */
  129.     i_len = otab.c_length[i];
  130.     for (j = 0; j < otab.n_strings; j++)
  131.     {
  132.         if (i == j || ! otab.c_pointer[j]) continue;
  133.         j_len = otab.c_length[j];
  134.         if (i_len <= j_len)    /* string i could be tail of string j */
  135.         {
  136.         tail = otab.c_pointer[j] + j_len - i_len;
  137.         if (! char_comp(otab.c_pointer[i], tail, i_len)) {
  138.             otab.c_pointer[i] = 0;
  139.             break;
  140.         }
  141.         }
  142.     }
  143.     }
  144.  
  145.     /* Compress the otab.c_data array */
  146.     char_pointer = otab.c_data;
  147.     for (i = j = 0; i < otab.n_strings; i++)
  148.     {
  149.     if (! (start = otab.c_pointer[i]))
  150.         continue;
  151.     otab.c_pointer[j] = char_pointer;
  152.     otab.c_length[j++] = otab.c_length[i];
  153.     for (i_len = otab.c_length[i]; i_len--;)
  154.         *char_pointer++ = *start++;
  155.     *char_pointer++ = 0;
  156.     }
  157.     otab.n_strings = j;
  158.     otab.c_size = char_pointer - otab.c_data;
  159.  
  160.     /* Now find each string in this table and provide an index to it */
  161.     t_stor.twinit = findstring(tp->twinit, &otab);
  162.     t_stor.twrest = findstring(tp->twrest, &otab);
  163.     t_stor.twnl = findstring(tp->twnl, &otab);
  164.     t_stor.hlr = findstring(tp->hlr, &otab);
  165.     t_stor.hlf = findstring(tp->hlf, &otab);
  166.     t_stor.flr = findstring(tp->flr, &otab);
  167.     t_stor.bdon = findstring(tp->bdon, &otab);
  168.     t_stor.bdoff = findstring(tp->bdoff, &otab);
  169.     t_stor.iton = findstring(tp->iton, &otab);
  170.     t_stor.itoff = findstring(tp->itoff, &otab);
  171.     t_stor.ploton = findstring(tp->ploton, &otab);
  172.     t_stor.plotoff = findstring(tp->plotoff, &otab);
  173.     t_stor.up = findstring(tp->up, &otab);
  174.     t_stor.down = findstring(tp->down, &otab);
  175.     t_stor.right = findstring(tp->right, &otab);
  176.     t_stor.left = findstring(tp->left, &otab);
  177.  
  178.     for (ch = CHARMIN; ch < CHARMAX; ch++)
  179.     if (tp->codetab[ch-CHARMIN] == (char *)NULL)
  180.         t_stor.codetab[ch-CHARMIN] = 0;    /* empty expansion */
  181.     else
  182.         t_stor.codetab[ch-CHARMIN]=findchar(tp->codetab[ch-CHARMIN],&otab);
  183.  
  184.     t_stor.zzz = 0;
  185.  
  186.     /* Write the character storage block size */
  187.     if (fwrite((char *)&otab.c_size, sizeof(otab.c_size), 1, fp) != 1)
  188.     write_err();
  189.  
  190.     /* now the fixed part */
  191.     if (fwrite(&t_stor, sizeof(t_stor), 1, fp) != 1)
  192.     write_err();
  193.  
  194.     /* finally, write the code table */
  195.     if (fwrite(otab.c_data,sizeof(*otab.c_data),otab.c_size,fp) != otab.c_size)
  196.     write_err();
  197. }
  198.  
  199. /* otwrite.c ends here */
  200.