home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 318_01 / redfmt.c < prev    next >
C/C++ Source or Header  |  1990-06-18  |  4KB  |  268 lines

  1. /*
  2.     RED output format module -- Full C version
  3.  
  4.     Source:  redfmt.c
  5.     Version: October 16, 1983; January 18, 1990;
  6.  
  7.     Written by
  8.     
  9.         Edward K. Ream
  10.         166 N. Prospect
  11.         Madison WI 53705
  12.         (608) 257-0802
  13.  
  14.  
  15.     PUBLIC DOMAIN SOFTWARE
  16.  
  17.     This software is in the public domain.
  18.  
  19.     See red.h for a disclaimer of warranties and other information.
  20. */
  21.  
  22. #include "red.h"
  23.  
  24. /*
  25.     Declare routines local to this module.
  26. */
  27. static void    fmtdevch    (char c);
  28. static int    fmtlench    (char c,int col);
  29. static void    fmtoutch    (char c,int col);
  30.  
  31. /*
  32.     Declare variables local to this module.
  33. */
  34. static int fmttab;    /* maximal tab length                */
  35. static int fmtdev;    /* device flag -- TRUE/FALSE = LIST/CONSOLE    */
  36. static int fmtwidth;    /* devide width.  LISTW/SCRNW1            */
  37.  
  38. /*
  39.     Adjust fmtcol[] to prepare for calls on fmtout() and
  40.     fmtlen().
  41.  
  42.     NOTE:  this routine is needed as an efficiency measure.
  43.     Without fmtadj(), calls on fmtlen() become too slow.
  44. */
  45. void
  46. fmtadj(char *buf, int minind, int maxind)
  47. {
  48.     int k;
  49.  
  50.     TRACEPB("fmtadj",  sl_lpout();
  51.         sl_sout(buf);    sl_csout();
  52.         sl_iout(minind); sl_csout(); 
  53.         sl_iout(maxind); sl_rpout());
  54.  
  55.     /* Line always starts at left margin. */
  56.     fmtcol[0] = 0;
  57.  
  58.     /* Start scanning at minind. */
  59.     k = minind;
  60.     while (k < maxind) {
  61.         fmtcol[k+1] = fmtcol[k]+fmtlench(buf[k],fmtcol[k]);
  62.         k++;
  63.     }
  64.  
  65.     TICKX("fmtadj");
  66. }
  67.  
  68. /*
  69.     Direct output from this module to either the console or
  70.     the list device.
  71. */
  72. void
  73. fmtassn(int listflag)
  74. {
  75.     TRACEPB("fmtassn", sl_lpout(); sl_iout(listflag); sl_rpout());
  76.  
  77.     if (listflag == TRUE) {
  78.         fmtdev = TRUE;
  79.         fmtwidth = LISTW;
  80.     }
  81.     else {
  82.         fmtdev = FALSE;
  83.         fmtwidth = SCRNW1;
  84.     }
  85.  
  86.     TICKX("fmtassn");
  87. }
  88.  
  89. /*
  90.     Output a newline to the current device.
  91. */
  92. void
  93. fmtcrlf(void)
  94. {
  95.     TICKB("fmtcrlf");
  96.  
  97.     if (fmtdev == TRUE) {
  98.         syslout('\r');
  99.         syslout('\n');
  100.     }
  101.     else if (hasdel == TRUE) {
  102.         outxy(0, 1);
  103.         outdel();
  104.         outxy(0, SCRNL1);
  105.         outdelln();
  106.     }
  107.     else {
  108.         outxy(0,SCRNL1);
  109.         outchar('\r');
  110.         outchar('\n');
  111.         pmtzap();
  112.         pmtupd();
  113.     }
  114.  
  115.     TICKX("fmtcrlf");
  116. }
  117.  
  118. /*
  119.     Output character to current device.
  120. */
  121. static void
  122. fmtdevch(char c)
  123. {
  124.     TRACEPB("fmtdevch", sl_lpout(); sl_cout(c); sl_rpout());
  125.  
  126.     if (fmtdev == TRUE) {
  127.         syslout(c);
  128.     }
  129.     else {
  130.         outchar(c);
  131.     }
  132.  
  133.     TICKX("fmtdevch");
  134. }
  135.  
  136. /*
  137.     Return length of char c at column col.
  138. */
  139. static int
  140. fmtlench(char c, int col)
  141. {
  142.     TRACEPB("fmtlench",   sl_lpout();
  143.         sl_cout(c);   sl_csout();
  144.         sl_iout(col); sl_rpout());
  145.  
  146.     if (c == '\t') {
  147.         /* tab every fmttab columns */
  148.         RETURN_INT("fmtlench",(fmttab-(col%fmttab)));
  149.     }
  150.     else if (c<32) {
  151.         /* control char */
  152.         RETURN_INT("fmtlench",(2));
  153.     }
  154.     else {
  155.         RETURN_INT("fmtlench",(1));
  156.     }
  157. }
  158.  
  159. /*
  160.     Output one character to current device.
  161.     Convert tabs to blanks.
  162. */
  163. static void
  164. fmtoutch(char c, int col)
  165. {
  166.     int k;
  167.  
  168.     TRACEPB("fmtoutch",   sl_lpout();
  169.         sl_cout(c);   sl_csout();
  170.         sl_iout(col); sl_rpout());
  171.  
  172.     if (c == '\t') {
  173.         k = fmtlench('\t',col);
  174.         while ((k--)>0) {
  175.             fmtdevch(' ');
  176.         }
  177.     }
  178.     else if (c<32) {
  179.         fmtdevch('^');
  180.         fmtdevch(c+64);
  181.     }
  182.     else {
  183.         fmtdevch(c);
  184.     }
  185.  
  186.     TICKX("fmtoutch");
  187. }
  188.  
  189. /*
  190.     Set tabs at every n columns.
  191. */
  192. void
  193. fmtset(int n)
  194. {
  195.     TRACEPB("fmtset", sl_lpout(); sl_iout(n); sl_rpout());
  196.  
  197.     fmttab = max(1,n);
  198.  
  199.     TICKX("fmtset");
  200. }
  201.  
  202. /*
  203.     Print string which ends with '\n' or '\0'.
  204.     to current device.
  205.     Truncate the string if it is too long.
  206. */
  207. void
  208. fmtsout(char *buf, int offset)
  209. {
  210.     char c;
  211.     int col,k;
  212.  
  213.     TRACEPB("fmtsout",  sl_lpout();
  214.         sl_sout(buf);    sl_csout();
  215.         sl_iout(offset); sl_rpout());
  216.  
  217.     col = 0;
  218.  
  219.     for (;;) {
  220.         c = *buf++;
  221.         if (c == '\0' || c == '\n') {
  222.             break;
  223.         }
  224.         k = fmtlench(c,col);
  225.         if (col + k + offset > fmtwidth) {
  226.             break;
  227.         }
  228.         fmtoutch(c,col);
  229.         col += k;
  230.     }
  231.  
  232.     TICKX("fmtsout");
  233. }
  234.  
  235. /*
  236.     Print buf[i] ... buf[j-1] on current device so long as
  237.     characters will not be printed in last column.
  238. */
  239. void
  240. fmtsubs(char *buf, int i, int j)
  241. {
  242.     int k;
  243.  
  244.     TRACEPB("fmtsubs", sl_lpout();
  245.         sl_sout(buf); sl_csout();
  246.         sl_iout(i);   sl_csout(); 
  247.         sl_iout(j);   sl_rpout());
  248.  
  249.     if (fmtcol[i] >= fmtwidth) {
  250.         RETURN_VOID("fmtsubs");
  251.     }
  252.  
  253.     /* Position the cursor. */
  254.     outxy(fmtcol[i], outy);
  255.     while (i < j) {
  256.         if (fmtcol[i+1] > fmtwidth) {
  257.             break;
  258.         }
  259.         fmtoutch(buf[i],fmtcol[i]);
  260.         i++;
  261.     }
  262.  
  263.     /* Clear rest of the line. */
  264.     outdeol();
  265.  
  266.     TICKX("fmtsubs");
  267. }
  268.