This commit is contained in:
jeanlemotan
2024-07-02 18:10:39 +02:00
commit 48ab06b1d9
733 changed files with 321088 additions and 0 deletions
+4
View File
@@ -0,0 +1,4 @@
tags
.p4config
build.bat
/build/
+18
View File
@@ -0,0 +1,18 @@
[submodule "test/packages/EAMain"]
path = test/packages/EAMain
url = git@github.com:electronicarts/EAMain.git
[submodule "test/packages/EATest"]
path = test/packages/EATest
url = git@github.com:electronicarts/EATest.git
[submodule "test/packages/EAStdC"]
path = test/packages/EAStdC
url = git@github.com:electronicarts/EAStdC.git
[submodule "test/packages/EAThread"]
path = test/packages/EAThread
url = git@github.com:electronicarts/EAThread.git
[submodule "test/packages/EASTL"]
path = test/packages/EASTL
url = git@github.com:electronicarts/EASTL.git
[submodule "test/packages/EABase"]
path = test/packages/EABase
url = git@github.com:electronicarts/EABase.git
+71
View File
@@ -0,0 +1,71 @@
language: cpp
cache:
- ccache: true
os:
- linux
- osx
- windows
compiler:
- gcc
- clang
- msvc
env:
- EA_CONFIG=Debug
- EA_CONFIG=Release
addons:
apt:
sources:
- ubuntu-toolchain-r-test
- george-edison55-precise-backports
- llvm-toolchain-trusty-7
packages:
- cmake
- cmake-data
- g++-7
- clang-7
matrix:
exclude:
- os: osx
compiler: gcc
- os: osx
compiler: msvc
- os: linux
compiler: msvc
- os: windows
compiler: clang
- os: windows
compiler: gcc
# Handle git submodules yourself
git:
submodules: false
# Use sed to replace the SSH URL with the public URL, then initialize submodules
before_install:
- sed --version >/dev/null 2>&1 && sed -i 's/git@github.com:/https:\/\/github.com\//' .gitmodules || sed -i "" 's/git@github.com:/https:\/\/github.com\//' .gitmodules
- git submodule update --init
install:
- if [[ "$CXX" == "g++" ]]; then export CC="gcc-7" ;fi
- if [[ "$CXX" == "g++" ]]; then export CXX="g++-7" ;fi
- if [[ "$CXX" == "clang++" && "${TRAVIS_OS_NAME}" != "osx" ]]; then export CC="clang-7" ;fi
- if [[ "$CXX" == "clang++" && "${TRAVIS_OS_NAME}" != "osx" ]]; then export CXX="clang++-7" ;fi
# Universal Setup
before_script:
- mkdir build_$EA_CONFIG
- cd build_$EA_CONFIG
- cmake .. -DEAASSERT_BUILD_TESTS:BOOL=ON
- cmake --build . --config $EA_CONFIG
script:
# Run Tests
- cd $TRAVIS_BUILD_DIR/build_$EA_CONFIG/test
- ctest -C $EA_CONFIG -V || exit 1
+45
View File
@@ -0,0 +1,45 @@
#-------------------------------------------------------------------------------------------
# Copyright (C) Electronic Arts Inc. All rights reserved.
#-------------------------------------------------------------------------------------------
cmake_minimum_required(VERSION 3.1)
project(EAAssert CXX)
#-------------------------------------------------------------------------------------------
# Options
#-------------------------------------------------------------------------------------------
option(EAASSERT_BUILD_TESTS "Enable generation of build files for tests" OFF)
#-------------------------------------------------------------------------------------------
# Compiler Flags
#-------------------------------------------------------------------------------------------
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/test/packages/EASTL/scripts/CMake")
include(CommonCppFlags)
#-------------------------------------------------------------------------------------------
# Library definition
#-------------------------------------------------------------------------------------------
file(GLOB EAASSERT_SOURCES "source/*.cpp")
add_library(EAAssert ${EAASSERT_SOURCES})
#-------------------------------------------------------------------------------------------
# Package Tests
#-------------------------------------------------------------------------------------------
if(EAASSERT_BUILD_TESTS)
add_subdirectory(test)
endif()
#-------------------------------------------------------------------------------------------
# Defines
#-------------------------------------------------------------------------------------------
add_definitions(-D_CHAR16T)
#-------------------------------------------------------------------------------------------
# Export Include Directories
#-------------------------------------------------------------------------------------------
target_include_directories(EAAssert PUBLIC include)
#-------------------------------------------------------------------------------------------
# Package Dependencies
#-------------------------------------------------------------------------------------------
target_link_libraries(EAAssert EABase)
+72
View File
@@ -0,0 +1,72 @@
## Contributing
Before you can contribute, EA must have a Contributor License Agreement (CLA) on file that has been signed by each contributor.
You can sign here: [Go to CLA](https://electronicarts.na1.echosign.com/public/esignWidget?wid=CBFCIBAA3AAABLblqZhByHRvZqmltGtliuExmuV-WNzlaJGPhbSRg2ufuPsM3P0QmILZjLpkGslg24-UJtek*)
### Pull Request Policy
All code contributions are submitted as [Github pull requests](https://help.github.com/articles/using-pull-requests/). All pull requests will be reviewed by a maintainer according to the guidelines found in the next section.
Your pull request should:
* merge cleanly
* come with tests
* tests should be minimal and stable
* fail before your fix is applied
* pass the test suite
* code formatting is encoded in clang format
* limit using clang format on new code
* do not deviate from style already established in the files
### Running the Unit Tests
EAAssert uses CMake as its build system.
* Create and navigate to "your_build_folder":
* mkdir your_build_folder && cd your_build_folder
* Generate build scripts:
* cmake source_folder -DEAASSERT_BUILD_TESTS:BOOL=ON
* Build unit tests for "your_config":
* cmake --build . --config your_config
* Run the unit tests for "your_config" from the test folder:
* cd test && ctest -C your_config
Here is an example batch file.
```batch
set build_folder=out
mkdir %build_folder%
pushd %build_folder%
call cmake .. -DEAASSERT_BUILD_TESTS:BOOL=ON
call cmake --build . --config Release
call cmake --build . --config Debug
call cmake --build . --config RelWithDebInfo
call cmake --build . --config MinSizeRel
pushd test
call ctest -C Release
call ctest -C Debug
call ctest -C RelWithDebInfo
call ctest -C MinSizeRel
popd
popd
```
Here is an example bash file
```bash
build_folder=out
mkdir $build_folder
pushd $build_folder
cmake .. -DEAASSERT_BUILD_TESTS:BOOL=ON
cmake --build . --config Release
cmake --build . --config Debug
cmake --build . --config RelWithDebInfo
cmake --build . --config MinSizeRel
pushd test
ctest -C Release
ctest -C Debug
ctest -C RelWithDebInfo
ctest -C MinSizeRel
popd
popd
```
+2
View File
@@ -0,0 +1,2 @@
(C) Electronic Arts. All rights reserved.
+27
View File
@@ -0,0 +1,27 @@
/*
Copyright (C) 2017 Electronic Arts Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Electronic Arts, Inc. ("EA") nor the names of
its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY ELECTRONIC ARTS AND ITS CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL ELECTRONIC ARTS OR ITS CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+25
View File
@@ -0,0 +1,25 @@
# EAAssert
[![Build Status](https://travis-ci.org/electronicarts/EAAssert.svg?branch=master)](https://travis-ci.org/electronicarts/EAAssert)
EAAssert is a simple and lightweight assert technology.
## Documentation
Please see [Introduction](https://rawgit.com/electronicarts/EAAssert/master/doc/eaassert.html).
## Compiling sources
Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details on compiling and testing the source.
## Credits
Roberto Parolin is the current EAAssert owner within EA and is responsible for the open source repository.
## License
Modified BSD License (3-Clause BSD license) see the file LICENSE in the project root.
+217
View File
@@ -0,0 +1,217 @@
<html>
<title>EA Assert</title>
<body>
<font face="tahoma">
<h1>EA Assert</h1>
<hr>
A simple lightweight package. Use...
<font color="#0000FF"><pre>
#include "EAAssert/eaassert.h"
</pre></font>
And get the following macros...
<ul>
<li>
<code><font color="#FF00EE">EA_ASSERT(expr)</font></code> where <code><font color="#000099">
expr</font></code> is an expression that evaluates to a boolean. For
example... <font color="#000099">
<pre> EA_ASSERT(3 != 5);</pre>
</font>
<li>
<code><font color="#FF00EE">EA_ASSERT_MSG(expr, msg)</font></code> where <code><font color="#000099">
msg</font></code> is an string (i.e., a <code><font color="#000099">char*</font></code>).
For example... <font color="#000099">
<pre> EA_ASSERT_MSG(3 != 5, "mathematics is flawed");</pre>
</font>
<li>
<code><font color="#FF00EE">EA_ASSERT_FORMATTED(expr, fmt)</font></code> where <code>
<font color="#000099">fmt</font></code> is a parentheses wrapped tuple of
which the first parameter is a string (i.e., a <code><font color="#000099">char*</font></code>)
and the rest are <code><font color="#000099">printf</font></code> style
parameters. For example... <font color="#000099">
<pre> EA_ASSERT_FORMATTED(3 != 5, ("The answer is: %d", 42));</pre>
</font>
<li>
<code><font color="#FF00EE">EA_FAIL()</font></code> similar to <code><font color="#000099">
EA_ASSERT(false)</font></code>
but avoids warning of constant conditional expression.
<li>
<code><font color="#FF00EE">EA_FAIL_MSG(msg)</font></code> similar to <code><font color="#000099">
EA_ASSERT_MSG(false, msg);</font></code>
<li>
<code><font color="#FF00EE">EA_FAIL_FORMATTED(fmt)</font></code> similar to <code><font color="#000099">
EA_ASSERT_FORMATTED(false, fmt);</font></code></li>
</ul>
For compatibility reasons (with existing EATrace practice), there are synonyms for <font color="#FF00EE">EA_ASSERT_MSG</font>, defined as <font color="#FF00EE">EA_ASSERT_MESSAGE</font> and <font color="#FF00EE">EA_ASSERT_M</font>.
<hr>
<h2>Enabling and Disabling</h2>
Whether or not <code><font color="#000099">EA_ASSERT</font></code> is enabled hinges on the following logic...
<font color="#000099">
<pre>
#ifdef EA_DEBUG
#define EA_ASSERT_ENABLED
#endif
#ifndef EA_ASSERT
#if EA_ASSERT_ENABLED
#define EA_ASSERT(expr) ...definition of EA_ASSERT...
#else
#define EA_ASSERT(expr) ((void)0)
#endif
#endif
</pre>
</font>
<hr />
<h2>Design Considerations</h2>
Below are some thoughts that went into the creation of this package...
<ul>
<li>Aim to be lightweight and simple.</li>
<li>Become the single most used ubiquitous assert technology, along EA Base lines.</li>
<li>Have minimal dependencies; e.g. EA Base only.</li>
<li>Ability for users to override functionality.</li>
<li>Ability for users to redirect assertions to their application's given system.</li>
<li>Ability for users to extend the system.</li>
<li>Enable users to rebuild other technology but have it use their assert system.</li>
<li>Make it easy to supply your own assert-failure callback function, but...
<ul>
<li>...don't enforce a link-time definition (i.e., provide a default)</li>
<li>...don't require a global #define.</li>
</ul>
The result is that we require a CPP file (and resulting library) where we can declare and store a function pointer that points to the current assert handler.</li>
</ul>
<hr />
<h2>Integration</h2>
<p>To use <code><font color="#000099">EA_ASSERT</font></code> in your own code you just include the header and use it.</p>
<p>To overwrite the default handler for assert failure, you need to implement the following function <font color="#000099">
<pre>
bool EAAssertFailure(
const char* expr, <font color=#009900>// Stringized version of the assert expression.</font>
const char* filename, <font color=#009900>// Name of the file in which the assert occured.</font>
int line, <font color=#009900>// Line number on which the assert occured.</font>
const char* function, <font color=#009900>// Name of the function the assert occured in.</font>
const char* msg, <font color=#009900>// Optional descriptive message.</font>
va_list args <font color=#009900>// Variable argument list (printf style) in case msg contains formatters.</font>
);
</pre>
</font>The return value of this function should be <code><font color="#000099">true</font></code>
if you want the failed assert to break into the debugger and <code><font color="#000099">
false</font></code>
if you want to continue running past the assert.
<p>To enable the use of this function, use:<font color="#000099">
<pre>
EA::Assert::SetFailureCallback(&yourCallback);
</pre>
</font>
</p>
<P>The simplest possible implementation of this function (which happens to be the default) just returns <code><font color="#000099">true</font></code> immediately, always triggering a debug break.</P>
<p>
For reference, here's an example implementation of <code><font color="#000099">EAAssertFailure</font></code>
that you can copy paste into your own code. <font color="#000099">
<pre>
bool EAAssertFailure(const char* expr, const char* filename, int line, const char* function, const char* msg, va_list args)
{
const int size = 1024;
char output[size + 1] = {};
char fmtMsg[size + 1] = {};
_vsnprintf(fmtMsg, size, msg, args);
_snprintf(output, size, "%s(%d) : assert failed: '%s' in function: %s\n, message: %s", filename, line, expr, function, fmtMsg);
printf(output);
return true;
}
</pre>
</font>
<P></P>
<h3>If You already Have Your Own Asserts</h3>
If you already have your own asserts and would like other technology to use
yours, you can easily forward <code><font color="#000099">EA_ASSERT</font></code>
to your own implementation. The trick is in the <code><font color="#000099">#EA_ASSERT_HAVE_OWN_HEADER</font></code>
macro. Define this to the name of your own header file that has equivalents of
the macros defined above (make sure you provide all of them). For example, you
could put the following in a file called "game/my_own_awesome_assert.h"... <font color="#000099">
<pre>
#define EA_ASSERT(expr) MY_OWN_AWESOME_ASSERT(expr)
#define EA_ASSERT_MSG(expr, msg) MY_OWN_AWESOME_ASSERT(expr)
#define EA_ASSERT_FORMATTED(expr, fmt) MY_OWN_AWESOME_ASSERT(expr)
#define EA_FAIL() MY_OWN_AWESOME_ASSERT(false)
#define EA_FAIL_MSG(msg) MY_OWN_AWESOME_ASSERT(false)
#define EA_FAIL_FORMATTED(fmt) MY_OWN_AWESOME_ASSERT(false)
</pre>
</font>Next, define <code><font color="#000099">#EA_ASSERT_HAVE_OWN_HEADER</font></code>
to <code><font color="#000099">"game/my_own_awesome_assert.h"</font></code> (including
the quotes) when you build <code><font color="#000099">EA_ASSERT</font></code> using
technology and it will automatically use your assert instead.
<hr>
<h2>Frequently Asked Questions</h2>
<ul>
<li>
<b>Why don't you supply <code><font color="#000099">EA_WARNING</font></code> macros?</b><p>Because
few people can use warnings properly. This often results in games spewing so
much output to the console that nobody cares anymore. If the problem is serious
enough, just assert. If it's not serious enough, put a bright pink texture on
it in the game.</p>
<li>
<b>But I really need <code><font color="#000099">EA_WARNING</font></code>, can't
you add it?</b><p>The truth is, the original author of this package didn't need
them. Warning support would increase the complexity of this package of
proportion (now you need warning levels, etc.) If you need warnings, write your
own.</p>
<li>
<b>I already have my own definitions of the <code><font color="#000099">EA_ASSERT</font></code>
macro and others, now what?</b><p>Use the <code><font color="#000099">EA_ASSERT_HAVE_OWN_HEADER</font></code>
feature described above. Now any library that uses <code><font color="#000099">EA_ASSERT</font></code>
automatically leverages your assert.</p>
<li>
<b>I need multilevel asserts, only enabling some when I really need to. Can you add
it?</b><p>This often occurs when you have asserts in a tight inner loop that
you only want enabled every now and then when you do very strict integrity
checking. Unfortunately it would complicate this library too much. We don't
feel enough technologies have a need for this. Fortunately you can implement
this yourself fairly easily by doing... <font color="#000099">
<pre>
#if MY_TECH_DEBUG_LEVEL == 1
#define MY_TECH_ASSERT(expr) EA_ASSERT(expr)
#define MY_TECH_HARDCORE_ASSERT(expr) ((void)0)
#else if MY_TECH_DEBUG_LEVEL == 1
#define MY_TECH_ASSERT(expr) EA_ASSERT(expr)
#define MY_TECH_HARDCORE_ASSERT(expr) EA_ASSERT(expr)
#endif
</pre>
</font>That way you can still leverage <code><font color="#000099">EA_ASSERT</font></code>
but have more fine grained control over assert subsets in your technology.
<P></P>
<li>
<b>Why aren't your asserts ignorable?</b><p>Because it would make things more
complicated than I'd like. Furthermore, ignorable asserts often flawed. People
end up using them to signal user errors that should be handled differently
(proper fallback mechanisms, bright pink textures, etc.). What happens is that
everybody starts ignoring asserts when they happen rather than fixing them or
reporting them. You get away with this for a while, until one day shit hits the
fan. Asserts are for programmer error, exceptions and other mechanisms are for
user error.</p>
<p>That said if you desperately need ignorable asserts, all is not lost. Either use
the <code><font color="#000099">#EA_ASSERT_HAVE_OWN_HEADER</font></code> feature,
or simply catch the filename and line-number in the handler function. Stick
them as a pair into a set. Whenever you find them in the set, return false from
the assert handler to ignore the assert.</p>
<li>
<b>Why isn't platform X supported?</b><p>I don't know. Let me know what its
break-into-debugger statement is and I'll gladly add it.</p>
<li>
<b>Why don't you have feature X?</b><p>Probably because I didn't need it.
Alternatively, because it would make this package more complicated than I'd
like. Perhaps feature X is best implemented in your own technology? Of course,
you can always try sending us an email. Maybe we'll add feature X.</p>
</li>
</ul>
<hr />
<h2>Acknowledgements</h2>
Input for this package came from Paul Pedriana, Ian Davids, James Fairweather, Max Burke, Bob Summerwill and others.
</font>
</body>
</html>
@@ -0,0 +1,538 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
#if defined(EA_PRAGMA_ONCE_SUPPORTED)
#pragma once // Some compilers (e.g. VC++) benefit significantly from using this. We've measured 3-4% build speed improvements in apps as a result.
#endif
#ifndef EAASSERT_EAASSERT_H
#define EAASSERT_EAASSERT_H
// Users can #define EA_ASSERT_HAVE_OWN_HEADER to their own header file and provide their
// own definition of EA_ASSERT. Make sure to include quotes in your
// definition, i.e. #define EA_ASSERT_HAVE_OWN_HEADER "my_game/my_game_assert.h"
//
// At minimum, this header needs to provide the following:
//
// EA_ASSERT(expr)
// EA_ASSERT_MSG(expr, msg)
// EA_ASSERT_FORMATTED(expr, fmt)
// EA_FAIL()
// EA_FAIL_MSG(msg)
// EA_FAIL_FORMATTED(fmt)
// EA_COMPILETIME_ASSERT(expr) Note: EABase (2.0.21 and later) has static_assert which should now be used in place of this.
// EA_PANIC(expr)
// EA_PANIC_MSG(expr, msg)
// EA_PANIC_FORMATTED(expr, fmt)
//
// Where:
//
// expr is an expression that evaluates to a boolean
// msg is a string (char*)
// fmt is a tuple wrapped in parentheses where the first message is
// a formatted string (char*) and the rest is printf style parameters
//
#ifdef EA_ASSERT_HAVE_OWN_HEADER
#include EA_ASSERT_HAVE_OWN_HEADER
#else // The user did not supply their own assert definition, so we'll use ours instead
#include "EABase/eabase.h"
#include <stdarg.h>
// The default assert handling mechanism just breaks into the debugger on an assert failure. If you wish to overwrite this
// functionality, simply implement the following callback:
//
// bool EAAssertFailure(
// const char* expr,
// const char* filename,
// int line,
// const char* function,
// const char* msg,
// va_list args)
//
// And then use:
//
// EA::Assert::SetCallback(&yourCallback);
//
#if defined(EA_DLL) && defined(_MSC_VER)
#ifndef EA_ASSERT_API
#define EA_ASSERT_API __declspec(dllimport)
#endif
#else
#define EA_ASSERT_API
#endif
#ifdef __cplusplus
namespace EA {
namespace Assert {
typedef bool (*FailureCallback)(const char*, const char*, int, const char*, const char*, va_list);
EA_ASSERT_API FailureCallback GetFailureCallback();
EA_ASSERT_API void SetFailureCallback(FailureCallback failureCallback);
namespace Detail {
EA_ASSERT_API bool VCall(const char *expr, const char *filename, int line, const char *function, const char *msg, ...);
EA_ASSERT_API bool Call(const char *expr, const char *filename, int line, const char *function, const char *msg);
EA_ASSERT_API bool Call(const char *expr, const char *filename, int line, const char *function);
}}}
#endif
///////////////////////////////////////////////////////////////////////////////
/// EA_DEBUG_BREAK
///
/// This function causes an app to immediately stop under the debugger.
/// It is implemented as a macro in order to all stopping at the site
/// of the call.
///
/// Example usage:
/// EA_DEBUG_BREAK();
///
/// The EA_DEBUG_BREAK function must be implemented on a per-platform basis.
/// On a PC, you would normally define this to function to be the inline
/// assembly: "asm int 3", which tells the debugger to stop here immediately.
/// A very basic platform-independent implementation of EA_DEBUG_BREAK could
/// be the following:
/// void EA_DEBUG_BREAK()
/// {
/// atoi(""); // Place a breakpoint here if you want to catch breaks.
/// }
///
/// The EA_DEBUG_BREAK default behaviour here can be disabled or changed by
/// globally defining EA_DEBUG_BREAK_DEFINED and implementing an alternative
/// implementation of it. Our implementation here doesn't simply always have
/// it be defined externally because a major convenience of EA_DEBUG_BREAK
/// being inline is that it stops right on the troublesome line of code and
/// not in another function.
///
#if ! defined EA_DEBUG_BREAK && ! defined EA_DEBUG_BREAK_DEFINED
#if defined(EA_PLATFORM_SONY) && defined(EA_PROCESSOR_X86_64)
#define EA_DEBUG_BREAK() do { { __asm volatile ("int $0x41"); } } while(0)
#elif defined _MSC_VER
#define EA_DEBUG_BREAK() __debugbreak()
#elif EA_COMPILER_HAS_BUILTIN(__builtin_debugtrap)
#define EA_DEBUG_BREAK() __builtin_debugtrap()
#elif (defined(EA_PROCESSOR_X86) || defined(EA_PROCESSOR_X86_64)) && defined(__GNUC__)
// Using __asm__ here instead of asm is more compatible with clang when compiling in c99 mode.
#define EA_DEBUG_BREAK() __asm__("int3")
#elif defined(EA_PROCESSOR_ARM64) && defined(__GNUC__)
#define EA_DEBUG_BREAK() asm("brk 10")
#elif defined(EA_PROCESSOR_ARM) && defined(__APPLE__)
#include <signal.h>
#include <unistd.h>
#define EA_DEBUG_BREAK() kill( getpid(), SIGINT )
#elif defined(EA_PROCESSOR_ARM) && defined(__GNUC__)
#define EA_DEBUG_BREAK() asm("BKPT 10") // The 10 is arbitrary. It's just a unique id.
#elif defined(EA_PROCESSOR_ARM) && defined(__ARMCC_VERSION)
#define EA_DEBUG_BREAK() __breakpoint(10)
#else
#define EA_DEBUG_BREAK() *(int*)(0) = 0
#endif
#define EA_DEBUG_BREAK_DEFINED
#endif
///////////////////////////////////////////////////////////////////////////////
/// EA_CRASH
///
/// Executes an invalid memory write, which should result in an exception
/// on most platforms.
///
#if !defined(EA_CRASH) && !defined(EA_CRASH_DEFINED)
#define EA_CRASH() *(volatile int*)(0) = 0
#define EA_CRASH_DEFINED
#endif
///////////////////////////////////////////////////////////////////////////////
/// EA_CURRENT_FUNCTION
///
/// Provides a consistent way to get the current function name as a macro
/// like the __FILE__ and __LINE__ macros work. The C99 standard specifies
/// that __func__ be provided by the compiler, but most compilers don't yet
/// follow that convention. However, many compilers have an alternative.
///
/// We also define EA_CURRENT_FUNCTION_SUPPORTED for when it is not possible
/// to have EA_CURRENT_FUNCTION work as expected.
///
/// Defined inside a function because otherwise the macro might not be
/// defined and code below might not compile. This happens with some
/// compilers.
///
#ifndef EA_CURRENT_FUNCTION
#if defined __GNUC__ || (defined __ICC && __ICC >= 600)
#define EA_CURRENT_FUNCTION __PRETTY_FUNCTION__
#elif defined(__FUNCSIG__)
#define EA_CURRENT_FUNCTION __FUNCSIG__
#elif (defined __INTEL_COMPILER && __INTEL_COMPILER >= 600) || (defined __IBMCPP__ && __IBMCPP__ >= 500) || (defined CS_UNDEFINED_STRING && CS_UNDEFINED_STRING >= 0x4200)
#define EA_CURRENT_FUNCTION __FUNCTION__
#elif defined __BORLANDC__ && __BORLANDC__ >= 0x550
#define EA_CURRENT_FUNCTION __FUNC__
#elif defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901
#define EA_CURRENT_FUNCTION __func__
#else
#define EA_CURRENT_FUNCTION "(unknown function)"
#endif
#endif
#ifdef __cplusplus
namespace EA {
namespace Assert {
namespace Detail
{
// The Forwarder class is deprecated on compilers that support variadic macros. Avoiding
// the temporary instances created by this code can result in significant code size savings.
// Code outside of the EAAssert library shouldn't be referencing API in the Detail namespace.
#ifdef EA_COMPILER_NO_VARIADIC_MACROS
#define EA_ASSERT_PREFIX_DEPRECATED
#define EA_ASSERT_POSTFIX_DEPRECATED
#else
#define EA_ASSERT_PREFIX_DEPRECATED EA_PREFIX_DEPRECATED
#define EA_ASSERT_POSTFIX_DEPRECATED EA_POSTFIX_DEPRECATED
#endif
struct Forwarder
{
const char* mExpr;
const char* mFunction;
const char* mFilename;
int mLine;
Forwarder(const char* expr, const char* filename, int line, const char* function) : mExpr(expr), mFunction(function), mFilename(filename), mLine(line) {}
EA_ASSERT_PREFIX_DEPRECATED bool Call(const char* msg, ...) const EA_ASSERT_POSTFIX_DEPRECATED
{
va_list args;
va_start(args, msg);
bool ret = (*GetFailureCallback())(mExpr, mFilename, mLine, mFunction, msg, args);
va_end(args);
return ret;
}
};
#ifdef EA_COMPILER_NO_VARIADIC_MACROS
#define EA_ASSERT_FORMATTED_HANDLER_CALL(EXPR, FILE, LINE, FUNCTION, FMT) EA::Assert::Detail::Forwarder(EXPR, FILE, LINE, FUNCTION).Call FMT
#else
#define EA_ASSERT_FORMATTED_HANDLER_CALL(EXPR, FILE, LINE, FUNCTION, FMT) EA::Assert::Detail::VCall(EXPR, FILE, LINE, FUNCTION, EA_ASSERT_EXPAND_VA_ARGS FMT)
#define EA_ASSERT_EXPAND_VA_ARGS(...) __VA_ARGS__
#endif
}}}
#endif
///////////////////////////////////////////////////////////////////////////////
/// EA_COMPILETIME_ASSERT
///
/// EA_COMPILETIME_ASSERT is a macro for compile time assertion checks, useful for
/// validating *constant* expressions. The advantage over using the ASSERT,
/// VERIFY, etc. macros is that errors are caught at compile time instead
/// of runtime.
///
/// This EA_COMPILETIME_ASSERT has a weakness in that when used at global scope (outside
/// functions) there can be two such statements on the same line of a given
/// file and some compilers might complain about this.
///
/// Example:
/// EA_COMPILETIME_ASSERT(sizeof(int) == 4);
///
#ifndef EA_COMPILETIME_ASSERT
#if defined(EA_COMPILER_EDG) || defined(EA_COMPILER_CLANG)
// Ideally static_assert would be used wherever possible because it allows for improved error reporting.
// However, using static_assert with Clang currently breaks code using EAOffsetOf. We need to fix this
// macro on clang before enabling the use of static_assert.
#define EAASSERT_TOKEN_PASTE(a,b) a ## b
#define EAASSERT_CONCATENATE_HELPER(a,b) EAASSERT_TOKEN_PASTE(a,b)
#define EA_COMPILETIME_ASSERT(expr) \
EA_DISABLE_CLANG_WARNING(-Wunknown-pragmas); /* Disable warnings about unknown pragmas in case -Wunused-local-typedefs is not supported*/ \
EA_DISABLE_CLANG_WARNING(-Wunused-local-typedef); \
typedef char EAASSERT_CONCATENATE_HELPER(compileTimeAssert,__LINE__) [((expr) != 0) ? 1 : -1]; \
EA_RESTORE_CLANG_WARNING() \
EA_RESTORE_CLANG_WARNING()
#else
#define EA_COMPILETIME_ASSERT(expr) static_assert(expr, EA_STRINGIFY(expr))
#endif
#endif
#ifndef EA_CT_ASSERT
#define EA_CT_ASSERT EA_COMPILETIME_ASSERT
#endif
#ifdef EA_DEBUG
#ifndef EA_ASSERT_ENABLED
#define EA_ASSERT_ENABLED 1
#endif
#ifndef EA_PANIC_ENABLED
#define EA_PANIC_ENABLED 1
#endif
#endif
#ifdef EA_ASSERT_ENABLED
#ifdef __cplusplus
#ifndef EA_ASSERT
#define EA_ASSERT(expr) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr) && EA::Assert::Detail::Call(#expr, __FILE__, __LINE__, EA_CURRENT_FUNCTION)) \
EA_DEBUG_BREAK(); \
else \
((void)0);\
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_ASSERT_MSG
#define EA_ASSERT_MSG(expr, msg) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr) && EA::Assert::Detail::Call(#expr, __FILE__, __LINE__, EA_CURRENT_FUNCTION, msg)) \
EA_DEBUG_BREAK(); \
else \
((void)0);\
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_ASSERT_FORMATTED
#define EA_ASSERT_FORMATTED(expr, fmt) if (!(expr) && EA_ASSERT_FORMATTED_HANDLER_CALL(#expr, __FILE__, __LINE__, EA_CURRENT_FUNCTION, fmt)) EA_DEBUG_BREAK(); else ((void)0)
#endif
#ifndef EA_FAIL
#define EA_FAIL() if ( EA::Assert::Detail::Call("EA_FAIL", __FILE__, __LINE__, EA_CURRENT_FUNCTION)) EA_DEBUG_BREAK(); else ((void)0)
#endif
#ifndef EA_FAIL_MSG
#define EA_FAIL_MSG(msg) if ( EA::Assert::Detail::Call("EA_FAIL", __FILE__, __LINE__, EA_CURRENT_FUNCTION, msg)) EA_DEBUG_BREAK(); else ((void)0)
#endif
#ifndef EA_FAIL_FORMATTED
#define EA_FAIL_FORMATTED(fmt) if (EA_ASSERT_FORMATTED_HANDLER_CALL("EA_FAIL", __FILE__, __LINE__, EA_CURRENT_FUNCTION, fmt)) EA_DEBUG_BREAK(); else ((void)0)
#endif
#else
#ifndef EA_ASSERT
#define EA_ASSERT(expr) \
EA_DISABLE_VC_WARNING(4127)\
do {\
EA_ANALYSIS_ASSUME(expr);\
if(!(expr))\
{\
printf("\nEA_ASSERT(%s) failed in %s(%d)\n", #expr, __FILE__, __LINE__); EA_DEBUG_BREAK();\
}\
else\
{\
((void)0);\
}\
} while(0)\
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_ASSERT_MSG
#define EA_ASSERT_MSG(expr, msg) \
EA_DISABLE_VC_WARNING(4127)\
do\
{ \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) \
{\
printf("\nEA_ASSERT(%s) failed in %s(%d): %s\n", #expr, __FILE__, __LINE__, msg);EA_DEBUG_BREAK();\
}\
else \
{ \
((void)0); \
} \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_ASSERT_FORMATTED
#define EA_ASSERT_FORMATTED(expr, fmt) \
EA_DISABLE_VC_WARNING(4127) \
do {\
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) \
{ \
printf fmt; EA_DEBUG_BREAK(); EA_DEBUG_BREAK(); \
} \
else \
{ \
((void)0); \
} \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_FAIL
#define EA_FAIL() \
EA_DISABLE_VC_WARNING(4127) \
do {\
printf("\nEA_FAIL: %s(%d)\n", __FILE__, __LINE__); EA_DEBUG_BREAK(); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_FAIL_MSG
#define EA_FAIL_MSG(msg) \
EA_DISABLE_VC_WARNING(4127) \
do {\
printf("\nEA_FAIL: %s(%d): %s\n", __FILE__, __LINE__, msg); EA_DEBUG_BREAK(); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_FAIL_FORMATTED
#define EA_FAIL_FORMATTED(fmt) \
EA_DISABLE_VC_WARNING(4127) \
do {\
printf fmt; EA_DEBUG_BREAK(); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#endif
#else
#ifndef EA_ASSERT
#define EA_ASSERT(expr) ((void)0)
#endif
#ifndef EA_ASSERT_MSG
#define EA_ASSERT_MSG(expr, msg) ((void)0)
#endif
#ifndef EA_ASSERT_FORMATTED
#define EA_ASSERT_FORMATTED(expr, fmt) ((void)0)
#endif
#ifndef EA_FAIL
#define EA_FAIL() ((void)0)
#endif
#ifndef EA_FAIL_MSG
#define EA_FAIL_MSG(msg) ((void)0)
#endif
#ifndef EA_FAIL_FORMATTED
#define EA_FAIL_FORMATTED(fmt) ((void)0)
#endif
#endif
///////////////////////////////////////////////////////////////////////////////
/// EA_PANIC
///
// EA_PANIC is a macro for runtime assertion checks in release builds. The difference
// between using the EA_ASSERT is rather than performing a EA_DEBUG_BREAK, EA_CRASH is
// used instead.
///
// What this provides is a conditional forced crash on non-final builds since EA_ASSERT
// is only enabled for debug builds which define a handler. The largest motivation
// for using EA_PANIC over EA_ASSERT should be when one wants to explicitly catch
// critical asserts in release builds.
/// Example:
/// EA_PANIC(myVar == theirVar);
///
#ifdef EA_PANIC_ENABLED
#ifdef __cplusplus
#ifndef EA_PANIC
#define EA_PANIC(expr) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) { \
EA::Assert::Detail::Call(#expr, __FILE__, __LINE__, EA_CURRENT_FUNCTION); EA_CRASH(); \
} else ((void)0); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_PANIC_MSG
#define EA_PANIC_MSG(expr, msg) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) { \
EA::Assert::Detail::Call(#expr, __FILE__, __LINE__, EA_CURRENT_FUNCTION, msg); EA_CRASH(); \
} else ((void)0); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_PANIC_FORMATTED
#define EA_PANIC_FORMATTED(expr, fmt) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) { \
EA_ASSERT_FORMATTED_HANDLER_CALL(#expr, __FILE__, __LINE__, EA_CURRENT_FUNCTION, fmt); EA_CRASH(); \
} else ((void)0); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#else
#ifndef EA_PANIC
#define EA_PANIC(expr) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) { \
printf("\nEA_PANIC(%s) failed in %s(%d)\n", #expr, __FILE__, __LINE__); EA_CRASH(); \
} else ((void)0); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_PANIC_MSG
#define EA_PANIC_MSG(expr, msg) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) { \
printf("\nEA_PANIC(%s) failed in %s(%d): %s\n", #expr, __FILE__, __LINE__, msg); EA_CRASH(); \
} else ((void)0); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#ifndef EA_PANIC_FORMATTED
#define EA_PANIC_FORMATTED(expr, fmt) \
EA_DISABLE_VC_WARNING(4127) \
do { \
EA_ANALYSIS_ASSUME(expr); \
if (!(expr)) { \
printf fmt; EA_CRASH(); \
} else ((void)0); \
} while(0) \
EA_RESTORE_VC_WARNING()
#endif
#endif
#else
#ifndef EA_PANIC
#define EA_PANIC(expr) ((void)0)
#endif
#ifndef EA_PANIC_MSG
#define EA_PANIC_MSG(expr, msg) ((void)0)
#endif
#ifndef EA_PANIC_FORMATTED
#define EA_PANIC_FORMATTED(expr, fmt) ((void)0)
#endif
#endif
#endif // EA_ASSERT_HAVE_OWN_HEADER
// We provide some synonyms for the message style macros, because we couldn't reach common ground
// and there was too much existing code using different versions. It's not pretty, but relatively harmless
#ifndef EA_ASSERT_M
#define EA_ASSERT_M EA_ASSERT_MSG
#endif
#ifndef EA_ASSERT_MESSAGE
#define EA_ASSERT_MESSAGE EA_ASSERT_MSG
#endif
#ifndef EA_FAIL_M
#define EA_FAIL_M EA_FAIL_MSG
#endif
#ifndef EA_FAIL_MESSAGE
#define EA_FAIL_MESSAGE EA_FAIL_MSG
#endif
#ifndef EA_PANIC_M
#define EA_PANIC_M EA_PANIC_MSG
#endif
#ifndef EA_PANIC_MESSAGE
#define EA_PANIC_MESSAGE EA_PANIC_MSG
#endif
#endif
@@ -0,0 +1,69 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
/**
\file
Define the major, minor and patch versions.
*/
#ifndef EAASSERT_VERSION_H
#define EAASSERT_VERSION_H
// Define the major, minor and patch versions.
// This information is updated with each release.
//! This define indicates the major version number for the filesys package.
//! \sa EAASSERT_VERSION_MAJOR
#define EAASSERT_VERSION_MAJOR 1
//! This define indicates the minor version number for the filesys package.
//! \sa EAASSERT_VERSION_MINOR
#define EAASSERT_VERSION_MINOR 5
//! This define indicates the patch version number for the filesys package.
//! \sa EAASSERT_VERSION_PATCH
#define EAASSERT_VERSION_PATCH 8
/*!
* This is a utility macro that users may use to create a single version number
* that can be compared against EAASSERT_VERSION.
*
* For example:
*
* \code
*
* #if EAASSERT_VERSION > EAASSERT_CREATE_VERSION_NUMBER( 1, 1, 0 )
* printf("Filesys version is greater than 1.1.0.\n");
* #endif
*
* \endcode
*/
#define EAASSERT_CREATE_VERSION_NUMBER( major_ver, minor_ver, patch_ver ) \
((major_ver) * 1000000 + (minor_ver) * 1000 + (patch_ver))
/*!
* This macro is an aggregate of the major, minor and patch version numbers.
* \sa EAASSERT_CREATE_VERSION_NUMBER
*/
#define EAASSERT_VERSION \
EAASSERT_CREATE_VERSION_NUMBER( EAASSERT_VERSION_MAJOR, EAASSERT_VERSION_MINOR, EAASSERT_VERSION_PATCH )
#define EAASSERT_VERSION_MAJOR_STR EAASSERT_VERSION_STRINGIFY(EAASSERT_VERSION_MAJOR)
#if EAASSERT_VERSION_MINOR >= 10
#define EAASSERT_VERSION_MINOR_STR EAASSERT_VERSION_STRINGIFY(EAASSERT_VERSION_MINOR)
#else
#define EAASSERT_VERSION_MINOR_STR "0" EAASSERT_VERSION_STRINGIFY(EAASSERT_VERSION_MINOR)
#endif
#if EAASSERT_VERSION_PATCH >= 10
#define EAASSERT_VERSION_PATCH_STR EAASSERT_VERSION_STRINGIFY(EAASSERT_VERSION_PATCH)
#else
#define EAASSERT_VERSION_PATCH_STR "0" EAASSERT_VERSION_STRINGIFY(EAASSERT_VERSION_PATCH)
#endif
/*!
* This macro returns a string version of the macro
* \sa EAASSERT_VERSION_STRING
*/
#define EAASSERT_VERSION_STRING EAASSERT_VERSION_MAJOR_STR "." EAASSERT_VERSION_MINOR_STR "." EAASSERT_VERSION_PATCH_STR
#endif // EAASSERT_VERSION_H
+140
View File
@@ -0,0 +1,140 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
#include "EAAssert/eaassert.h"
#ifndef EA_ASSERT_HAVE_OWN_HEADER
#include <stdio.h>
#if defined(EA_PLATFORM_MICROSOFT)
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0400)
#undef _WIN32_WINNT
#define _WIN32_WINNT 0x0400
#endif
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#pragma warning(push,0)
#include <Windows.h> // ::IsDebuggerPresent
#pragma warning(pop)
#endif
#if !defined(EA_ASSERT_VSNPRINTF)
#if defined(EA_PLATFORM_MICROSOFT)
#define EA_ASSERT_VSNPRINTF _vsnprintf
#define EA_ASSERT_SNPRINTF _snprintf
#else
#define EA_ASSERT_VSNPRINTF vsnprintf
#define EA_ASSERT_SNPRINTF snprintf
#endif
#endif
namespace EA {
namespace Assert {
namespace Detail {
namespace {
#if defined(EA_ASSERT_ENABLED)
static void PlatformPrint(const char *str)
{
#if defined(EA_PLATFORM_MICROSOFT)
if (IsDebuggerPresent())
{
::OutputDebugStringA(str);
}
#endif
puts(str);
#if defined(EA_PLATFORM_MOBILE)
fflush(stdout); // Mobile platforms need this because otherwise you can easily lose output if the device crashes.
#endif
}
#endif
bool DefaultFailureCallback(const char* expr, const char* filename, int line, const char* function, const char* msg, va_list args)
{
#if defined(EA_ASSERT_ENABLED)
const int largeEnough = 2048;
char output[largeEnough + 1] = {};
char fmtMsg[largeEnough + 1] = {};
int len = EA_ASSERT_VSNPRINTF(fmtMsg, largeEnough, msg, args);
if(len==0)
{
len = EA_ASSERT_SNPRINTF(fmtMsg, largeEnough, "none");
}
// different platforms return different values for the error, but in both
// cases it'll be out of bounds, so clamp the return value to largeEnough.
if (len < 0 || len > largeEnough)
len = largeEnough;
fmtMsg[len] = '\0';
len = EA_ASSERT_SNPRINTF(output, largeEnough,
"%s(%d) : EA_ASSERT failed: '%s' in function: %s\n, message: %s",
filename, line, expr, function, fmtMsg);
if (len < 0 || len > largeEnough)
len = largeEnough;
output[len] = '\0';
PlatformPrint(output);
#else
EA_UNUSED(expr);
EA_UNUSED(filename);
EA_UNUSED(line);
EA_UNUSED(function);
EA_UNUSED(msg);
EA_UNUSED(args);
#endif
return true;
}
FailureCallback gFailureCallback = &DefaultFailureCallback;
}}
void SetFailureCallback(FailureCallback failureCallback)
{
Detail::gFailureCallback = failureCallback;
}
FailureCallback GetFailureCallback()
{
return Detail::gFailureCallback;
}
bool Detail::VCall(const char *expr, const char *filename, int line, const char *function, const char *msg, ...)
{
va_list args;
va_start(args, msg);
bool ret = (*GetFailureCallback())(expr, filename, line, function, msg, args);
va_end(args);
return ret;
}
bool Detail::Call(const char *expr, const char *filename, int line, const char *function)
{
// Pass an empty string as msg parameter. Some FailureCallback implementation (Frostbite)
// will display only msg and discard the rest of the data when msg is non empty.
return VCall(expr, filename, line, function, "");
}
bool Detail::Call(const char *expr, const char *filename, int line, const char *function, const char* msg)
{
return VCall(expr, filename, line, function, "%s", msg);
}
}}
#endif
@@ -0,0 +1,8 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
// EAMain/EAEntryPointMain.inl contains C++ code but it exposes the application entry point with C linkage.
#include "EAMain/EAEntryPointMain.inl"
#include "EATest/EASTLNewOperatorGuard.inl"
@@ -0,0 +1,58 @@
#-------------------------------------------------------------------------------------------
# Copyright (C) Electronic Arts Inc. All rights reserved.
#-------------------------------------------------------------------------------------------
#-------------------------------------------------------------------------------------------
# CMake info
#-------------------------------------------------------------------------------------------
cmake_minimum_required(VERSION 3.1)
project(EAAssertTest CXX)
include(CTest)
#-------------------------------------------------------------------------------------------
# Defines
#-------------------------------------------------------------------------------------------
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
add_definitions(-D_SCL_SECURE_NO_WARNINGS)
add_definitions(-D_CHAR16T)
#-------------------------------------------------------------------------------------------
# Compiler Flags
#-------------------------------------------------------------------------------------------
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/packages/EASTL/scripts/CMake")
include(CommonCppFlags)
#-------------------------------------------------------------------------------------------
# Source files
#-------------------------------------------------------------------------------------------
file(GLOB EAASSERTTEST_SOURCES "TestEAAssert.cpp")
set(SOURCES ${EAASSERTTEST_SOURCES})
#-------------------------------------------------------------------------------------------
# Executable definition
#-------------------------------------------------------------------------------------------
add_executable(EAAssertTest ${SOURCES})
#-------------------------------------------------------------------------------------------
# Dependencies
#-------------------------------------------------------------------------------------------
add_subdirectory(packages/EABase)
add_subdirectory(packages/EAMain)
add_subdirectory(packages/EASTL)
add_subdirectory(packages/EAStdC)
add_subdirectory(packages/EATest)
add_subdirectory(packages/EAThread)
target_link_libraries(EAAssertTest EABase)
target_link_libraries(EAAssertTest EAMain)
target_link_libraries(EAAssertTest EASTL)
target_link_libraries(EAAssertTest EAStdC)
target_link_libraries(EAAssertTest EATest)
target_link_libraries(EAAssertTest EAThread)
#-------------------------------------------------------------------------------------------
# Run Unit tests and verify the results.
#-------------------------------------------------------------------------------------------
add_test(EAAssertTestRuns EAAssertTest)
set_tests_properties (EAAssertTestRuns PROPERTIES PASS_REGULAR_EXPRESSION "RETURNCODE=0")
@@ -0,0 +1,187 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
#include <EAAssert/eaassert.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#ifdef _MSC_VER
#pragma warning(disable: 4127)
#endif
#include "EAMain/EAEntryPointMain.inl"
#include "EATest/EASTLNewOperatorGuard.inl"
namespace
{
const char* expectedExpr = 0;
const char* expectedFilename = 0;
const char* expectedFunction = 0;
const char* expectedMessage = 0;
int expectedLine = 0;
bool assertCalled = false;
bool expressionCalled = false;
}
static void Expect(const char* expr, const char* filename, int line, const char* function, const char* msg)
{
expectedExpr = expr;
expectedFilename = filename;
expectedFunction = function;
expectedMessage = msg;
expectedLine = line;
}
// similar to assert in libc, but this function is not compiled out in a
// release build
// \param condition should be true when EA_ASSERT_ENABLED is defined,
// false when EA_ASSERT_ENABLED is not defined.
// \param always the condition should be true regardless of whether
// EA_ASSERT_ENABLED is defined or not.
static void TestCondition(bool condition, bool always)
{
if (always)
{
if (!condition)
{
EA::EAMain::Report("Test failed\n");
EA_DEBUG_BREAK();
}
return;
}
#if defined(EA_ASSERT_ENABLED)
if (!condition)
{
EA::EAMain::Report("Test failed\n");
EA_DEBUG_BREAK();
}
#else
if (condition)
{
EA::EAMain::Report("Test failed\n");
EA_DEBUG_BREAK();
}
#endif
}
static bool EAAssertFailure(const char* expr, const char* filename, int line, const char* function, const char* msg, va_list args)
{
assertCalled = true;
TestCondition(0 == strcmp(expr, expectedExpr), false);
TestCondition(0 != strstr(filename, expectedFilename), false);
TestCondition(0 != strstr(function, expectedFunction), false);
const int size = 2048;
char fmtMsg[size + 1] = {};
vsprintf(fmtMsg, msg, args);
TestCondition(0 == strcmp(fmtMsg, expectedMessage), false);
TestCondition(line == expectedLine, false);
return false;
}
bool TestExpression(bool *x)
{
*x = !*x;
return *x;
}
EA_COMPILETIME_ASSERT(true);
int EAMain(int argc, char**)
{
EA::Assert::SetFailureCallback(&EAAssertFailure);
EA_COMPILETIME_ASSERT(true);
#ifndef EA_COMPILER_GNUC
// TODO(rparolin): Disabling this test on GCC because the compiler correctly wanrs that the output of EA_OFFSETOF is
// not constexpr. Unfortunately, the implementation is attempting to support calculating offsets within
// non-standard-layout types which is not supported by the Cpp Standard. Fix required.
{
struct OffsetOfTestStruct
{
int member;
};
// Note:
//
// User code currently exists that uses EA_COMPILETIME_ASSERT with results from EA_OFFSETOF.
// Modifying the implementation of either EA_COMPILETIME_ASSERT or EA_OFFSETOF could cause this
// code to break. (We have observed failures on clang.)
//
// See also:
// - EAStdC's EAOffsetOf works properly with static_assert, but also needs to suppress compiler
// warnings to compile warning free in all situations. We chose not to perform this suppression
// in EABase's EA_OFFSETOF because it would leak into files including eabase.
EA_COMPILETIME_ASSERT(EA_OFFSETOF(OffsetOfTestStruct, member) == 0);
}
#endif
assertCalled = false;
EA_ASSERT(true);
TestCondition(assertCalled == false, true);
const char* testMsg = "The quick brown fox jumps over the lazy dog.";
const char* mainName = "EAMain";
assertCalled = false;
Expect("3 == 4", __FILE__, __LINE__ + 1, mainName, testMsg);
EA_ASSERT_M(3 == 4, testMsg);
TestCondition(assertCalled, false);
assertCalled = false;
Expect("3 == 4", __FILE__, __LINE__ + 1, mainName, testMsg);
EA_ASSERT_MESSAGE(3 == 4, testMsg);
TestCondition(assertCalled, false);
assertCalled = false;
Expect("3 == 4", __FILE__, __LINE__ + 1, mainName, testMsg);
EA_ASSERT_MSG(3 == 4, testMsg);
TestCondition(assertCalled, false);
assertCalled = false;
Expect("8 == 2", __FILE__, __LINE__ + 1, mainName, testMsg);
EA_ASSERT_FORMATTED(8 == 2, ("The quick brown fox jumps over the %s dog.", "lazy"));
TestCondition(assertCalled, false);
assertCalled = false;
Expect("3 % 8 == 2", __FILE__, __LINE__ + 1, mainName, "");
EA_ASSERT(3 % 8 == 2);
TestCondition(assertCalled, false);
bool expectToBeSet = false;
if (false)
EA_ASSERT(false);
else
expectToBeSet = true;
TestCondition(expectToBeSet, true);
// Regression test for checking whether an expression is compiled
// out when asserts are disabled.
EA_ASSERT(TestExpression(&expressionCalled));
TestCondition(expressionCalled, false);
// Ensure that the unconditional assertion format behaves correctly
Expect("EA_FAIL", __FILE__, __LINE__ + 1, mainName, "");
EA_FAIL();
Expect("EA_FAIL", __FILE__, __LINE__ + 1, mainName, testMsg);
EA_FAIL_MSG(testMsg);
Expect("EA_FAIL", __FILE__, __LINE__ + 1, mainName, testMsg);
EA_FAIL_FORMATTED(("%s", testMsg));
EA::EAMain::Report("Test complete - all tests passed.\n");
return 0;
}
@@ -0,0 +1,49 @@
///////////////////////////////////////////////////////////////////////////////
// Copyright (c) Electronic Arts Inc. All rights reserved.
///////////////////////////////////////////////////////////////////////////////
// We can't override EA_ASSERTS failure callback so we won't be able to test EAAssert in C but at least we can
// prove it builds our macros correctly
#include <stdio.h>
#include <EAAssert/eaassert.h>
#ifdef _MSC_VER
#pragma warning(disable: 4127)
#endif
int EAMain(int argc, char** argv)
{
const char* testMsg = "The quick brown fox jumps over the lazy dog.";
int nErrorCount = 0;
int expectToBeSet = 0;
EA_COMPILETIME_ASSERT(1);
EA_ASSERT(1);
EA_UNUSED(testMsg);
EA_UNUSED(expectToBeSet);
EA_ASSERT_M(4 == 4, testMsg);
EA_ASSERT_MESSAGE(4 == 4, testMsg);
EA_ASSERT_MSG(4 == 4, testMsg);
EA_ASSERT_FORMATTED(8 == 8, ("The quick brown fox jumps over the %s dog.", "lazy"));
EA_ASSERT(3 % 8 == 3);
expectToBeSet = 0;
if (0)
EA_ASSERT(0);
else
expectToBeSet = 1;
EA_ASSERT(expectToBeSet == 1);
EA_PANIC_M(4 == 4, testMsg);
EA_PANIC_MESSAGE(4 == 4, testMsg);
EA_PANIC_MSG(4 == 4, testMsg);
EA_PANIC_FORMATTED(8 == 8, ("The quick brown fox jumps over the %s dog.", "lazy"));
EA_PANIC(3 % 8 == 3);
return nErrorCount;
}