+// -------------------- testing support internal functions ------------------------------
+/*
+ Returns an interface name that is valid in this environment (keeps us from
+ having to know/guess a name to test with.
+*/
+static char* get_ifname( ) {
+ struct ifaddrs *ifs; // pointer to head
+ struct ifaddrs *ele; // pointer into the list
+ char* rstr = NULL; // return string
+ char octs[NI_MAXHOST+1];
+
+ getifaddrs( &ifs );
+ for( ele = ifs; ele; ele = ele->ifa_next ) {
+ if( ele && strcmp( ele->ifa_name, "lo" ) ) {
+ memset( octs, 0, sizeof( octs ) );
+ getnameinfo( ele->ifa_addr, sizeof( struct sockaddr_in6 ), octs, NI_MAXHOST, NULL, 0, NI_NUMERICHOST );
+ if( *octs ) {
+ rstr = strdup( ele->ifa_name );
+ fprintf( stderr, "<INFO> found interface with address: %s\n", rstr );
+ break;
+ }
+ }
+ }
+
+ if( rstr == NULL ) {
+ fprintf( stderr, "<ERROR> no interface with an address was found!\n" );
+ }
+ return rstr;
+}
+
+/*
+ Build an if-addr list from what we "see" on the current system. Keeps us from
+ having to guess about what we _might_ find in some random test setup.
+ If the inc_lo0 boolean is true, then the loop back address(es) will be
+ included.
+*/
+static if_addrs_t* get_iflist( int inc_lo0 ) {
+ if_addrs_t* l;
+ struct ifaddrs *ifs; // pointer to head
+ struct ifaddrs *ele; // pointer into the list
+ char octs[NI_MAXHOST+1];
+ int max_addrs = 128;
+
+
+ if( (l = (if_addrs_t *) malloc( sizeof( if_addrs_t ) )) == NULL ) {
+ fprintf( stderr, "<FAIL> malloc of if_addrs failed\n" );
+ return NULL;
+ }
+ memset( l, 0, sizeof( if_addrs_t ) );
+ l->addrs = (char **) malloc( sizeof( char* ) * max_addrs );
+ if( l->addrs == NULL ) {
+ fprintf( stderr, "<FAIL> malloc of if_addrs array failed\n" );
+ free( l );
+ return NULL;
+ }
+
+ getifaddrs( &ifs );
+ for( ele = ifs; ele; ele = ele->ifa_next ) {
+ if( ele && (inc_lo0 || strcmp( ele->ifa_name, "lo" )) ) {
+ memset( octs, 0, sizeof( octs ) );
+ getnameinfo( ele->ifa_addr, sizeof( struct sockaddr_in6 ), octs, NI_MAXHOST, NULL, 0, NI_NUMERICHOST );
+ if( *octs && l->naddrs < max_addrs ) {
+ l->addrs[l->naddrs] = strdup( ele->ifa_name );
+ l->naddrs++;
+ }
+ }
+ }
+
+ return l;
+}
+
+
+
+// ------------ internal functions to drive various categories of tests --------------------------------------
+
+static int ztbf_test() {
+ int errors = 0;
+ char buf[128];
+ char* sshort = "Stand up and cheer! Cheer long and loud for old Ohio.";
+ char* slong = "Now is the time for the bobcat in the forest to make its way back to Court St for a round of pints at the Pub.";
+ int l1;
+
+ l1 = zt_buf_fill( NULL, sshort, 64 ); // drive for coverage
+ errors += fail_not_equal( l1, -1, "nil check (buf) on zt_buf_fill did not return expected value" );
+ l1 = zt_buf_fill( buf, NULL, 64 );
+ errors += fail_not_equal( l1, -1, "nil check (str) on zt_buf_fill did not return expected value" );
+
+ l1 = zt_buf_fill( buf, sshort, 64 );
+ errors += fail_not_equal( l1, strlen( sshort ), "zt_buf_fill of short buf returned unexpected len" );
+ errors += fail_not_equal( l1, strlen( buf ), "zt_buf_fill of short buf returned len did not match strlen" );
+
+ l1 = zt_buf_fill( buf, slong, 64 );
+ errors += fail_if_equal( l1, strlen( slong ), "zt_buf_fill of long buf returned unexpected len" );
+ errors += fail_not_equal( l1, strlen( buf ), "zt_buf_fill of long buf returned len did not match strlen" );
+
+ l1 = zt_buf_fill( buf, sshort, strlen( sshort ) ); // edge case of exact size
+ errors += fail_not_equal( l1, strlen( sshort )-1, "zt_buf_fill exact length edge case failed" );
+
+ l1 = zt_buf_fill( buf, sshort, 1 ); // unrealistic edge case
+ errors += fail_not_equal( l1, 0, "zt_buf_fill dest len == 1 test failed" );
+
+ return errors;
+}
+
+/*
+ various tokenising tests.
+*/
+static int tok_tests( ) {