Skip to content

Commit

Permalink
Merge branch 'master' into feature/generic-parser-2-cleanup
Browse files Browse the repository at this point in the history
# Conflicts:
#	shared/qcommon/safe/sscanf.h
  • Loading branch information
mrwonko committed Nov 21, 2015
2 parents 142f345 + bad3bbc commit ccd6495
Show file tree
Hide file tree
Showing 10 changed files with 125 additions and 83 deletions.
3 changes: 1 addition & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,6 @@ if(APPLE)
option(MakeApplicationBundles "Whether to build .app application bundles for engines built" ON)
endif()



# Custom CMake Modules needed
list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/CMakeModules")

Expand Down Expand Up @@ -348,5 +346,6 @@ if(WIN32 AND MSVC)
add_subdirectory("tools/WinSymbol")
endif()
if(BuildTests)
enable_testing()
add_subdirectory("tests")
endif()
9 changes: 6 additions & 3 deletions code/qcommon/safe/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,17 +80,20 @@ namespace Zone
using other = Allocator< U, tag >;
};
};

template< typename T >
using UniquePtr = std::unique_ptr< T, Deleter >;

/**
make_unique using Zone Allocations (with appropriate deleter)
*/
template< typename T, memtag_t tag, typename... Args >
inline std::unique_ptr< T, Deleter > make_unique( Args&&... args )
inline UniquePtr< T > make_unique( Args&&... args )
{
std::unique_ptr< void, Deleter > memory( Allocator< T, tag >{}.allocate( 1 ) );
UniquePtr< void > memory( Allocator< T, tag >{}.allocate( 1 ) );
// placement new. may throw, in which case the unique_ptr will take care of freeing the memory.
T* obj = new( memory )T( std::forward< Args >( args )... );
memory.release();
return std::unique_ptr< T, Deleter >( obj );
return UniquePtr< T >( obj );
}
}
87 changes: 54 additions & 33 deletions codemp/client/cl_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ cvar_t *cl_inGameVideo;
cvar_t *cl_serverStatusResendTime;
cvar_t *cl_framerate;

// cvar to enable sending a "ja_guid" player identifier in userinfo to servers
// ja_guid is a persistent "cookie" that allows servers to track players across game sessions
cvar_t *cl_enableGuid;
cvar_t *cl_guidServerUniq;

cvar_t *cl_autolodscale;
Expand Down Expand Up @@ -724,17 +727,32 @@ update cl_guid using QKEY_FILE and optional prefix
*/
static void CL_UpdateGUID( const char *prefix, int prefix_len )
{
fileHandle_t f;
int len;
if (cl_enableGuid->integer) {
fileHandle_t f;
int len;

len = FS_SV_FOpenFileRead( QKEY_FILE, &f );
FS_FCloseFile( f );
len = FS_SV_FOpenFileRead( QKEY_FILE, &f );
FS_FCloseFile( f );

if( len != QKEY_SIZE )
Cvar_Set( "ja_guid", "" );
else
Cvar_Set( "ja_guid", Com_MD5File( QKEY_FILE, QKEY_SIZE,
prefix, prefix_len ) );
// initialize the cvar here in case it's unset or was user-created
// while tracking was disabled (removes CVAR_USER_CREATED)
Cvar_Get( "ja_guid", "", CVAR_USERINFO | CVAR_ROM );

if( len != QKEY_SIZE ) {
Cvar_Set( "ja_guid", "" );
} else {
Cvar_Set( "ja_guid", Com_MD5File( QKEY_FILE, QKEY_SIZE,
prefix, prefix_len ) );
}
} else {
// Remove the cvar entirely if tracking is disabled
uint32_t flags = Cvar_Flags("ja_guid");
// keep the cvar if it's user-created, but destroy it otherwise
if (flags != CVAR_NONEXISTENT && !(flags & CVAR_USER_CREATED)) {
cvar_t *ja_guid = Cvar_Get("ja_guid", "", 0);
Cvar_Unset(ja_guid);
}
}
}

