home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_100 / 150_01 / roff2.c < prev    next >
Text File  |  1985-09-07  |  11KB  |  477 lines

  1. /*
  2.        HEADER:  150.??;
  3.         TITLE:  ROFF - "RUNOFF" Text Formatter Program;
  4.       VERSION:  5.1;
  5.          DATE:  08/28/1982;
  6.   DESCRIPTION:  "This is the second ROFF source file.  See ROFF1.C for the
  7.                  complete description.";
  8.      KEYWORDS:  ROFF, Text Formatter, Software Tools;
  9.        SYSTEM:  any system with C compiler;
  10.      FILENAME:  ROFF2.C;
  11.      SEE-ALSO:  ROFF.DOC, ROFF.H, ROFF.HE, ROFF1.C, ROFF.EXE;
  12.       AUTHORS:  modified "for IBM-PC" by M. S. Zachmann;
  13.     COMPILERS:  BDS-C originally, IBM C compiler unknown;
  14.    REFERENCES:  AUTHORS: M. S. Zachmann; TITLE: "ROFF";
  15.                 CITATION: "PC-SIG Disk 50 or 142";
  16.                 AUTHORS: Kernighan and Plauger; TITLE: "Software Tools";
  17.                 CITATION: "available in many computer stores" 
  18.        ENDREF;
  19. */
  20. /* 7 MAY 81 */
  21.  
  22. #include "stdio.h"
  23. #include "ctype.h"
  24. #include "roff.he"
  25.  
  26. /****************************************************************
  27. handles case of leading blanks or tabs; empty lines 
  28. ******************************************************************/
  29.  
  30. leadbl (line)
  31. char *line;
  32. {
  33.     int i, j;
  34.  
  35.  
  36.     brk();
  37.  
  38.     /* find first non-blank */
  39.     for( i=0; line[i] == BLANK; i++ );
  40.  
  41.     if ( line[i] != NEWLINE ) 
  42.         TIVAL = i;
  43.     while (line[i] == TAB)
  44.     { TIVAL += 8;
  45.         i++;
  46.     }
  47.  
  48.     /* move line to left */
  49.     for (j=0; (line[j] = line[i]) != '\0'; j++, i++ );
  50.  
  51.  
  52.     return;
  53. }
  54.  
  55.  
  56.  
  57. /*******************************************************************
  58. get indices of first and last occurrences of c in string
  59. ********************************************************************/
  60. int find_char (string, c, first, last)
  61. char *string, c;
  62. int *first, *last;
  63. {
  64.     int i, j, k;
  65.  
  66.     *first = -1;
  67.     *last = -1;
  68.     for (i=0; string[i] != '\0'; i++)
  69.     {
  70.         if (string[i] == c)
  71.         { *last = i;
  72.             if (*first == -1)    *first = i;
  73.         }
  74.     }
  75.     return;
  76. }
  77.  
  78. /***************************************************************
  79.     replace c1 in string with c2
  80. ****************************************************************/
  81. replace_char (string, c1, c2)
  82. char *string, c1, c2;
  83. {
  84.     int i;
  85.  
  86.     for (i=0; string[i] != '\0'; i++)
  87.         if (string[i] == c1)    string[i] = c2;
  88.  
  89.     return;
  90. }
  91.  
  92.  
  93. /********************************************************************
  94.         produces n empty lines
  95. *********************************************************************/
  96. skip (n)
  97. int n;
  98. {
  99.     int i;
  100.  
  101.     if DEBUG fprintf(stderr,"\n    SKIP %d line(s)", n);
  102.  
  103.     for ( i=0; i<n; i++)
  104.     { if DEBUG putchar('!');
  105.         putchar(NEWLINE);
  106.     }
  107.  
  108.     return;
  109. }
  110.  
  111.  
  112. /******************************************************************
  113.     indents the proper number of spaces
  114. *******************************************************************/
  115. indent(val)
  116. int val;
  117. {
  118.     int i;
  119.  
  120.     if DEBUG fprintf(stderr,"\n    INDENT %d spaces(s)",val);
  121.  
  122.     for ( i=0; i<val; i++ )        putchar( BLANK );
  123.  
  124.  
  125. }
  126.  
  127.  
  128.  
  129. /*******************************************************************
  130.         puts out page header
  131. *******************************************************************/
  132. phead()
  133. {
  134.  
  135.  
  136.     CURPAG = NEWPAG;
  137.     NEWPAG++;
  138.  
  139.     if ( M1VAL > 0 )
  140.     { skip ( M1VAL - 1 );
  141.         puttl ( HEADER, CURPAG );
  142.     }
  143.  
  144.     skip ( M2VAL );
  145.  
  146.     LINENO = M1VAL + M2VAL + 1;
  147.     if DEBUG fprintf(stderr,"\nLINENO=%d", LINENO);
  148.     return;
  149. }
  150.  
  151.  
  152. /*********************************************************************
  153.         puts out page footer
  154. *********************************************************************/
  155. pfoot()
  156. {
  157.  
  158.  
  159.     skip ( M3VAL );
  160.     if ( M4VAL > 0 )
  161.     { puttl ( FOOTER, CURPAG );
  162.         skip ( M4VAL - 1 );
  163.     }
  164.     return;
  165.  
  166. }
  167.  
  168.  
  169. /*******************************************************************
  170.     put out title line with optional page no.
  171. *******************************************************************/
  172. puttl ( title_str, pageno )
  173. char *title_str;
  174. int pageno;
  175. {
  176.     int i;
  177.  
  178.  
  179.     for ( i=0; title_str[i] != '\0'; i++ )
  180.         if ( title_str[i] == NUMSIGN )
  181.             putdec ( pageno, 1 );    /* print pageno, width >= 1 */
  182.     else
  183.         putchar( title_str[i]);
  184.  
  185.     return;
  186. }
  187.  
  188. /*******************************************************************
  189.     put out num in string of width >= w
  190. ******************************************************************/
  191. putdec ( num, w )
  192. int num;
  193. int w;
  194. {
  195.     int i, nd;
  196.     char chars[10];
  197.  
  198.  
  199.     nd = itoc ( num, chars, 10 );
  200.     for ( i=nd + 1; i<=w; i++ )
  201.         putchar(BLANK);
  202.     for ( i=0;i<=nd; i++)
  203.         putchar( chars[i] );
  204.  
  205.     return;
  206. }
  207.  
  208. /*******************************************************************
  209.     convert int num to char string in numstr
  210. *********************************************************************/
  211. itoc ( num, numstr, size )
  212. int num;
  213. char *numstr;
  214. int size;    /* largest size of numstr */
  215. {
  216.     int absnum, i, j, k, d;
  217.  
  218.  
  219.     absnum = abs(num);
  220.     numstr[0] = '\0';
  221.     i = 0;
  222.  
  223.     do
  224.     { i++;
  225.         d = absnum % 10;
  226.         numstr[i] = d + '0';
  227.         absnum = absnum/10;
  228.     } while ( absnum != 0 && i<size );
  229.  
  230.     if ( num < 0 && i<size )
  231.     { i++;
  232.         numstr[i] = '-';
  233.     }
  234.  
  235.     for ( j=0; j<i; j++ )
  236.     { k = numstr[i];
  237.         numstr[i] = numstr[j];
  238.         numstr[j] = k;
  239.         i--;
  240.     }
  241.  
  242.     return ( strlen(numstr) );
  243. }
  244.  
  245. /********************************************************************
  246.     copy title from com_line to ttl
  247. **********************************************************************/
  248. gettl ( com_line, ttl )
  249. char *com_line, *ttl;
  250. {
  251.     int i;
  252.     char local[ MAXLINE ];
  253.  
  254.  
  255.     if DEBUG fprintf(stderr,"\n\nGETTL command line= <%s>", com_line);
  256.  
  257.     i=0;
  258.     while ( com_line[i]!= ' ' && com_line[i]!='\t' && com_line[i]!='\n')
  259.         i++;
  260.  
  261.     strcpy ( local, com_line );
  262.     skip_blanks (&local[i]);
  263.  
  264.     /* strip quote if found */
  265.     if ( local[i]==SQUOTE || local[i]==DQUOTE)    i++;
  266.  
  267.     strcpy ( ttl, &local[i] );
  268.     if DEBUG fprintf(stderr,"\ntitle = <%s>", ttl);
  269.  
  270.     return;
  271. }
  272.  
  273.  
  274. /******************************************************************
  275.     space n lines or to bottom of the page
  276. *******************************************************************/
  277. space (n)
  278. int n;
  279. {
  280.  
  281.     if DEBUG fprintf(stderr,"\nSPACE %d line(s), LINENO= %d", n, LINENO);
  282.  
  283.     brk();    /* flush out last unfilled line */
  284.     if (LINENO > BOTTOM)    return;    /* end of page */
  285.  
  286.     if ( LINENO == 0 )    /* top of page */
  287.         phead();
  288.  
  289.     skip( min( n, BOTTOM+1-LINENO ));    /* can't skip past bottom  */
  290.     LINENO = LINENO + n;    /* obvious */
  291.  
  292.     if DEBUG fprintf(stderr,"\n    LINENO = %d", LINENO);
  293.     if (LINENO > BOTTOM)
  294.     {
  295.         pfoot();    /* print footer if bottom */
  296.     }
  297.  
  298.     return;
  299. }
  300.  
  301.  
  302. /*******************************************************
  303.     yet ANOTHER version of text !!! no. 59,999,999
  304. get it right this time Kath dear
  305. *******************************************************/
  306. text (line)
  307. char *line;
  308. {
  309.     char wrdbuf [MAXLINE];
  310.     int i, j, k;
  311.     char *p1, *p2;
  312.  
  313.     if DEBUG fprintf(stderr,"\n\nTEXT:<%s>", line);
  314.     if (line[0] == BLANK || line[0] == NEWLINE || line[0] == TAB)
  315.         leadbl (line);
  316.     if (ULVAL > 0)    /* set high bits of all non-white space chars */
  317.     {
  318.         ULVAL--;
  319.         p1 = p2 = line;
  320.         while (*p2)
  321.         { if (*p2 == TAB || *p2 == BLANK || *p2 == NEWLINE)
  322.                 *p1++ = *p2++;
  323.             else 
  324.                 *p1++ = *p2++ | 0x80;
  325.         }
  326.     }
  327.     if (CEVAL > 0)
  328.     { center (line);
  329.         put (line);
  330.         CEVAL--;
  331.     }
  332.     else if ( line[0] == NEWLINE || FILL == NO )
  333.         put (line);
  334.     else while (WE_HAVE_A_WORD == getwrd (line, wrdbuf))
  335.             putwrd (wrdbuf);
  336.     return;
  337. }
  338.  
  339. /***********************************************************
  340.     put out a line of text with correct indentation
  341.     underlining if specified
  342. ************************************************************/
  343. put (line)
  344. char *line;
  345. {
  346.     int i, j, k;
  347.  
  348.     if DEBUG fprintf(stderr,"\n\nPUT<%s>",line);
  349.     if (LINENO == 0 || LINENO > BOTTOM )    phead();
  350.     indent (TIVAL);
  351.     putline (line);
  352.     TIVAL = INVAL;
  353.     skip (min(LSVAL-1, BOTTOM-LINENO));
  354.     LINENO = LINENO + LSVAL;
  355.     if DEBUG fprintf(stderr,"\nLINENO=%d,  LSVAL=%d",LINENO, LSVAL);
  356.     if (LINENO > BOTTOM)    pfoot();
  357.     return;
  358. }
  359. /***********************************************************
  360. concatenates the word onto the end of OUTBUF for filled text
  361. ************************************************************/
  362. putwrd (wrdbuf)
  363. char *wrdbuf;
  364. {
  365.     int i, j, k;
  366.     char s[MAXLINE], ch;
  367.     int line_len, outw, new_out_width, wid;
  368.     int nextra;
  369.  
  370.     if DEBUG fprintf(stderr,"\nwrdbuf = <%s>",wrdbuf);
  371.     skip_blanks (wrdbuf);
  372.     trunc_bl (wrdbuf);
  373.     wid = strlen (wrdbuf);
  374.     if DEBUG fprintf(stderr,"\nwid = %d",wid);
  375.  
  376.     line_len = RMVAL - TIVAL;
  377.     outw = strlen (OUTBUF);
  378.     new_out_width = wid + outw + 1;    /* one for blank */
  379.     if DEBUG fprintf(stderr,"\nnew_out_width=%d, outw=%d, wid=%d, line_len=%d",
  380.       new_out_width,    outw,    wid,    line_len   );
  381.     if (new_out_width > min(line_len, MAXLINE-1))
  382.     { nextra = min(line_len, MAXLINE-1) -outw + 1;
  383.         spread (OUTBUF, nextra, OUTWRDS);
  384.         brk();
  385.     }
  386.  
  387.     strcat (OUTBUF, wrdbuf);
  388.     strcat (OUTBUF, " ");
  389.     if DEBUG fprintf(stderr,"\nPUTWRD:OUTBUF=<%s>",OUTBUF);
  390.     OUTWRDS++;
  391.     return;
  392. }
  393.  
  394. /**************************************************************
  395.     returns no. of ch in string
  396. ***************************************************************/
  397. int count_char (string, ch)
  398. char *string, ch;
  399. {
  400.     int n;
  401.     char *p;
  402.  
  403.     p = string;
  404.     n=0;
  405.     while (*p)    if (*p++ == ch)    n++;
  406.     return (n);
  407. }
  408.  
  409. /***********************************************************
  410.     remove all occurrences of ch; first, last, and no.
  411.     of occurrences returned in parameters
  412. ************************************************************/
  413. remove_char (string, ch, first, last, n_ch)
  414. char *string, ch;
  415. int *first, *last, *n_ch;
  416. {
  417.     char *p1, *p2;
  418.     find_char (string, ch, first, last);
  419.     *n_ch = count_char (string, ch);
  420.     p1=p2=string;
  421.     while (*p1 = *p2++)    if (*p1 != ch)    p1++;
  422.     return;
  423. }
  424.  
  425. /**************************************************************
  426.     a new putline routine; sends line to current output
  427. ***************************************************************/
  428. putline (line)
  429. char *line;
  430. {
  431.     int i;
  432.  
  433.     if (ULVAL >=0)
  434.     { replace_char (line, NEWLINE, CR);
  435.         fputs (line, stdout);
  436.         indent (TIVAL);
  437.         for (i=0; line[i] != '\0'; i++)
  438.             if (line[i] & 0x80)    putchar(UNDERLINE);
  439.         else putchar(line[i]);
  440.         putchar(CR);
  441.         putchar(NEWLINE);
  442.         if (ULVAL==0)    ULVAL--;
  443.     }
  444.     else fputs (line, stdout);
  445.     return;
  446. }
  447.  
  448.  
  449. /* extras needed by roff */
  450.  
  451. movwrd(in,out)
  452. char *in, *out;
  453.     {
  454.   char *tmp;
  455.   tmp = out;
  456. if(! *in) { *out = '\0' ; return(0) ; }
  457. while (*in && !isspace(*out = *in))
  458.     { out++; in++; }
  459.  *out = '\0';
  460.   return( out != tmp );
  461.     }
  462.  
  463.  
  464. #define TRUE 1
  465. #define FALSE 0
  466.  
  467. /* can be used for at most one character ptr argument */
  468.  errprnt(cs, arg)
  469.  char *cs, *arg;
  470.     {
  471.  fprintf( stderr, cs, arg);
  472.   fflush(stderr);
  473.     }
  474.  
  475.  
  476.  
  477.