Index: libcfa/src/containers/string.cfa
===================================================================
--- libcfa/src/containers/string.cfa	(revision 7e1dbd72b91978bc0a2745abacb829909bdfc517)
+++ libcfa/src/containers/string.cfa	(revision 38de9140a8f433055812c963db9866dac5191483)
@@ -10,6 +10,6 @@
 // Created On       : Fri Sep 03 11:00:00 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Aug 28 19:00:45 2023
-// Update Count     : 146
+// Last Modified On : Tue Aug 29 18:32:34 2023
+// Update Count     : 153
 //
 
@@ -118,34 +118,18 @@
 }
 
-static void readstr( ifstream & is, _Istream_str f, char fmtstr[], char cstr[] ) {
-	int check = f.rwd - 1;
-
-	if ( ! f.flags.rwd ) cstr[check] = '\0';			// insert sentinel
-	int len = fmt( is, fmtstr, cstr );
-	// fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, cstr[check], cstr );
-
-	if ( ! f.flags.rwd && cstr[check] != '\0' )			// sentinel overwritten ?
-		throw (cstring_length){ &cstring_length_vt };
-
-	if ( f.flags.delimit ) {							// getline ?
-		if ( len == 0 ) cstr[0] = '\0';					// empty read => argument unchanged => set empty
-		if ( ! eof( is ) ) fmt( is, "%*c" );			// ignore delimiter
-	} //if
-} // readstr
-
 ifstream & ?|?( ifstream & is, _Istream_str f ) {
 	// skip, same as for char *
 	if ( ! &f.s ) {
 		// fprintf( stderr,  "skip %s %d\n", f.scanset, f.wd );
-		if ( f.rwd == -1 ) fmt( is, f.scanset, "" ); // no input arguments
-		else for ( f.rwd ) fmt( is, "%*c" );
+		if ( f.wd == -1 ) fmt( is, f.scanset, "" ); // no input arguments
+		else for ( f.wd ) fmt( is, "%*c" );
 		return is;
 	} // if
 
-	enum { gwd = 16 + 2, wd = gwd - 1 };				// guarded and unguarded width
+	enum { gwd = 128 + 2, wd = gwd - 1 };				// guarded and unguarded width
 	char cstr[gwd];										// read in chunks
 	bool cont = false;;
 
-	if ( f.rwd == -1 ) f.rwd = wd;
+	if ( f.wd == -1 ) f.wd = wd;
 	const char * scanset = f.scanset;;
 	if ( f.flags.delimit ) scanset = f.delimit;			// getline ?
@@ -157,5 +141,5 @@
 	fmtstr[0] = '%';
 	if ( f.flags.ignore ) { fmtstr[1] = '*'; start += 1; }
-	if ( f.rwd != -1 ) { start += sprintf( &fmtstr[start], "%d", f.rwd ); }
+	if ( f.wd != -1 ) { start += sprintf( &fmtstr[start], "%d", f.wd ); }
 
 	if ( ! scanset ) {
Index: libcfa/src/containers/string.hfa
===================================================================
--- libcfa/src/containers/string.hfa	(revision 7e1dbd72b91978bc0a2745abacb829909bdfc517)
+++ libcfa/src/containers/string.hfa	(revision 38de9140a8f433055812c963db9866dac5191483)
@@ -10,6 +10,6 @@
 // Created On       : Fri Sep 03 11:00:00 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Aug 28 18:32:59 2023
-// Update Count     : 40
+// Last Modified On : Tue Aug 29 18:28:04 2023
+// Update Count     : 47
 //
 
@@ -58,39 +58,25 @@
 void ?|?( ifstream & in, string & this );
 
-
 struct _Istream_str {
 	string & s;
-	union {
-		const char * scanset;
-		char delimit[2];
-	};
-	int rwd;											// read width
-	union {
-		unsigned char all;
-		struct {
-			unsigned char ignore:1;						// do not change input argument
-			unsigned char inex:1;						// include/exclude characters in scanset
-			unsigned char delimit:1;					// delimit character
-			unsigned char rwd:1;						// read width
-		} flags;
-	};
+	inline _Istream_str_base;
 }; // _Istream_str
 
 static inline {
 	// read width does not include null terminator
-	_Istream_str wdi( unsigned int rwd, string & s ) { return (_Istream_str)@{ s, {0p}, rwd, {.flags.rwd : true} }; }
-	_Istream_str skip( const char scanset[] ) { return (_Istream_str)@{ *0p, {scanset}, -1, {.all : 0} }; }
-	_Istream_str skip( unsigned int wd ) { return (_Istream_str)@{ *0p, {0p}, wd, {.all : 0} }; }
+	_Istream_str wdi( unsigned int rwd, string & s ) { return (_Istream_str)@{ s, {{0p}, rwd, {.flags.rwd : true}} }; }
+	_Istream_str skip( const char scanset[] ) { return (_Istream_str)@{ *0p, {{scanset}, -1, {.all : 0}} }; }
+	_Istream_str skip( unsigned int wd ) { return (_Istream_str)@{ *0p, {{0p}, wd, {.all : 0}} }; }
 	_Istream_str getline( string & s, const char delimit = '\n' ) {
-		return (_Istream_str)@{ s, {.delimit : { delimit, '\0' } }, -1, {.flags.delimit : true, .flags.inex : true} };
+		return (_Istream_str)@{ s, {{.delimit : { delimit, '\0' } }, -1, {.flags.delimit : true, .flags.inex : true}} };
 	}
 	_Istream_str & getline( _Istream_str & fmt, const char delimit = '\n' ) {
 		fmt.delimit[0] = delimit; fmt.delimit[1] = '\0'; fmt.flags.delimit = true; fmt.flags.inex = true; return fmt;
 	}
-	_Istream_str incl( const char scanset[], string & s ) { return (_Istream_str)@{ s, {scanset}, -1, {.flags.inex : false} }; }
+	_Istream_str incl( const char scanset[], string & s ) { return (_Istream_str)@{ s, {{scanset}, -1, {.flags.inex : false}} }; }
 	_Istream_str & incl( const char scanset[], _Istream_str & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
-	_Istream_str excl( const char scanset[], string & s ) { return (_Istream_str)@{ s, {scanset}, -1, {.flags.inex : true} }; }
+	_Istream_str excl( const char scanset[], string & s ) { return (_Istream_str)@{ s, {{scanset}, -1, {.flags.inex : true}} }; }
 	_Istream_str & excl( const char scanset[], _Istream_str & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
-	_Istream_str ignore( string & s ) { return (_Istream_str)@{ s, {0p}, -1, {.flags.ignore : true} }; }
+	_Istream_str ignore( string & s ) { return (_Istream_str)@{ s, {{0p}, -1, {.flags.ignore : true}} }; }
 	_Istream_str & ignore( _Istream_str & fmt ) { fmt.flags.ignore = true; return fmt; }
 } // distribution
Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision 7e1dbd72b91978bc0a2745abacb829909bdfc517)
+++ libcfa/src/iostream.cfa	(revision 38de9140a8f433055812c963db9866dac5191483)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Aug 28 13:36:16 2023
-// Update Count     : 1527
+// Last Modified On : Wed Aug 30 10:56:08 2023
+// Update Count     : 1541
 //
 
@@ -962,4 +962,20 @@
 
 forall( istype & | basic_istream( istype ) ) {
+	void readstr( istype & is, _Istream_str_base f, char fmtstr[], char cstr[] ) {
+		int check = f.wd - 1;
+
+		if ( ! f.flags.rwd ) cstr[check] = '\0';		// insert sentinel
+		int len = fmt( is, fmtstr, cstr );
+		// fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, cstr[check], cstr );
+
+		if ( ! f.flags.rwd && cstr[check] != '\0' )		// sentinel overwritten ?
+			throw (cstring_length){ &cstring_length_vt };
+
+		if ( f.flags.delimit ) {						// getline ?
+			if ( len == 0 ) cstr[0] = '\0';				// empty read => argument unchanged => set empty
+			if ( ! eof( is ) ) fmt( is, "%*c" );		// ignore delimiter
+		} //if
+	} // readstr
+
 	istype & ?|?( istype & is, _Istream_Cstr f ) {
 		// skip
@@ -971,22 +987,6 @@
 		} // if
 
-		int check = f.wd - 1;
-		const char * scanset = f.scanset;;
+		const char * scanset = f.scanset;
 		if ( f.flags.delimit ) scanset = f.delimit;		// getline ?
-
-		// getline
-		// if ( f.flags.delimit ) {
-		// 	enum { size = 32 };
-		// 	char fmtstr[size];
-		// 	snprintf( fmtstr, size, "%%%d[^%c]s", f.wd, f.delimit );
-		// 	if ( ! f.flags.rwd ) f.s[check] = '\0';		// insert sentinel
-		// 	int len = fmt( is, fmtstr, f.s );			// read upto delimiter
-		// 	if ( ! f.flags.rwd && f.s[check] != '\0' )	// sentinel overwritten ?
-		// 		throw (cstring_length){ &cstring_length_vt };
-		// 	if ( len == 0 ) f.s[0] = '\0';				// empty read => argument unchanged => set empty
-		// 	// fprintf( stderr, "getline %s %s %d %d %d '%c'\n", fmtstr, f.s, len, f.wd, check, f.s[check] );
-		// 	if ( ! eof( is ) ) fmt( is, "%*c" );		// ignore delimiter
-		// 	return is;
-		// } // if
 
 		size_t len = 0;
@@ -1013,14 +1013,17 @@
 		} // if
 
-		if ( ! f.flags.rwd ) f.s[check] = '\0';			// insert sentinel
-		len = fmt( is, fmtstr, f.s );
-		//fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, f.s[check], f.s );
-		if ( ! f.flags.rwd && f.s[check] != '\0' )		// sentinel overwritten ?
-			throw (cstring_length){ &cstring_length_vt };
-
-		if ( f.flags.delimit ) {						// getline ?
-		 	if ( len == 0 ) f.s[0] = '\0';				// empty read => argument unchanged => set empty
-		 	if ( ! eof( is ) ) fmt( is, "%*c" );		// ignore delimiter
-		} //if
+		readstr( is, f, fmtstr, f.s );
+		// int check = f.wd - 1;
+
+		// if ( ! f.flags.rwd ) f.s[check] = '\0';			// insert sentinel
+		// len = fmt( is, fmtstr, f.s );
+		// //fprintf( stderr, "KK %s %zd %d %c %s\n", fmtstr, len, check, f.s[check], f.s );
+		// if ( ! f.flags.rwd && f.s[check] != '\0' )		// sentinel overwritten ?
+		// 	throw (cstring_length){ &cstring_length_vt };
+
+		// if ( f.flags.delimit ) {						// getline ?
+		//  	if ( len == 0 ) f.s[0] = '\0';				// empty read => argument unchanged => set empty
+		//  	if ( ! eof( is ) ) fmt( is, "%*c" );		// ignore delimiter
+		// } //if
 		return is;
 	} // ?|?
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision 7e1dbd72b91978bc0a2745abacb829909bdfc517)
+++ libcfa/src/iostream.hfa	(revision 38de9140a8f433055812c963db9866dac5191483)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug 25 14:55:06 2023
-// Update Count     : 535
+// Last Modified On : Tue Aug 29 19:15:06 2023
+// Update Count     : 542
 //
 
@@ -406,6 +406,5 @@
 // *********************************** manipulators ***********************************
 
-struct _Istream_Cstr {
-	char * s;
+struct _Istream_str_base {
 	union {
 		const char * scanset;
@@ -422,24 +421,30 @@
 		} flags;
 	};
+}; // _Istream_str_base
+
+struct _Istream_Cstr {
+	char * s;
+	inline _Istream_str_base;
 }; // _Istream_Cstr
 
 static inline {
 	// width must include room for null terminator
-	_Istream_Cstr wdi( unsigned int wd, char s[] ) { return (_Istream_Cstr)@{ s, {0p}, wd, {.all : 0} }; }
+	_Istream_Cstr wdi( unsigned int wd, char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, wd, {.all : 0} } }; }
 	// read width does not include null terminator
 	_Istream_Cstr wdi( unsigned int wd, unsigned int rwd, char s[] ) {
 		if ( wd <= rwd ) throw (cstring_length){ &cstring_length_vt };
-		return (_Istream_Cstr)@{ s, {0p}, rwd, {.flags.rwd : true} };
+		return (_Istream_Cstr)@{ s, { {0p}, rwd, {.flags.rwd : true} } };
 	}