/*
Expand Down Expand Up @@ -2606,34 +2624,36 @@ it by filling it with 2048 bytes of random data.

static void CL_GenerateQKey(void)
{
int len = 0;
unsigned char buff[ QKEY_SIZE ];
fileHandle_t f;
if (cl_enableGuid->integer) {
int len = 0;
unsigned char buff[ QKEY_SIZE ];
fileHandle_t f;

len = FS_SV_FOpenFileRead( QKEY_FILE, &f );
FS_FCloseFile( f );
if( len == QKEY_SIZE ) {
Com_Printf( "QKEY found.\n" );
return;
}
else {
if( len > 0 ) {
Com_Printf( "QKEY file size != %d, regenerating\n",
QKEY_SIZE );
len = FS_SV_FOpenFileRead( QKEY_FILE, &f );
FS_FCloseFile( f );
if( len == QKEY_SIZE ) {
Com_Printf( "QKEY found.\n" );
return;
}
else {
if( len > 0 ) {
Com_Printf( "QKEY file size != %d, regenerating\n",
QKEY_SIZE );
}

Com_Printf( "QKEY building random string\n" );
Com_RandomBytes( buff, sizeof(buff) );
Com_Printf( "QKEY building random string\n" );
Com_RandomBytes( buff, sizeof(buff) );

f = FS_SV_FOpenFileWrite( QKEY_FILE );
if( !f ) {
Com_Printf( "QKEY could not open %s for write\n",
QKEY_FILE );
return;
f = FS_SV_FOpenFileWrite( QKEY_FILE );
if( !f ) {
Com_Printf( "QKEY could not open %s for write\n",
QKEY_FILE );
return;
}
FS_Write( buff, sizeof(buff), f );
FS_FCloseFile( f );
Com_Printf( "QKEY generated\n" );
}
FS_Write( buff, sizeof(buff), f );
FS_FCloseFile( f );
Com_Printf( "QKEY generated\n" );
}
}

Expand Down Expand Up @@ -2736,6 +2756,8 @@ void CL_Init( void ) {

cl_lanForcePackets = Cvar_Get ("cl_lanForcePackets", "1", CVAR_ARCHIVE);

// enable the ja_guid player identifier in userinfo by default in OpenJK
cl_enableGuid = Cvar_Get("cl_enableGuid", "1", CVAR_ARCHIVE);
cl_guidServerUniq = Cvar_Get ("cl_guidServerUniq", "1", CVAR_ARCHIVE);

// ~ and `, as keys and characters
Expand Down Expand Up @@ -2810,7 +2832,6 @@ void CL_Init( void ) {
G2VertSpaceClient = new CMiniHeap (G2_VERT_SPACE_CLIENT_SIZE * 1024);

CL_GenerateQKey();
Cvar_Get( "ja_guid", "", CVAR_USERINFO | CVAR_ROM );
CL_UpdateGUID( NULL, 0 );

// Com_Printf( "----- Client Initialization Complete -----\n" );
Expand Down
2 changes: 2 additions & 0 deletions codemp/qcommon/qcommon.h
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ void Cvar_WriteVariables( fileHandle_t f );
// writes lines containing "set variable value" for all variables
// with the archive flag set to true.

cvar_t *Cvar_Unset(cvar_t *cv);

void Cvar_Init( void );

char *Cvar_InfoString( int bit );
Expand Down
3 changes: 2 additions & 1 deletion shared/qcommon/q_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,9 @@ along with this program; if not, see <http://www.gnu.org/licenses/>.
#define DLL_EXT ".so"
#endif

#if defined( _MSC_VER ) && (_MSC_VER < 1900)
#if (defined( _MSC_VER ) && (_MSC_VER < 1900)) || (defined(__GNUC__))
// VS2013, which for some reason we still support, does not support noexcept
// GCC GNU has the same problem: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52869
#define NOEXCEPT
#define NOEXCEPT_IF(x)
#define IS_NOEXCEPT(x) false
Expand Down
28 changes: 14 additions & 14 deletions shared/qcommon/safe/limited_vector.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,20 +86,6 @@ namespace Q
return maximum;
}

bool push_back( const T& value ) NOEXCEPT_IF( IS_NOEXCEPT(
emplace_back( static_cast< const T& >( std::declval< T >() ) )
) )
{
return emplace_back( value );
}

bool push_back( T&& value ) NOEXCEPT_IF( IS_NOEXCEPT(
emplace_back( std::move( std::declval< T >() ) )
) )
{
return emplace_back( std::move( value ) );
}

template< typename... Args >
bool emplace_back( Args&&... args ) NOEXCEPT_IF( IS_NOEXCEPT(
T{ std::forward< Args >( std::declval< Args >() )... }
Expand All @@ -116,6 +102,20 @@ namespace Q
return true;
}

bool push_back( const T& value ) NOEXCEPT_IF( IS_NOEXCEPT(
emplace_back( static_cast< const T& >( std::declval< T >() ) )
) )
{
return emplace_back( value );
}

bool push_back( T&& value ) NOEXCEPT_IF( IS_NOEXCEPT(
emplace_back( std::move( std::declval< T >() ) )
) )
{
return emplace_back( std::move( value ) );
}

void pop_back() NOEXCEPT
{
if( size() == 0 )
Expand Down
40 changes: 23 additions & 17 deletions shared/qcommon/safe/sscanf.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ namespace Q
{
// it is not written to, but the basic_streambuf interface still wants a non-const CharT.
char* data = const_cast< CharT* >( view.data() );
setg( data, data, data + view.size() );
this->setg( data, data, data + view.size() );
}

protected:
Expand All @@ -124,7 +124,7 @@ namespace Q
newPos += static_cast< int >( off );
if( this->eback() <= newPos && newPos <= this->egptr() )
{
setg( this->eback(), newPos, this->egptr() );
this->setg( this->eback(), newPos, this->egptr() );
return newPos - this->eback();
}
else
Expand All @@ -142,9 +142,29 @@ namespace Q
}

/**
Conversion using std::istream's operator>>
Forward declaration.
*/
template< bool skipws = true, typename T, typename... Tail >
std::size_t sscanf_impl_stream( const gsl::cstring_view& input, const std::size_t accumulator, T& value, Tail&&... tail );

