Index: libcfa/src/strstream.cfa
===================================================================
--- libcfa/src/strstream.cfa	(revision f4511776e3624956eae41ab1c26f7ff2170560a5)
+++ libcfa/src/strstream.cfa	(revision 666483d3c12841a6d84496e37920d1d44a67365d)
@@ -10,6 +10,6 @@
 // Created On       : Thu Apr 22 22:24:35 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Apr 24 11:15:47 2021
-// Update Count     : 73
+// Last Modified On : Tue Apr 27 20:59:53 2021
+// Update Count     : 78
 // 
 
@@ -23,4 +23,5 @@
 #include <unistd.h>										// sbrk, sysconf
 
+
 // *********************************** strstream ***********************************
 
@@ -29,17 +30,17 @@
 
 // private
-bool sepPrt$( strstream & os ) { setNL$( os, false ); return os.sepOnOff$; }
-void sepReset$( strstream & os ) { os.sepOnOff$ = os.sepDefault$; }
-void sepReset$( strstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }
-const char * sepGetCur$( strstream & os ) { return os.sepCur$; }
-void sepSetCur$( strstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }
-bool getNL$( strstream & os ) { return os.sawNL$; }
-void setNL$( strstream & os, bool state ) { os.sawNL$ = state; }
-bool getANL$( strstream & os ) { return os.nlOnOff$; }
-bool getPrt$( strstream & os ) { return os.prt$; }
-void setPrt$( strstream & os, bool state ) { os.prt$ = state; }
+bool sepPrt$( ostrstream & os ) { setNL$( os, false ); return os.sepOnOff$; }
+void sepReset$( ostrstream & os ) { os.sepOnOff$ = os.sepDefault$; }
+void sepReset$( ostrstream & os, bool reset ) { os.sepDefault$ = reset; os.sepOnOff$ = os.sepDefault$; }
+const char * sepGetCur$( ostrstream & os ) { return os.sepCur$; }
+void sepSetCur$( ostrstream & os, const char sepCur[] ) { os.sepCur$ = sepCur; }
+bool getNL$( ostrstream & os ) { return os.sawNL$; }
+void setNL$( ostrstream & os, bool state ) { os.sawNL$ = state; }
+bool getANL$( ostrstream & os ) { return os.nlOnOff$; }
+bool getPrt$( ostrstream & os ) { return os.prt$; }
+void setPrt$( ostrstream & os, bool state ) { os.prt$ = state; }
 
 // public
