home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / compiler / m2posx14 / bin / x2d.c < prev    next >
C/C++ Source or Header  |  1992-02-06  |  7KB  |  252 lines

  1. /*
  2.  * Benutzung:        'X2D' ['-'lines] ['<'infile] ['>'outfile]
  3.  *             oder  [input '|'] 'X2D' ['-'lines] ['|' output]
  4.  *
  5.  * Dieses kurze Programm wird als Filter zwischen Standardeingabe und
  6.  * Standardausgabe benutzt. X2D steht dabei fuer UNIX TO DOS.
  7.  * Es wandelt alle UNIX-Zeilenenden, d.h. separat stehende LF's in 
  8.  * DOS/TOS-Zeilenenden um ( CR + LF ).
  9.  * Bereits in der Eingabe stehende CR/LF-Sequenzen werden unveraendert
  10.  * uebertragen. Leerzeichen am Ende einer Zeile werden entfernt.
  11.  *
  12.  * Falls die Optionsangabe aus genau einem Minuszeichen besteht, dem
  13.  * direkt, d.h. ohne Leerzeichen, eine Ziffer zwischen Null und Neun
  14.  * folgt, wird diese Angabe als maximale Anzahl erlaubter aufeinander-
  15.  * folgender Leerzeilen interpretiert; wenn in der Eingabe mehr Leerzeilen
  16.  * direkt hintereinander stehen, werden diese nicht mehr in die Ausgabe
  17.  * uebertragen. Mit X2D -0 enthaelt also die Ausgabe keine Leerzeilen mehr.
  18.  *
  19.  * Folgen in der Eingabe mehr als 256 Blanks, Tabs usw. hintereinander,
  20.  * werden die restlichen Leerzeichen nicht uebertragen.
  21.  *
  22.  * Das Programm wurde mit GCC 1.37.1 und der MiNTLIB uebersetzt und ist in
  23.  * erster Linie fuer M2-Quelltexte gedacht, die mit dem GNU-CPP bearbeitet 
  24.  * wurden. Fuer diese Aufgabe ist der Aufruf mit 'X2D -1'  sinnvoll.
  25.  *
  26.  *
  27.  * Die Dateien:
  28.  *
  29.  *   X2D.C
  30.  *   X2D.TTP
  31.  *   X2D1.C
  32.  *   X2D1.TOS
  33.  *
  34.  * gehoeren zusammen, und muessen auch immer zusammen weitergegeben werden,
  35.  * alles weitere wie in COPYLEFT von FSF.
  36.  *
  37.  *    hk, 15-Nov-91
  38.  */
  39.  
  40.  
  41. /*
  42. **  I M P O R T
  43. */
  44.  
  45. #include <osbind.h>   /* Fwrite( ), Fread( )               */
  46. #include <limits.h>   /* SHRT_MAX                          */
  47. #include <minimal.h>  /* _main( ), exit( )                 */
  48. #include <ctype.h>    /* isascii(), isspace( ), isdigit( ) */
  49. #include <string.h>   /* strlen( )                         */
  50.  
  51.  
  52. /*
  53. **  K O N S T A N T E N
  54. */
  55.  
  56. #define BUFSIZE  0x2000L  /* 8 kB Puffer fuer Ein/Ausgabe */
  57. #define MAXSPACE 256      /* maximal 256 aufeinanderfolgende Leerzeichen */
  58.  
  59. #define CON    (-1)
  60. #define STDIN  0
  61. #define STDOUT 1
  62.  
  63. #define CR 0x0D
  64. #define LF 0x0A
  65.  
  66. #define FALSE 0
  67. #define TRUE  1
  68. #define EOF   (-1)
  69.  
  70.  
  71.  
  72. /*
  73. **  G L O B A L E   V A R I A B L E N
  74. */
  75.  
  76. char  input[BUFSIZE];                 /* Eingabepuffer */
  77. char  output[BUFSIZE];                /* Ausgabepuffer */
  78. char  spacebuf[MAXSPACE];             /* Puffer fuer Leerz. innerhalb Zeile */
  79. char  *input_ptr  = input  + BUFSIZE; /* -> naechstes Eingabezechen */
  80. char  *output_ptr = output;           /* -> naechstes Ausgabezeichen */
  81. char  *space_ptr;                     /* -> naechstes Ein/Ausgabe-Leerzeichen */
  82. char  *input_end  = input  + BUFSIZE; /* -> Ausgabepufferende + 1 */
  83. char  *output_end = output + BUFSIZE; /* -> Eingabepufferende + 1 */
  84. char  *space_end  = spacebuf + MAXSPACE;
  85. short akt_char, unch;                 /* letztes Eingabezeichen */
  86. char  errmsg[] = "\n+++ FEHLER BEIM SCHREIBEN !\n";
  87. short unread = FALSE;
  88.  
  89.  
  90. /*
  91. **  F U N K T I O N E N
  92. */
  93.  
  94.  
  95.  
  96. short
  97. read_char( )
  98.  
  99. /* Das naechste Zeichen aus dem Puffer wird gelesen und als auf 'short'
  100.  * erweiterter Wert zurueckgeliefert. Ist der Puffer leer, wird ein
  101.  * neuer Puffer von 'stdin' eingelesen. Ist die Eingabedatei abgearbeitet,
  102.  * wird 'EOF' zurueckgeliefert. 
  103.  */
  104. {
  105.   long  size;
  106.  
  107.   if( unread )
  108.   { unread = FALSE;
  109.     return( unch );
  110.   }
  111.   if( input_ptr >= input_end )
  112.   { if(( size = Fread( STDIN, BUFSIZE, input )) <= 0L )
  113.       return( EOF );
  114.     input_end = input + size;
  115.     input_ptr = input;
  116.   }
  117.   return((short)(*input_ptr++));
  118. }
  119.  
  120. /*--------------------------------------------------------------------------*/
  121.  
  122. void
  123. flush( )
  124.  
  125. /* Die bisher im Ausgabepuffer stehenden Zeichen werden komplett
  126.  * nach 'stdout' geschrieben.
  127.  */
  128. {
  129.   if( Fwrite( STDOUT, output_ptr - output, output ) != output_ptr - output )
  130.   { (void)Fwrite( CON, strlen( errmsg ), errmsg );
  131.     exit(-1 );
  132.   }
  133.   output_ptr = output;
  134. }
  135.  
  136. /*--------------------------------------------------------------------------*/
  137.  
  138. void
  139. write_char( char ch )
  140.  
  141. /* Das Zeichen <ch> wird in den Ausgabepuffer geschrieben; ist
  142.  * der Puffer voll, wird er komplett nach 'stdout' geschrieben.
  143.  */
  144. {
  145.   if( output_ptr >= output_end ) flush( );
  146.   *output_ptr++ = ch;
  147. }
  148.  
  149. /*--------------------------------------------------------------------------*/
  150.  
  151. void 
  152. read_space( )
  153.  
  154. /* von der Eingabe werden solange Zeichen nach 'spacebuf' geschrieben,
  155.  * bis das Dateiende, das (UNIX-)Zeilenende oder ein Zeichen
  156.  * auftritt, dass kein `space'-Zeichen ist. Dieses Zeichen steht
  157.  * global in 'akt_char' zur Verfuegung.
  158.  *
  159.  * Bei Ueberlauf des Puffers wird nur noch ueberlesen, aber nicht
  160.  * mehr abgespeichert !
  161.  */
  162. {
  163.   space_ptr = spacebuf;
  164.   while( isascii(akt_char=read_char( )) && isspace(akt_char) && akt_char != LF)
  165.     if( space_ptr < space_end )
  166.       *space_ptr++ = akt_char;
  167. }
  168.  
  169. /*--------------------------------------------------------------------------*/
  170.  
  171. void
  172. write_space( )
  173.  
  174. /* Alle Zeichen aus 'spacebuf' werden in die Ausgabe geschrieben */
  175. {
  176.   char *space_max = space_ptr;
  177.   
  178.   for( space_ptr=spacebuf; space_ptr<space_max; write_char( *space_ptr++ ))
  179.     ;
  180. }
  181.  
  182. /*--------------------------------------------------------------------------*/
  183.  
  184. short 
  185. copyline( )
  186.  
  187. /* Eine Zeile aus dem Eingabepuffer, die mit einem einzelnen 'LF' 
  188.  * abgeschlossen ist, wird ohne Zeilenende nach 'stdout' geschrieben,
  189.  * falls die Zeile nicht nur aus `space'-Zeichen bestand oder leer war.
  190.  * Der letzte Teil der Ausgabe kann noch im Ausgabepuffer stehen. Das
  191.  * die Zeile beendende Zeichen ( 'LF' oder 'EOF' ) steht global in 
  192.  * 'akt_char' zur Verfuegung. 
  193.  * Als Funktionswert wird zurueckgeliefert, ob die Zeile eine Leerzeile
  194.  * war.
  195.  */
  196. {
  197.   short empty = TRUE;
  198.   
  199.   do
  200.   { read_space( );
  201.     if( akt_char == EOF || akt_char == LF ) return( empty );
  202.     write_space( );
  203.     empty = FALSE;
  204.  
  205.     do
  206.     {
  207.       write_char( akt_char );
  208.     } while(    !( isascii( akt_char=read_char()) && isspace( akt_char )) 
  209.              && akt_char != EOF  &&  akt_char != LF );
  210.  
  211.     unread = TRUE;
  212.     unch   = akt_char;
  213.  
  214.   } while( akt_char != EOF && akt_char != LF );
  215.  
  216.   unread = FALSE;
  217.   return( FALSE );
  218. }
  219.  
  220.  
  221. /*
  222. **  H A U P T P R O G R A M M
  223. */
  224.  
  225. int  
  226. main( int argc, char *argv[] )
  227. {
  228.   short  max_empty;
  229.   short  empty_lines = 0;
  230.  
  231.  
  232.   if( argc > 1 && *argv[1] == '-'
  233.                && isascii(*++argv[1]) && isdigit(*argv[1]))
  234.     max_empty = *argv[1] - '0';
  235.   else
  236.     max_empty = SHRT_MAX;
  237.       
  238.   do
  239.   { if( copyline( ))
  240.       empty_lines++;
  241.     else
  242.       empty_lines = 0;
  243.     
  244.     if( empty_lines <= max_empty && akt_char != EOF )
  245.     { write_char( CR );
  246.       write_char( LF );
  247.     }
  248.   } while( akt_char != EOF );
  249.   flush( );
  250.   return( 0 );
  251. }
  252.