First
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
tags
|
||||
.p4config
|
||||
build.bat
|
||||
/build/
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
```
|
||||
@@ -0,0 +1,2 @@
|
||||
(C) Electronic Arts. All rights reserved.
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
@@ -0,0 +1,25 @@
|
||||
# EAAssert
|
||||
|
||||
[](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.
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user