Index: libcfa/src/collections/string_res.cfa
===================================================================
--- libcfa/src/collections/string_res.cfa	(revision a51dc0de37fbbde4fc497460bcc75e0b98fc4a8f)
+++ libcfa/src/collections/string_res.cfa	(revision 3ac5fd8bcb3728ce8676e2b55b9fd4f691a06719)
@@ -10,6 +10,6 @@
 // Created On       : Fri Sep 03 11:00:00 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Mon Apr 15 21:56:27 2024
-// Update Count     : 85
+// Last Modified On : Sat Aug 17 14:08:01 2024
+// Update Count     : 86
 //
 
@@ -251,5 +251,5 @@
 
 ifstream & ?|?( ifstream & is, _Istream_Rquoted f ) with( f.rstr ) {
-	if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+	if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 	int args;
   fini: {
Index: libcfa/src/enum.cfa
===================================================================
--- libcfa/src/enum.cfa	(revision a51dc0de37fbbde4fc497460bcc75e0b98fc4a8f)
+++ libcfa/src/enum.cfa	(revision 3ac5fd8bcb3728ce8676e2b55b9fd4f691a06719)
@@ -40,5 +40,5 @@
 istype & ?|?( istype & is, E & e ) {
 //	fprintf( stderr, "here0\n" );
-	if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+	if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 
 	// Match longest input enumerator string to enumerator labels, where enumerator names are unique.
@@ -59,4 +59,6 @@
 
 	fmt( is, " " );										// skip optional whitespace
+	if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
+
 	for ( c; max ) {									// scan columns of the label matix (some columns missing)
 		int args = fmt( is, "%c", &ch );				// read character
Index: libcfa/src/iostream.cfa
===================================================================
--- libcfa/src/iostream.cfa	(revision a51dc0de37fbbde4fc497460bcc75e0b98fc4a8f)
+++ libcfa/src/iostream.cfa	(revision 3ac5fd8bcb3728ce8676e2b55b9fd4f691a06719)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug  2 07:38:44 2024
-// Update Count     : 2021
+// Last Modified On : Sat Aug 17 12:31:47 2024
+// Update Count     : 2038
 //
 
@@ -777,7 +777,7 @@
 forall( istype & | basic_istream( istype ) ) {
 	istype & ?|?( istype & is, bool & b ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int len = -1;									// len not set if no match
-		// Optional leading whitespace at start of strings.
+		// remove optional leading whitespace at start of strings.
 		fmt( is, " " FALSE "%n", &len );				// try false
 		if ( len != sizeof( FALSE ) - 1 ) {				// -1 removes null terminate
@@ -792,12 +792,12 @@
 
 	istype & ?|?( istype & is, char & c ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		char temp;
 		for () {
 			int args = fmt( is, "%c", &temp );
-			if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
+			if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
+			assert( args == 1 );						// if not EOF => a single character must be read
 			// do not overwrite parameter with newline unless appropriate
 			if ( temp != '\n' || getANL$( is ) ) { c = temp; break; }
-			if ( eof( is ) ) break;
 		} // for
 		return is;
@@ -805,13 +805,13 @@
 
 	istype & ?|?( istype & is, signed char & sc ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
-		int args = fmt( is, "%hhi", &sc );
-		if ( args != 1 ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
+		int args = fmt( is, "%hhi", &sc );				// can be multiple characters (100)
+		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
 		return is;
 	} // ?|?
 
 	istype & ?|?( istype & is, unsigned char & usc ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
-		int args = fmt( is, "%hhi", &usc );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
+		int args = fmt( is, "%hhi", &usc );				// can be multiple characters (-100)
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
 		return is;
@@ -819,5 +819,5 @@
 
 	istype & ?|?( istype & is, short int & si ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%hi", &si );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -826,5 +826,5 @@
 
 	istype & ?|?( istype & is, unsigned short int & usi ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%hi", &usi );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -833,5 +833,5 @@
 
 	istype & ?|?( istype & is, int & i ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%i", &i );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -840,5 +840,5 @@
 
 	istype & ?|?( istype & is, unsigned int & ui ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%i", &ui );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -847,5 +847,5 @@
 
 	istype & ?|?( istype & is, long int & li ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%li", &li );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -854,5 +854,5 @@
 
 	istype & ?|?( istype & is, unsigned long int & ulli ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%li", &ulli );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -861,5 +861,5 @@
 
 	istype & ?|?( istype & is, long long int & lli ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%lli", &lli );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -868,5 +868,5 @@
 
 	istype & ?|?( istype & is, unsigned long long int & ulli ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%lli", &ulli );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -891,5 +891,5 @@
 			} // for
 			if ( sign ) ullli = -ullli;
-		} else if ( sign ) ungetc( '-', is );			// return minus when no digits
+		} // if
 		return is;
 	} // ?|?
@@ -897,5 +897,5 @@
 
 	istype & ?|?( istype & is, float & f ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%f", &f );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -904,5 +904,5 @@
 
 	istype & ?|?( istype & is, double & d ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%lf", &d );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -911,5 +911,5 @@
 
 	istype & ?|?( istype & is, long double & ld ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args = fmt( is, "%Lf", &ld );
 		if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
@@ -918,5 +918,5 @@
 
 	istype & ?|?( istype & is, float _Complex & fc ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		float re, im;
 		int args = fmt( is, "%f%fi", &re, &im );
@@ -927,5 +927,5 @@
 
 	istype & ?|?( istype & is, double _Complex & dc ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		double re, im;
 		int args = fmt( is, "%lf%lfi", &re, &im );
@@ -936,5 +936,5 @@
 
 	istype & ?|?( istype & is, long double _Complex & ldc ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		long double re, im;
 		int args = fmt( is, "%Lf%Lfi", &re, &im );
@@ -945,5 +945,5 @@
 
 	istype & ?|?( istype & is, const char fmt[] ) {		// match text
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		size_t len = strlen( fmt );
 		char fmtstr[len + 16];
@@ -953,5 +953,5 @@
 		// scanf cursor does not move if no match
 		fmt( is, fmtstr, &len );
-		if ( ! eof( is ) && len == -1 ) throwResume ExceptionInst( missing_data );
+		if ( len == -1 ) throwResume ExceptionInst( missing_data );
 		return is;
 	} // ?|?
@@ -987,5 +987,5 @@
 forall( istype & | basic_istream( istype ) ) {
 	istype & ?|?( istype & is, _Istream_Cskip f ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		if ( f.scanset ) {
 			int nscanset = strlen(f.scanset);
@@ -1000,5 +1000,5 @@
 			for ( f.wd ) {								// skip N characters
 				int args = fmt( is, "%c", &ch );
-				if ( args != 1 ) throwResume ExceptionInst( missing_data );
+				if ( ! eof( is ) && args != 1 ) throwResume ExceptionInst( missing_data );
 			} // for
 		} // if
@@ -1007,5 +1007,5 @@
 
 	istype & ?|?( istype & is, _Istream_Cquoted f ) with( f.cstr ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		int args;
 	  fini: {
@@ -1032,5 +1032,5 @@
 
 	istype & ?|?( istype & is, _Istream_Cstr f ) with( f.cstr ) {
-		if ( eof( is ) ) throwResume ExceptionInst( missing_data );
+		if ( eof( is ) ) throwResume ExceptionInst( end_of_file );
 		const char * scanset;
 		size_t nscanset = 0;
Index: libcfa/src/iostream.hfa
===================================================================
--- libcfa/src/iostream.hfa	(revision a51dc0de37fbbde4fc497460bcc75e0b98fc4a8f)
+++ libcfa/src/iostream.hfa	(revision 3ac5fd8bcb3728ce8676e2b55b9fd4f691a06719)
@@ -10,6 +10,6 @@
 // Created On       : Wed May 27 17:56:53 2015
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Aug  2 07:37:57 2024
-// Update Count     : 760
+// Last Modified On : Thu Aug 15 18:21:22 2024
+// Update Count     : 761
 //
 
@@ -374,4 +374,5 @@
 // *********************************** exceptions ***********************************
 
+ExceptionDecl( end_of_file );							// read encounters end of file
 ExceptionDecl( missing_data );							// read finds no appropriate data
 ExceptionDecl( cstring_length );						// character string size exceeded
Index: libcfa/src/parseconfig.cfa
===================================================================
--- libcfa/src/parseconfig.cfa	(revision a51dc0de37fbbde4fc497460bcc75e0b98fc4a8f)
+++ libcfa/src/parseconfig.cfa	(revision 3ac5fd8bcb3728ce8676e2b55b9fd4f691a06719)
@@ -105,10 +105,15 @@
 
 static [ bool ] comments( & ifstream in, size_t size, [] char name ) {
-	while () {
-		in | wdi( size, name );
-	  if ( eof( in ) ) return true;
-	  if ( name[0] != '#' ) return false;
-		in | nl;										// ignore remainder of line
-	} // while
+	bool comment = false;
+	try {
+		while () {
+			in | wdi( size, name );
+			if ( name[0] != '#' ) break;
+			in | nl;									// ignore remainder of line
+		} // while
+	} catch( end_of_file * ) {
+		comment = true;
+	} // try
+	return comment;
 } // comments
 
@@ -125,15 +130,17 @@
 		[256] char value;
 
-		while () {										// parameter names can appear in any order
-		  	// NOTE: Must add check to see if already read in value for this key,
-			// once we switch to using hash table as intermediate storage
-		  if ( comments( in, 64, key ) ) break;			// eof ?
-			in | wdi( 256, value );
-
-			add_kv_pair( *kv_pairs, key, value );
-
-		  if ( eof( in ) ) break;
-			in | nl;									// ignore remainder of line
-		} // for
+		try {
+			while () {										// parameter names can appear in any order
+				// NOTE: Must add check to see if already read in value for this key,
+				// once we switch to using hash table as intermediate storage
+				if ( comments( in, 64, key ) ) break;			// eof ?
+				in | wdi( 256, value );
+
+				add_kv_pair( *kv_pairs, key, value );
+
+				in | nl;									// ignore remainder of line
+			} // while
+		} catch( end_of_file * ) {
+		} // try
 	} catch( open_failure * ex; ex->istream == &in ) {
 		delete( kv_pairs );
