Index: libcfa/src/collections/string.cfa
===================================================================
--- libcfa/src/collections/string.cfa	(revision 30548de557fe51569fd989d9a2f6f14e66179173)
+++ libcfa/src/collections/string.cfa	(revision b0296dbafa72b5b6a020276daf55dc8a2fbf3142)
@@ -10,6 +10,6 @@
 // Created On       : Fri Sep 03 11:00:00 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Apr 11 18:18:07 2025
-// Update Count     : 370
+// Last Modified On : Sun Apr 13 07:58:55 2025
+// Update Count     : 390
 //
 
@@ -202,4 +202,9 @@
 	return s;
 }
+
+////////////////////////////////////////////////////////
+// Getter
+
+size_t strnlen( const string & s, size_t maxlen ) { return min( len( s ), maxlen ); }
 
 ////////////////////////////////////////////////////////
@@ -265,31 +270,4 @@
 
 ////////////////////////////////////////////////////////
-// Comparison
-
-int strcmp( const string & s1, const string & s2 ) { return strcmp( *s1.inner, *s2.inner ); }
-bool ?==?( const string & s1, const string & s2 ) { return *s1.inner == *s2.inner; }
-bool ?!=?( const string & s1, const string & s2 ) { return *s1.inner != *s2.inner; }
-bool ?>? ( const string & s1, const string & s2 ) { return *s1.inner >  *s2.inner; }
-bool ?>=?( const string & s1, const string & s2 ) { return *s1.inner >= *s2.inner; }
-bool ?<=?( const string & s1, const string & s2 ) { return *s1.inner <= *s2.inner; }
-bool ?<? ( const string & s1, const string & s2 ) { return *s1.inner <  *s2.inner; }
-
-int strcmp( const string & s1, const char * s2 ) { return strcmp( *s1.inner, s2 ); }
-bool ?==?( const string & s1, const char * s2 ) { return *s1.inner == s2; }
-bool ?!=?( const string & s1, const char * s2 ) { return *s1.inner != s2; }
-bool ?>? ( const string & s1, const char * s2 ) { return *s1.inner >  s2; }
-bool ?>=?( const string & s1, const char * s2 ) { return *s1.inner >= s2; }
-bool ?<=?( const string & s1, const char * s2 ) { return *s1.inner <= s2; }
-bool ?<? ( const string & s1, const char * s2 ) { return *s1.inner <  s2; }
-
-int strcmp( const char * s1, const string & s2 ) { return strcmp( s1, *s2.inner ); }
-bool ?==?( const char * s1, const string & s2 ) { return s1 == *s2.inner; }
-bool ?!=?( const char * s1, const string & s2 ) { return s1 != *s2.inner; }
-bool ?>? ( const char * s1, const string & s2 ) { return s1 >  *s2.inner; }
-bool ?>=?( const char * s1, const string & s2 ) { return s1 >= *s2.inner; }
-bool ?<=?( const char * s1, const string & s2 ) { return s1 <= *s2.inner; }
-bool ?<? ( const char * s1, const string & s2 ) { return s1 <  *s2.inner; }
-
-////////////////////////////////////////////////////////
 // Concatenation
 
