Added test for bugs 2792371 and 2694060. Cleaned up code.
git-svn-id: svn://svn.code.sf.net/p/loki-lib/code/trunk@1136 7ec92016-0320-0410-acc4-a06ded1c099a
This commit is contained in:
parent
5fdebe2bf7
commit
cda3ef96a2
1 changed files with 370 additions and 138 deletions
|
@ -16,6 +16,8 @@
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#include "../SmallObj/timer.h"
|
#include "../SmallObj/timer.h"
|
||||||
|
|
||||||
|
@ -104,142 +106,7 @@ void TestCase2(const string& fmt, T value, U value2)
|
||||||
assert(s == buf);
|
assert(s == buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
// ----------------------------------------------------------------------------
|
||||||
{
|
|
||||||
|
|
||||||
if (argc == 2)
|
|
||||||
{
|
|
||||||
// test speed
|
|
||||||
|
|
||||||
Timer t;
|
|
||||||
|
|
||||||
int loop = atoi(argv[1]);
|
|
||||||
|
|
||||||
if(loop < 100)
|
|
||||||
loop = 100;
|
|
||||||
|
|
||||||
t.start();
|
|
||||||
for (int i=loop; i > 0; --i)
|
|
||||||
printf("Hey, %u frobnicators and %u twiddlicators\n",i, i);
|
|
||||||
t.stop();
|
|
||||||
t.t100 = t.t();
|
|
||||||
int t_printf = t.t();
|
|
||||||
|
|
||||||
|
|
||||||
t.start();
|
|
||||||
for (int i=loop; i > 0; --i)
|
|
||||||
Printf("Hey, %u frobnicators and %u twiddlicators\n")(i)(i);
|
|
||||||
t.stop();
|
|
||||||
int t_Printf = t.t();
|
|
||||||
|
|
||||||
|
|
||||||
t.start();
|
|
||||||
for (int i=loop; i > 0; --i)
|
|
||||||
cout << "Hey, " << i << " frobnicators and " << i <<" twiddlicators\n";
|
|
||||||
t.stop();
|
|
||||||
int t_cout = t.t();
|
|
||||||
|
|
||||||
|
|
||||||
Printf("\n\nElapsed time for %i outputs\n\n")(loop);
|
|
||||||
t.print(t_printf,"printf : ");
|
|
||||||
t.print(t_Printf,"Printf : ");
|
|
||||||
t.print(t_cout, "std::cout: ");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
//srand(time(0));
|
|
||||||
srand(0);
|
|
||||||
printf("\nNumber of tests:\n");
|
|
||||||
for (unsigned i = 0; ; ++i)
|
|
||||||
{
|
|
||||||
printf("%u\r", i);
|
|
||||||
|
|
||||||
// Generate a random string for the head
|
|
||||||
string lead = RandomString(100);
|
|
||||||
// This string will hold a random format specification
|
|
||||||
string formatSpec(lead + "|%");
|
|
||||||
// Generate a random set of flags
|
|
||||||
static const string flags("-+0 #");
|
|
||||||
size_t maxFlags = RandomInt(0u, flags.length() - 1);
|
|
||||||
for (size_t i = 0; i != maxFlags; ++i)
|
|
||||||
{
|
|
||||||
formatSpec += flags[RandomInt(0u, flags.length() - 1)];
|
|
||||||
}
|
|
||||||
// Generate an optional random width
|
|
||||||
if (RandomInt(0, 1))
|
|
||||||
{
|
|
||||||
const unsigned int width = RandomInt(0, 100);
|
|
||||||
char buf[4];
|
|
||||||
sprintf(buf, "%u", width);
|
|
||||||
formatSpec += buf;
|
|
||||||
}
|
|
||||||
// Generate an optional random precision
|
|
||||||
if (RandomInt(0, 1))
|
|
||||||
{
|
|
||||||
const unsigned int prec = RandomInt(0, 100);
|
|
||||||
char buf[4];
|
|
||||||
sprintf(buf, "%u", prec);
|
|
||||||
formatSpec += '.';
|
|
||||||
formatSpec += buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generate a random type character
|
|
||||||
static const string type("cdeEfgGinopsuxX");
|
|
||||||
|
|
||||||
const char typeSpec = type[RandomInt(0u, type.size() - 1)];
|
|
||||||
// Generate an optional type prefix
|
|
||||||
static const string prefix("hl");
|
|
||||||
if (typeSpec != 's' && RandomInt(0, 1))
|
|
||||||
{
|
|
||||||
formatSpec += prefix[RandomInt(0u, prefix.size() - 1)];
|
|
||||||
}
|
|
||||||
formatSpec += typeSpec;
|
|
||||||
formatSpec += '|';
|
|
||||||
formatSpec += RandomString(100);
|
|
||||||
|
|
||||||
switch (typeSpec)
|
|
||||||
{
|
|
||||||
case 'c':
|
|
||||||
TestCase(formatSpec, RandomInt(1, 127));
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
case 'o':
|
|
||||||
case 'u':
|
|
||||||
case 'x':
|
|
||||||
case 'X':
|
|
||||||
//TestCase(formatSpec, RandomInt(-10000, 10000));
|
|
||||||
// don't test negative values on 64bit systems, because
|
|
||||||
// snprintf does not support 64 Bit values
|
|
||||||
TestCase(formatSpec, RandomInt( -10000 * (sizeof(size_t)>4 ? 0 : 1) , 10000));
|
|
||||||
break;
|
|
||||||
case 'e':
|
|
||||||
case 'E':
|
|
||||||
case 'f':
|
|
||||||
case 'g':
|
|
||||||
case 'G':
|
|
||||||
TestCase(formatSpec,
|
|
||||||
RandomInt(-10000, 10000) / double(RandomInt(1, 100)));
|
|
||||||
break;
|
|
||||||
case 'n':
|
|
||||||
break;
|
|
||||||
case 'p':
|
|
||||||
{
|
|
||||||
void * p = malloc(RandomInt(1, 1000));
|
|
||||||
TestCase(formatSpec, p);
|
|
||||||
free(p);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 's':
|
|
||||||
TestCase(formatSpec, RandomString(100).c_str());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void test_dword()
|
void test_dword()
|
||||||
{
|
{
|
||||||
|
@ -247,14 +114,379 @@ void test_dword()
|
||||||
typedef unsigned int UInt;
|
typedef unsigned int UInt;
|
||||||
typedef signed long Long;
|
typedef signed long Long;
|
||||||
typedef unsigned long ULong;
|
typedef unsigned long ULong;
|
||||||
Int i(0);
|
Int i(0);
|
||||||
UInt ui(0);
|
UInt ui(0);
|
||||||
Long l(0);
|
Long l(0);
|
||||||
ULong ul(0);
|
ULong ul(0);
|
||||||
Printf("%d")(i);
|
Printf("%d")(i);
|
||||||
Printf("%d")(ui);
|
Printf("%d")(ui);
|
||||||
Printf("%d")(l);
|
Printf("%d")(l);
|
||||||
Printf("%d")(ul);
|
Printf("%d")(ul);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void SpeedTest( unsigned int loop )
|
||||||
|
{
|
||||||
|
cout << "Starting SpeedTest" << endl;
|
||||||
|
|
||||||
|
// test speed
|
||||||
|
Timer t;
|
||||||
|
|
||||||
|
if(loop < 100)
|
||||||
|
loop = 100;
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
for (int i=loop; i > 0; --i)
|
||||||
|
printf("Hey, %u frobnicators and %u twiddlicators\n",i, i);
|
||||||
|
t.stop();
|
||||||
|
t.t100 = t.t();
|
||||||
|
int t_printf = t.t();
|
||||||
|
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
for (int i=loop; i > 0; --i)
|
||||||
|
Printf("Hey, %u frobnicators and %u twiddlicators\n")(i)(i);
|
||||||
|
t.stop();
|
||||||
|
int t_Printf = t.t();
|
||||||
|
|
||||||
|
|
||||||
|
t.start();
|
||||||
|
for (int i=loop; i > 0; --i)
|
||||||
|
cout << "Hey, " << i << " frobnicators and " << i <<" twiddlicators\n";
|
||||||
|
t.stop();
|
||||||
|
int t_cout = t.t();
|
||||||
|
|
||||||
|
|
||||||
|
Printf("\n\nElapsed time for %i outputs\n\n")(loop);
|
||||||
|
t.print(t_printf,"printf : ");
|
||||||
|
t.print(t_Printf,"Printf : ");
|
||||||
|
t.print(t_cout, "std::cout: ");
|
||||||
|
|
||||||
|
cout << "Finished SpeedTest" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void FormatTest( void )
|
||||||
|
{
|
||||||
|
cout << "Starting FormatTest" << endl;
|
||||||
|
|
||||||
|
string result;
|
||||||
|
unsigned int i = 1;
|
||||||
|
signed short ss = 2;
|
||||||
|
float f = 3.4;
|
||||||
|
const char * message = " over here! ";
|
||||||
|
|
||||||
|
const char * format = "";
|
||||||
|
::Loki::SPrintf( result, format );
|
||||||
|
assert( result == format );
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "abc";
|
||||||
|
::Loki::SPrintf( result, format );
|
||||||
|
assert( result == format );
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "%%";
|
||||||
|
::Loki::SPrintf( result, format );
|
||||||
|
assert( result == "%" );
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "%d";
|
||||||
|
::Loki::SPrintf( result, format )( i );
|
||||||
|
assert( result == "1" );
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "%s";
|
||||||
|
::Loki::SPrintf( result, format )( message );
|
||||||
|
assert( result == message );
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "%d";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
::Loki::SPrintf( result, format )( i )( message );
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
catch ( const ::std::logic_error & ex )
|
||||||
|
{
|
||||||
|
assert( true );
|
||||||
|
}
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "%d";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
::Loki::SPrintf( result, format )( i )( message )( ss );
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
catch ( const ::std::logic_error & ex )
|
||||||
|
{
|
||||||
|
assert( true );
|
||||||
|
}
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "%d";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
::Loki::SPrintf( result, format )( i )( ss );
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
catch ( const ::std::logic_error & ex )
|
||||||
|
{
|
||||||
|
assert( true );
|
||||||
|
}
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
format = "%d";
|
||||||
|
try
|
||||||
|
{
|
||||||
|
::Loki::SPrintf( result, format )( i )( f );
|
||||||
|
assert( false );
|
||||||
|
}
|
||||||
|
catch ( const ::std::logic_error & ex )
|
||||||
|
{
|
||||||
|
assert( true );
|
||||||
|
}
|
||||||
|
result.clear();
|
||||||
|
|
||||||
|
cout << "Finished FormatTest" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void RandomTest( unsigned int loopCount )
|
||||||
|
{
|
||||||
|
cout << "Starting RandomTest" << endl;
|
||||||
|
if ( loopCount < 100 )
|
||||||
|
loopCount = 100;
|
||||||
|
|
||||||
|
//srand(time(0));
|
||||||
|
srand(0);
|
||||||
|
printf("\nNumber of tests:\n");
|
||||||
|
for ( unsigned int i = 0; i < loopCount; ++i )
|
||||||
|
{
|
||||||
|
printf("%u\r", i);
|
||||||
|
|
||||||
|
// Generate a random string for the head
|
||||||
|
string lead = RandomString(100);
|
||||||
|
// This string will hold a random format specification
|
||||||
|
string formatSpec(lead + "|%");
|
||||||
|
// Generate a random set of flags
|
||||||
|
static const string flags("-+0 #");
|
||||||
|
size_t maxFlags = RandomInt(0u, flags.length() - 1);
|
||||||
|
for (size_t i = 0; i != maxFlags; ++i)
|
||||||
|
{
|
||||||
|
formatSpec += flags[RandomInt(0u, flags.length() - 1)];
|
||||||
|
}
|
||||||
|
// Generate an optional random width
|
||||||
|
if (RandomInt(0, 1))
|
||||||
|
{
|
||||||
|
const unsigned int width = RandomInt(0, 100);
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%u", width);
|
||||||
|
formatSpec += buf;
|
||||||
|
}
|
||||||
|
// Generate an optional random precision
|
||||||
|
if (RandomInt(0, 1))
|
||||||
|
{
|
||||||
|
const unsigned int prec = RandomInt(0, 100);
|
||||||
|
char buf[4];
|
||||||
|
sprintf(buf, "%u", prec);
|
||||||
|
formatSpec += '.';
|
||||||
|
formatSpec += buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate a random type character
|
||||||
|
static const string type("cdeEfgGinopsuxX");
|
||||||
|
|
||||||
|
const char typeSpec = type[RandomInt(0u, type.size() - 1)];
|
||||||
|
// Generate an optional type prefix
|
||||||
|
static const string prefix("hl");
|
||||||
|
if (typeSpec != 's' && RandomInt(0, 1))
|
||||||
|
{
|
||||||
|
formatSpec += prefix[RandomInt(0u, prefix.size() - 1)];
|
||||||
|
}
|
||||||
|
formatSpec += typeSpec;
|
||||||
|
formatSpec += '|';
|
||||||
|
formatSpec += RandomString(100);
|
||||||
|
|
||||||
|
switch (typeSpec)
|
||||||
|
{
|
||||||
|
case 'c':
|
||||||
|
TestCase(formatSpec, RandomInt(1, 127));
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
case 'i':
|
||||||
|
case 'o':
|
||||||
|
case 'u':
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
//TestCase(formatSpec, RandomInt(-10000, 10000));
|
||||||
|
// don't test negative values on 64bit systems, because
|
||||||
|
// snprintf does not support 64 Bit values
|
||||||
|
TestCase(formatSpec, RandomInt( -10000 * (sizeof(size_t)>4 ? 0 : 1) , 10000));
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case 'f':
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
TestCase(formatSpec,
|
||||||
|
RandomInt(-10000, 10000) / double(RandomInt(1, 100)));
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
{
|
||||||
|
void * p = malloc(RandomInt(1, 1000));
|
||||||
|
TestCase(formatSpec, p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
TestCase(formatSpec, RandomString(100).c_str());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << endl << "Finished RandomTest" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CommandLineArgs
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
CommandLineArgs( unsigned int argc, const char * argv[] );
|
||||||
|
|
||||||
|
inline unsigned int GetSpeedLoopCount( void ) const { return m_speedLoopCount; }
|
||||||
|
inline unsigned int GetRandomLoopCount( void ) const { return m_randomLoopCount; }
|
||||||
|
|
||||||
|
inline bool DoSpeedTest( void ) const { return ( 0 < m_speedLoopCount ); }
|
||||||
|
inline bool DoRandomTest( void ) const { return ( 0 < m_randomLoopCount ); }
|
||||||
|
inline bool DoFormatTest( void ) const { return m_doFormatTest; }
|
||||||
|
inline bool DoShowHelp( void ) const { return m_showHelp; }
|
||||||
|
|
||||||
|
void ShowHelp( void ) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
unsigned int m_speedLoopCount;
|
||||||
|
unsigned int m_randomLoopCount;
|
||||||
|
bool m_doFormatTest;
|
||||||
|
bool m_showHelp;
|
||||||
|
const char * m_exeName;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
CommandLineArgs::CommandLineArgs( unsigned int argc, const char * argv[] ) :
|
||||||
|
m_speedLoopCount( 0 ),
|
||||||
|
m_randomLoopCount( 0 ),
|
||||||
|
m_doFormatTest( false ),
|
||||||
|
m_showHelp( false ),
|
||||||
|
m_exeName( argv[0] )
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( argc < 2 )
|
||||||
|
{
|
||||||
|
m_showHelp = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isValid = true;
|
||||||
|
for ( unsigned int ii = 1; ( isValid ) && ( ii < argc ); ++ii )
|
||||||
|
{
|
||||||
|
const char * arg = argv[ii];
|
||||||
|
const unsigned int length = ::strlen( arg );
|
||||||
|
if ( ( '-' != *arg ) || ( length < 2 ) )
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( arg[1] )
|
||||||
|
{
|
||||||
|
default: isValid = false; break;
|
||||||
|
case 'h': m_showHelp = true; break;
|
||||||
|
case 'f': m_doFormatTest = true; break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
{
|
||||||
|
if ( ( length < 3 ) || ( ':' != arg[2] ) || ( 0 == isdigit( arg[3] ) ) )
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_randomLoopCount = ::atoi( arg + 3 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
{
|
||||||
|
if ( ( length < 3 ) || ( ':' != arg[2] ) || ( 0 == isdigit( arg[3] ) ) )
|
||||||
|
{
|
||||||
|
isValid = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_speedLoopCount = ::atoi( arg + 3 );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !isValid )
|
||||||
|
{
|
||||||
|
m_showHelp = true;
|
||||||
|
m_speedLoopCount = 0;
|
||||||
|
m_randomLoopCount = 0;
|
||||||
|
m_doFormatTest = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void CommandLineArgs::ShowHelp( void ) const
|
||||||
|
{
|
||||||
|
cout << "Usage: " << m_exeName << " [-h] [-f] [-r:#] [-s:#]" << endl;
|
||||||
|
cout << " -h Show this help info and exit. Overrides all other options." << endl;
|
||||||
|
cout << " -f Run formatting tests." << endl;
|
||||||
|
cout << " -r:# Run random tests for # of loops. # is a positive decimal value greater than 100." << endl;
|
||||||
|
cout << " -s:# Run speed tests for # of loops. # is a positive decimal value greater than 100." << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
int main( int argc, const char * argv[] )
|
||||||
|
{
|
||||||
|
|
||||||
|
const CommandLineArgs args( argc, argv );
|
||||||
|
|
||||||
|
if ( args.DoShowHelp() )
|
||||||
|
{
|
||||||
|
args.ShowHelp();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( args.DoSpeedTest() )
|
||||||
|
{
|
||||||
|
SpeedTest( args.GetSpeedLoopCount() );
|
||||||
|
}
|
||||||
|
if ( args.DoRandomTest() )
|
||||||
|
{
|
||||||
|
RandomTest( args.GetRandomLoopCount() );
|
||||||
|
}
|
||||||
|
if ( args.DoFormatTest() )
|
||||||
|
{
|
||||||
|
FormatTest();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in a new issue