// Float
template< typename... Tail >
std::size_t sscanf_impl( const gsl::cstring_view& input, const std::size_t accumulator, float& f, Tail&&... tail )
{
return sscanf_impl_stream( input, accumulator, f, std::forward< Tail >( tail )... );
}

// Int
template< typename... Tail >
std::size_t sscanf_impl( const gsl::cstring_view& input, const std::size_t accumulator, int& i, Tail&&... tail )
{
return sscanf_impl_stream( input, accumulator, i, std::forward< Tail >( tail )... );
}

/**
Conversion using std::istream's operator>>
*/
template< bool skipws, typename T, typename... Tail >
std::size_t sscanf_impl_stream( const gsl::cstring_view& input, const std::size_t accumulator, T& value, Tail&&... tail )
{
auto buf = MakeStreambuf( input );
Expand All @@ -171,20 +191,6 @@ namespace Q
return accumulator;
}
}

// Float
template< typename... Tail >
std::size_t sscanf_impl( const gsl::cstring_view& input, const std::size_t accumulator, float& f, Tail&&... tail )
{
return sscanf_impl_stream( input, accumulator, f, std::forward< Tail >( tail )... );
}

// Int
template< typename... Tail >
std::size_t sscanf_impl( const gsl::cstring_view& input, const std::size_t accumulator, int& i, Tail&&... tail )
{
return sscanf_impl_stream( input, accumulator, i, std::forward< Tail >( tail )... );
}
}

