home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / enterprs / c128 / util / 128c.arc / FORMAT.C < prev    next >
Text File  |  1993-03-04  |  8KB  |  381 lines

  1. #INCLUDE <STDIO.H>
  2.  
  3. #DEFINE ╔╬╙╔┌┼      100
  4. #DEFINE ═┴╪╠╔╬┼     100
  5. #DEFINE ═┴╪╧╒╘      200
  6. #DEFINE ├╧══┴╬─     '.'
  7. #DEFINE ╨┴╟┼╬╒═     '#'
  8. #DEFINE ╚╒╟┼       1000
  9. #DEFINE ╨┴╟┼╠┼╬      66
  10. #DEFINE ╨┴╟┼╫╔─╘╚    60
  11. #DEFINE ┘┼╙           1
  12. #DEFINE ╬╧            0
  13. #DEFINE ═┴╥╟╔╬        3
  14.  
  15. #DEFINE ╒╬╦╬╧╫╬  0
  16. #DEFINE ╞╔       1
  17. #DEFINE ╬╞       2
  18. #DEFINE ┬╥       3
  19. #DEFINE ╠╙       4
  20. #DEFINE ┬╨       5
  21. #DEFINE ╙╨       6
  22. #DEFINE ╔╬       7
  23. #DEFINE ╥═       8
  24. #DEFINE ╘╔       9
  25. #DEFINE ├┼      10
  26. #DEFINE ╚┼      11
  27. #DEFINE ╞╧      12
  28. #DEFINE ╨╠      13
  29. #DEFINE ═1      14
  30. #DEFINE ═2      15
  31. #DEFINE ═3      16
  32. #DEFINE ═4      17
  33. #DEFINE ╬┼      18
  34. #DEFINE ╬├═─╙   18
  35.  
  36. #DEFINE MAX(X,Y)  ( (X) > (Y) ? (X) : (Y) )
  37. #DEFINE MIN(X,Y)  ( (X) > (Y) ? (Y) : (X) )
  38.  
  39. INT  FILL,         /* FILL IS ┘┼╙ */
  40.      LSVAL,        /* CURRENT LINE SPACING */
  41.      INVAL,        /* CURRENT INDENT */
  42.      RMVAL,        /* CURRENT RIGHT MARGIN */
  43.      TIVAL,        /* CURRENT TEMPORARY INDENT */
  44.      CEVAL,        /* NUMBER OF LINES TO CENTER */
  45.      CURPAG,       /* CURRENT OUTPUT PAGE NUMBER */
  46.      NEWPAG,       /* NEXT OUTPUT PAGE NUMBER */
  47.      LINENO,       /* NEXT LINE TO BE PRINTED */
  48.      PLVAL,        /* PAGE LENGTH IN LINES */
  49.      M1VAL,        /* MARGIN BEFORE AND INCLUDING HEADER */ 
  50.      M2VAL,        /* MARGIN AFTER HEADER */
  51.      M3VAL,        /* MARGIN AFTER LAST LINE */
  52.      M4VAL,        /* BOTTOM MARGIN, INCLUDING FOOTER */
  53.      BOTTOM;       /* LAST LIVE LINE ON PAGE, = PLVAL - M3VAL - M4VAL */
  54.  
  55. CHAR HEADL[═┴╪╠╔╬┼], HEADC[═┴╪╠╔╬┼], HEADR[═┴╪╠╔╬┼];  /* TOP OF PAGE TITLE */
  56. CHAR FOOTL[═┴╪╠╔╬┼], FOOTC[═┴╪╠╔╬┼], FOOTR[═┴╪╠╔╬┼];  /* END OF PAGE TITLE */
  57.  
  58. CHAR OUTBUF[═┴╪╧╒╘];   /* OUTPUT BUFFER */
  59. INT  OUTP,            /* LAST CHAR POSITION IN OUTBUF */
  60.      OUTW,         /* WIDTH OF TEXT CURRENTLY IN OUTBUF */
  61.      OUTWDS;       /* NUMBER OF WORDS IN OUTBUF */
  62.  
  63.  
  64. MAIN (ARGC, ARGV) /* TEXT FORMATTER */
  65. UNSIGNED ARGC;
  66. CHAR **ARGV;
  67.    ╞╔╠┼ FIN;
  68.  
  69.    INIT();
  70.    IF (ARGC == 1)
  71.       FORMAT (STDIN);
  72.    ELSE
  73.       WHILE (--ARGC) █
  74.          IF ((FIN = FOPEN (*++ARGV, "R")) == ╬╒╠╠ ▀▀ FERROR()) █
  75.             PRINTF ("CAN'T OPEN %S\N", *ARGV);
  76.             EXIT();
  77.          ▌
  78.          FORMAT (FIN);
  79.          FCLOSE (FIN);
  80.       ▌
  81.    IF (LINENO > 0)
  82.       SPACE (╚╒╟┼);
  83.  
  84. FORMAT (FIN)
  85. ╞╔╠┼ FIN;
  86.    STATIC CHAR INBUF[╔╬╙╔┌┼];
  87.  
  88.    WHILE (FGETS (INBUF, ╔╬╙╔┌┼, FIN) != ╬╒╠╠)
  89.       IF (*INBUF == ├╧══┴╬─)
  90.          COMMAND (INBUF);
  91.       ELSE
  92.          TEXT (INBUF);
  93.  
  94. INIT() /* INITIALIZE VARIABLES */
  95.    CURPAG = 0;
  96.    NEWPAG = 1;
  97.    LINENO = 0;
  98.    PLVAL  = ╨┴╟┼╠┼╬;
  99.    *HEADL = '\0';
  100.    *HEADC = '\0';
  101.    *HEADR = '\0';
  102.    *FOOTL = '\0';
  103.    *FOOTC = '\0';
  104.    *FOOTR = '\0';
  105.    FILL = ┘┼╙;
  106.    LSVAL = 1;
  107.    INVAL = 0;
  108.    RMVAL = ╨┴╟┼╫╔─╘╚;
  109.    TIVAL = 0;
  110.    CEVAL = 0;
  111.    OUTP = -1;
  112.    OUTW = 0;
  113.    OUTWDS = 0;
  114.    M1VAL = ═┴╥╟╔╬;
  115.    M2VAL = ═┴╥╟╔╬;
  116.    M3VAL = ═┴╥╟╔╬;
  117.    M4VAL = ═┴╥╟╔╬;
  118.    BOTTOM = PLVAL - M3VAL - M4VAL;
  119.  
  120. COMMAND (BUF) /* PERFORM FORMATTING COMMAND */
  121. CHAR *BUF;
  122.    INT CT;
  123.    INT VAL;
  124.    STATIC CHAR ARGTYP;
  125.    STATIC SPVAL;
  126.  
  127.    IF ((CT = COMTYP(BUF)) == ╒╬╦╬╧╫╬)
  128.       RETURN;
  129.    VAL = GETVAL (BUF, &ARGTYP);
  130.    SWITCH (CT) █
  131.       CASE ╞╔:
  132.          BRK();
  133.          FILL = ┘┼╙;
  134.          BREAK;
  135.       CASE ╬╞:
  136.          BRK();
  137.          FILL = ╬╧;
  138.          BREAK;
  139.       CASE ┬╥:
  140.          BRK();
  141.          BREAK;
  142.       CASE ╠╙:
  143.          SET (&LSVAL, VAL, ARGTYP, 1, 1, ╚╒╟┼);
  144.          BREAK;
  145.       CASE ╙╨:
  146.          SET (&SPVAL, VAL, ARGTYP, 1, 0, ╚╒╟┼);
  147.          SPACE (SPVAL);
  148.          BREAK;
  149.       CASE ┬╨:
  150.          IF (LINENO > 0)
  151.             SPACE (╚╒╟┼);
  152.          SET (&CURPAG, VAL, ARGTYP, CURPAG+1, -╚╒╟┼, ╚╒╟┼);
  153.          NEWPAG = CURPAG;
  154.          BREAK;
  155.       CASE ╨╠:
  156.          SET (&PLVAL, VAL, ARGTYP, ╨┴╟┼╠┼╬, M1VAL+M2VAL+M3VAL+M4VAL+1, ╚╒╟┼);
  157.          BOTTOM = PLVAL - M3VAL - M4VAL;
  158.          BREAK;
  159.       CASE ╔╬:
  160.          SET (&INVAL, VAL, ARGTYP, 0, 0, RMVAL - 1);
  161.          TIVAL = INVAL;
  162.          BREAK;
  163.       CASE ╥═:
  164.          SET (&RMVAL, VAL, ARGTYP, ╨┴╟┼╫╔─╘╚, TIVAL+1, ╚╒╟┼);
  165.          BREAK;
  166.       CASE ╘╔:
  167.          SET (&TIVAL, VAL, ARGTYP, 0, 0, RMVAL);
  168.          BREAK;
  169.       CASE ├┼:
  170.          BRK();
  171.          SET (&CEVAL, VAL, ARGTYP, 1, 0, ╚╒╟┼);
  172.          BREAK;
  173.       CASE ╚┼:
  174.          GETTL (BUF, HEADL, HEADC, HEADR);
  175.          BREAK;
  176.       CASE ╞╧:
  177.          GETTL (BUF, FOOTL, FOOTC, FOOTR);
  178.          BREAK;
  179.       CASE ═1:
  180.          SET (&M1VAL, VAL, ARGTYP, ═┴╥╟╔╬, 0, PLVAL-M2VAL-M3VAL-M4VAL-1);
  181.          BREAK;
  182.       CASE ═2:
  183.          SET (&M2VAL, VAL, ARGTYP, ═┴╥╟╔╬, 0, PLVAL-M1VAL-M3VAL-M4VAL-1);
  184.          BREAK;
  185.       CASE ═3:
  186.          SET (&M3VAL, VAL, ARGTYP, ═┴╥╟╔╬, 0, PLVAL-M1VAL-M2VAL-M4VAL-1);
  187.          BOTTOM = PLVAL - M3VAL - M4VAL;
  188.          BREAK;
  189.       CASE ═4:
  190.          SET (&M4VAL, VAL, ARGTYP, ═┴╥╟╔╬, 0, PLVAL-M1VAL-M2VAL-M3VAL-1);
  191.          BOTTOM = PLVAL - M3VAL - M4VAL;
  192.          BREAK;
  193.       CASE ╬┼:
  194.          BRK();
  195.          IF (VAL > BOTTOM - LINENO + 1)
  196.             SPACE (╚╒╟┼);
  197.          BREAK;
  198.    ▌
  199.  
  200. COMTYP (BUF)
  201. CHAR *BUF;
  202.    STATIC CHAR COMMANDS[][3] = █
  203.                   "FI", "NF", "BR", "LS", "BP",
  204.                   "SP", "IN", "RM", "TI", "CE",
  205.                   "HE", "FO", "PL", "M1", "M2",
  206.                   "M3", "M4", "NE"
  207.                ▌;
  208.    CHAR *P;
  209.    UNSIGNED I;
  210.  
  211.    FOR (P=COMMANDS, I=1; I <= ╬├═─╙; I++, P+=3)
  212.       IF (BUF[1] == *P && BUF[2] == *(P+1))
  213.          RETURN (I);
  214.    RETURN ╒╬╦╬╧╫╬;
  215.  
  216. GETVAL (BUF, ARGTYP)  /* EVALUATE OPTIONAL NUMERIC ARGUMENT */
  217. CHAR *BUF, *ARGTYP;
  218.    CHAR *SKIPB();
  219.  
  220.    BUF = SKIPB (BUF + 3);
  221.    *ARGTYP = *BUF;
  222.    IF (*ARGTYP == '+' ▀▀ *ARGTYP == '-')
  223.       BUF++;
  224.    RETURN (ATOI(BUF));
  225.  
  226. SET (PARAM, VAL, ARGTYP, DEFVAL, MINVAL, MAXVAL)
  227. INT *PARAM;
  228.    SWITCH (ARGTYP) █
  229.       CASE '\N':
  230.          *PARAM = DEFVAL;
  231.          BREAK;
  232.       CASE '+':
  233.          *PARAM += VAL;
  234.          BREAK;
  235.       CASE '-':
  236.          *PARAM -= VAL;
  237.          BREAK;
  238.       DEFAULT:
  239.          *PARAM = VAL;
  240.    ▌
  241.    *PARAM = MIN (*PARAM, MAXVAL);
  242.    *PARAM = MAX (*PARAM, MINVAL);
  243.  
  244. PUT (BUF) /* PUT OUT LINE WITH PROPER SPACING AND INDENTING */
  245. CHAR *BUF;
  246.    UNSIGNED I;
  247.  
  248.    IF (LINENO == 0 ▀▀ LINENO > BOTTOM)
  249.       PHEAD();
  250.    FOR (I = TIVAL; I--;)
  251.       PUTCHAR (' ');
  252.    TIVAL = INVAL;
  253.    FPUTS (BUF, STDOUT);
  254.    SKIP (MIN(LSVAL-1, BOTTOM-LINENO));
  255.    LINENO += LSVAL;
  256.    IF (LINENO > BOTTOM)
  257.       PFOOT();
  258.  
  259. PHEAD()  /* PUT OUT PAGE HEADER */
  260.    CURPAG = NEWPAG++;
  261.    IF (M1VAL > 0) █
  262.       SKIP (M1VAL - 1);
  263.       PUTTL (HEADL, HEADC, HEADR, CURPAG);
  264.    ▌
  265.    SKIP (M2VAL);
  266.    LINENO = M1VAL + M2VAL + 1;
  267.  
  268. PFOOT()  /* PUT OUT PAGE FOOTER */
  269.    SKIP (M3VAL);
  270.    IF (M4VAL > 0) █
  271.       PUTTL (FOOTL, FOOTC, FOOTR, CURPAG);
  272.       SKIP (M4VAL - 1);
  273.    ▌
  274.  
  275. PUTTL (TTLL, TTLC, TTLR, PAGENO) /* PUT OUT TITLE LINE WITH OPTIONAL PAGE NUMBER */
  276. CHAR *TTLL, *TTLC, *TTLR;
  277.    STATIC CHAR TTLOUT[═┴╪╠╔╬┼];
  278.    INT LEN, NCHARS, SHIFT;
  279.  
  280.    NCHARS = EXPAND (TTLOUT, TTLL, PAGENO) + TIVAL;
  281.    PRINTF ("%*S", NCHARS, TTLOUT);
  282.    LEN = EXPAND (TTLOUT, TTLC, PAGENO);
  283.    SHIFT = ((RMVAL + TIVAL - LEN) >> 1) - NCHARS;
  284.    PRINTF ("%*S", SHIFT+LEN, TTLOUT);
  285.    NCHARS += SHIFT + LEN;
  286.    EXPAND (TTLOUT, TTLR, PAGENO);
  287.    PRINTF ("%*S\N", MAX(RMVAL-NCHARS,0), TTLOUT);
  288.  
  289. EXPAND (OUT, IN, PAGENO)
  290. CHAR *OUT, *IN;
  291.    CHAR *I;
  292.  
  293.    FOR (I = OUT; *IN; IN++)
  294.       IF (*IN == ╨┴╟┼╬╒═) █
  295.          SPRINTF (I, "%D", PAGENO);
  296.          FOR (; *I; I++)
  297.             ;
  298.       ▌ ELSE
  299.          *I++ = *IN;
  300.    *I = '\0';
  301.    RETURN (STRLEN(OUT));
  302.  
  303. GETTL (BUF, TTLL, TTLC, TTLR)  /* COPY TITLE FROM BUF TO TTL */
  304. CHAR *BUF, *TTLL, *TTLC, *TTLR;
  305.    IF ((BUF = GETTL2 (BUF, TTLL)) == ╬╒╠╠)
  306.       RETURN;
  307.    IF ((BUF = GETTL2 (BUF, TTLL)) == ╬╒╠╠)
  308.       RETURN;
  309.    IF ((BUF = GETTL2 (BUF, TTLC)) == ╬╒╠╠)
  310.       RETURN;
  311.    GETTL2 (BUF, TTLR);
  312.  
  313. GETTL2 (BUF, TTL)
  314. CHAR *BUF, *TTL;
  315.    FOR (BUF++; *BUF != '/'; BUF++) █
  316.       IF (*BUF == '\N') █
  317.          *TTL = '\0';
  318.          RETURN ╬╒╠╠;
  319.       ▌
  320.       *TTL++ = *BUF;
  321.    ▌
  322.    *TTL = '\0';
  323.    RETURN BUF;
  324.  
  325. SPACE (N)  /* SPACE N LINES OR TO BOTTOM OF PAGE */
  326.    BRK();
  327.    IF (LINENO > BOTTOM)
  328.       RETURN;
  329.    IF (LINENO == 0)
  330.       PHEAD();
  331.    SKIP (MIN(N, BOTTOM+1-LINENO));
  332.    LINENO += N;
  333.    IF (LINENO > BOTTOM)
  334.       PFOOT();
  335.  
  336. SKIP (N)  /* OUTPUT N BLANK LINES */
  337.    INT I;
  338.  
  339.    FOR (I = 1; I <= N; I++)
  340.       PUTCHAR ('\N');
  341.  
  342. CHAR *SKIPB (P)
  343. CHAR *P;
  344.    FOR (; *P == ' '; P++)
  345.       ;
  346.    RETURN P;
  347.