home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / txtutl / manprep.arc / MANPREP.C next >
C/C++ Source or Header  |  1987-12-14  |  5KB  |  167 lines

  1. /*
  2.                   MANPREP.C
  3.  
  4.    Reformat a "generic printer" doc file for video
  5.    output.  I call this MANPREP in honor of the wonderful
  6.    micro-MAN program by David L. Rick.  
  7.  
  8.     manprep does 2 things:
  9.         remove adjacent "blank" lines greater than a parameter, and
  10.         "back up" over a character followed by a backspace.
  11.         
  12.     Input and output files default to stdin and stdout.
  13.     The -l<n> parameter defaults to 2.
  14.  
  15.    Copyright 1987 by Francis X. Guidry
  16.    All Rights Reserved
  17.       
  18. */
  19.  
  20.  
  21. #include <stdio.h>
  22. #include <ctype.h>
  23.  
  24. /*--------------------------------------------------------------------
  25.     main() does the command line processing "in the raw," then calls
  26.     a driver to do the real work.        */
  27.  
  28. main(argc,argv)
  29. int argc;
  30. char *argv[];
  31. {
  32. /*        Initialize the variables to the defaults instead of 0 - it's
  33.         just as easy to test, and maybe a little clearer to read.    */
  34.  
  35.    int i=1, n=2;
  36.    FILE *in=stdin, *out=stdout;
  37.    int insave;
  38.  
  39. /* Command line processing is such a drag.  I feel silly
  40.    linking in a library routine for two filenames and one
  41.    option, so I just do the command line here in main().
  42.  
  43.     I would love to be able to omit the file names and use only
  44.     i/o redirection, but that is very slow on my old PC.
  45.  
  46.     I prefer to allow numeric options to be contiguous with or 
  47.     separate from the option letter, so "-l2" and "-l 2" are 
  48.     both valid.  And I prefer to allow options to precede, 
  49.     follow, or be intermixed with file names.  All this flexibility
  50.     makes the code a mess, but I think it cuts down on frustration
  51.     for the user.
  52. */
  53.    while(i < argc) {
  54.       if(argv[i][0] ==  '-')
  55.          if(argv[i][1] == 'l') {
  56.             if(argv[i][2] && isdigit(argv[i][2]))
  57.                n = atoi(argv[i]+2);
  58.             else if(isdigit(argv[i+1][1]))
  59.                 n = atoi(argv[++i]);
  60.             else merror("-l option requires a numeric parameter.");
  61.             ++i;
  62.             continue;
  63.          } else merror("invalid option.");
  64.  
  65.       if(in == stdin) { 
  66.          if(!(in = fopen(argv[i],"r")))
  67.             merror("unable to open input file.");
  68.          else insave = i;
  69.       } else if(out != stdout) 
  70.          merror("too many parameters.");
  71.       else if(!strcmp(argv[i],argv[insave]))
  72.          merror("input and output files _must_ be different!");
  73.       else if(!(out = fopen(argv[i],"w")))
  74.          merror("unable to open output file.");
  75.       ++i;
  76.    }
  77.  
  78. /* Finally, we can do some work. */
  79.  
  80.    process(in,out,n);
  81.    fclose(in);
  82.    fclose(out);
  83.    exit(0);
  84. }
  85.  
  86. /*----------------------------------------------------------------------
  87.     This function runs the show, reading input, passing out the lines
  88.     to be worked on, then writing out the good stuff.    */
  89.  
  90. #define BSIZE 320
  91. char line[BSIZE];
  92. char *strchar();
  93.  
  94. process(in,out,n)
  95. FILE *in, *out;
  96. int n;
  97. {
  98.    int t = 0;
  99.    int counter = 0;
  100.     char *fold();
  101.    
  102.    while(fgets(line,BSIZE,in)) {
  103.       if((t = test(line)) < 1)
  104.          counter++;
  105.       else counter = 0;
  106.       if(counter < n)
  107.             if(strchr(line,'\b'))
  108.                 fputs(fold(line),out);
  109.          else fputs(line,out);
  110.    }
  111. }
  112.  
  113.  
  114. /*----------------------------------------------------------------------
  115.     test() returns a failing grade for "blank" lines, those with no
  116.     character greater than a space.        */
  117.     
  118. int test(line)
  119. char *line;
  120. {
  121.    do {
  122.       if(*line > ' ')
  123.          return(1);
  124.    } while(*(++line));
  125.    return(0);
  126. }
  127.  
  128.     
  129. /*----------------------------------------------------------------------
  130.     fold() gets rid of unsightly backspace clutter, by "backing up"
  131.     over the preceding character and throwing away the backspace.    
  132.     The only tricky part is avoiding backing up past the beginning of
  133.     the output buffer.     */
  134.     
  135. char oline[BSIZE];
  136. char *fold(line)
  137. char *line;
  138. {
  139.     char *o = oline;
  140.     
  141.     while(*line == '\b')
  142.         line++;
  143.     while(*o = *line) {
  144.         if(*line == '\b')
  145.             o = o > oline ? --o : o;
  146.         else o++;
  147.         line++;
  148.     }
  149.     return(oline);
  150. }
  151.  
  152. /*----------------------------------------------------------------------
  153.     merror() is a one-way function.  After printing the message it
  154.     terminates the program with an errorlevel.    */
  155.     
  156. merror(s)
  157. char *s;
  158. {
  159.    printf("manprep v1.1 copyright 1987 by Francis X. Guidry\n\n",s);
  160.    printf("Sorry, %s\n\n",s);
  161.    printf("Usage: manprep [filein] [fileout] [-l<n> | -l <n>]\n");
  162.    printf("Defaults:       stdin    stdout    -l2\n");
  163.    printf("-l<n>:  <n> is a number which specifies maximum \n");
  164.    printf("        adjacent blank lines in the output.\n");
  165.    exit(1);
  166. }
  167.