@@ -403,4 +381,32 @@
 	string ret = { *s.inner, index, 1 };
 	return ret`share;
+}
+
+////////////////////////////////////////////////////////
+// Comparison
+
+#define STRNCPY_FMT "**** Error **** strncpy: maximum length %zu is greater than string lengths %zd or %zd."
+
+int strncmp( const string & s1, const string & s2, size_t maxlen ) {
+	if ( maxlen > len( s1 ) || maxlen > len( s2 ) ) {
+		abort( STRNCPY_FMT, maxlen, len( s1 ), len( s2 ) );
+	} // if
+	return strcmp$( s1.inner->Handle.s, maxlen, s2.inner->Handle.s, maxlen );
+}
+
+int strncmp( const string & s1, const char * s2, size_t maxlen ) {
+	size_t s2len = len( s2 );
+	if ( maxlen > len( s1 ) || maxlen > s2len ) {
+		abort( STRNCPY_FMT, maxlen, len( s1 ), s2len );
+	} // if
+	return strcmp$( s1.inner->Handle.s, maxlen, s2, maxlen );
+}
+
+int strncmp( const char * s1, const string & s2, size_t maxlen ) {
+	size_t s1len = len( s1 );
+	if ( maxlen > s1len || maxlen > len( s2 ) ) {
+		abort( STRNCPY_FMT, maxlen, s1len, len( s2 ) );
+	} // if
+	return strcmp$( s1, maxlen, s2.inner->Handle.s, maxlen );
 }
 
@@ -523,5 +529,5 @@
 }
 
-size_t test( const string & s, int (*f)( int ) ) {
+size_t include( const string & s, int (*f)( int ) ) {
 	size_t l = len( s );
 	for ( i; l ) {
@@ -531,5 +537,13 @@
 }
 
-string replace( string & s, const string & from, const string & to ) {
+size_t exclude( const string & s, int (*f)( int ) ) {
+	size_t l = len( s );
+	for ( i; l ) {
+		if ( f( s[i] ) ) return i;
+	} // for
+	return l;
+}
+
+string replace( const string & s, const string & from, const string & to ) {
 	ssize_t pos;
     string r;
Index: libcfa/src/collections/string.hfa
===================================================================
--- libcfa/src/collections/string.hfa	(revision 30548de557fe51569fd989d9a2f6f14e66179173)
+++ libcfa/src/collections/string.hfa	(revision b0296dbafa72b5b6a020276daf55dc8a2fbf3142)
@@ -10,6 +10,6 @@
 // Created On       : Fri Sep 03 11:00:00 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Apr 11 18:13:35 2025
-// Update Count     : 261
+// Last Modified On : Sun Apr 13 21:03:35 2025
+// Update Count     : 284
 //
 
@@ -80,4 +80,5 @@
 static inline size_t len( const char * cs ) { return strlen( cs ); };
 static inline size_t strlen( const string & s ) { return len( s ); }
+size_t strnlen( const string & s, size_t maxlen );
 
 // IO Operator
@@ -125,5 +126,4 @@
 	_Istream_Swidth wdi( unsigned int rwd, string & s ) { return (_Istream_Swidth)@{ .s = s, { {.scanset = 0p}, .wd = rwd, {.flags.rwd = true} } }; }
 	_Istream_Sstr getline( string & s, const char delimiter = '\n' ) {
-//		return (_Istream_Sstr)@{ { .s = s, { {.delimiters = { delimiter, '\0' } }, .wd = -1, {.flags.delimiter = true} } } };
 		return (_Istream_Sstr)@{ .s = s, { {.delimiters = { delimiter, '\0' } }, .wd = -1, {.flags.delimiter = true} } };
 	}
@@ -138,15 +138,11 @@
 		return (_Istream_Squote &)f;
 	}
-//	_Istream_Sstr incl( const char scanset[], string & s ) { return (_Istream_Sstr)@{ { .s = s, { {.scanset = scanset}, .wd = -1, {.flags.inex = false} } } }; }
 	_Istream_Sstr incl( const char scanset[], string & s ) { return (_Istream_Sstr)@{ .s = s, { {.scanset = scanset}, .wd = -1, {.flags.inex = false} } }; }
 	_Istream_Sstr & incl( const char scanset[], _Istream_Swidth & f ) { f.scanset = scanset; f.flags.inex = false; return (_Istream_Sstr &)f; }
-//	_Istream_Sstr excl( const char scanset[], string & s ) { return (_Istream_Sstr)@{ { .s = s, { {.scanset = scanset}, .wd = -1, {.flags.inex = true} } } }; }
 	_Istream_Sstr excl( const char scanset[], string & s ) { return (_Istream_Sstr)@{ .s = s, { {.scanset = scanset}, .wd = -1, {.flags.inex = true} } }; }
 	_Istream_Sstr & excl( const char scanset[], _Istream_Swidth & f ) { f.scanset = scanset; f.flags.inex = true; return (_Istream_Sstr &)f; }
-//	_Istream_Sstr ignore( string & s ) { return (_Istream_Sstr)@{ { .s = s, { {.scanset = 0p}, .wd = -1, {.flags.ignore = true} } } }; }
 	_Istream_Sstr ignore( string & s ) { return (_Istream_Sstr)@{ .s = s, { {.scanset = 0p}, .wd = -1, {.flags.ignore = true} } }; }
 	_Istream_Sstr & ignore( _Istream_Swidth & f ) { f.flags.ignore = true; return (_Istream_Sstr &)f; }
 	_Istream_Squote & ignore( _Istream_Squote & f ) { f.sstr.flags.ignore = true; return (_Istream_Squote &)f; }
-//	_Istream_Sstr & ignore( _Istream_Sstr & f ) { f.sstr.flags.ignore = true; return (_Istream_Sstr &)f; }
 	_Istream_Sstr & ignore( _Istream_Sstr & f ) { f.flags.ignore = true; return (_Istream_Sstr &)f; }
 } // distribution
@@ -201,27 +197,30 @@
 
 // Comparisons
-int strcmp ( const string &, const string & );
-bool ?==?( const string &, const string & );
-bool ?!=?( const string &, const string & );
-bool ?>? ( const string &, const string & );
-bool ?>=?( const string &, const string & );
-bool ?<=?( const string &, const string & );
-bool ?<? ( const string &, const string & );
-
-int strcmp( const string &, const char * );
-bool ?==?( const string &, const char * );
-bool ?!=?( const string &, const char * );
-bool ?>? ( const string &, const char * );
-bool ?>=?( const string &, const char * );
-bool ?<=?( const string &, const char * );
-bool ?<? ( const string &, const char * );
-
-int strcmp( const char *, const string & );
-bool ?==?( const char *, const string & );
-bool ?!=?( const char *, const string & );
-bool ?>? ( const char *, const string & );
-bool ?>=?( const char *, const string & );
-bool ?<=?( const char *, const string & );
-bool ?<? ( const char *, const string & );
+static inline int strcmp( const string & s1, const string & s2 ) { return strcmp( *s1.inner, *s2.inner ); }
+int strncmp( const string & s1, const string & s2, size_t maxlen );
+static inline bool ?==?( const string & s1, const string & s2 ) { return *s1.inner == *s2.inner; }
+static inline bool ?!=?( const string & s1, const string & s2 ) { return *s1.inner != *s2.inner; }
+static inline bool ?>? ( const string & s1, const string & s2 ) { return *s1.inner >  *s2.inner; }
+static inline bool ?>=?( const string & s1, const string & s2 ) { return *s1.inner >= *s2.inner; }
+static inline bool ?<=?( const string & s1, const string & s2 ) { return *s1.inner <= *s2.inner; }
+static inline bool ?<? ( const string & s1, const string & s2 ) { return *s1.inner <  *s2.inner; }
+
+static inline int strcmp( const string & s1, const char * s2 ) { return strcmp( *s1.inner, s2 ); }
+int strncmp( const string & s1, const char * s2, size_t maxlen );
+static inline bool ?==?( const string & s1, const char * s2 ) { return *s1.inner == s2; }
+static inline bool ?!=?( const string & s1, const char * s2 ) { return *s1.inner != s2; }
+static inline bool ?>? ( const string & s1, const char * s2 ) { return *s1.inner >  s2; }
+static inline bool ?>=?( const string & s1, const char * s2 ) { return *s1.inner >= s2; }
+static inline bool ?<=?( const string & s1, const char * s2 ) { return *s1.inner <= s2; }
+static inline bool ?<? ( const string & s1, const char * s2 ) { return *s1.inner <  s2; }
+
+static inline int strcmp( const char * s1, const string & s2 ) { return strcmp( s1, *s2.inner ); }
+int strncmp( const char * s1, const string & s2, size_t maxlen );
+static inline bool ?==?( const char * s1, const string & s2 ) { return s1 == *s2.inner; }
+static inline bool ?!=?( const char * s1, const string & s2 ) { return s1 != *s2.inner; }
+static inline bool ?>? ( const char * s1, const string & s2 ) { return s1 >  *s2.inner; }
+static inline bool ?>=?( const char * s1, const string & s2 ) { return s1 >= *s2.inner; }
+static inline bool ?<=?( const char * s1, const string & s2 ) { return s1 <= *s2.inner; }
+static inline bool ?<? ( const char * s1, const string & s2 ) { return s1 <  *s2.inner; }
 
 // String search
@@ -279,42 +278,31 @@
 
 size_t include( const string & s, const charclass & mask );
-static inline size_t include( const char * s, const charclass & mask ) { string temp = s; return include( temp, mask ); }
-static inline string include( const string & s, const charclass & mask ) { ssize_t i = include( s, mask ); return s( 0, i )`share; }
-static inline string include( const char * s, const charclass & mask ) { string temp = s; ssize_t i = include( temp, mask ); return temp( 0, i ); }
+static inline size_t include( const char * cs, const charclass & mask ) { const string s = cs; return include( s, mask ); }
+static inline string include( const string & s, const charclass & mask ) { return s( 0, include( s, mask ) ); }
+static inline string include( const char * cs, const charclass & mask ) { const string s = cs; return s( 0, include( s, mask ) ); }
 
 size_t exclude( const string & s, const charclass & mask );
