home *** CD-ROM | disk | FTP | other *** search
/ Simtel MSDOS 1992 December / simtel1292_SIMTEL_1292_Walnut_Creek.iso / msdos / txtutl / ovrsgr.arc / OVRSGR.C next >
C/C++ Source or Header  |  1986-11-06  |  21KB  |  1,018 lines

  1. /*********************************************************************
  2.  
  3. Name:        ovrsgr.c
  4. Version:    1.0
  5.  
  6.   COPYRIGHT (c) 1985 BY DIGITAL EQUIPMENT CORPORATION, MAYNARD MASS.
  7.              ALL RIGHTS RESERVED.
  8.  
  9. Permission to copy without fee all or part of this material is granted
  10. provided that copies are not made or distributed for direct commercial
  11. advantage, the Digital Equipment Corporation copyright notice appears,
  12. the  disclaimer  below appears, and notice is given that copying is by
  13. permission  of  Digital  Equipment  Corporation.   To  copy  otherwise
  14. requires a specific license.
  15.  
  16. DISCLAIMER:
  17.  
  18. The  information herein is subject to change without notice and should
  19. not be construed as a commitment by Digital Equipment Corporation.
  20.  
  21. Digital Equipment Corporation assumes no responsibility for the use or
  22. reliability of this software.  This  software  is  provided  "as  is,"
  23. without  any  warranty  of  any  kind,  express  or  implied.  Digital
  24. Equipment Corporation will not be liable in any event for any  damages
  25. including  any  loss  of  data, profit, or savings, claims against the
  26. user by any other party, or  any  other  incidental  or  consequential
  27. damages arising out of the use of, or inability to use, this software,
  28. even if Digital Equipment Corporation is advised of the possibility of
  29. such damage.
  30.  
  31. DEFECT REPORTING AND SUGGESTIONS:
  32.  
  33. Please send reports of defects or suggestions for improvement directly
  34. to the author:
  35.  
  36.     Brian Hetrick
  37.     Digital Equipment Corporation
  38.     110 Spit Brook Road  ZKO1-2/J10
  39.     Nashua NH  03062-2698
  40.  
  41. Do NOT file a Software Performance Report on this software,  call  the
  42. Telephone Support Center regarding this software, contact your Digital
  43. Field Office regarding this  software,  or  use  any  other  mechanism
  44. provided for Digital's supported and warranted software.
  45.  
  46.  
  47. FACILITY:
  48.  
  49.     General utility programs.
  50.  
  51. ABSTRACT:
  52.  
  53.     Converts a file encoded in eight-bit ASCII  with  limited  control
  54.     character  use  into  an  equivalent  file  using the "set graphic
  55.     rendition" escape sequences to indicate bolding and underlining.
  56.  
  57.     Applicable ANSI standards are X3.4 (7-bit ASCII), X3.64 (Addition-
  58.     al controls for use with  ASCII),  and  (proposed)  X3.4.2  (8-bit
  59.     ASCII).
  60.  
  61. ENVIRONMENT:
  62.  
  63.     CP/M-86/80, compiled with Mark Williams Co. MWC86.
  64.     MS-DOS, compiled with Computer Innovations Co. C86.
  65.     VAX/VMS, compiled with VAX C.
  66.  
  67. AUTHOR:    Brian Hetrick, CREATION DATE: 10 May 1985.
  68.  
  69. MODIFIED BY:
  70.  
  71.     Brian Hetrick, 10-May-85: Version 1.0
  72.   000 -    Original creation of module.
  73.  
  74.   1986/11/06 -- Rahul Dhesi -- For ANSI.SYS on Iclones:  (a) changed
  75.      blob to be rectangular graphics character;  (b) changed underlining
  76.      to be inverse video.  See "#ifdef ICLONE".
  77.  
  78. *********************************************************************/
  79.  
  80. /*
  81.  *  INCLUDE FILES:
  82.  */
  83.  
  84. #include <stdio.h>
  85.  
  86. /*
  87.  *  TABLE OF CONTENTS:
  88.  */
  89.  
  90. /*
  91.  *  MACROS:
  92.  */
  93.  
  94. #define    MAXLINLEN    512        /*  Maximum width of line   */
  95.  
  96. #define    FLG_SPAN    1        /*  Span whitespace         */
  97.  
  98. #define    ATR_BLOB    1        /*  Different char overprint*/
  99. #define    ATR_UNDR    2        /*  Underline overprint        */
  100. #define    ATR_BOLD    4        /*  Same char overprint        */
  101.  
  102. /*
  103.  *  The following character is device dependent.  It should  print  as
  104.  *  a  blob of some type.  It is used to indicate that several dissim-
  105.  *  ilar characters have been overprinted.  The sequence given invokes
  106.  *  the  G1  character set, prints a lowercase 'a', and returns to the
  107.  *  G0 character set.  On devices such as Digital's  VT1xx  and  VT2xx
  108.  *  terminals, where the G1 set has been set to the "special graphics"
  109.  *  character set, this prints a checkerboard pattern.  The  SCS  (set
  110.  *  character  set)  escape sequence to put the special graphics char-
  111.  *  acter set into G1 is <ESC>)0.
  112.  */
  113.  
  114. #ifdef ICLONE
  115. #define  CHR_BLOB "\xFE"      /* small rectangle */
  116. #else
  117. #define    CHR_BLOB    "\016a\017"    /*  Checkerboard        */
  118. #endif
  119.  
  120. /*
  121.  *  OWN STORAGE:
  122.  */
  123.  
  124. struct chr_pos
  125. {
  126.     char        cp_attr;
  127.     char        cp_char;
  128. };
  129.  
  130. static FILE
  131.     * outfile;
  132.  
  133. static int
  134.     flags,
  135.     hpos = 0,
  136.     indent;
  137.  
  138. static struct chr_pos
  139.     line_image [MAXLINLEN];
  140.  
  141. /*
  142.  *  EXTERNAL REFERENCES:
  143.  */
  144.  
  145. static change_attr (old_attr, new_attr)
  146.  
  147. int
  148.     old_attr,
  149.     new_attr;
  150.  
  151. /*********************************************************************
  152.  
  153. FUNCTIONAL DESCRIPTION:
  154.  
  155.     Minimally updates "set graphic rendition" attributes.
  156.  
  157.     The term "minimal" is used advisedly.  The VT100 series and clones
  158.     allow  only  clearing all attributes and setting particular attri-
  159.     butes, while the VT200 series additionally allows clearing partic-
  160.     ular attributes.  Also, the VT100 series and clones allow only the
  161.     7-bit ASCII representation of CSI.  For maximal  device  independ-
  162.     ence, the VT100 limitations are assumed.
  163.  
  164. FORMAL PARAMETERS:
  165.  
  166.     Old_attribute.rg.v - The set of graphic rendition attributes  cur-
  167.     rently in effect.
  168.     New_attributes.rg.v - The  set  of graphic rendition attributes to
  169.     be put into effect.
  170.  
  171. RETURN VALUE:
  172.  
  173.     None.
  174.  
  175. IMPLICIT INPUTS:
  176.  
  177.     outfile - The file to which the escape sequence is to be sent.
  178.  
  179. IMPLICIT OUTPUTS:
  180.  
  181.     None.
  182.  
  183. SIDE EFFECTS:
  184.  
  185.     Sends an escape sequence to the output file.
  186.  
  187. *********************************************************************/
  188.  
  189. {
  190.     int
  191.     first_code;
  192.  
  193.     if (old_attr != new_attr)
  194.     {
  195.     /*
  196.      *  Have to do something.  Start the escape sequence.
  197.      */
  198.  
  199.     putc ('\033', outfile);
  200.     putc ('[', outfile);
  201.  
  202.     /*
  203.      *  See if must reset attributes.
  204.      */
  205.  
  206.     if (old_attr & (~ new_attr))
  207.     {
  208.         putc ('0', outfile);
  209.         first_code = 0;
  210.         old_attr = 0;
  211.     }
  212.     else
  213.     {
  214.         first_code = 1;
  215.     }
  216.  
  217.     /*
  218.      *  Need only attributes to be added.
  219.      */
  220.  
  221.     new_attr &= ~ old_attr;
  222.  
  223.     /*
  224.      *  Do the attributes.
  225.      */
  226.  
  227.     if (new_attr & ATR_BOLD)
  228.     {
  229.         if (! first_code)
  230.         {
  231.         putc (';', outfile);
  232.         }
  233.         putc ('1', outfile);
  234.         first_code = 0;
  235.     }
  236.  
  237.     if (new_attr & ATR_UNDR)
  238.     {
  239.         if (! first_code)
  240.         {
  241.         putc (';', outfile);
  242.         }
  243. #ifdef ICLONE
  244.        putc ('7', outfile);
  245. #else
  246.         putc ('4', outfile);
  247. #endif
  248.     }
  249.  
  250.     /*
  251.      *  End the escape sequence.
  252.      */
  253.  
  254.     putc ('m', outfile);
  255.     }
  256. }
  257.  
  258. static outlin (eol)
  259.  
  260. char
  261.     eol;
  262.  
  263. /*********************************************************************
  264.  
  265. FUNCTIONAL DESCRIPTION:
  266.  
  267.     Creates a text line corresponding to the line_image array.
  268.  
  269. FORMAL PARAMETERS:
  270.  
  271.     eol.rc.v - The vertical movement character that ended the line.
  272.  
  273. RETURN VALUE:
  274.  
  275.     None.
  276.  
  277. IMPLICIT INPUTS:
  278.  
  279.     line_image - A description of the line to be created.
  280.     outfile - The pointer to the stream upon which the line is  to  be
  281.     created.
  282.  
  283. IMPLICIT OUTPUTS:
  284.  
  285.     None.
  286.  
  287. SIDE EFFECTS:
  288.  
  289.     Produces output upon outfile.
  290.  
  291. *********************************************************************/
  292.  
  293. {
  294.     int
  295.     column,
  296.     last_attr,
  297.     span_attr;
  298.  
  299.     struct chr_pos
  300.     * end_ptr,
  301.     * max_ptr,
  302.     * start_ptr;
  303.  
  304.     /*
  305.      *  Turn NULs into spaces and find line length.
  306.      */
  307.  
  308.     for (start_ptr = & line_image [0], max_ptr = & line_image [-1];
  309.          start_ptr < & line_image [MAXLINLEN];
  310.          start_ptr ++)
  311.     {
  312.         if (0 == start_ptr -> cp_char)
  313.         {
  314.         start_ptr -> cp_char = ' ';
  315.         if (0 != start_ptr -> cp_attr)
  316.         {
  317.         max_ptr = start_ptr;
  318.         }
  319.     }
  320.     else
  321.     {
  322.         /*
  323.          *  It is not a space.
  324.          */
  325.  
  326.         max_ptr = start_ptr;
  327.     }
  328.     }
  329.  
  330.     last_attr = 0;
  331.     if (max_ptr != & line_image [-1])
  332.     {
  333.     /*
  334.      *  If necessary, make attributes span  blanks.   Do  this  by
  335.      *  finding  characters surrounding spans of blanks, and ORing
  336.      *  the blank's attributes with the AND of the  attributes  of
  337.      *  the surrounding characters.
  338.      *
  339.      *  In the following, start_pos is  the  index  of  the  first
  340.      *  blank  to  treat, and start_ptr points at its line_image[]
  341.      *  entry;  end_pos is the index of the first character not to
  342.      *  treat, and end_ptr points at its line_image[] entry.  Note
  343.      *  that any initial blanks are NOT to be treated.
  344.      */
  345.  
  346.     if (flags & FLG_SPAN)
  347.     {
  348.         start_ptr = & line_image [-1];
  349.         span_attr = 0;
  350.         while (start_ptr <= max_ptr)
  351.         {
  352.         /*
  353.          *  Find first non-blank  character  following  start_
  354.          *  ptr.
  355.          */
  356.  
  357.         end_ptr = start_ptr + 1;
  358.         while ((end_ptr <= max_ptr) &&
  359.                (' ' == end_ptr -> cp_char))
  360.         {
  361.             end_ptr ++;
  362.         }
  363.         if (end_ptr > max_ptr)
  364.         {
  365.             /*
  366.              *  There  is  no  first  non-blank character fol-
  367.              *  lowing start_ptr.
  368.              */
  369.  
  370.             break;
  371.         }
  372.  
  373.         /*
  374.          *  Find attributes to span.
  375.          */
  376.  
  377.         span_attr &= end_ptr -> cp_attr;
  378.         if (0 != span_attr)
  379.         {
  380.             /*
  381.              *  Span them.
  382.              */
  383.  
  384.             while (start_ptr < end_ptr)
  385.             {
  386.             (start_ptr ++) -> cp_attr |= span_attr;
  387.             }
  388.         }
  389.  
  390.         /*
  391.          *  Advance to next space, and retain attribute of im-
  392.          *  mediately previous character.
  393.          */
  394.  
  395.         span_attr = end_ptr -> cp_attr;
  396.         start_ptr = end_ptr + 1;
  397.         while ((start_ptr <= max_ptr) &&
  398.                (' ' != start_ptr -> cp_char))
  399.         {
  400.             span_attr = ((start_ptr ++) -> cp_attr) &
  401.             (~ ATR_BLOB);
  402.         }
  403.         }
  404.     }
  405.  
  406.     /*
  407.      *  Finally, put out the line.
  408.      */
  409.  
  410.     for (column = 0; column < indent; column ++)
  411.     {
  412.         putc (' ', outfile);
  413.     }
  414.     start_ptr = & line_image [0];
  415.     while (start_ptr <= max_ptr)
  416.     {
  417.         if (start_ptr -> cp_attr != last_attr)
  418.         {
  419.         change_attr (last_attr, start_ptr -> cp_attr);
  420.         last_attr = start_ptr -> cp_attr;
  421.         }
  422.  
  423.         /*
  424.          *  Put out a character.
  425.          */
  426.  
  427.         if (start_ptr -> cp_attr & ATR_BLOB)
  428.         {
  429.         fputs (CHR_BLOB, outfile);
  430.         }
  431.         else
  432.         {
  433.         putc (start_ptr -> cp_char, outfile);
  434.         }
  435.  
  436.         start_ptr ++;
  437.     }
  438.     }
  439.  
  440.     /*
  441.      *  Reset attributes.
  442.      */
  443.  
  444.     if (last_attr != 0)
  445.     {
  446.     change_attr (last_attr, 0);
  447.     }
  448.  
  449.     /*
  450.      *  Put out end of line.
  451.      */
  452.  
  453.     if ((max_ptr != & line_image [-1]) && (eol != '\n') &&
  454.     (eol != '\205'))
  455.     {
  456.     putc ('\r', outfile);
  457.     }
  458.  
  459.     if (eol != '\0')
  460.     {
  461.     putc (eol, outfile);
  462.     }
  463. }
  464.  
  465. static int inlin (infile, eol)
  466.  
  467. FILE
  468.     * infile;
  469.  
  470. char
  471.     * eol;
  472.  
  473. /*********************************************************************
  474.  
  475. FUNCTIONAL DESCRIPTION:
  476.     
  477.     Creates a line_image array corresponding to a text line.
  478.  
  479.     The end of the line is assumed to coincide with  a  control  char-
  480.     acter  causing  vertical  motion.   These  control  characters are
  481.     LF/NL, VT, FF, IND, NEL, PLD, PLU, and RI.  Note that LF/NL is as-
  482.     sumed to be NL, which returns the active  position  to  the  first
  483.     character  on  a  line,  while VT and FF are assumed not to do so.
  484.     ANSI X3.4 permits either behavior with any or all of  these  char-
  485.     acters.   Also,  the  7-bit representations of IND, NEL, PLD, PLU,
  486.     and RI are not recognized.
  487.  
  488. FORMAL PARAMETERS:
  489.  
  490.     infile.mr.r - The stream from which a line is to be retrieved.
  491.     eol.wc.r - The vertical movement character that  ended  the  line.
  492.     NUL if the line was terminated by end of file.
  493.  
  494. RETURN VALUE:
  495.  
  496.     0 - A line was successfully retrieved.  line_image has  the  image
  497.     of the line retrieved.
  498.     EOF - End of file was encountered.  line_image does not  have  the
  499.     image of a line.
  500.  
  501. IMPLICIT INPUTS:
  502.  
  503.     hpos - horizontal position in line as of entry.
  504.  
  505. IMPLICIT OUTPUTS:
  506.  
  507.     hpos - horizontal position in line as of exit.
  508.     line_image - A description of the line that was read.
  509.  
  510. SIDE EFFECTS:
  511.  
  512.     Consumes input from infile.
  513.  
  514. *********************************************************************/
  515.  
  516. {
  517.     static char
  518.  
  519.     /*
  520.      *  Map of what characters cause special horizontal motion.
  521.      *
  522.      *  BS   0x08,   8, 0010
  523.      *  HT   0x09,   9, 0011
  524.      *  CR   0x0D,  13, 0015
  525.      *  SP   0x20,  32, 0040
  526.      *  NEL  0x85, 133, 0205
  527.      *  NBSP 0xA0, 160, 0240
  528.      *
  529.      *  Of the characters above, NEL alone  also  causes  vertical
  530.      *  motion.
  531.      */
  532.  
  533.     hm_map [] =
  534.        {0x00, 0x23, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  535.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  536.         0x20, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  537.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  538.  
  539.     /*
  540.      *  Map of what characters cause vertical motion.
  541.      *
  542.      *  LF   0x0A,  10, 0012  (also known as NL)
  543.      *  VT   0x0B,  11, 0013
  544.      *  FF   0x0C,  12, 0014
  545.      *  IND  0x84, 132, 0204
  546.      *  NEL  0x85, 133, 0205
  547.      *  PLD  0x8B, 139, 0213
  548.      *  PLU  0x8C, 140, 0214
  549.      *  RI   0x8D, 141, 0215
  550.      *
  551.      *  Note that NEL alone of the above causes horizontal motion.
  552.      *  But with "text" I/O in C, LF is NL, and so  implies  hori-
  553.      *  zontal motion.
  554.      */
  555.  
  556.     vm_map [] =
  557.        {0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  558.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  559.         0x30, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  560.         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
  561.  
  562.     /*
  563.      *  Map of bit encodings used in the above tables.
  564.      */
  565.  
  566.     bit_mask [] =
  567.        {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
  568.  
  569.     int
  570.     in_char,
  571.     in_pos;
  572.  
  573.     struct chr_pos
  574.     * in_ptr;
  575.  
  576.     /*
  577.      *  Check for end of file.
  578.      */
  579.  
  580.     if (feof (infile))
  581.     {
  582.     return (EOF);
  583.     }
  584.  
  585.     /*
  586.      *  Initialize the line image.
  587.      */
  588.  
  589.     if (hpos == 0)
  590.     {
  591.     for (in_ptr = & line_image [0];
  592.          in_ptr < & line_image [MAXLINLEN];
  593.          in_ptr ++)
  594.     {
  595.         in_ptr -> cp_attr = 0;
  596.         in_ptr -> cp_char = 0;
  597.     }
  598.     }
  599.  
  600.     /*
  601.      *  Get the line.
  602.      */
  603.  
  604.     in_ptr = & line_image [hpos];
  605.  
  606.     while (EOF != (in_char = getc (infile)))
  607.     {
  608.     /*
  609.      *  Check if the character is a line terminator.
  610.      */
  611.  
  612.     if (vm_map [in_char >> 3] & bit_mask [in_char & 7])
  613.     {
  614.         /*
  615.          *  Check for LF and NEL.
  616.          */
  617.  
  618.         if (('\n' == in_char) || ('\205' == in_char))
  619.         {
  620.         /*
  621.          *  Yes.  Effect return to margin.
  622.          */
  623.  
  624.         in_ptr = & line_image [0];
  625.         }
  626.  
  627.         break;
  628.     }
  629.  
  630.     /*
  631.      *  Check for special horizontal motion.
  632.      */
  633.  
  634.     if (hm_map [in_char >> 3] & bit_mask [in_char & 7])
  635.     {
  636.         /*
  637.          *  Yes.  Do what depends on character.  Cases  are  given
  638.          *  hopefully  in  most  efficient  order.   NBSP has same
  639.          *  action as SP, but SP occurs far more frequently.
  640.          */
  641.  
  642.         switch (in_char)
  643.         {
  644.         case '\040':        /*  Space.  */
  645.         in_ptr ++;
  646.         if (in_ptr >= & line_image [MAXLINLEN])
  647.         {
  648.             in_ptr --;
  649.         }
  650.         break;
  651.  
  652.         case '\011':        /*  Horizontal tab.  */
  653.         in_pos = in_ptr - & line_image [0];
  654.         in_pos &= ~ 7;
  655.         in_pos += 8;
  656.         if (in_pos >= MAXLINLEN)
  657.         {
  658.             in_pos = MAXLINLEN - 1;
  659.         }
  660.         in_ptr = & line_image [in_pos];
  661.         break;
  662.  
  663.         case '\015':        /*  Carriage return.  */
  664.         in_ptr = & line_image [0];
  665.         break;
  666.  
  667.         case '\010':        /*  Backspace.  */
  668.         in_ptr --;
  669.         if (in_ptr < & line_image [0])
  670.         {
  671.             in_ptr = & line_image [0];
  672.         }
  673.         break;
  674.  
  675.         default:        /*  Non-break space.  */
  676.         in_ptr ++;
  677.         if (in_ptr >= & line_image [MAXLINLEN])
  678.         {
  679.             in_ptr --;
  680.         }
  681.         break;
  682.         }
  683.     }
  684.     else
  685.     {
  686.         /*
  687.          *  No special horizontal motion.  Check for control char-
  688.          *  acter.
  689.          */
  690.  
  691.         if ((in_char & 0x60) && (in_char != 0x7F))
  692.         {
  693.         /*
  694.          *  Is not 0x00 to 0x1F or 0x80 to 0x9F or  0x7F.   Is
  695.          *  a  graphic  character.  But handle underline spec-
  696.          *  ially.
  697.          */
  698.  
  699.         if ('_' == in_char)
  700.         {
  701.             /*
  702.              *  Mark underline as underscoring.
  703.              */
  704.  
  705.             in_ptr -> cp_attr |= ATR_UNDR;
  706.         }
  707.         else if (0 == in_ptr -> cp_char)
  708.         {
  709.             /*
  710.              *  Not already a character at this position.
  711.              */
  712.  
  713.             in_ptr -> cp_char = in_char;
  714.         }
  715.         else if (in_char == in_ptr -> cp_char)
  716.         {
  717.             /*
  718.              *  Already same character at this position.
  719.              */
  720.  
  721.             in_ptr -> cp_attr |= ATR_BOLD;
  722.         }
  723.         else
  724.         {
  725.             /*
  726.              *  Multiple overstrikes.
  727.              */
  728.  
  729.             in_ptr -> cp_attr |= ATR_BLOB;
  730.         }
  731.         in_ptr ++;
  732.         }
  733.     }
  734.     }
  735.  
  736.     /*
  737.      *  Remember horizontal position.
  738.      */
  739.  
  740.     hpos = in_ptr - & line_image [0];
  741.  
  742.     /*
  743.      *  Return the line terminator.
  744.      */
  745.  
  746.     if (EOF == in_char)
  747.     {
  748.     * eol = '\0';
  749.     }
  750.     else
  751.     {
  752.     * eol = in_char;
  753.     }
  754.  
  755.     return 0;
  756. }
  757.  
  758. static dofile (infile)
  759.  
  760. FILE
  761.     * infile;
  762.  
  763. /*********************************************************************
  764.  
  765. FUNCTIONAL DESCRIPTION:
  766.  
  767.     Processes all lines of an input file.
  768.  
  769. FORMAL PARAMETERS:
  770.  
  771.     Input_file.mr.r - The stream from which input is taken.
  772.  
  773. RETURN VALUE:
  774.  
  775.     None.
  776.  
  777. IMPLICIT INPUTS:
  778.  
  779.     hpos - If 0, the line just read may be printed.
  780.  
  781. IMPLICIT OUTPUTS:
  782.  
  783.     None.
  784.  
  785. SIDE EFFECTS:
  786.  
  787.     Consumes input from the input file, and  produces  output  on  the
  788.     output file.
  789.  
  790. *********************************************************************/
  791.  
  792. {
  793.     char
  794.     eol;
  795.  
  796.     while (EOF != inlin (infile, & eol))
  797.     {
  798.     if (hpos == 0)
  799.     {
  800.         outlin (eol);
  801.     }
  802.     }
  803. }
  804.  
  805. int main (argc, argv)
  806.  
  807. int
  808.     argc;
  809.  
  810. char
  811.     * argv [];
  812.  
  813. /*********************************************************************
  814.  
  815. FUNCTIONAL DESCRIPTION:
  816.  
  817.     Main program for overstrike to SGR translator.
  818.  
  819.     Parses the command line.  The command line is of the form:
  820.  
  821.     ovrsgr [-i indent] [-o outfile] [-s] infile [...]
  822.  
  823.     where:
  824.  
  825.     ovrsgr is the name of the program.
  826.  
  827.     -i indicates that the following token is a decimal integer that is
  828.     the number of characters by which the print  image  is  to  be
  829.     shifted right.
  830.  
  831.     -o indicates that the following token is the name  of  a  file  to
  832.     which output is to be sent.
  833.  
  834.     -s  indicates that bold and underline are to "span" whitespace, so
  835.     that phrases may be underlined as a whole.
  836.  
  837.     infile is the name of an input file.  Several such  names  may  be
  838.     given;  if so, the files are processed as if they were concat-
  839.     enated into a single file.
  840.  
  841.     If no input files are given, input is taken from the standard  in-
  842.     put.   If  no output file is given, output is sent to the standard
  843.     output.
  844.  
  845. FORMAL PARAMETERS:
  846.  
  847.     Argument_count.rg.v - A count of the number of elements  of  Argu-
  848.     ment_vector that are valid.
  849.     Argument_vector.rt.ra - The individual tokens of the command line.
  850.  
  851. RETURN VALUE:
  852.  
  853.     None.  Program termination is always via exit.  Exit codes on  VMS
  854.     are:
  855.  
  856.     1 - All okay.
  857.     4 - Could not open output file.
  858.  
  859.     Exit codes on other than VMS are:
  860.  
  861.     0 - All okay.
  862.     1 - Could not open output file.
  863.  
  864. IMPLICIT INPUTS:
  865.  
  866.     hpos - If non-zero, the last line must be printed.
  867.     stdin - A pointer to the standard input stream.
  868.     stdout - A pointer to the standard output stream.
  869.     stderr - A pointer to the standard error stream.
  870.  
  871. IMPLICIT OUTPUTS:
  872.  
  873.     flags - A vector of flags indicating processing options.
  874.     indent - A count of the number of spaces to prepend to  the  print
  875.     image.
  876.     outfile - The pointer to the stream to which output is to be sent.
  877.  
  878. SIDE EFFECTS:
  879.  
  880.     Reads the input files.  Writes the output file.
  881.  
  882. *********************************************************************/
  883.  
  884. {
  885.     char
  886.     * argp,
  887.     * outname;
  888.  
  889.     FILE
  890.     * infile;
  891.  
  892.     int
  893.     argch,
  894.     argi;
  895.  
  896.     /*
  897.      *  Parse flags.
  898.      */
  899.  
  900.     outname = (char *) NULL;
  901.     flags = 0;
  902.     indent = 0;
  903.  
  904.     for (argi = 1; argi < argc; argi ++)
  905.     {
  906.     argp = argv [argi];
  907.     if ('-' != * argp ++)
  908.     {
  909.         break;
  910.     }
  911.  
  912.     while ('\0' != (argch = * argp ++))
  913.     {
  914.         switch (argch)
  915.         {
  916.         case 'i':
  917.         /*
  918.          *  Indent amount.
  919.          */
  920.  
  921.         indent = atoi (argv [++ argi]);
  922.         break;
  923.  
  924.         case 'o':
  925.         /*
  926.          *  Output file name.
  927.          */
  928.  
  929.         outname = argv [++ argi];
  930.         break;
  931.  
  932.         case 's':
  933.         /*
  934.          *  Span white space.
  935.          */
  936.  
  937.         flags |= FLG_SPAN;
  938.         break;
  939.  
  940.         default:
  941.         /*
  942.          *  Unknown.
  943.          */
  944.  
  945.         fputs ("Unknown flag: ", stderr);
  946.         putc (argch, stderr);
  947.         fputs (", ignored\n", stderr);
  948.         break;
  949.         }
  950.     }
  951.     }
  952.  
  953.     /*
  954.      *  Get output file.
  955.      */
  956.  
  957.     if ((char *) NULL != outname)
  958.     {
  959. #ifdef vms
  960.     if ((FILE *) NULL == (outfile =
  961.         fdopen (creat (outname, 0644, "rat=cr", "rfm=var", "mrs=0"), "w")))
  962. #else
  963.     if ((FILE *) NULL == (outfile = fopen (outname, "w")))
  964. #endif
  965.     {
  966.         fputs ("Cannot open file ", stderr);
  967.         fputs (outname, stderr);
  968.         fputs (", aborting\n", stderr);
  969. #ifdef vms
  970.         exit (2);
  971. #else
  972.         exit (1);
  973. #endif
  974.     }
  975.     }
  976.     else
  977.     {
  978.     outfile = stdout;
  979.     }
  980.  
  981.     /*
  982.      *  Do input files.
  983.      */
  984.  
  985.     if (argi == argc)
  986.     {
  987.     dofile (stdin);
  988.     }
  989.     else
  990.     {
  991.     for ( ; argi < argc; argi ++)
  992.     {
  993.         if ((FILE *) NULL == (infile = fopen (argv [argi], "r")))
  994.         {
  995.         fputs ("Cannot open file ", stderr);
  996.         fputs (argv [argi], stderr);
  997.         fputs (", continuing\n", stderr);
  998.         }
  999.         else
  1000.         {
  1001.         dofile (infile);
  1002.         fclose (infile);
  1003.         }
  1004.     }
  1005.     }
  1006.  
  1007.     if (hpos != 0)
  1008.     {
  1009.     outlin ('\n');
  1010.     }
  1011.  
  1012. #ifdef vms
  1013.     exit (1);
  1014. #else
  1015.     exit (0);
  1016. #endif
  1017. }
  1018.