home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.4 / utils / prlong.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-20  |  5.1 KB  |  206 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: prlong.c,v 5.2 1993/04/21 01:41:14 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 5.2 $
  6.  *
  7.  *             Copyright (c) 1988-1992 USENET Community Trust
  8.  *             Copyright (c) 1986,1987 Dave Taylor
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log: prlong.c,v $
  17.  * Revision 5.2  1993/04/21  01:41:14  syd
  18.  * Needs ctype.h
  19.  * From: Syd
  20.  *
  21.  * Revision 5.1  1993/04/12  02:09:44  syd
  22.  * Initial checkin
  23.  *
  24.  *
  25.  ******************************************************************************/
  26.  
  27.  
  28. /*
  29.  * Format large amounts of output, folding across multiple lines.
  30.  *
  31.  * Input is read in a line at a time, and the input records are joined
  32.  * together into output records up to a maximum line width.  A field
  33.  * seperator is placed between every input record, and a configurable
  34.  * leader is printed at the front of each line.  The default field
  35.  * seperator is a single space.  The default output leader is an empty
  36.  * string for the first output line, and a single tab for all subsequent
  37.  * lines.
  38.  *
  39.  * Usage:
  40.  *
  41.  *    prlong [-w wid] [-1 first_leader] [-l leader] [-f sep] < data
  42.  *
  43.  * Options:
  44.  *
  45.  *    -w wid        Maximum output line width.
  46.  *    -1 leader    Leader for the first line of output.
  47.  *    -l leader    Leader for all subsequent lines of output.
  48.  *    -f sep        Field seperator.
  49.  *
  50.  * Example:
  51.  *
  52.  *    $ elmalias -en friends | /usr/lib/elm/prlong -w40
  53.  *    tom@sleepy.acme.com (Tom Smith) 
  54.  *        dick@dopey.acme.com (Dick Jones) 
  55.  *        harry@grumpy.acme.com
  56.  *    $ elmalias -en friends | /usr/lib/elm/prlong -w40 -1 "To: " -f ", "
  57.  *    To: tom@sleepy.acme.com (Tom Smith), 
  58.  *        dick@dopey.acme.com (Dick Jones), 
  59.  *        harry@grumpy.acme.com
  60.  */
  61.  
  62.  
  63. #include <stdio.h>
  64. #include <ctype.h>
  65. #include "defs.h"
  66.  
  67. #define MAXWID        78    /* default maximum line width        */
  68. #define ONE_LDR        ""    /* default leader for first line    */
  69. #define DFLT_LDR    "\t"    /* default leader for other lines    */
  70. #define FLDSEP        " "    /* default field seperator        */
  71.  
  72. char inbuf[1024];        /* space to hold an input record    */
  73. char outbuf[4096];        /* space to accumulate output record    */
  74.  
  75. int calc_col();            /* calculate output column position    */
  76.  
  77.  
  78. void usage_error(prog)
  79. char *prog;
  80. {
  81.     fprintf(stderr,
  82.     "usage: %s [-w wid] [-1 first_leader] [-l leader] [-f sep]\n", prog);
  83.     exit(1);
  84. }
  85.  
  86.  
  87. main(argc, argv)
  88. int argc;
  89. char *argv[];
  90. {
  91.     char *one_ldr;        /* output leader to use on first line    */
  92.     char *dflt_ldr;        /* output leader for subsequent lines    */
  93.     char *fld_sep;        /* selected field seperator        */
  94.     char *curr_sep;        /* text to output before next field    */
  95.     int maxwid;            /* maximum output line width        */
  96.     int outb_col;        /* current column pos in output rec    */
  97.     int outb_len;        /* current length of output record    */
  98.     int i;
  99.     extern int optind;
  100.     extern char *optarg;
  101.  
  102. #ifdef I_LOCALE
  103.     setlocale(LC_ALL, "");
  104. #endif
  105.  
  106.     /*
  107.      * Initialize defaults.
  108.      */
  109.     maxwid = MAXWID;
  110.     one_ldr = ONE_LDR;
  111.     dflt_ldr = DFLT_LDR;
  112.     fld_sep = FLDSEP;
  113.  
  114.     /*
  115.      * Crack command line.
  116.      */
  117.     while ((i = getopt(argc, argv, "w:1:l:f:")) != EOF) {
  118.     switch (i) {
  119.         case 'w':    maxwid = atoi(optarg);    break;
  120.         case '1':    one_ldr = optarg;    break;
  121.         case 'l':    dflt_ldr = optarg;    break;
  122.         case 'f':    fld_sep = optarg;    break;
  123.         default:    usage_error(argv[0]);
  124.     }
  125.     }
  126.     if (optind != argc)
  127.     usage_error(argv[0]);
  128.  
  129.     /*
  130.      * Initialize output buffer.
  131.      */
  132.     (void) strfcpy(outbuf, one_ldr, sizeof(outbuf));
  133.     outb_col = calc_col(0, one_ldr);
  134.     outb_len = strlen(one_ldr);
  135.     curr_sep = "";
  136.  
  137.     /*
  138.      * Process the input a line at a time.
  139.      */
  140.     while (fgets(inbuf, sizeof(inbuf), stdin) != NULL) {
  141.  
  142.     /*
  143.      * Trim trailing space.  Skip blank lines.
  144.      */
  145.     for (i = strlen(inbuf) - 1 ; i >= 0 && isspace(inbuf[i]) ; --i)
  146.         ;
  147.     inbuf[i+1] = '\0';
  148.     if (inbuf[0] == '\0')
  149.         continue;
  150.  
  151.     /*
  152.      * If this text exceeds the line length then print the stored
  153.      * info and reset the line.
  154.      */
  155.     if (calc_col(calc_col(outb_col, curr_sep), inbuf) >= maxwid) {
  156.         printf("%s%s\n", outbuf, curr_sep);
  157.         curr_sep = dflt_ldr;
  158.         outb_col = 0;
  159.         outb_len = 0;
  160.         outbuf[0] = '\0';
  161.     }
  162.  
  163.     /*
  164.      * Append the current field seperator to the stored info.
  165.      */
  166.     (void) strfcpy(outbuf+outb_len, curr_sep, sizeof(outbuf)-outb_len);
  167.     outb_col = calc_col(outb_col, outbuf+outb_len);
  168.     outb_len += strlen(outbuf+outb_len);
  169.  
  170.     /*
  171.      * Append the text to the stored info.
  172.      */
  173.     (void) strfcpy(outbuf+outb_len, inbuf, sizeof(outbuf)-outb_len);
  174.     outb_col = calc_col(outb_col, outbuf+outb_len);
  175.     outb_len += strlen(outbuf+outb_len);
  176.  
  177.     /*
  178.      * Enable the field seperator.
  179.      */
  180.     curr_sep = fld_sep;
  181.  
  182.     }
  183.  
  184.     if (*outbuf != '\0')
  185.     puts(outbuf);
  186.     exit(0);
  187. }
  188.  
  189.  
  190. int calc_col(col, s)
  191. register int col;
  192. register char *s;
  193. {
  194.     while (*s != '\0') {
  195.     switch (*s) {
  196.         case '\b':    --col;            break;
  197.         case '\r':    col = 0;        break;
  198.         case '\t':    col = ((col + 8) & ~7);    break;
  199.         default:    ++col;            break;
  200.     }
  201.     ++s;
  202.     }
  203.     return col;
  204. }
  205.  
  206.