home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / program / m2posx02 / x2d1.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-23  |  5.4 KB  |  228 lines

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