-void ?{}( strstream & os, char buf[], size_t size ) {
+void ?{}( ostrstream & os, char buf[], size_t size ) {
 	os.buf$ = buf;
 	os.size$ = size;
@@ -55,8 +56,8 @@
 } // ?{}
 
-void sepOn( strstream & os ) { os.sepOnOff$ = ! getNL$( os ); }
-void sepOff( strstream & os ) { os.sepOnOff$ = false; }
+void sepOn( ostrstream & os ) { os.sepOnOff$ = ! getNL$( os ); }
+void sepOff( ostrstream & os ) { os.sepOnOff$ = false; }
 
-bool sepDisable( strstream & os ) {
+bool sepDisable( ostrstream & os ) {
 	bool temp = os.sepDefault$;
 	os.sepDefault$ = false;
@@ -65,5 +66,5 @@
 } // sepDisable
 
-bool sepEnable( strstream & os ) {
+bool sepEnable( ostrstream & os ) {
 	bool temp = os.sepDefault$;
 	os.sepDefault$ = true;
@@ -72,37 +73,37 @@
 } // sepEnable
 
-void nlOn( strstream & os ) { os.nlOnOff$ = true; }
-void nlOff( strstream & os ) { os.nlOnOff$ = false; }
+void nlOn( ostrstream & os ) { os.nlOnOff$ = true; }
+void nlOff( ostrstream & os ) { os.nlOnOff$ = false; }
 
-const char * sepGet( strstream & os ) { return os.separator$; }
-void sepSet( strstream & os, const char s[] ) {
+const char * sepGet( ostrstream & os ) { return os.separator$; }
+void sepSet( ostrstream & os, const char s[] ) {
 	assert( s );
-	strncpy( os.separator$, s, strstream_sepSize - 1 );
-	os.separator$[strstream_sepSize - 1] = '\0';
+	strncpy( os.separator$, s, ostrstream_sepSize - 1 );
+	os.separator$[ostrstream_sepSize - 1] = '\0';
 } // sepSet
 
-const char * sepGetTuple( strstream & os ) { return os.tupleSeparator$; }
-void sepSetTuple( strstream & os, const char s[] ) {
+const char * sepGetTuple( ostrstream & os ) { return os.tupleSeparator$; }
+void sepSetTuple( ostrstream & os, const char s[] ) {
 	assert( s );
-	strncpy( os.tupleSeparator$, s, strstream_sepSize - 1 );
-	os.tupleSeparator$[strstream_sepSize - 1] = '\0';
+	strncpy( os.tupleSeparator$, s, ostrstream_sepSize - 1 );
+	os.tupleSeparator$[ostrstream_sepSize - 1] = '\0';
 } // sepSet
 
-void ends( strstream & os ) {
+void ends( ostrstream & os ) {
 	if ( getANL$( os ) ) nl( os );
 	else setPrt$( os, false );							// turn off
 } // ends
 
-int fmt( strstream & os, const char format[], ... ) {
+int fmt( ostrstream & os, const char format[], ... ) {
 	va_list args;
 	va_start( args, format );
 	int len = vsnprintf( os.buf$ + os.cursor$, os.size$ - os.cursor$, format, args );
+	va_end( args );
 	os.cursor$ += len;
 	if ( os.cursor$ >= os.size$ ) {						// cursor exceeded buffer size?
-		#define fmtmsg IO_MSG "strstream truncated write, buffer too small.\n"
+		#define fmtmsg IO_MSG "ostrstream truncated write, buffer too small.\n"
 		write( STDERR_FILENO, fmtmsg, sizeof(fmtmsg) - 1 );
 		abort();
 	} // if
-	va_end( args );
 
 	setPrt$( os, true );								// called in output cascade
@@ -111,15 +112,8 @@
 } // fmt
 
-int flush( strstream & ) {								// match trait, not used
-	return 0;
-} // flush
-
-strstream & write( strstream & os ) {
-	return write( os, stdout );
-} // write
-strstream & write( strstream & os, FILE * stream ) {
+ostrstream & write( ostrstream & os, FILE * stream ) {
 	if ( fwrite( os.buf$, 1, os.cursor$, stream ) != os.cursor$ ) {
-		#define writemsg IO_MSG "strstream write error.\n"
-		write( STDERR_FILENO, writemsg, sizeof(writemsg) - 1 );
+		#define ostrwritemsg IO_MSG "ostrstream write error.\n"
+		write( STDERR_FILENO, ostrwritemsg, sizeof(ostrwritemsg) - 1 );
 		abort();
 	} // if
@@ -127,5 +121,50 @@
 } // write
 
-strstream & sstr;
+ostrstream & write( ostrstream & os ) {
+	return write( os, stdout );
+} // write
+
+
+// *********************************** istrstream ***********************************
+
+
+// public
+void ?{}( istrstream & is, char buf[] ) {
+	is.buf$ = buf;
+	is.cursor$ = 0;
+	is.nlOnOff$ = false;
+} // ?{}
+
+bool getANL( istrstream & is ) { return is.nlOnOff$; }
+void nlOn( istrstream & is ) { is.nlOnOff$ = true; }
+void nlOff( istrstream & is ) { is.nlOnOff$ = false; }
+
+void ends( istrstream & is ) {
+} // ends
+
+int eof( istrstream & is ) {
+	return 0;
+} // eof
+
+istrstream &ungetc( istrstream & is, char c ) {
+	// if ( ungetc( c, (FILE *)(is.file$) ) == EOF ) {
+	// 	abort | IO_MSG "ungetc" | nl | strerror( errno );
+	// } // if
+	return is;
+} // ungetc
+
+int fmt( istrstream & is, const char format[], ... ) {
+	va_list args;
+	va_start( args, format );
+	// This does not work because vsscanf does not return buffer position.
+	int len = vsscanf( is.buf$ + is.cursor$, format, args );
+	va_end( args );
+	if ( len == EOF ) {
+		int j;
+		printf( "X %d%n\n", len, &j );
+	} // if
+	is.cursor$ += len;
+	return len;
+} // fmt
 
 // Local Variables: //
Index: libcfa/src/strstream.hfa
===================================================================
--- libcfa/src/strstream.hfa	(revision f4511776e3624956eae41ab1c26f7ff2170560a5)
+++ libcfa/src/strstream.hfa	(revision 666483d3c12841a6d84496e37920d1d44a67365d)
@@ -10,6 +10,6 @@
 // Created On       : Thu Apr 22 22:20:59 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Sat Apr 24 11:17:33 2021
-// Update Count     : 37
+// Last Modified On : Tue Apr 27 20:58:50 2021
+// Update Count     : 41
 // 
 
@@ -20,9 +20,9 @@
 
 
-// *********************************** strstream ***********************************
+// *********************************** ostrstream ***********************************
 
 
-enum { strstream_sepSize = 16 };
-struct strstream {										// satisfied basic_ostream
+enum { ostrstream_sepSize = 16 };
+struct ostrstream {										// satisfied basic_ostream
 	char * buf$;
 	size_t size$;
@@ -34,45 +34,65 @@
 	bool sawNL$;
 	const char * sepCur$;
-	char separator$[strstream_sepSize];
-	char tupleSeparator$[strstream_sepSize];
-}; // strstream
+	char separator$[ostrstream_sepSize];
+	char tupleSeparator$[ostrstream_sepSize];
+}; // ostrstream
 
 // Satisfies basic_ostream
 
 // private
-bool sepPrt$( strstream & );
-void sepReset$( strstream & );
-void sepReset$( strstream &, bool );
-const char * sepGetCur$( strstream & );
-void sepSetCur$( strstream &, const char [] );
-bool getNL$( strstream & );
-void setNL$( strstream &, bool );
-bool getANL$( strstream & );
-bool getPrt$( strstream & );
-void setPrt$( strstream &, bool );
+bool sepPrt$( ostrstream & );
+void sepReset$( ostrstream & );
+void sepReset$( ostrstream &, bool );
+const char * sepGetCur$( ostrstream & );
+void sepSetCur$( ostrstream &, const char [] );
+bool getNL$( ostrstream & );
+void setNL$( ostrstream &, bool );
+bool getANL$( ostrstream & );
+bool getPrt$( ostrstream & );
+void setPrt$( ostrstream &, bool );
 
 // public
-void sepOn( strstream & );
-void sepOff( strstream & );
-bool sepDisable( strstream & );
-bool sepEnable( strstream & );
-void nlOn( strstream & );
-void nlOff( strstream & );
+void sepOn( ostrstream & );
+void sepOff( ostrstream & );
+bool sepDisable( ostrstream & );
+bool sepEnable( ostrstream & );
+void nlOn( ostrstream & );
+void nlOff( ostrstream & );
 
-const char * sepGet( strstream & );
-void sepSet( strstream &, const char [] );
-const char * sepGetTuple( strstream & );
-void sepSetTuple( strstream &, const char [] );
+const char * sepGet( ostrstream & );
+void sepSet( ostrstream &, const char [] );
+const char * sepGetTuple( ostrstream & );
+void sepSetTuple( ostrstream &, const char [] );
 
-void ends( strstream & );
-int fmt( strstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
-int flush( strstream & );
+void ends( ostrstream & );
+int fmt( ostrstream &, const char format[], ... ) __attribute__(( format(printf, 2, 3) ));
 
-strstream & write( strstream & os );					// use stdout, default value not working
-strstream & write( strstream & os, FILE * stream = stdout );
+ostrstream & write( ostrstream & os, FILE * stream ); // FIX ME: use default = stdout
+ostrstream & write( ostrstream & os );
 
-void ?{}( strstream &, char buf[], size_t size );
+void ?{}( ostrstream &, char buf[], size_t size );
 
-extern strstream & sstr;
+
+// *********************************** istrstream ***********************************
+
+
+struct istrstream {
+	char * buf$;
+	size_t cursor$;
+	bool nlOnOff$;
+}; // istrstream
+
+// Satisfies basic_istream
+
+// public
+bool getANL( istrstream & );
+void nlOn( istrstream & );
+void nlOff( istrstream & );
+void ends( istrstream & );
+int fmt( istrstream &, const char format[], ... ) __attribute__(( format(scanf, 2, 3) ));
+istrstream & ungetc( istrstream & is, char c );
+int eof( istrstream & is );
+
+void ?{}( istrstream & is, char buf[] );
 
 // Local Variables: //