/**
Expand Down
12 changes: 10 additions & 2 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ source_group( "tests" REGULAR_EXPRESSION ".*")
source_group( "tests\\safe" REGULAR_EXPRESSION "safe/.*" )
source_group( "qcommon\\safe" REGULAR_EXPRESSION "${SharedDir}/qcommon/safe/.*" )

set( Boost_USE_STATIC_LIBS ON )
if(MSVC)
set( Boost_USE_STATIC_LIBS ON )
endif()
find_package( Boost COMPONENTS unit_test_framework REQUIRED )

set(TestTarget "UnitTests")
Expand All @@ -49,10 +51,16 @@ set(TestIncludeDirectories
)
set(TestDefines "${SharedDefines}")


add_executable(${TestTarget} ${TestFiles})
set_target_properties(${TestTarget} PROPERTIES COMPILE_DEFINITIONS "${TestDefines}")
set_target_properties(${TestTarget} PROPERTIES INCLUDE_DIRECTORIES "${TestIncludeDirectories}")
set_target_properties(${TestTarget} PROPERTIES PROJECT_LABEL "Unit Tests")
target_link_libraries(${TestTarget} ${TestLibraries})
install(TARGETS ${TestTarget} DESTINATION ".")

if(NOT MSVC)
#Generate a main function
target_compile_definitions(${TestTarget} PRIVATE BOOST_TEST_DYN_LINK)
endif()

add_test(NAME unittests COMMAND ${TestTarget})
4 changes: 4 additions & 0 deletions tests/main.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
// create default module initialization
#define BOOST_TEST_MODULE OpenJK

// let the boost unit test framework create a main function
#define BOOST_TEST_MAIN

#include <boost/test/unit_test.hpp>
20 changes: 9 additions & 11 deletions tests/safe/limited_vector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@

#include <boost/test/unit_test.hpp>

using namespace std::string_literals;

using IntVector = Q::LimitedVector< int, 10 >;
using StringVector = Q::LimitedVector< std::string, 10 >;
using IntPtrVector = Q::LimitedVector< std::unique_ptr< int >, 10 >;
Expand Down Expand Up @@ -44,18 +42,18 @@ BOOST_AUTO_TEST_CASE( fill_and_copy )

BOOST_CHECK( it != stringVec.end() );
BOOST_CHECK( cit != stringVec.end() );
BOOST_CHECK_EQUAL( *it, "hello world"s );
BOOST_CHECK_EQUAL( *cit, "hello world"s );
BOOST_CHECK_EQUAL( stringVec[ 0 ], "hello world"s );
BOOST_CHECK_EQUAL( *it, "hello world" );
BOOST_CHECK_EQUAL( *cit, "hello world" );
BOOST_CHECK_EQUAL( stringVec[ 0 ], "hello world" );

++it;
++cit;

BOOST_CHECK( it != stringVec.end() );
BOOST_CHECK( cit != stringVec.end() );
BOOST_CHECK_EQUAL( *it, "emplaced"s );
BOOST_CHECK_EQUAL( *cit, "emplaced"s );
BOOST_CHECK_EQUAL( stringVec[ 1 ], "emplaced"s );
BOOST_CHECK_EQUAL( *it, "emplaced" );
BOOST_CHECK_EQUAL( *cit, "emplaced" );
BOOST_CHECK_EQUAL( stringVec[ 1 ], "emplaced" );

++it;
++cit;
Expand Down Expand Up @@ -92,9 +90,9 @@ BOOST_AUTO_TEST_CASE( fill_and_copy )
BOOST_AUTO_TEST_CASE( fill_and_move )
{
IntPtrVector vec1, vec2;
BOOST_CHECK( vec1.push_back( std::make_unique< int >( 42 ) ) );
BOOST_CHECK( vec1.push_back( std::make_unique< int >( 1337 ) ) );
BOOST_CHECK( vec2.push_back( std::make_unique< int >( 0 ) ) );
BOOST_CHECK( vec1.push_back( std::unique_ptr< int >( new int(42) ) ) );
BOOST_CHECK( vec1.push_back( std::unique_ptr< int >( new int(1337) ) ) );
BOOST_CHECK( vec2.push_back( std::unique_ptr< int >( new int(0) ) ) );
BOOST_CHECK( vec2.emplace_back() ); // nullptr3

BOOST_CHECK_EQUAL( vec1.size(), 2 );
Expand Down

0 comments on commit ccd6495

Please sign in to comment.