home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / cawf407.zip / src / output.c < prev    next >
C/C++ Source or Header  |  1993-12-28  |  7KB  |  321 lines

  1. /*
  2.  *    output-c - output support functions for cawf(1)
  3.  */
  4.  
  5. /*
  6.  *    Copyright (c) 1991 Purdue University Research Foundation,
  7.  *    West Lafayette, Indiana 47907.  All rights reserved.
  8.  *
  9.  *    Written by Victor A. Abell <abe@mace.cc.purdue.edu>,  Purdue
  10.  *    University Computing Center.  Not derived from licensed software;
  11.  *    derived from awf(1) by Henry Spencer of the University of Toronto.
  12.  *
  13.  *    Permission is granted to anyone to use this software for any
  14.  *    purpose on any computer system, and to alter it and redistribute
  15.  *    it freely, subject to the following restrictions:
  16.  *
  17.  *    1. The author is not responsible for any consequences of use of
  18.  *       this software, even if they arise from flaws in it.
  19.  *
  20.  *    2. The origin of this software must not be misrepresented, either
  21.  *       by explicit claim or by omission.  Credits must appear in the
  22.  *       documentation.
  23.  *
  24.  *    3. Altered versions must be plainly marked as such, and must not
  25.  *       be misrepresented as being the original software.  Credits must
  26.  *       appear in the documentation.
  27.  *
  28.  *    4. This notice may not be removed or altered.
  29.  */
  30.  
  31. #include "cawf.h"
  32.  
  33. _PROTOTYPE(static char *FontHF,(char *cf, char *nf, char *pf, unsigned char **b, int bl, int *n, int t));
  34. _PROTOTYPE(static char *PutHFstr,(unsigned char *buf, int l, char *cf, unsigned char **b, int bl, int *n, int t));
  35.  
  36.  
  37. /*
  38.  * FontHF(cf, nf, pf, b, bl, n, t) - change font in a header or footer line
  39.  */
  40.  
  41. static char *
  42. FontHF(cf, nf, pf, b, bl, n, t)
  43.     char *cf;            /* current font */
  44.     char *nf;            /* new font */
  45.     char *pf;            /* previous font */
  46.     unsigned char **b;        /* optional buffer address pointer */
  47.     int bl;                /* optional limit on buffer */
  48.     int *n;                /* optional buffer character count */
  49.     int t;                /* type: 0 = get interpolated length
  50.                      *     1 = print */
  51. {
  52.     char f;                /* font */
  53.     int fl;                /* font string length */
  54.     int i;                /* temporary index */
  55.     unsigned char *fp;        /* font string pointer */
  56.  
  57.     f = (*nf == 'P') ? *pf : *nf;
  58.     if (*cf == f)
  59.         return(NULL);
  60.     switch (f) {
  61.     case 'B':
  62.         fl = Fstr.bl;
  63.         fp = Fstr.b;
  64.         break;
  65.     case 'I':
  66.         fl = Fstr.itl;
  67.         fp = Fstr.it;
  68.         break;
  69.     case 'R':
  70.         fl = Fstr.rl;
  71.         fp = Fstr.r;
  72.         break;
  73.     default:
  74.         return(" unknown font ");
  75.     }
  76.     if (b && (*n + fl) > bl)
  77.         return(" font change makes title too long ");
  78.     if (Fontctl) {
  79.         if (t) {
  80.             for (i = 0; i < fl; i++, fp++) {
  81.                 if ( ! b) {
  82.                     Charput(fp);
  83.                 } else {
  84.                     **b = *fp;
  85.                     (*b)++;
  86.                 }
  87.             }
  88.         }
  89.     }
  90.     *pf = *cf;
  91.     *cf = f;
  92.     *n += fl;
  93.     return(NULL);
  94. }
  95.  
  96.  
  97. /*
  98.  * LenprtHF(s, p, t, b, bl) - get length of print header or footer with page
  99.  *              number, number register, string interpolation, and
  100.  *              font control
  101.  */
  102.  
  103. int
  104. LenprtHF(s, p, t, b, bl)
  105.     unsigned char *s;        /* header/footer string */
  106.     int p;                /* page number */
  107.     int t;                /* type: 0 = get interpolated length
  108.                      *     1 = print */
  109.     unsigned char **b;        /* optional buffer address pointer */
  110.     int bl;                /* optional limit on buffer */
  111. {
  112.     unsigned char buf[MAXLINE];    /* buffer for page number */
  113.     char cf[1], pf[1];        /* fonts */
  114.     unsigned char *cp, *cp1;    /* character pointers */
  115.     char *err;            /* font change error message */
  116.     int i, j, k, n;            /* temporary indexes */
  117.     int len;            /* line length */
  118.     unsigned char nm[4];        /* name buffer */
  119.     
  120.     if (s == NULL)
  121.         return(0);
  122.     if (b)
  123.         n = 0;
  124.     *cf = *pf = 'R';
  125. /*
  126.  * Process the string, interpolating % as page number and \f[BIPR]
  127.  * for font changes.
  128.  */
  129.     for (cp = s, len = 0; *cp; cp++) {
  130.         switch (*cp) {
  131.         case '%':
  132.             (void) sprintf((char *)buf, "%d", p);
  133.             j = strlen((char *)buf);
  134.             if ((err = PutHFstr(buf, j, cf, b, bl, &n, t))
  135.             != NULL)
  136.                 goto hf_err;
  137.             len += j;
  138.             continue;
  139.         case '\\':
  140.             k = 0;
  141.             cp++;
  142.             switch (*cp) {
  143.         /*
  144.          * Font change -- "\\fN"
  145.          */
  146.             case 'f':
  147.                 cp1 = cp + 1;
  148.                 if (*cp1 == 'B' || *cp1 == 'I' || *cp1 == 'P'
  149.                 ||  *cp1 == 'R') {
  150.                 if ((err = FontHF(cf, (char *)cp1, pf,
  151.                        b, bl, &n, t))
  152.                 != NULL)
  153.                     goto hf_err;
  154.                 cp++;
  155.                 k++;
  156.                 break;
  157.                 }
  158.                 break;
  159.         /*
  160.              * Interpolate number - "\\n(NN" or "\\nN"
  161.          */
  162.             case 'n':
  163.                 cp = Asmcode(&cp, nm);
  164.                 if ((i = Findnum(nm, 0, 0)) < 0) {
  165.                 err = " unknown number register ";
  166.                 goto hf_err;
  167.                 }
  168.                 (void) sprintf((char *)buf, "%d", Numb[i].val);
  169.                 j = strlen((char *)buf);
  170.                 if ((err = PutHFstr(buf, j, cf, b, bl, &n, t))
  171.                 != NULL)
  172.                 goto hf_err;
  173.                 len += j;
  174.                 k++;
  175.                 break;
  176.         /*
  177.          * Interpolate string - "\\*(NN" or "\\*N"
  178.          */
  179.             case '*':
  180.                 cp = Asmcode(&cp, nm);
  181.                 cp1 = Findstr(nm, NULL, 0);
  182.                 j = strlen((char *)cp1);
  183.                 if ((err = PutHFstr(cp1, j, cf, b, bl, &n, t))
  184.                 != NULL)
  185.                 goto hf_err;
  186.                 len += j;
  187.                 k++;
  188.                 break;
  189.             }
  190.             if (k)
  191.                 break;
  192.             /* fall through */
  193.         default:
  194.             if ((err = PutHFstr(&Trtbl[(int)*cp], 1, cf, b, bl,
  195.                    &n, t))
  196.             != NULL)
  197.                 goto hf_err;
  198.             len++;
  199.         }
  200.     }
  201. /*
  202.  * Restore the initial font, as required.
  203.  */
  204.     if (Fontctl && *cf != 'R') {
  205.         if ((err = FontHF(cf, "R", pf, b, bl, &n, t)) != NULL)
  206.  
  207. hf_err:
  208.  
  209.         {
  210.             Error(WARN, LINE, err, NULL);
  211.             return(0);
  212.         }
  213.     }
  214.     return(len);
  215. }
  216.  
  217.  
  218. /*
  219.  * PageInRange(pg) - is page number in printable range?
  220.  */
  221.  
  222. int
  223. PageInRange(pg)                /* page number */
  224.     int pg;
  225. {
  226.     struct pgrange *pr;
  227.  
  228.     if (!PgRange)
  229.         return(1);
  230.     for (pr = PgRange; pr; pr = pr->next) {
  231.         if (pg >= pr->l && pg <= pr->u)
  232.             return(1);
  233.     }
  234.     return(0);
  235. }
  236.  
  237.  
  238. /*
  239.  * PutHFstr(buf, l, cf, b, bl, n, t) - put header/footer string
  240.  */
  241.  
  242. static char *
  243. PutHFstr(buf, l, cf, b, bl, n, t)
  244.     unsigned char *buf;        /* string to put */
  245.     int l;                /* length of string */
  246.     char *cf;            /* current font */
  247.     unsigned char **b;        /* optional buffer address pointer */
  248.     int bl;                /* optional limit on buffer */
  249.     int *n;                /* optional buffer character count */
  250.     int t;                /* type: 0 = get interpolated length
  251.                      *     1 = print */
  252. {
  253.     unsigned char cb[4];
  254.     int i;
  255.  
  256.     if (b) {
  257.         if (Fontctl == 0) {
  258.             if (*cf == 'B')
  259.                 i = 5;
  260.             else if (*cf == 'I')
  261.                 i = 3;
  262.             else
  263.                 i = 1;
  264.         } else
  265.             i = 1;
  266.         if ((*n + i) > bl)
  267.             return(" title too long ");
  268.         *n += i;
  269.     }
  270.     if (t) {
  271.         for (i = 0; i < l; i++) {
  272.             if ( ! b) {
  273.                 if (Fontctl == 0) {
  274.                 if (*cf == 'B') {
  275.                     cb[1] = cb[3] = (unsigned char)'\b';
  276.                     cb[0] = cb[2] = buf[i];
  277.                     Stringput(cb, 4);
  278.                 } else if (*cf == 'I')
  279.                     Stringput((unsigned char *)"_\b", 2);
  280.                 }
  281.                 Charput(&buf[i]);
  282.             } else {
  283.                 if (Fontctl == 0) {
  284.                 if (*cf == 'B') {
  285.                     **b = buf[i];
  286.                     (*b)++;
  287.                     **b = (unsigned char)'\b';
  288.                     (*b)++;
  289.                     **b = buf[i];
  290.                     (*b)++;
  291.                     **b = (unsigned char)'\b';
  292.                     (*b)++;
  293.                 } else if (*cf == 'I') {
  294.                     **b = (unsigned char)'_';
  295.                     (*b)++;
  296.                     **b = (unsigned char)'\b';
  297.                     (*b)++;
  298.                 }
  299.                 }
  300.                 **b = buf[i];
  301.                 (*b)++;
  302.             }
  303.         }
  304.     }
  305.     return(NULL);
  306. }
  307.  
  308.  
  309. /*
  310.  * Stringput(s) - put a string to output, subject to diversion
  311.  */
  312.  
  313. void
  314. Stringput(s, l)
  315.     unsigned char *s;    /* string to put */
  316.     int l;            /* length */
  317. {
  318.     if (!Divert && Pageprt)
  319.         (void) fwrite(s, l, 1, stdout);
  320. }
  321.