-static inline size_t exclude( const char * s, const charclass & mask ) { string temp = s; return exclude( temp, mask ); }
-static inline string exclude( const string & s, const charclass & mask ) { ssize_t i = exclude( s, mask ); return s( 0, i )`share; }
-static inline string exclude( const char * s, const charclass & mask ) { string temp = s; ssize_t i = exclude( temp, mask ); return temp( 0, i ); }
-
-size_t test( const string & s, int (*f)( int ) );
-static inline size_t test( const char * c, int (*f)( int ) ) {
-	const string S = c;
-	return test( S, f );
-}
-
-string replace( string & s, const string & from, const string & to );
-static inline string replace( const char * s, const char * from, const char * to ) {
-	string S = s, From = from, To = to;
-	return replace( S, From, To );
-}
-static inline string replace( string & s, const char * from, const char * to ) {
-	string From = from, To = to;
-	return replace( s, From, To );
-}
-static inline string replace( string & s, const char * from, const string & to ) {
-	string From = from;
-	return replace( s, From, to );
-}
-static inline string replace( string & s, string & from, const char * to ) {
-	string To = to;
-	return replace( s, from, To );
-}
+static inline size_t exclude( const char * cs, const charclass & mask ) { const string s = cs; return exclude( s, mask ); }
+static inline string exclude( const string & s, const charclass & mask ) { return s( 0, exclude( s, mask ) ); }
+static inline string exclude( const char * cs, const charclass & mask ) { const string s = cs; return s( 0, exclude( s, mask ) ); }
+
+size_t include( const string & s, int (*f)( int ) );
+static inline size_t include( const char * cs, int (*f)( int ) ) { const string S = cs; return include( S, f ); }
+static inline string include( const string & s, int (*f)( int ) ) { return s( 0, include( s, f ) ); }
+static inline string include( const char * cs, int (*f)( int ) ) { const string s = cs; return s( 0, include( s, f ) ); }
+
+size_t exclude( const string & s, int (*f)( int ) );
+static inline size_t exclude( const char * cs, int (*f)( int ) ) { const string s = cs; return exclude( s, f ); }
+static inline string exclude( const string & s, int (*f)( int ) ) { return s( 0, exclude( s, f ) ); }
+static inline string exclude( const char * cs, int (*f)( int ) ) { const string s = cs; return s( 0, exclude( s, f ) ); }
+
+string replace( const string & s, const string & from, const string & to );
+static inline string replace( const char * s, const char * from, const char * to ) { string S = s, From = from, To = to; return replace( S, From, To ); }
+static inline string replace( const string & s, const char * from, const char * to ) { const string From = from, To = to; return replace( s, From, To ); }
+static inline string replace( const string & s, const char * from, const string & to ) { const string From = from; return replace( s, From, to ); }
+static inline string replace( const string & s, string & from, const char * to ) { const string To = to; return replace( s, from, To ); }
 
 string translate( const string & s, int (*f)( int ) );
-static inline string translate( const char * c, int (*f)( int ) ) {
-	const string S = c;
-	return translate( S, f );
-}
+static inline string translate( const char * c, int (*f)( int ) ) { const string S = c; return translate( S, f ); }
 
 #ifndef _COMPILING_STRING_CFA_
Index: libcfa/src/collections/string_res.hfa
===================================================================
--- libcfa/src/collections/string_res.hfa	(revision 30548de557fe51569fd989d9a2f6f14e66179173)
+++ libcfa/src/collections/string_res.hfa	(revision b0296dbafa72b5b6a020276daf55dc8a2fbf3142)
@@ -10,6 +10,6 @@
 // Created On       : Fri Sep 03 11:00:00 2021
 // Last Modified By : Peter A. Buhr
-// Last Modified On : Fri Apr 11 18:11:05 2025
-// Update Count     : 77
+// Last Modified On : Sun Apr 13 21:03:37 2025
+// Update Count     : 79
 //
 
@@ -148,5 +148,4 @@
 	_Istream_Rwidth wdi( unsigned int rwd, string_res & s ) { return (_Istream_Rwidth)@{ .s = &s, { {.scanset = 0p}, .wd = rwd, {.flags.rwd = true} } }; }
 	_Istream_Rstr getline( string_res & s, const char delimiter = '\n' ) {
-//		return (_Istream_Rstr)@{ { .s = &s, { {.delimiters = { delimiter, '\0' } }, .wd = -1, {.flags.delimiter = true} } } };
 		return (_Istream_Rstr)@{ .s = &s, { {.delimiters = { delimiter, '\0' } }, .wd = -1, {.flags.delimiter = true} } };
 	}
