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

  1. /*
  2.  *    nreq.c - cawf(1) processing of nroff requests
  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. #include <ctype.h>
  33.  
  34.  
  35. /*
  36.  * Prototypes for request processing functions.
  37.  */
  38.  
  39. _PROTOTYPE(static void nr_UL,(unsigned char *line, int brk));
  40. _PROTOTYPE(static void nr_Ub,(unsigned char *line, int brk));
  41. _PROTOTYPE(static void nr_Uc,(unsigned char *line, int brk));
  42. _PROTOTYPE(static void nr_Uf,(unsigned char *line, int brk));
  43. _PROTOTYPE(static void nr_Ur,(unsigned char *line, int brk));
  44. _PROTOTYPE(static void nr_ad,(unsigned char *line, int brk));
  45. _PROTOTYPE(static void nr_bp,(unsigned char *line, int brk));
  46. _PROTOTYPE(static void nr_br,(unsigned char *line, int brk));
  47. _PROTOTYPE(static void nr_ce,(unsigned char *line, int brk));
  48. _PROTOTYPE(static void nr_di,(unsigned char *line, int brk));
  49. _PROTOTYPE(static void nr_ds,(unsigned char *line, int brk));
  50. _PROTOTYPE(static void nr_fi,(unsigned char *line, int brk));
  51. _PROTOTYPE(static void nr_fl,(unsigned char *line, int brk));
  52. _PROTOTYPE(static void nr_ft,(unsigned char *line, int brk));
  53. _PROTOTYPE(static void nr_it,(unsigned char *line, int brk));
  54. _PROTOTYPE(static void nr_na,(unsigned char *line, int brk));
  55. _PROTOTYPE(static void nr_nf,(unsigned char *line, int brk));
  56. _PROTOTYPE(static void nr_ns,(unsigned char *line, int brk));
  57. _PROTOTYPE(static void nr_rm,(unsigned char *line, int brk));
  58. _PROTOTYPE(static void nr_rn,(unsigned char *line, int brk));
  59. _PROTOTYPE(static void nr_rr,(unsigned char *line, int brk));
  60. _PROTOTYPE(static void nr_rs,(unsigned char *line, int brk));
  61. _PROTOTYPE(static void nr_tl,(unsigned char *line, int brk));
  62. _PROTOTYPE(static void nr_tm,(unsigned char *line, int brk));
  63. _PROTOTYPE(static void nr_tr,(unsigned char *line, int brk));
  64.  
  65. _PROTOTYPE(static void nr_nil,(unsigned char *line, int brk));
  66.  
  67.  
  68. /*
  69.  * NrReqt[] - nroff request processing table
  70.  *
  71.  * CAUTION: place new entries in their proper alphabetical order, since
  72.  *        this table is processed with a binary search.
  73.  */
  74.  
  75. static struct nr_req {
  76.     char *nm;            /* nroff request */
  77.     void (*fun)();            /* processing function */
  78. } NrReqt[] = {
  79.     { "\\\"",    nr_nil },    /* backslash-quote */
  80.     { "^#",        nr_UL  },
  81.     { "^=",        nr_UL  },
  82.     { "^b",        nr_Ub  },
  83.     { "^c",        nr_Uc  },
  84.     { "^d",        nr_nil },
  85.     { "^e",        nr_nil },
  86.     { "^f",        nr_Uf  },
  87.     { "^r",        nr_Ur  },
  88.     { "^x",        nr_nil },
  89.     { "ad",        nr_ad  },
  90.     { "bp",        nr_bp  },
  91.     { "br",        nr_br  },
  92.     { "ce",        nr_ce  },
  93.     { "di",        nr_di  },
  94.     { "ds",        nr_ds  },
  95.     { "fi",        nr_fi  },
  96.     { "fl",        nr_fl  },
  97.     { "ft",        nr_ft  },
  98.     { "i0",        nr_nil },
  99.     { "it",        nr_it  },
  100.     { "lg",        nr_nil },
  101.     { "li",        nr_nil },
  102.     { "na",        nr_na  },
  103.     { "nf",        nr_nf  },
  104.     { "ns",        nr_ns  },
  105.     { "ps",        nr_nil },
  106.     { "rm",        nr_rm  },
  107.     { "rn",        nr_rn  },
  108.     { "rr",        nr_rr  },
  109.     { "rs",        nr_rs  },
  110.     { "tl",        nr_tl  },
  111.     { "tm",        nr_tm  },
  112.     { "tr",        nr_tr  },
  113.     { "vs",        nr_nil },
  114. };
  115. /*
  116.  * Nreq(line, brk) - process miscellaneous nroff requests from line
  117.  *             buffer with request status of (brk)
  118.  */
  119.  
  120. void
  121. Nreq(line, brk)
  122.     unsigned char *line;
  123.     int brk;
  124. {
  125.     unsigned char c[3];        /* command buffer */
  126.     int cmp, hi, low, mid;        /* binary search indixes */
  127.  
  128.     c[0] = c[1] = c[2] = '\0';
  129.     if ((c[0] = line[1]) != '\0')
  130.         c[1] = line[2];
  131.  
  132.     low = mid = 0;
  133.     hi = (sizeof(NrReqt) / sizeof(struct nr_req)) - 1;
  134.     while (low <= hi) {
  135.         mid = (low + hi) / 2;
  136.         if ((cmp = strcmp((char *)c, NrReqt[mid].nm)) < 0)
  137.             hi = mid - 1;
  138.         else if (cmp > 0)
  139.             low = mid + 1;
  140.         else {
  141.  
  142. #ifdef    _BCC
  143. #pragma warn -pro
  144. #endif
  145.  
  146.             (void) (*NrReqt[mid].fun)(line, brk);
  147.  
  148. #ifdef    _BCC
  149. #pragma warn -pro
  150. #endif
  151.  
  152.             return;
  153.         }
  154.     }
  155.     /*
  156.      * Unknown request starting with a '.' or '\''..
  157.      */
  158.     Error(WARN, LINE, " unknown request", NULL);
  159. }
  160.  
  161.  
  162. /*
  163.  * Adjust - "^[.']ad"
  164.  */
  165.  
  166. #ifdef    _BCC
  167. #pragma    argsused
  168. #endif
  169.  
  170. static void
  171. nr_ad(line, brk)
  172.     unsigned char *line;
  173.     int brk;
  174. {
  175.     Pass3(NOBREAK, (unsigned char *)"both", -1, NULL, 0);
  176. }
  177.  
  178.  
  179. /*
  180. * Begin new page - "^[.']bp"
  181. */
  182.  
  183. #ifdef    _BCC
  184. #pragma    argsused
  185. #endif
  186.  
  187.  
  188. static void
  189. nr_bp(line, brk)
  190.     unsigned char *line;
  191.     int brk;
  192. {
  193.     Pass3(brk, (unsigned char *)"need", -1, NULL, 999);
  194. }
  195.  
  196.  
  197. /*
  198. * Break - "^[.']br"
  199. */
  200.  
  201. #ifdef    _BCC
  202. #pragma    argsused
  203. #endif
  204.  
  205.  
  206. static void
  207. nr_br(line, brk)
  208.     unsigned char *line;
  209.     int brk;
  210. {
  211.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  212. }
  213.  
  214.  
  215. /*
  216.  * Center - "^[.']ce"
  217.  */
  218.  
  219. #ifdef    _BCC
  220. #pragma    argsused
  221. #endif
  222.  
  223.  
  224. static void
  225. nr_ce(line, brk)
  226.     unsigned char *line;
  227.     int brk;
  228. {
  229.     unsigned char *s;            /* string poiner */
  230.  
  231.     if ((s = Field(2, line, 0)) != NULL)
  232.         Centering = atoi((char *)s);
  233.     else
  234.         Centering = 1;
  235. }
  236.  
  237.  
  238. /*
  239.  * Diversion on and off - "^[.']di"
  240.  */
  241.  
  242. #ifdef    _BCC
  243. #pragma    argsused
  244. #endif
  245.  
  246.  
  247. static void
  248. nr_di(line, brk)
  249.     unsigned char *line;
  250.     int brk;
  251. {
  252.     Pass3(DOBREAK, (unsigned char *)"flush", -1, NULL, 0);
  253.     Divert ^= 1;
  254. }
  255.  
  256.  
  257. /*
  258.  * Define string - "^[.']ds"
  259.  */
  260.  
  261. #ifdef    _BCC
  262. #pragma    argsused
  263. #endif
  264.  
  265.  
  266. static void
  267. nr_ds(line, brk)
  268.     unsigned char *line;
  269.     int brk;
  270. {
  271.     unsigned char buf[MAXLINE];    /* temporary buffer */
  272.     unsigned char nm[4], nm1[4];    /* name buffers */
  273.     unsigned char *s1, *s2, *s4,    /* temporary string pointers */
  274.                *s5;
  275.  
  276.     if (Asmname(&line[3], nm) == 0) {
  277.         Error(WARN, LINE, " no name", NULL);
  278.         return;
  279.     }
  280.     if ((s4 = Field(3, line, 0)) == NULL)
  281.         s4 = (unsigned char *)"";
  282. /*
  283.  * Convert "\\b" to '\b' and "\\\\" to '\\'.  Pass all other sequences,
  284.  * beginning with '\\', unmodified.
  285.  */
  286.     s1 = buf;
  287.     while ((s5 = (unsigned char *)strchr((char *)s4, '\\')) != NULL) {
  288.         while (s5 > s4)
  289.             *s1++ = *s4++;
  290.         s4 = ++s5;
  291.         if (*s5 == '\\')
  292.             *s1++ = '\\';
  293.         else if (*s5 == 'b')
  294.             *s1++ = '\b';
  295.         else {
  296.             *s1++ = '\\';
  297.             *s1++ = *s5;
  298.         }
  299.         if (*s4)
  300.             s4++;
  301.     }
  302.  
  303. #ifdef    _BCC
  304. #pragma warn -pia
  305. #endif
  306.  
  307.     while (*s1++ = *s4++)
  308.         ;
  309.  
  310. #ifdef    _BCC
  311. #pragma warn +pia
  312. #endif
  313.  
  314. /*
  315.  * Install the string and see if it's an indirect reference -- e.g.,
  316.  *
  317.  *    .ds S1 \*(S2
  318.  */
  319.     s2 = Findstr(nm, buf, 1);
  320.     while (*s2 == '\\' && *(s2 + 1) == '*') {
  321.         s2++;
  322.         (void) Asmcode(&s2, nm1);
  323.         s2 = Findstr(nm1, NULL, 0);
  324.     }
  325.     if (Hdft) {
  326.  
  327. /*
  328.  * Look for names LH, LF, CH, CF, RH, RF.
  329.  */
  330.         if ((nm[0]=='L' || nm[0]=='C' || nm[0]=='R')
  331.         &&  (nm[1]=='F' || nm[1]=='H')) {
  332.             (void) sprintf((char *)buf, "%s", (char *)nm);
  333.             Pass3(NOBREAK, buf, -1, s2, 0);
  334.         }
  335.     }
  336. }
  337.  
  338.  
  339.  
  340. /*
  341.  * Fill - "^[.']fi"
  342.  */
  343.  
  344. #ifdef    _BCC
  345. #pragma    argsused
  346. #endif
  347.  
  348.  
  349. static void
  350. nr_fi(line, brk)
  351.     unsigned char *line;
  352.     int brk;
  353. {
  354.     Fill = 1;
  355.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  356. }
  357.  
  358.  
  359. /*
  360.  * Flush - "^[.']fl"
  361.  */
  362.  
  363. #ifdef    _BCC
  364. #pragma    argsused
  365. #endif
  366.  
  367.  
  368. static void
  369. nr_fl(line, brk)
  370.     unsigned char *line;
  371.     int brk;
  372. {
  373.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  374. }
  375.  
  376.  
  377. /*
  378.  * Font - "^[.']ft <font_name>"
  379.  */
  380.  
  381. #ifdef    _BCC
  382. #pragma    argsused
  383. #endif
  384.  
  385.  
  386. static void
  387. nr_ft(line, brk)
  388.     unsigned char *line;
  389.     int brk;
  390. {
  391.     int i;                /* temporary index */
  392.  
  393.     if (line[3] == '\0' || line[4] == '\0')
  394.         line[4] = 'P';
  395.     if (line[4] == 'P') {
  396.         Font[0] = Prevfont;
  397.         return;
  398.     }
  399.     for (i = 0; Fcode[i].nm; i++) {
  400.         if (Fcode[i].nm == line[4])
  401.         break;
  402.     }
  403.     if (Fcode[i].status == '\0') {
  404.         Error(WARN, LINE, " bad font code", NULL);
  405.         return;
  406.     }
  407.     Prevfont = Font[0];
  408.     Font[0] = line[4];
  409. }
  410.  
  411.  
  412. /*
  413.  * Input trap - "^[.']it [1 <request>]"
  414.  */
  415.  
  416. #ifdef    _BCC
  417. #pragma    argsused
  418. #endif
  419.  
  420.  
  421. static void
  422. nr_it(line, brk)
  423.     unsigned char *line;
  424.     int brk;
  425.  
  426. {
  427.     unsigned char buf[MAXLINE];    /* temporary buffer */
  428.     unsigned char *s1, *s2;        /* temporary string pointers */
  429.  
  430.     if ((s1 = Field(2, line, 0)) == NULL) {
  431.         Free(&Aftnxt);
  432.         return;
  433.     }
  434.     if (atoi((char *)s1) != 1) {
  435.         Error(WARN, LINE, " first .it arg must be 1", NULL);
  436.         return;
  437.     }
  438.     if ((s2 = Field(3, line, 0)) == NULL)
  439.         Free(&Aftnxt);
  440.     else {
  441.         (void) sprintf((char *)buf, "%s,%s",
  442.             (Aftnxt == NULL) ? "" : (char *)Aftnxt,
  443.             (char *)s2);
  444.         Free(&Aftnxt);
  445.         Aftnxt = Newstr(buf);
  446.     }
  447. }
  448.  
  449.  
  450. /*
  451.  * Comment - "^[.']\\" - do nothing
  452.  *
  453.  * Debug - "^[.']\^d" - do nothing
  454.  *
  455.  * Finalization - "[.']\^e" - do nothing
  456.  *
  457.  * Error file - "^[.']\^x <name>" - do nothing
  458.  *
  459.  * "^[.']i0", "^[.']lg" and "^[.']li" - do nothing
  460.  *
  461.  * Point size - "^[.']ps" - do nothing
  462.  *
  463.  * Vertical spacing - "^[.']vs" - do nothing
  464.  *
  465.  */
  466.  
  467. #ifdef    _BCC
  468. #pragma    argsused
  469. #endif
  470.  
  471.  
  472. static void
  473. nr_nil(line, brk)
  474.     unsigned char *line;
  475.     int brk;
  476. {
  477. }
  478.  
  479.  
  480. /*
  481.  * No adjust "^[.']na"
  482.  */
  483.  
  484. #ifdef    _BCC
  485. #pragma    argsused
  486. #endif
  487.  
  488.  
  489. static void
  490. nr_na(line, brk)
  491.     unsigned char *line;
  492.     int brk;
  493. {
  494.     Pass3(NOBREAK, (unsigned char *)"left", -1, NULL, 0);
  495. }
  496.  
  497.  
  498. /*
  499.  * No fill - "^[.']nf"
  500.  */
  501.  
  502. #ifdef    _BCC
  503. #pragma    argsused
  504. #endif
  505.  
  506.  
  507. static void
  508. nr_nf(line, brk)
  509.     unsigned char *line;
  510.     int brk;
  511. {
  512.     Fill = 0;
  513.     Pass3(brk, (unsigned char *)"flush", -1, NULL, 0);
  514. }
  515.  
  516.  
  517. /*
  518.  * No space - "^[.']ns"
  519.  */
  520.  
  521. #ifdef    _BCC
  522. #pragma    argsused
  523. #endif
  524.  
  525.  
  526. static void
  527. nr_ns(line, brk)
  528.     unsigned char *line;
  529.     int brk;
  530. {
  531.     Pass3(NOBREAK, (unsigned char *)"nospace", -1, NULL, 0);
  532. }
  533.  
  534.  
  535. /*
  536.  * Remove macro or string - "^[.']rm"
  537.  */
  538.  
  539. #ifdef    _BCC
  540. #pragma    argsused
  541. #endif
  542.  
  543.  
  544. static void
  545. nr_rm(line, brk)
  546.     unsigned char *line;
  547.     int brk;
  548. {
  549.     int i;                /* temporary index */
  550.     unsigned char nm[4];        /* name buffer */
  551.  
  552.     if (Asmname(&line[3], nm) == 0) {
  553.         Error(WARN, LINE, " no name", NULL);
  554.         return;
  555.     }
  556.     if ((i = Findmacro(nm, 0)) >= 0) {
  557.         Delmacro(i);
  558.         return;
  559.             }
  560.     (void) Findstr(nm, NULL, 0);
  561.         if (Sx >= 0) {
  562.             Delstr(Sx);
  563.             return;
  564.     }
  565.     Error(WARN, LINE, " no macro/string", NULL);
  566. }
  567.  
  568.  
  569. /*
  570.  * Rename macro or string - "^[.']rn"
  571.  */
  572.  
  573. #ifdef    _BCC
  574. #pragma    argsused
  575. #endif
  576.  
  577.  
  578. static void
  579. nr_rn(line, brk)
  580.     unsigned char *line;
  581.     int brk;
  582. {
  583.     int i, j;            /* temporary indexes */
  584.     unsigned char nm[4], nm1[4];    /* name buffers */
  585.     unsigned char *s1;        /* temporary string pointer */
  586.  
  587.     if ((s1 = Field(2, line, 0)) == NULL ||  Asmname(s1, nm) == 0) {
  588.         Error(WARN, LINE, " no name", NULL);
  589.         return;
  590.     }
  591.     if ((s1 = Field(3, line, 0)) == NULL ||  Asmname(s1, nm1) == 0) {
  592.         Error(WARN, LINE, " no new name", NULL);
  593.         return;
  594.     }
  595.     if ((i = Findmacro(nm, 0)) >= 0) {
  596.         if ((j = Findmacro(nm1, 0)) >= 0)
  597.             Delmacro(j);
  598.         j = Findmacro(nm1, 1);
  599.         Macrotab[j].bx = Macrotab[i].bx;
  600.         Macrotab[i].bx = -1;
  601.         Macrotab[j].ct = Macrotab[i].ct;
  602.         Macrotab[i].ct = 0;
  603.         Delmacro(i);
  604.         return;
  605.     }
  606.     (void) Findstr(nm, NULL, 0);
  607.     if ((i = Sx) >= 0) {
  608.         (void) Findstr(nm1, Str[i].str, 1);
  609.         Delstr(i);
  610.         return;
  611.     }
  612.     if (Findmacro(nm1, 0) < 0)
  613.         (void) Findmacro(nm1, 1);
  614. }
  615.  
  616.  
  617. /*
  618.  * Remove register - "^[.']rr"
  619.  */
  620.  
  621. #ifdef    _BCC
  622. #pragma    argsused
  623. #endif
  624.  
  625.  
  626. static void
  627. nr_rr(line, brk)
  628.     unsigned char *line;
  629.     int brk;
  630. {
  631.     int i;                /* temporary index */
  632.     unsigned char nm[4];        /* name buffer */
  633.  
  634.     if (Asmname(&line[3], nm) == 0) {
  635.         Error(WARN, LINE, " no name", NULL);
  636.         return;
  637.     }
  638.     if ((i = Findnum(nm, 0, 0)) < 0) {
  639.         Error(WARN, LINE, " no register", NULL);
  640.         return;
  641.     }
  642.     Delnum(i);
  643. }
  644.  
  645.  
  646. /*
  647.  * Resume space - "^[.']rs"
  648.  */
  649.  
  650. #ifdef    _BCC
  651. #pragma    argsused
  652. #endif
  653.  
  654.  
  655. static void
  656. nr_rs(line, brk)
  657.     unsigned char *line;
  658.     int brk;
  659. {
  660.     Pass3(NOBREAK, (unsigned char *)"yesspace", -1, NULL, 0);
  661. }
  662.  
  663.  
  664. /*
  665.  * Three part title - "^[.'tl]"
  666.  */
  667.  
  668. #ifdef    _BCC
  669. #pragma    argsused
  670. #endif
  671.  
  672.  
  673. static void
  674. nr_tl(line, brk)
  675.     unsigned char *line;
  676.     int brk;
  677. {
  678.     unsigned char buf[MAXLINE];    /* temporary buffer */
  679.     unsigned char *be, *bp;        /* buffer pointers */
  680.     int i, j, k, n;            /* temporary indexes */
  681.     unsigned char sep;        /* title separator */
  682.     unsigned char *tl, *tm, *tp,    /* title string pointers */
  683.               *tr, *ttl;
  684.  
  685.     for (bp = &line[3]; *bp == ' ' || *bp == '\t'; bp++)
  686.         ;
  687.     tl = ttl = Newstr(bp);
  688.     if ((sep = *tl++) == '\0') {
  689.  
  690. bad_title:
  691.         Error(WARN, LINE, " bad 3-part title", NULL);
  692.         Free(&ttl);
  693.         return;
  694.     }
  695.     for (tm = tl, tr = NULL; *tm && *tm != sep; tm++)
  696.         ;
  697.     if (*tm) {
  698.         *tm++ = '\0';
  699.         for (tr = tm; *tr && *tr != sep; tr++)
  700.             ;
  701.         if (*tr) {
  702.             *tr++ = '\0';
  703.             for (tp = tr; *tp && *tp != sep; tp++)
  704.                 ;
  705.             if (*tp)
  706.                 *tp = '\0';
  707.         }
  708.     }
  709.     i = LenprtHF(tl, Thispg, 0, NULL, 0) + LenprtHF(tm, Thispg, 0, NULL, 0)
  710.       + LenprtHF(tr, Thispg, 0, NULL, 0) + 2;
  711.     if (i > (sizeof(buf) - 2) || i > LT)
  712.         goto bad_title;
  713.     j = (LT - i - Pgoff) / 2 + 1;
  714.     n = LT - Pgoff - i - j + 2;
  715.     be = &buf[sizeof(buf) - 1];
  716.     for (bp = buf, k = 0; k < Pgoff; k++)
  717.         *bp++ = ' ';
  718.     if (tl)
  719.         (void) LenprtHF(tl, Thispg, 1, &bp, be - bp);
  720.     while (j--)
  721.         *bp++ = ' ';
  722.     if (tm)
  723.         (void) LenprtHF(tm, Thispg, 1, &bp, be - bp);
  724.     while (n--)
  725.         *bp++ = ' ';
  726.     if (tr)
  727.         (void) LenprtHF(tr, Thispg, 1, &bp, be - bp);
  728.     *bp = '\0';
  729.     Pass3(RAWLINE, (unsigned char *)"title3", -1, buf, 0);
  730.     Free(&ttl);
  731. }
  732.  
  733.  
  734. /*
  735.  * Message - "^[.']tm"
  736.  */
  737.  
  738. #ifdef    _BCC
  739. #pragma    argsused
  740. #endif
  741.  
  742.  
  743. static void
  744. nr_tm(line, brk)
  745.     unsigned char *line;
  746.     int brk;
  747. {
  748.     Pass3(MESSAGE, Inname, -1, (line[3] == ' ') ? &line[4] : &line[3], NR);
  749. }
  750.  
  751.  
  752. /*
  753.  * Translate - "^[.']tr abcd..."
  754.  */
  755.  
  756. #ifdef    _BCC
  757. #pragma    argsused
  758. #endif
  759.  
  760.  
  761. static void
  762. nr_tr(line, brk)
  763.     unsigned char *line;
  764.     int brk;
  765. {
  766.     unsigned char buf[MAXLINE];    /* temporary buffer */
  767.     int i, j;            /* temporary indexes */
  768.     unsigned char nm[4], nm1[4];    /* name buffers */
  769.     unsigned char *s1, *s2;        /* temporary string pointers */
  770.     int trin, trout;        /* types: 0 = char; 1 = named char */
  771.     unsigned char xbuf[MAXLINE];    /* temporary buffer */
  772.  
  773.     if (line[3] != ' ') {
  774.         Error(WARN, LINE, " unknown translation", NULL);
  775.         return;
  776.     }
  777.     for (s1 = &line[4]; *s1;) {
  778.         nm[1] = nm[2] = '\0';
  779.         s2 = s1 + 1;
  780.     /*
  781.      * Assemble the input value.
  782.      */
  783.         if (*s1 == '\\' && (*s2 == '*' || *s2 == '(')) {
  784.         if (*s2 == '(') {
  785.         /*
  786.          * Input is named character -- "\(xx".
  787.          */
  788.             trin = 1;
  789.             s1 = s2 + 1;
  790.             if ((nm[0] = *s1) != '\0') {
  791.             s1++;
  792.             if ((nm[1] = *s1) != '\0')
  793.                 s1++;
  794.             }
  795.         } else {
  796.         /*
  797.          * Input is interpolated string -- "\*x" or "\*(xx".
  798.          */
  799.             s1 = Asmcode(&s2, nm);
  800.             if (*s1)
  801.             s1++;
  802.             s2 = Findstr(nm, NULL, 0);
  803.             if (*s2 != '\0') {
  804.             if ((strlen((char *)s2) + strlen((char *)s1) + 1)
  805.             >= MAXLINE)
  806.                 Error(WARN, LINE, " string too long: ", (char *)nm);
  807.             else {
  808.                 (void) sprintf((char *)buf, "%s%s",
  809.                 (char *)s2, (char *)s1);
  810.                 (void) strcpy((char *)xbuf, (char *)buf);
  811.                 s1 = xbuf;
  812.             }
  813.             }
  814.             continue;
  815.         }
  816.         } else {
  817.  
  818.         /*
  819.          * Input is a simple character.
  820.          */
  821.         trin = 0;
  822.         if ((nm[0] = *s1) != '\0')
  823.             s1++;
  824.         }
  825.     /*
  826.      * Assemble the output value.
  827.      */
  828.  
  829. assemble_output:
  830.         nm1[1] = nm1[2] = '\0';
  831.         if (*s1 == '\0') {
  832.  
  833.         /*
  834.          * Supply a space if there is no output character.
  835.          */
  836.         trout = 0;
  837.         nm1[0] = ' ';
  838.         } else {
  839.         s2 = s1 + 1;
  840.         if (*s1 == '\\' && (*s2 == '(' || *s2 == '*')) {
  841.             if (*s2 == '(') {
  842.         /*
  843.          * The output is a named character -- "\(xx".
  844.          */
  845.             trout = 1;
  846.             s1 = s2 + 1;
  847.             if ((nm1[0] = *s1) != '\0') {
  848.                 s1++;
  849.                 if ((nm1[1] = *s1) != '\0')
  850.                 s1++;
  851.             }
  852.             } else {
  853.         /*
  854.          * The output is an interpolated string -- * "\*x" or "\*(xx".
  855.          */
  856.             s1 = Asmcode(&s2, nm1);
  857.             if (*s1)
  858.                 s1++;
  859.             s2 = Findstr(nm1, NULL, 0);
  860.             if (*s2 != '\0') {
  861.             /*
  862.              * Interpolate a string value.
  863.              */
  864.                 if ((strlen((char *)s2) + strlen((char *)s1) + 1)
  865.                 >= MAXLINE)
  866.                 Error(WARN, LINE, " string too long: ",
  867.                     (char *)nm);
  868.                 else {
  869.                 (void) sprintf((char *)buf, "%s%s", (char *)s2,
  870.                     (char *)s1);
  871.                 (void) strcpy((char *)xbuf, (char *)buf);
  872.                     s1 = xbuf;
  873.                 }
  874.             }
  875.             goto assemble_output;
  876.             }
  877.         } else {
  878.             trout = 0;
  879.             if ((nm1[0] = *s1) != '0')
  880.             s1++;
  881.             else
  882.             nm1[0] = ' ';
  883.         }
  884.         }
  885.     /*
  886.      * Do the translation.
  887.      */
  888.         switch (trin) {
  889.  
  890.         case 0:            /* simple char */
  891.         switch (trout) {
  892.  
  893.         case 0:            /* to simple char */
  894.             Trtbl[(int)nm[0]] = nm1[0];
  895.             break;
  896.         case 1:            /* to named char */
  897.             if ((i = Findchar(nm1, 0, NULL, 0)) < 0
  898.             ||  strlen((char *)Schar[i].str) != 1)
  899.             Error(WARN, LINE, " bad named character: ",
  900.                 (char *)nm1);
  901.             else
  902.             Trtbl[(int)nm[0]] = *(Schar[i].str);
  903.             break;
  904.         }
  905.         break;
  906.         case 1:            /* named char */
  907.         if ((i = Findchar(nm, 0, NULL, 0)) < 0)
  908.             Error(WARN, LINE, " unknown named character: ", (char *)nm);
  909.         else {
  910.             switch (trout) {
  911.  
  912.             case 0:        /* to simple char */
  913.             Free(&Schar[i].str);
  914.             Schar[i].str = Newstr(nm1);
  915.             Schar[i].len = 1;
  916.             break;
  917.             case 1:        /* to named char */
  918.             if ((j = Findchar(nm1, 0, NULL, 0)) < 0)
  919.                 Error(WARN, LINE, " unknown named character: ",
  920.                 (char *)nm1);
  921.             else
  922.                 (void) Findchar(nm, Schar[j].len, Schar[j].str, 1);
  923.             break;
  924.             }
  925.         }
  926.         break;
  927.         }
  928.     }
  929. }
  930.  
  931.  
  932. /*
  933.  * Initialization - "^[.']\^b (fh|HF|NH) [01]"
  934.  *
  935.  * fh = first page header status
  936.  * HF = header/footer status
  937.  * NH = initialize number headers
  938.  *
  939.  * Initialization - "^[.']\^b lf n" -- set footer line count to n
  940.  *
  941.  * Initialization - "^[.']\^b lh n" -- set header line count to n
  942.  */
  943.  
  944. #ifdef    _BCC
  945. #pragma    argsused
  946. #endif
  947.  
  948.  
  949. static void
  950. nr_Ub(line, brk)
  951.     unsigned char *line;
  952.     int brk;
  953. {
  954.     int i;                /* temporary index */
  955.     unsigned char *s1, *s2;        /* temporary string pointers */
  956.  
  957.     if ((s1 = Field(2, line, 0)) == NULL)
  958.         return;
  959.     if ((s2 = Field(3, line, 0)) == NULL)
  960.         i = 0;
  961.     else
  962.         i = atoi((char *)s2);
  963.     if (s1[0] == 'f' && s1[1] == 'h')
  964.         Pass3(NOBREAK, (unsigned char *)"fph", -1, NULL, i);
  965.     else if (s1[0] == 'H' && s1[1] == 'F')
  966.         Hdft = i;
  967.     else if (s1[0] == 'N' && s1[1] == 'H') {
  968.         for (i = 0; i < MAXNHNR; i++)
  969.             Nhnr[i] = 0;
  970.     } else if (s1[0] == 'l' && s1[1] == 'f')
  971.         Botmarg = i;
  972.     else if (s1[0] == 'l' && s1[1] == 'h')
  973.         Topmarg = i;
  974.     else
  975.         Error(WARN, LINE, " unknown initialization", NULL);
  976. }
  977.  
  978.  
  979. /*
  980.  * Character definitions - "^[.']\^c"
  981.  */
  982.  
  983. #ifdef    _BCC
  984. #pragma    argsused
  985. #endif
  986.  
  987.  
  988. static void
  989. nr_Uc(line, brk)
  990.     unsigned char *line;
  991.     int brk;
  992. {
  993.     unsigned char buf[MAXLINE];    /* temporary buffer */
  994.     int i;                /* temporary index */
  995.     unsigned char *s1, *s2, *s4,    /* temporary string pointers */
  996.               *s5;
  997.  
  998.     s2 = Field(2, line, 0);
  999.     i = atoi((char *)Field(3, line, 0));
  1000.     s4 = Field(4, line, 0);
  1001.     if (i < 0 || i > MAXLINE/2 || *s2 == '\0') {
  1002.         Error(WARN, LINE, " bad character definition", NULL);
  1003.         return;
  1004.     }
  1005.     if (s4 == NULL)
  1006.         s4 = (unsigned char *)"";
  1007.     else if (*s4 == '"')
  1008.         s4++;
  1009.     s1 = buf;
  1010.     while ((s5 = (unsigned char *)strchr((char *)s4, '\\')) != NULL) {
  1011.         while (s5 > s4)
  1012.             *s1++ = *s4++;
  1013.         s4 = ++s5;
  1014.         if (*s5 == '\\')
  1015.             *s1++ = '\\';
  1016.         else if (*s5 == 'b')
  1017.             *s1++ = '\b';
  1018.         if (*s4)
  1019.             s4++;
  1020.     }
  1021.  
  1022. #ifdef    _BCC
  1023. #pragma warn -pia
  1024. #endif
  1025.  
  1026.     while (*s1++ = *s4++)
  1027.         ;
  1028.  
  1029. #ifdef    _BCC
  1030. #pragma warn +pia
  1031. #endif
  1032.  
  1033.     if (*s2 == 'h' && *(s2+1) == 'y')
  1034.         (void) Findhy(buf, i, 1);
  1035.     else
  1036.         (void) Findchar(s2, i, buf, 1);
  1037. }
  1038.  
  1039.  
  1040. /*
  1041.  * Font is OK - "[.']\^f <font_name_character>"
  1042.  */
  1043.  
  1044. #ifdef    _BCC
  1045. #pragma    argsused
  1046. #endif
  1047.  
  1048.  
  1049. static void
  1050. nr_Uf(line, brk)
  1051.     unsigned char *line;
  1052.     int brk;
  1053. {
  1054.     int i;                /* temporary index */
  1055.  
  1056.     if (line[3] != '\0' && line[4] != '\0') {
  1057.         for (i = 0; Fcode[i].nm; i++) {
  1058.             if (line[4] == Fcode[i].nm) {
  1059.                 Fcode[i].status = '1';
  1060.                 return;
  1061.             }
  1062.         }
  1063.     }
  1064.     Error(WARN, LINE, " unknown font", NULL);
  1065. }
  1066.  
  1067.  
  1068. /*
  1069.  * Resolutions - "[.']\^r cpi horizontal vertical"
  1070.  */
  1071.  
  1072. #ifdef    _BCC
  1073. #pragma    argsused
  1074. #endif
  1075.  
  1076.  
  1077. static void
  1078. nr_Ur(line, brk)
  1079.     unsigned char *line;
  1080.     int brk;
  1081. {
  1082.     unsigned char buf[MAXLINE];    /* temporary buffer */
  1083.     int i, j;            /* temporary indexes */
  1084.     double tval;            /* temporary value */
  1085.  
  1086.     if ((i = atoi((char *)Field(3, line, 0))) <= 0
  1087.     ||  (j = atoi((char *)Field(4, line, 0))) <= 0) {
  1088.         Error(WARN, LINE, " bad cpi resolutions", NULL);
  1089.         return;
  1090.     }
  1091.     tval = (double) (240.0 / (double) i);
  1092.     if (Findscale((int)'m', tval, 1) < 0)
  1093.         Error(FATAL, LINE, " missing Scal['m']", NULL);
  1094.     Scalen = tval;
  1095.     if (Scalen <= 0.0) {
  1096.         (void) sprintf((char *)buf, " bad Scale['n'] (%f)", Scalen);
  1097.         Error(FATAL, LINE, (char *)buf, NULL);
  1098.     }
  1099.     if (Findscale((int)'n', tval, 1) < 0)
  1100.         Error(FATAL, LINE, " missing Scale['n']", NULL);
  1101.     Scalev = (double) (240.0 / (double) j);
  1102.     if (Scalev <= 0.0) {
  1103.         (void) sprintf((char *)buf, " bad Scale['v'] (%f)", Scalen);
  1104.         Error(FATAL, LINE, (char *)buf, NULL);
  1105.     }
  1106.     if (Findscale((int)'v', Scalev, 1) < 0)
  1107.         Error(FATAL, LINE, " missing Scale['v']", NULL);
  1108. }
  1109.  
  1110.  
  1111. /*
  1112.  * Set line number and file name - "^[.']\^# <number> <file>"
  1113.  *
  1114.  * Lock line number and file name - "^[.']\^= <number> <file>"
  1115.  */
  1116.  
  1117. #ifdef    _BCC
  1118. #pragma    argsused
  1119. #endif
  1120.  
  1121.  
  1122. static void
  1123. nr_UL(line, brk)
  1124.     unsigned char *line;
  1125.     int brk;
  1126. {
  1127.     unsigned char *s1;        /* temporary string pointer */
  1128.  
  1129.     if ((s1 = Field(2, line, 0)) != NULL)
  1130.         P2il = atoi((char *)s1) - 1;
  1131.     else
  1132.         P2il = 0;
  1133.     Lockil = (line[2] == '#') ? 0 : 1;
  1134.     Free(&P2name);
  1135.     if (Field(3, line, 1) != NULL) {
  1136.         P2name = F;
  1137.         F = NULL;
  1138.     } else
  1139.         P2name = NULL;
  1140. }
  1141.