-	_Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr)@{ 0p, {scanset}, -1, {.all : 0} }; }
-	_Istream_Cstr skip( unsigned int wd ) { return (_Istream_Cstr)@{ 0p, {0p}, wd, {.all : 0} }; }
+	_Istream_Cstr skip( const char scanset[] ) { return (_Istream_Cstr)@{ 0p, { {scanset}, -1, {.all : 0} } }; }
+	_Istream_Cstr skip( unsigned int wd ) { return (_Istream_Cstr)@{ 0p, { {0p}, wd, {.all : 0} } }; }
 	_Istream_Cstr & getline( _Istream_Cstr & fmt, const char delimit = '\n' ) {
 		fmt.delimit[0] = delimit; fmt.delimit[1] = '\0'; fmt.flags.delimit = true; fmt.flags.inex = true; return fmt; }
 	_Istream_Cstr & incl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = false; return fmt; }
 	_Istream_Cstr & excl( const char scanset[], _Istream_Cstr & fmt ) { fmt.scanset = scanset; fmt.flags.inex = true; return fmt; }
-	_Istream_Cstr ignore( char s[] ) { return (_Istream_Cstr)@{ s, {0p}, -1, {.flags.ignore : true} }; }
+	_Istream_Cstr ignore( char s[] ) { return (_Istream_Cstr)@{ s, { {0p}, -1, {.flags.ignore : true} } }; }
 	_Istream_Cstr & ignore( _Istream_Cstr & fmt ) { fmt.flags.ignore = true; return fmt; }
 } // distribution
 forall( istype & | basic_istream( istype ) ) {
+	void readstr( istype & is, _Istream_str_base f, char fmtstr[], char cstr[] );
 	istype & ?|?( istype & is, _Istream_Cstr f );
 	ISTYPE_VOID( _Istream_Cstr );
