diff options
140 files changed, 40765 insertions, 4674 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 04b8912..2b9582a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,13 @@ set(CMAKE_CXX_FLAGS_RELEASE "-O2 -Wall -Wold-style-cast -std=gnu++0x") set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wold-style-cast -std=gnu++0x") # Include cmake directory -SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${colobot_SOURCE_DIR}/cmake") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${colobot_SOURCE_DIR}/cmake") + +enable_testing() + +# Google Test library +set(GTEST_DIR "${colobot_SOURCE_DIR}/lib/gtest") +add_subdirectory(lib/gtest bin/test) # Subdirectory with sources add_subdirectory(src bin) diff --git a/lib/README.txt b/lib/README.txt new file mode 100644 index 0000000..2173335 --- /dev/null +++ b/lib/README.txt @@ -0,0 +1 @@ +External libraries used in the project. diff --git a/lib/gtest/CMakeLists.txt b/lib/gtest/CMakeLists.txt new file mode 100644 index 0000000..1279f7d --- /dev/null +++ b/lib/gtest/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.8) + +include_directories(. include) + +# pthread is not necessary +add_definitions(-DGTEST_HAS_PTHREAD=0) + +# gtest-all.cc includes all other sources +add_library(gtest STATIC src/gtest-all.cc) diff --git a/lib/gtest/COPYING.txt b/lib/gtest/COPYING.txt new file mode 100644 index 0000000..1941a11 --- /dev/null +++ b/lib/gtest/COPYING.txt @@ -0,0 +1,28 @@ +Copyright 2008, Google 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: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +OWNER OR 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. diff --git a/lib/gtest/README-gtest.txt b/lib/gtest/README-gtest.txt new file mode 100644 index 0000000..51a9376 --- /dev/null +++ b/lib/gtest/README-gtest.txt @@ -0,0 +1,424 @@ +Google C++ Testing Framework +============================ + +http://code.google.com/p/googletest/ + +Overview +-------- + +Google's framework for writing C++ tests on a variety of platforms +(Linux, Mac OS X, Windows, Windows CE, Symbian, etc). Based on the +xUnit architecture. Supports automatic test discovery, a rich set of +assertions, user-defined assertions, death tests, fatal and non-fatal +failures, various options for running the tests, and XML test report +generation. + +Please see the project page above for more information as well as the +mailing list for questions, discussions, and development. There is +also an IRC channel on OFTC (irc.oftc.net) #gtest available. Please +join us! + +Requirements for End Users +-------------------------- + +Google Test is designed to have fairly minimal requirements to build +and use with your projects, but there are some. Currently, we support +Linux, Windows, Mac OS X, and Cygwin. We will also make our best +effort to support other platforms (e.g. Solaris, AIX, and z/OS). +However, since core members of the Google Test project have no access +to these platforms, Google Test may have outstanding issues there. If +you notice any problems on your platform, please notify +googletestframework@googlegroups.com. Patches for fixing them are +even more welcome! + +### Linux Requirements ### + +These are the base requirements to build and use Google Test from a source +package (as described below): + * GNU-compatible Make or gmake + * POSIX-standard shell + * POSIX(-2) Regular Expressions (regex.h) + * A C++98-standard-compliant compiler + +### Windows Requirements ### + + * Microsoft Visual C++ 7.1 or newer + +### Cygwin Requirements ### + + * Cygwin 1.5.25-14 or newer + +### Mac OS X Requirements ### + + * Mac OS X 10.4 Tiger or newer + * Developer Tools Installed + +Also, you'll need CMake 2.6.4 or higher if you want to build the +samples using the provided CMake script, regardless of the platform. + +Requirements for Contributors +----------------------------- + +We welcome patches. If you plan to contribute a patch, you need to +build Google Test and its own tests from an SVN checkout (described +below), which has further requirements: + + * Python version 2.3 or newer (for running some of the tests and + re-generating certain source files from templates) + * CMake 2.6.4 or newer + +Getting the Source +------------------ + +There are two primary ways of getting Google Test's source code: you +can download a stable source release in your preferred archive format, +or directly check out the source from our Subversion (SVN) repositary. +The SVN checkout requires a few extra steps and some extra software +packages on your system, but lets you track the latest development and +make patches much more easily, so we highly encourage it. + +### Source Package ### + +Google Test is released in versioned source packages which can be +downloaded from the download page [1]. Several different archive +formats are provided, but the only difference is the tools used to +manipulate them, and the size of the resulting file. Download +whichever you are most comfortable with. + + [1] http://code.google.com/p/googletest/downloads/list + +Once the package is downloaded, expand it using whichever tools you +prefer for that type. This will result in a new directory with the +name "gtest-X.Y.Z" which contains all of the source code. Here are +some examples on Linux: + + tar -xvzf gtest-X.Y.Z.tar.gz + tar -xvjf gtest-X.Y.Z.tar.bz2 + unzip gtest-X.Y.Z.zip + +### SVN Checkout ### + +To check out the main branch (also known as the "trunk") of Google +Test, run the following Subversion command: + + svn checkout http://googletest.googlecode.com/svn/trunk/ gtest-svn + +Setting up the Build +-------------------- + +To build Google Test and your tests that use it, you need to tell your +build system where to find its headers and source files. The exact +way to do it depends on which build system you use, and is usually +straightforward. + +### Generic Build Instructions ### + +Suppose you put Google Test in directory ${GTEST_DIR}. To build it, +create a library build target (or a project as called by Visual Studio +and Xcode) to compile + + ${GTEST_DIR}/src/gtest-all.cc + +with + + ${GTEST_DIR}/include and ${GTEST_DIR} + +in the header search path. Assuming a Linux-like system and gcc, +something like the following will do: + + g++ -I${GTEST_DIR}/include -I${GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc + ar -rv libgtest.a gtest-all.o + +Next, you should compile your test source file with +${GTEST_DIR}/include in the header search path, and link it with gtest +and any other necessary libraries: + + g++ -I${GTEST_DIR}/include path/to/your_test.cc libgtest.a -o your_test + +As an example, the make/ directory contains a Makefile that you can +use to build Google Test on systems where GNU make is available +(e.g. Linux, Mac OS X, and Cygwin). It doesn't try to build Google +Test's own tests. Instead, it just builds the Google Test library and +a sample test. You can use it as a starting point for your own build +script. + +If the default settings are correct for your environment, the +following commands should succeed: + + cd ${GTEST_DIR}/make + make + ./sample1_unittest + +If you see errors, try to tweak the contents of make/Makefile to make +them go away. There are instructions in make/Makefile on how to do +it. + +### Using CMake ### + +Google Test comes with a CMake build script (CMakeLists.txt) that can +be used on a wide range of platforms ("C" stands for cross-platofrm.). +If you don't have CMake installed already, you can download it for +free from http://www.cmake.org/. + +CMake works by generating native makefiles or build projects that can +be used in the compiler environment of your choice. The typical +workflow starts with: + + mkdir mybuild # Create a directory to hold the build output. + cd mybuild + cmake ${GTEST_DIR} # Generate native build scripts. + +If you want to build Google Test's samples, you should replace the +last command with + + cmake -Dgtest_build_samples=ON ${GTEST_DIR} + +If you are on a *nix system, you should now see a Makefile in the +current directory. Just type 'make' to build gtest. + +If you use Windows and have Vistual Studio installed, a gtest.sln file +and several .vcproj files will be created. You can then build them +using Visual Studio. + +On Mac OS X with Xcode installed, a .xcodeproj file will be generated. + +### Legacy Build Scripts ### + +Before settling on CMake, we have been providing hand-maintained build +projects/scripts for Visual Studio, Xcode, and Autotools. While we +continue to provide them for convenience, they are not actively +maintained any more. We highly recommend that you follow the +instructions in the previous two sections to integrate Google Test +with your existing build system. + +If you still need to use the legacy build scripts, here's how: + +The msvc\ folder contains two solutions with Visual C++ projects. +Open the gtest.sln or gtest-md.sln file using Visual Studio, and you +are ready to build Google Test the same way you build any Visual +Studio project. Files that have names ending with -md use DLL +versions of Microsoft runtime libraries (the /MD or the /MDd compiler +option). Files without that suffix use static versions of the runtime +libraries (the /MT or the /MTd option). Please note that one must use +the same option to compile both gtest and the test code. If you use +Visual Studio 2005 or above, we recommend the -md version as /MD is +the default for new projects in these versions of Visual Studio. + +On Mac OS X, open the gtest.xcodeproj in the xcode/ folder using +Xcode. Build the "gtest" target. The universal binary framework will +end up in your selected build directory (selected in the Xcode +"Preferences..." -> "Building" pane and defaults to xcode/build). +Alternatively, at the command line, enter: + + xcodebuild + +This will build the "Release" configuration of gtest.framework in your +default build location. See the "xcodebuild" man page for more +information about building different configurations and building in +different locations. + +Tweaking Google Test +-------------------- + +Google Test can be used in diverse environments. The default +configuration may not work (or may not work well) out of the box in +some environments. However, you can easily tweak Google Test by +defining control macros on the compiler command line. Generally, +these macros are named like GTEST_XYZ and you define them to either 1 +or 0 to enable or disable a certain feature. + +We list the most frequently used macros below. For a complete list, +see file include/gtest/internal/gtest-port.h. + +### Choosing a TR1 Tuple Library ### + +Some Google Test features require the C++ Technical Report 1 (TR1) +tuple library, which is not yet available with all compilers. The +good news is that Google Test implements a subset of TR1 tuple that's +enough for its own need, and will automatically use this when the +compiler doesn't provide TR1 tuple. + +Usually you don't need to care about which tuple library Google Test +uses. However, if your project already uses TR1 tuple, you need to +tell Google Test to use the same TR1 tuple library the rest of your +project uses, or the two tuple implementations will clash. To do +that, add + + -DGTEST_USE_OWN_TR1_TUPLE=0 + +to the compiler flags while compiling Google Test and your tests. If +you want to force Google Test to use its own tuple library, just add + + -DGTEST_USE_OWN_TR1_TUPLE=1 + +to the compiler flags instead. + +If you don't want Google Test to use tuple at all, add + + -DGTEST_HAS_TR1_TUPLE=0 + +and all features using tuple will be disabled. + +### Multi-threaded Tests ### + +Google Test is thread-safe where the pthread library is available. +After #include "gtest/gtest.h", you can check the GTEST_IS_THREADSAFE +macro to see whether this is the case (yes if the macro is #defined to +1, no if it's undefined.). + +If Google Test doesn't correctly detect whether pthread is available +in your environment, you can force it with + + -DGTEST_HAS_PTHREAD=1 + +or + + -DGTEST_HAS_PTHREAD=0 + +When Google Test uses pthread, you may need to add flags to your +compiler and/or linker to select the pthread library, or you'll get +link errors. If you use the CMake script or the deprecated Autotools +script, this is taken care of for you. If you use your own build +script, you'll need to read your compiler and linker's manual to +figure out what flags to add. + +### As a Shared Library (DLL) ### + +Google Test is compact, so most users can build and link it as a +static library for the simplicity. You can choose to use Google Test +as a shared library (known as a DLL on Windows) if you prefer. + +To compile *gtest* as a shared library, add + + -DGTEST_CREATE_SHARED_LIBRARY=1 + +to the compiler flags. You'll also need to tell the linker to produce +a shared library instead - consult your linker's manual for how to do +it. + +To compile your *tests* that use the gtest shared library, add + + -DGTEST_LINKED_AS_SHARED_LIBRARY=1 + +to the compiler flags. + +Note: while the above steps aren't technically necessary today when +using some compilers (e.g. GCC), they may become necessary in the +future, if we decide to improve the speed of loading the library (see +http://gcc.gnu.org/wiki/Visibility for details). Therefore you are +recommended to always add the above flags when using Google Test as a +shared library. Otherwise a future release of Google Test may break +your build script. + +### Avoiding Macro Name Clashes ### + +In C++, macros don't obey namespaces. Therefore two libraries that +both define a macro of the same name will clash if you #include both +definitions. In case a Google Test macro clashes with another +library, you can force Google Test to rename its macro to avoid the +conflict. + +Specifically, if both Google Test and some other code define macro +FOO, you can add + + -DGTEST_DONT_DEFINE_FOO=1 + +to the compiler flags to tell Google Test to change the macro's name +from FOO to GTEST_FOO. Currently FOO can be FAIL, SUCCEED, or TEST. +For example, with -DGTEST_DONT_DEFINE_TEST=1, you'll need to write + + GTEST_TEST(SomeTest, DoesThis) { ... } + +instead of + + TEST(SomeTest, DoesThis) { ... } + +in order to define a test. + +Upgrating from an Earlier Version +--------------------------------- + +We strive to keep Google Test releases backward compatible. +Sometimes, though, we have to make some breaking changes for the +users' long-term benefits. This section describes what you'll need to +do if you are upgrading from an earlier version of Google Test. + +### Upgrading from 1.3.0 or Earlier ### + +You may need to explicitly enable or disable Google Test's own TR1 +tuple library. See the instructions in section "Choosing a TR1 Tuple +Library". + +### Upgrading from 1.4.0 or Earlier ### + +The Autotools build script (configure + make) is no longer officially +supportted. You are encouraged to migrate to your own build system or +use CMake. If you still need to use Autotools, you can find +instructions in the README file from Google Test 1.4.0. + +On platforms where the pthread library is available, Google Test uses +it in order to be thread-safe. See the "Multi-threaded Tests" section +for what this means to your build script. + +If you use Microsoft Visual C++ 7.1 with exceptions disabled, Google +Test will no longer compile. This should affect very few people, as a +large portion of STL (including <string>) doesn't compile in this mode +anyway. We decided to stop supporting it in order to greatly simplify +Google Test's implementation. + +Developing Google Test +---------------------- + +This section discusses how to make your own changes to Google Test. + +### Testing Google Test Itself ### + +To make sure your changes work as intended and don't break existing +functionality, you'll want to compile and run Google Test's own tests. +For that you can use CMake: + + mkdir mybuild + cd mybuild + cmake -Dgtest_build_tests=ON ${GTEST_DIR} + +Make sure you have Python installed, as some of Google Test's tests +are written in Python. If the cmake command complains about not being +able to find Python ("Could NOT find PythonInterp (missing: +PYTHON_EXECUTABLE)"), try telling it explicitly where your Python +executable can be found: + + cmake -DPYTHON_EXECUTABLE=path/to/python -Dgtest_build_tests=ON ${GTEST_DIR} + +Next, you can build Google Test and all of its own tests. On *nix, +this is usually done by 'make'. To run the tests, do + + make test + +All tests should pass. + +### Regenerating Source Files ### + +Some of Google Test's source files are generated from templates (not +in the C++ sense) using a script. A template file is named FOO.pump, +where FOO is the name of the file it will generate. For example, the +file include/gtest/internal/gtest-type-util.h.pump is used to generate +gtest-type-util.h in the same directory. + +Normally you don't need to worry about regenerating the source files, +unless you need to modify them. In that case, you should modify the +corresponding .pump files instead and run the pump.py Python script to +regenerate them. You can find pump.py in the scripts/ directory. +Read the Pump manual [2] for how to use it. + + [2] http://code.google.com/p/googletest/wiki/PumpManual + +### Contributing a Patch ### + +We welcome patches. Please read the Google Test developer's guide [3] +for how you can contribute. In particular, make sure you have signed +the Contributor License Agreement, or we won't be able to accept the +patch. + + [3] http://code.google.com/p/googletest/wiki/GoogleTestDevGuide + +Happy testing! diff --git a/lib/gtest/README.txt b/lib/gtest/README.txt new file mode 100644 index 0000000..390886f --- /dev/null +++ b/lib/gtest/README.txt @@ -0,0 +1,5 @@ +This directory contains part of distribution of Google Test (http://code.google.com/p/googletest/) + - a C++ framework for unit tests. There are source files, include headers and a custom CMakeLists.txt +to compile static library. Only these files are kept from the official distribution as only +they are necessary. For more info, see the original README file from gtest: REDME-gtest.txt. +License info is kept in the original COPYING.txt. diff --git a/lib/gtest/include/gtest/gtest-death-test.h b/lib/gtest/include/gtest/gtest-death-test.h new file mode 100644 index 0000000..a27883f --- /dev/null +++ b/lib/gtest/include/gtest/gtest-death-test.h @@ -0,0 +1,283 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for death tests. It is +// #included by gtest.h so a user doesn't need to include this +// directly. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ + +#include "gtest/internal/gtest-death-test-internal.h" + +namespace testing { + +// This flag controls the style of death tests. Valid values are "threadsafe", +// meaning that the death test child process will re-execute the test binary +// from the start, running only a single death test, or "fast", +// meaning that the child process will execute the test logic immediately +// after forking. +GTEST_DECLARE_string_(death_test_style); + +#if GTEST_HAS_DEATH_TEST + +// The following macros are useful for writing death tests. + +// Here's what happens when an ASSERT_DEATH* or EXPECT_DEATH* is +// executed: +// +// 1. It generates a warning if there is more than one active +// thread. This is because it's safe to fork() or clone() only +// when there is a single thread. +// +// 2. The parent process clone()s a sub-process and runs the death +// test in it; the sub-process exits with code 0 at the end of the +// death test, if it hasn't exited already. +// +// 3. The parent process waits for the sub-process to terminate. +// +// 4. The parent process checks the exit code and error message of +// the sub-process. +// +// Examples: +// +// ASSERT_DEATH(server.SendMessage(56, "Hello"), "Invalid port number"); +// for (int i = 0; i < 5; i++) { +// EXPECT_DEATH(server.ProcessRequest(i), +// "Invalid request .* in ProcessRequest()") +// << "Failed to die on request " << i); +// } +// +// ASSERT_EXIT(server.ExitNow(), ::testing::ExitedWithCode(0), "Exiting"); +// +// bool KilledBySIGHUP(int exit_code) { +// return WIFSIGNALED(exit_code) && WTERMSIG(exit_code) == SIGHUP; +// } +// +// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!"); +// +// On the regular expressions used in death tests: +// +// On POSIX-compliant systems (*nix), we use the <regex.h> library, +// which uses the POSIX extended regex syntax. +// +// On other platforms (e.g. Windows), we only support a simple regex +// syntax implemented as part of Google Test. This limited +// implementation should be enough most of the time when writing +// death tests; though it lacks many features you can find in PCRE +// or POSIX extended regex syntax. For example, we don't support +// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and +// repetition count ("x{5,7}"), among others. +// +// Below is the syntax that we do support. We chose it to be a +// subset of both PCRE and POSIX extended regex, so it's easy to +// learn wherever you come from. In the following: 'A' denotes a +// literal character, period (.), or a single \\ escape sequence; +// 'x' and 'y' denote regular expressions; 'm' and 'n' are for +// natural numbers. +// +// c matches any literal character c +// \\d matches any decimal digit +// \\D matches any character that's not a decimal digit +// \\f matches \f +// \\n matches \n +// \\r matches \r +// \\s matches any ASCII whitespace, including \n +// \\S matches any character that's not a whitespace +// \\t matches \t +// \\v matches \v +// \\w matches any letter, _, or decimal digit +// \\W matches any character that \\w doesn't match +// \\c matches any literal character c, which must be a punctuation +// . matches any single character except \n +// A? matches 0 or 1 occurrences of A +// A* matches 0 or many occurrences of A +// A+ matches 1 or many occurrences of A +// ^ matches the beginning of a string (not that of each line) +// $ matches the end of a string (not that of each line) +// xy matches x followed by y +// +// If you accidentally use PCRE or POSIX extended regex features +// not implemented by us, you will get a run-time failure. In that +// case, please try to rewrite your regular expression within the +// above syntax. +// +// This implementation is *not* meant to be as highly tuned or robust +// as a compiled regex library, but should perform well enough for a +// death test, which already incurs significant overhead by launching +// a child process. +// +// Known caveats: +// +// A "threadsafe" style death test obtains the path to the test +// program from argv[0] and re-executes it in the sub-process. For +// simplicity, the current implementation doesn't search the PATH +// when launching the sub-process. This means that the user must +// invoke the test program via a path that contains at least one +// path separator (e.g. path/to/foo_test and +// /absolute/path/to/bar_test are fine, but foo_test is not). This +// is rarely a problem as people usually don't put the test binary +// directory in PATH. +// +// TODO(wan@google.com): make thread-safe death tests search the PATH. + +// Asserts that a given statement causes the program to exit, with an +// integer exit status that satisfies predicate, and emitting error output +// that matches regex. +# define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) + +// Like ASSERT_EXIT, but continues on to successive tests in the +// test case, if any: +# define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) + +// Asserts that a given statement causes the program to exit, either by +// explicitly exiting with a nonzero exit code or being killed by a +// signal, and emitting error output that matches regex. +# define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Like ASSERT_DEATH, but continues on to successive tests in the +// test case, if any: +# define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) + +// Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: + +// Tests that an exit code describes a normal exit with a given exit code. +class GTEST_API_ ExitedWithCode { + public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; + private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; +}; + +# if !GTEST_OS_WINDOWS +// Tests that an exit code describes an exit due to termination by a +// given signal. +class GTEST_API_ KilledBySignal { + public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + private: + const int signum_; +}; +# endif // !GTEST_OS_WINDOWS + +// EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. +// The death testing framework causes this to have interesting semantics, +// since the sideeffects of the call are only visible in opt mode, and not +// in debug mode. +// +// In practice, this can be used to test functions that utilize the +// LOG(DFATAL) macro using the following style: +// +// int DieInDebugOr12(int* sideeffect) { +// if (sideeffect) { +// *sideeffect = 12; +// } +// LOG(DFATAL) << "death"; +// return 12; +// } +// +// TEST(TestCase, TestDieOr12WorksInDgbAndOpt) { +// int sideeffect = 0; +// // Only asserts in dbg. +// EXPECT_DEBUG_DEATH(DieInDebugOr12(&sideeffect), "death"); +// +// #ifdef NDEBUG +// // opt-mode has sideeffect visible. +// EXPECT_EQ(12, sideeffect); +// #else +// // dbg-mode no visible sideeffect. +// EXPECT_EQ(0, sideeffect); +// #endif +// } +// +// This will assert that DieInDebugReturn12InOpt() crashes in debug +// mode, usually due to a DCHECK or LOG(DFATAL), but returns the +// appropriate fallback value (12 in this case) in opt mode. If you +// need to test that a function has appropriate side-effects in opt +// mode, include assertions against the side-effects. A general +// pattern for this is: +// +// EXPECT_DEBUG_DEATH({ +// // Side-effects here will have an effect after this statement in +// // opt mode, but none in debug mode. +// EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); +// }, "death"); +// +# ifdef NDEBUG + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + do { statement; } while (::testing::internal::AlwaysFalse()) + +# else + +# define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) + +# define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) + +# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // GTEST_HAS_DEATH_TEST + +// EXPECT_DEATH_IF_SUPPORTED(statement, regex) and +// ASSERT_DEATH_IF_SUPPORTED(statement, regex) expand to real death tests if +// death tests are supported; otherwise they just issue a warning. This is +// useful when you are combining death test assertions with normal test +// assertions in one test. +#if GTEST_HAS_DEATH_TEST +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) +#else +# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#endif + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_DEATH_TEST_H_ diff --git a/lib/gtest/include/gtest/gtest-message.h b/lib/gtest/include/gtest/gtest-message.h new file mode 100644 index 0000000..9b7142f --- /dev/null +++ b/lib/gtest/include/gtest/gtest-message.h @@ -0,0 +1,230 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the Message class. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! + +#ifndef GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ +#define GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ + +#include <limits> + +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-internal.h" + +namespace testing { + +// The Message class works like an ostream repeater. +// +// Typical usage: +// +// 1. You stream a bunch of values to a Message object. +// It will remember the text in a stringstream. +// 2. Then you stream the Message object to an ostream. +// This causes the text in the Message to be streamed +// to the ostream. +// +// For example; +// +// testing::Message foo; +// foo << 1 << " != " << 2; +// std::cout << foo; +// +// will print "1 != 2". +// +// Message is not intended to be inherited from. In particular, its +// destructor is not virtual. +// +// Note that stringstream behaves differently in gcc and in MSVC. You +// can stream a NULL char pointer to it in the former, but not in the +// latter (it causes an access violation if you do). The Message +// class hides this difference by treating a NULL char pointer as +// "(null)". +class GTEST_API_ Message { + private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); + + public: + // Constructs an empty Message. + // We allocate the stringstream separately because otherwise each use of + // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's + // stack frame leading to huge stack frames in some cases; gcc does not reuse + // the stack space. + Message() : ss_(new ::std::stringstream) { + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits<double>::digits10 + 2); + } + + // Copy constructor. + Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT + *ss_ << msg.GetString(); + } + + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new ::std::stringstream) { + *ss_ << str; + } + +#if GTEST_OS_SYMBIAN + // Streams a value (either a pointer or not) to this object. + template <typename T> + inline Message& operator <<(const T& value) { + StreamHelper(typename internal::is_pointer<T>::type(), value); + return *this; + } +#else + // Streams a non-pointer value to this object. + template <typename T> + inline Message& operator <<(const T& val) { + ::GTestStreamToHelper(ss_.get(), val); + return *this; + } + + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template <typename T> + inline Message& operator <<(T* const& pointer) { // NOLINT + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_.get(), pointer); + } + return *this; + } +#endif // GTEST_OS_SYMBIAN + + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator <<(BasicNarrowIoManip val) { + *ss_ << val; + return *this; + } + + // Instead of 1/0, we want to see true/false for bool values. + Message& operator <<(bool b) { + return *this << (b ? "true" : "false"); + } + + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator <<(const wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + Message& operator <<(wchar_t* wide_c_str) { + return *this << internal::String::ShowWideCString(wide_c_str); + } + +#if GTEST_HAS_STD_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::std::wstring& wstr); +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator <<(const ::wstring& wstr); +#endif // GTEST_HAS_GLOBAL_WSTRING + + // Gets the text streamed to this object so far as a String. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::String GetString() const { + return internal::StringStreamToString(ss_.get()); + } + + private: + +#if GTEST_OS_SYMBIAN + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template <typename T> + inline void StreamHelper(internal::true_type /*dummy*/, T* pointer) { + if (pointer == NULL) { + *ss_ << "(null)"; + } else { + ::GTestStreamToHelper(ss_.get(), pointer); + } + } + template <typename T> + inline void StreamHelper(internal::false_type /*dummy*/, const T& value) { + ::GTestStreamToHelper(ss_.get(), value); + } +#endif // GTEST_OS_SYMBIAN + + // We'll hold the text streamed to this object here. + const internal::scoped_ptr< ::std::stringstream> ss_; + + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); +}; + +// Streams a Message to an ostream. +inline std::ostream& operator <<(std::ostream& os, const Message& sb) { + return os << sb.GetString(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_MESSAGE_H_ diff --git a/lib/gtest/include/gtest/gtest-param-test.h b/lib/gtest/include/gtest/gtest-param-test.h new file mode 100644 index 0000000..6407cfd --- /dev/null +++ b/lib/gtest/include/gtest/gtest-param-test.h @@ -0,0 +1,1421 @@ +// This file was GENERATED by command: +// pump.py gtest-param-test.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam<T> (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam<T> is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam<const char*> { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam<T> class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface<T>, where T is the type of the parameter +// values. Inheriting from TestWithParam<T> satisfies that requirement because +// TestWithParam<T> inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + +#include "gtest/internal/gtest-port.h" + +#if !GTEST_OS_SYMBIAN +# include <utility> +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-param-util-generated.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam<int> { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template <typename T, typename IncrementT> +internal::ParamGenerator<T> Range(T start, T end, IncrementT step) { + return internal::ParamGenerator<T>( + new internal::RangeGenerator<T, IncrementT>(start, end, step)); +} + +template <typename T> +internal::ParamGenerator<T> Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list<char> GetParameterChars() { +// ::std::list<char> list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list<char> l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template <typename ForwardIterator> +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits<ForwardIterator> + ::value_type ParamType; + return internal::ParamGenerator<ParamType>( + new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end)); +} + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to 50 parameters. +// +template <typename T1> +internal::ValueArray1<T1> Values(T1 v1) { + return internal::ValueArray1<T1>(v1); +} + +template <typename T1, typename T2> +internal::ValueArray2<T1, T2> Values(T1 v1, T2 v2) { + return internal::ValueArray2<T1, T2>(v1, v2); +} + +template <typename T1, typename T2, typename T3> +internal::ValueArray3<T1, T2, T3> Values(T1 v1, T2 v2, T3 v3) { + return internal::ValueArray3<T1, T2, T3>(v1, v2, v3); +} + +template <typename T1, typename T2, typename T3, typename T4> +internal::ValueArray4<T1, T2, T3, T4> Values(T1 v1, T2 v2, T3 v3, T4 v4) { + return internal::ValueArray4<T1, T2, T3, T4>(v1, v2, v3, v4); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +internal::ValueArray5<T1, T2, T3, T4, T5> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5) { + return internal::ValueArray5<T1, T2, T3, T4, T5>(v1, v2, v3, v4, v5); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +internal::ValueArray6<T1, T2, T3, T4, T5, T6> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6) { + return internal::ValueArray6<T1, T2, T3, T4, T5, T6>(v1, v2, v3, v4, v5, v6); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7) { + return internal::ValueArray7<T1, T2, T3, T4, T5, T6, T7>(v1, v2, v3, v4, v5, + v6, v7); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { + return internal::ValueArray8<T1, T2, T3, T4, T5, T6, T7, T8>(v1, v2, v3, v4, + v5, v6, v7, v8); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { + return internal::ValueArray9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(v1, v2, v3, + v4, v5, v6, v7, v8, v9); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { + return internal::ValueArray10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, + T11> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) { + return internal::ValueArray11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, + T11>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) { + return internal::ValueArray12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) { + return internal::ValueArray13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { + return internal::ValueArray14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { + return internal::ValueArray15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) { + return internal::ValueArray16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) { + return internal::ValueArray17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) { + return internal::ValueArray18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18>(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { + return internal::ValueArray19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19>(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { + return internal::ValueArray20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20>(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { + return internal::ValueArray21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) { + return internal::ValueArray22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) { + return internal::ValueArray23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) { + return internal::ValueArray24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { + return internal::ValueArray25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25>(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) { + return internal::ValueArray26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) { + return internal::ValueArray27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) { + return internal::ValueArray28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) { + return internal::ValueArray29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { + return internal::ValueArray30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { + return internal::ValueArray31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) { + return internal::ValueArray32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32>(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) { + return internal::ValueArray33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33>(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) { + return internal::ValueArray34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34>(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { + return internal::ValueArray35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35>(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { + return internal::ValueArray36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36>(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37> Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) { + return internal::ValueArray37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37>(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) { + return internal::ValueArray38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38>(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) { + return internal::ValueArray39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39>(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { + return internal::ValueArray40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { + return internal::ValueArray41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) { + return internal::ValueArray42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) { + return internal::ValueArray43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) { + return internal::ValueArray44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { + return internal::ValueArray45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45>(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { + return internal::ValueArray46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46>(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { + return internal::ValueArray47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47>(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) { + return internal::ValueArray48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47, T48>(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49> Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) { + return internal::ValueArray49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47, T48, T49>(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { + return internal::ValueArray50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26, T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40, T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); +} + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam<bool> { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator<bool> Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to 10 arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam<tuple<const char*, Color> > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam<tuple(bool, bool)> > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +template <typename Generator1, typename Generator2> +internal::CartesianProductHolder2<Generator1, Generator2> Combine( + const Generator1& g1, const Generator2& g2) { + return internal::CartesianProductHolder2<Generator1, Generator2>( + g1, g2); +} + +template <typename Generator1, typename Generator2, typename Generator3> +internal::CartesianProductHolder3<Generator1, Generator2, Generator3> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3) { + return internal::CartesianProductHolder3<Generator1, Generator2, Generator3>( + g1, g2, g3); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4> +internal::CartesianProductHolder4<Generator1, Generator2, Generator3, + Generator4> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) { + return internal::CartesianProductHolder4<Generator1, Generator2, Generator3, + Generator4>( + g1, g2, g3, g4); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5> +internal::CartesianProductHolder5<Generator1, Generator2, Generator3, + Generator4, Generator5> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) { + return internal::CartesianProductHolder5<Generator1, Generator2, Generator3, + Generator4, Generator5>( + g1, g2, g3, g4, g5); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6> +internal::CartesianProductHolder6<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) { + return internal::CartesianProductHolder6<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6>( + g1, g2, g3, g4, g5, g6); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7> +internal::CartesianProductHolder7<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) { + return internal::CartesianProductHolder7<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7>( + g1, g2, g3, g4, g5, g6, g7); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8> +internal::CartesianProductHolder8<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) { + return internal::CartesianProductHolder8<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8>( + g1, g2, g3, g4, g5, g6, g7, g8); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8, typename Generator9> +internal::CartesianProductHolder9<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, + Generator9> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) { + return internal::CartesianProductHolder9<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, Generator9>( + g1, g2, g3, g4, g5, g6, g7, g8, g9); +} + +template <typename Generator1, typename Generator2, typename Generator3, + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8, typename Generator9, + typename Generator10> +internal::CartesianProductHolder10<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, Generator9, + Generator10> Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) { + return internal::CartesianProductHolder10<Generator1, Generator2, Generator3, + Generator4, Generator5, Generator6, Generator7, Generator8, Generator9, + Generator10>( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); +} +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder<test_case_name>(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator<test_case_name::ParamType> \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder<test_case_name>(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/lib/gtest/include/gtest/gtest-param-test.h.pump b/lib/gtest/include/gtest/gtest-param-test.h.pump new file mode 100644 index 0000000..401cb51 --- /dev/null +++ b/lib/gtest/include/gtest/gtest-param-test.h.pump @@ -0,0 +1,487 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of Values arguments we want to support. +$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: vladl@google.com (Vlad Losev) +// +// Macros and functions for implementing parameterized tests +// in Google C++ Testing Framework (Google Test) +// +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +#ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ + + +// Value-parameterized tests allow you to test your code with different +// parameters without writing multiple copies of the same test. +// +// Here is how you use value-parameterized tests: + +#if 0 + +// To write value-parameterized tests, first you should define a fixture +// class. It is usually derived from testing::TestWithParam<T> (see below for +// another inheritance scheme that's sometimes useful in more complicated +// class hierarchies), where the type of your parameter values. +// TestWithParam<T> is itself derived from testing::Test. T can be any +// copyable type. If it's a raw pointer, you are responsible for managing the +// lifespan of the pointed values. + +class FooTest : public ::testing::TestWithParam<const char*> { + // You can implement all the usual class fixture members here. +}; + +// Then, use the TEST_P macro to define as many parameterized tests +// for this fixture as you want. The _P suffix is for "parameterized" +// or "pattern", whichever you prefer to think. + +TEST_P(FooTest, DoesBlah) { + // Inside a test, access the test parameter with the GetParam() method + // of the TestWithParam<T> class: + EXPECT_TRUE(foo.Blah(GetParam())); + ... +} + +TEST_P(FooTest, HasBlahBlah) { + ... +} + +// Finally, you can use INSTANTIATE_TEST_CASE_P to instantiate the test +// case with any set of parameters you want. Google Test defines a number +// of functions for generating test parameters. They return what we call +// (surprise!) parameter generators. Here is a summary of them, which +// are all in the testing namespace: +// +// +// Range(begin, end [, step]) - Yields values {begin, begin+step, +// begin+step+step, ...}. The values do not +// include end. step defaults to 1. +// Values(v1, v2, ..., vN) - Yields values {v1, v2, ..., vN}. +// ValuesIn(container) - Yields values from a C-style array, an STL +// ValuesIn(begin,end) container, or an iterator range [begin, end). +// Bool() - Yields sequence {false, true}. +// Combine(g1, g2, ..., gN) - Yields all combinations (the Cartesian product +// for the math savvy) of the values generated +// by the N generators. +// +// For more details, see comments at the definitions of these functions below +// in this file. +// +// The following statement will instantiate tests from the FooTest test case +// each with parameter values "meeny", "miny", and "moe". + +INSTANTIATE_TEST_CASE_P(InstantiationName, + FooTest, + Values("meeny", "miny", "moe")); + +// To distinguish different instances of the pattern, (yes, you +// can instantiate it more then once) the first argument to the +// INSTANTIATE_TEST_CASE_P macro is a prefix that will be added to the +// actual test case name. Remember to pick unique prefixes for different +// instantiations. The tests from the instantiation above will have +// these names: +// +// * InstantiationName/FooTest.DoesBlah/0 for "meeny" +// * InstantiationName/FooTest.DoesBlah/1 for "miny" +// * InstantiationName/FooTest.DoesBlah/2 for "moe" +// * InstantiationName/FooTest.HasBlahBlah/0 for "meeny" +// * InstantiationName/FooTest.HasBlahBlah/1 for "miny" +// * InstantiationName/FooTest.HasBlahBlah/2 for "moe" +// +// You can use these names in --gtest_filter. +// +// This statement will instantiate all tests from FooTest again, each +// with parameter values "cat" and "dog": + +const char* pets[] = {"cat", "dog"}; +INSTANTIATE_TEST_CASE_P(AnotherInstantiationName, FooTest, ValuesIn(pets)); + +// The tests from the instantiation above will have these names: +// +// * AnotherInstantiationName/FooTest.DoesBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.DoesBlah/1 for "dog" +// * AnotherInstantiationName/FooTest.HasBlahBlah/0 for "cat" +// * AnotherInstantiationName/FooTest.HasBlahBlah/1 for "dog" +// +// Please note that INSTANTIATE_TEST_CASE_P will instantiate all tests +// in the given test case, whether their definitions come before or +// AFTER the INSTANTIATE_TEST_CASE_P statement. +// +// Please also note that generator expressions (including parameters to the +// generators) are evaluated in InitGoogleTest(), after main() has started. +// This allows the user on one hand, to adjust generator parameters in order +// to dynamically determine a set of tests to run and on the other hand, +// give the user a chance to inspect the generated tests with Google Test +// reflection API before RUN_ALL_TESTS() is executed. +// +// You can see samples/sample7_unittest.cc and samples/sample8_unittest.cc +// for more examples. +// +// In the future, we plan to publish the API for defining new parameter +// generators. But for now this interface remains part of the internal +// implementation and is subject to change. +// +// +// A parameterized test fixture must be derived from testing::Test and from +// testing::WithParamInterface<T>, where T is the type of the parameter +// values. Inheriting from TestWithParam<T> satisfies that requirement because +// TestWithParam<T> inherits from both Test and WithParamInterface. In more +// complicated hierarchies, however, it is occasionally useful to inherit +// separately from Test and WithParamInterface. For example: + +class BaseTest : public ::testing::Test { + // You can inherit all the usual members for a non-parameterized test + // fixture here. +}; + +class DerivedTest : public BaseTest, public ::testing::WithParamInterface<int> { + // The usual test fixture members go here too. +}; + +TEST_F(BaseTest, HasFoo) { + // This is an ordinary non-parameterized test. +} + +TEST_P(DerivedTest, DoesBlah) { + // GetParam works just the same here as if you inherit from TestWithParam. + EXPECT_TRUE(foo.Blah(GetParam())); +} + +#endif // 0 + +#include "gtest/internal/gtest-port.h" + +#if !GTEST_OS_SYMBIAN +# include <utility> +#endif + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-param-util-generated.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Functions producing parameter generators. +// +// Google Test uses these generators to produce parameters for value- +// parameterized tests. When a parameterized test case is instantiated +// with a particular generator, Google Test creates and runs tests +// for each element in the sequence produced by the generator. +// +// In the following sample, tests from test case FooTest are instantiated +// each three times with parameter values 3, 5, and 8: +// +// class FooTest : public TestWithParam<int> { ... }; +// +// TEST_P(FooTest, TestThis) { +// } +// TEST_P(FooTest, TestThat) { +// } +// INSTANTIATE_TEST_CASE_P(TestSequence, FooTest, Values(3, 5, 8)); +// + +// Range() returns generators providing sequences of values in a range. +// +// Synopsis: +// Range(start, end) +// - returns a generator producing a sequence of values {start, start+1, +// start+2, ..., }. +// Range(start, end, step) +// - returns a generator producing a sequence of values {start, start+step, +// start+step+step, ..., }. +// Notes: +// * The generated sequences never include end. For example, Range(1, 5) +// returns a generator producing a sequence {1, 2, 3, 4}. Range(1, 9, 2) +// returns a generator producing {1, 3, 5, 7}. +// * start and end must have the same type. That type may be any integral or +// floating-point type or a user defined type satisfying these conditions: +// * It must be assignable (have operator=() defined). +// * It must have operator+() (operator+(int-compatible type) for +// two-operand version). +// * It must have operator<() defined. +// Elements in the resulting sequences will also have that type. +// * Condition start < end must be satisfied in order for resulting sequences +// to contain any elements. +// +template <typename T, typename IncrementT> +internal::ParamGenerator<T> Range(T start, T end, IncrementT step) { + return internal::ParamGenerator<T>( + new internal::RangeGenerator<T, IncrementT>(start, end, step)); +} + +template <typename T> +internal::ParamGenerator<T> Range(T start, T end) { + return Range(start, end, 1); +} + +// ValuesIn() function allows generation of tests with parameters coming from +// a container. +// +// Synopsis: +// ValuesIn(const T (&array)[N]) +// - returns a generator producing sequences with elements from +// a C-style array. +// ValuesIn(const Container& container) +// - returns a generator producing sequences with elements from +// an STL-style container. +// ValuesIn(Iterator begin, Iterator end) +// - returns a generator producing sequences with elements from +// a range [begin, end) defined by a pair of STL-style iterators. These +// iterators can also be plain C pointers. +// +// Please note that ValuesIn copies the values from the containers +// passed in and keeps them to generate tests in RUN_ALL_TESTS(). +// +// Examples: +// +// This instantiates tests from test case StringTest +// each with C-string values of "foo", "bar", and "baz": +// +// const char* strings[] = {"foo", "bar", "baz"}; +// INSTANTIATE_TEST_CASE_P(StringSequence, SrtingTest, ValuesIn(strings)); +// +// This instantiates tests from test case StlStringTest +// each with STL strings with values "a" and "b": +// +// ::std::vector< ::std::string> GetParameterStrings() { +// ::std::vector< ::std::string> v; +// v.push_back("a"); +// v.push_back("b"); +// return v; +// } +// +// INSTANTIATE_TEST_CASE_P(CharSequence, +// StlStringTest, +// ValuesIn(GetParameterStrings())); +// +// +// This will also instantiate tests from CharTest +// each with parameter values 'a' and 'b': +// +// ::std::list<char> GetParameterChars() { +// ::std::list<char> list; +// list.push_back('a'); +// list.push_back('b'); +// return list; +// } +// ::std::list<char> l = GetParameterChars(); +// INSTANTIATE_TEST_CASE_P(CharSequence2, +// CharTest, +// ValuesIn(l.begin(), l.end())); +// +template <typename ForwardIterator> +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) { + typedef typename ::testing::internal::IteratorTraits<ForwardIterator> + ::value_type ParamType; + return internal::ParamGenerator<ParamType>( + new internal::ValuesInIteratorRangeGenerator<ParamType>(begin, end)); +} + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]) { + return ValuesIn(array, array + N); +} + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( + const Container& container) { + return ValuesIn(container.begin(), container.end()); +} + +// Values() allows generating tests from explicitly specified list of +// parameters. +// +// Synopsis: +// Values(T v1, T v2, ..., T vN) +// - returns a generator producing sequences with elements v1, v2, ..., vN. +// +// For example, this instantiates tests from test case BarTest each +// with values "one", "two", and "three": +// +// INSTANTIATE_TEST_CASE_P(NumSequence, BarTest, Values("one", "two", "three")); +// +// This instantiates tests from test case BazTest each with values 1, 2, 3.5. +// The exact type of values will depend on the type of parameter in BazTest. +// +// INSTANTIATE_TEST_CASE_P(FloatingNumbers, BazTest, Values(1, 2, 3.5)); +// +// Currently, Values() supports from 1 to $n parameters. +// +$range i 1..n +$for i [[ +$range j 1..i + +template <$for j, [[typename T$j]]> +internal::ValueArray$i<$for j, [[T$j]]> Values($for j, [[T$j v$j]]) { + return internal::ValueArray$i<$for j, [[T$j]]>($for j, [[v$j]]); +} + +]] + +// Bool() allows generating tests with parameters in a set of (false, true). +// +// Synopsis: +// Bool() +// - returns a generator producing sequences with elements {false, true}. +// +// It is useful when testing code that depends on Boolean flags. Combinations +// of multiple flags can be tested when several Bool()'s are combined using +// Combine() function. +// +// In the following example all tests in the test case FlagDependentTest +// will be instantiated twice with parameters false and true. +// +// class FlagDependentTest : public testing::TestWithParam<bool> { +// virtual void SetUp() { +// external_flag = GetParam(); +// } +// } +// INSTANTIATE_TEST_CASE_P(BoolSequence, FlagDependentTest, Bool()); +// +inline internal::ParamGenerator<bool> Bool() { + return Values(false, true); +} + +# if GTEST_HAS_COMBINE +// Combine() allows the user to combine two or more sequences to produce +// values of a Cartesian product of those sequences' elements. +// +// Synopsis: +// Combine(gen1, gen2, ..., genN) +// - returns a generator producing sequences with elements coming from +// the Cartesian product of elements from the sequences generated by +// gen1, gen2, ..., genN. The sequence elements will have a type of +// tuple<T1, T2, ..., TN> where T1, T2, ..., TN are the types +// of elements from sequences produces by gen1, gen2, ..., genN. +// +// Combine can have up to $maxtuple arguments. This number is currently limited +// by the maximum number of elements in the tuple implementation used by Google +// Test. +// +// Example: +// +// This will instantiate tests in test case AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// class AnimalTest +// : public testing::TestWithParam<tuple<const char*, Color> > {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_CASE_P(AnimalVariations, AnimalTest, +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE))); +// +// This will instantiate tests in FlagDependentTest with all variations of two +// Boolean flags: +// +// class FlagDependentTest +// : public testing::TestWithParam<tuple(bool, bool)> > { +// virtual void SetUp() { +// // Assigns external_flag_1 and external_flag_2 values from the tuple. +// tie(external_flag_1, external_flag_2) = GetParam(); +// } +// }; +// +// TEST_P(FlagDependentTest, TestFeature1) { +// // Test your code using external_flag_1 and external_flag_2 here. +// } +// INSTANTIATE_TEST_CASE_P(TwoBoolSequence, FlagDependentTest, +// Combine(Bool(), Bool())); +// +$range i 2..maxtuple +$for i [[ +$range j 1..i + +template <$for j, [[typename Generator$j]]> +internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( + $for j, [[const Generator$j& g$j]]) { + return internal::CartesianProductHolder$i<$for j, [[Generator$j]]>( + $for j, [[g$j]]); +} + +]] +# endif // GTEST_HAS_COMBINE + + + +# define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ + virtual void TestBody(); \ + private: \ + static int AddToRegistry() { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder<test_case_name>(\ + #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator<test_case_name::ParamType> \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ + GetTestCasePatternHolder<test_case_name>(\ + #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) + +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ diff --git a/lib/gtest/include/gtest/gtest-printers.h b/lib/gtest/include/gtest/gtest-printers.h new file mode 100644 index 0000000..9cbab3f --- /dev/null +++ b/lib/gtest/include/gtest/gtest-printers.h @@ -0,0 +1,796 @@ +// Copyright 2007, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr); +// +// A user can teach this function how to print a class type T by +// defining either operator<<() or PrintTo() in the namespace that +// defines T. More specifically, the FIRST defined function in the +// following list will be used (assuming T is defined in namespace +// foo): +// +// 1. foo::PrintTo(const T&, ostream*) +// 2. operator<<(ostream&, const T&) defined in either foo or the +// global namespace. +// +// If none of the above is defined, it will print the debug string of +// the value if it is a protocol buffer, or print the raw bytes in the +// value otherwise. +// +// To aid debugging: when T is a reference type, the address of the +// value is also printed; when T is a (const) char pointer, both the +// pointer value and the NUL-terminated string it points to are +// printed. +// +// We also provide some convenient wrappers: +// +// // Prints a value to a string. For a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// std::string ::testing::PrintToString(const T& value); +// +// // Prints a value tersely: for a reference type, the referenced +// // value (but not the address) is printed; for a (const or not) char +// // pointer, the NUL-terminated string (but not the pointer) is +// // printed. +// void ::testing::internal::UniversalTersePrint(const T& value, ostream*); +// +// // Prints value using the type inferred by the compiler. The difference +// // from UniversalTersePrint() is that this function prints both the +// // pointer and the NUL-terminated string for a (const or not) char pointer. +// void ::testing::internal::UniversalPrint(const T& value, ostream*); +// +// // Prints the fields of a tuple tersely to a string vector, one +// // element for each field. Tuple support must be enabled in +// // gtest-port.h. +// std::vector<string> UniversalTersePrintTupleFieldsToStrings( +// const Tuple& value); +// +// Known limitation: +// +// The print primitives print the elements of an STL-style container +// using the compiler-inferred type of *iter where iter is a +// const_iterator of the container. When const_iterator is an input +// iterator but not a forward iterator, this inferred type may not +// match value_type, and the print output may be incorrect. In +// practice, this is rarely a problem as for most containers +// const_iterator is a forward iterator. We'll fix this if there's an +// actual need for it. Note that this fix cannot rely on value_type +// being defined as many user-defined container types don't have +// value_type. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ + +#include <ostream> // NOLINT +#include <sstream> +#include <string> +#include <utility> +#include <vector> +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-internal.h" + +namespace testing { + +// Definitions in the 'internal' and 'internal2' name spaces are +// subject to change without notice. DO NOT USE THEM IN USER CODE! +namespace internal2 { + +// Prints the given number of bytes in the given object to the given +// ostream. +GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, + size_t count, + ::std::ostream* os); + +// For selecting which printer to use when a given type has neither << +// nor PrintTo(). +enum TypeKind { + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType // anything else +}; + +// TypeWithoutFormatter<T, kTypeKind>::PrintValue(value, os) is called +// by the universal printer to print a value of type T when neither +// operator<< nor PrintTo() is defined for T, where kTypeKind is the +// "kind" of T as defined by enum TypeKind. +template <typename T, TypeKind kTypeKind> +class TypeWithoutFormatter { + public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) { + PrintBytesInObjectTo(reinterpret_cast<const unsigned char*>(&value), + sizeof(value), os); + } +}; + +// We print a protobuf using its ShortDebugString() when the string +// doesn't exceed this many characters; otherwise we print it using +// DebugString() for better readability. +const size_t kProtobufOneLinerMaxLength = 50; + +template <typename T> +class TypeWithoutFormatter<T, kProtobuf> { + public: + static void PrintValue(const T& value, ::std::ostream* os) { + const ::testing::internal::string short_str = value.ShortDebugString(); + const ::testing::internal::string pretty_str = + short_str.length() <= kProtobufOneLinerMaxLength ? + short_str : ("\n" + value.DebugString()); + *os << ("<" + pretty_str + ">"); + } +}; + +template <typename T> +class TypeWithoutFormatter<T, kConvertibleToInteger> { + public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } +}; + +// Prints the given value to the given ostream. If the value is a +// protocol message, its debug string is printed; if it's an enum or +// of a type implicitly convertible to BiggestInt, it's printed as an +// integer; otherwise the bytes in the value are printed. This is +// what UniversalPrinter<T>::Print() does when it knows nothing about +// type T and T has neither << operator nor PrintTo(). +// +// A user can override this behavior for a class type Foo by defining +// a << operator in the namespace where Foo is defined. +// +// We put this operator in namespace 'internal2' instead of 'internal' +// to simplify the implementation, as much code in 'internal' needs to +// use << in STL, which would conflict with our own << were it defined +// in 'internal'. +// +// Note that this operator<< takes a generic std::basic_ostream<Char, +// CharTraits> type instead of the more restricted std::ostream. If +// we define it to take an std::ostream instead, we'll get an +// "ambiguous overloads" compiler error when trying to print a type +// Foo that supports streaming to std::basic_ostream<Char, +// CharTraits>, as the compiler cannot tell whether +// operator<<(std::ostream&, const T&) or +// operator<<(std::basic_stream<Char, CharTraits>, const Foo&) is more +// specific. +template <typename Char, typename CharTraits, typename T> +::std::basic_ostream<Char, CharTraits>& operator<<( + ::std::basic_ostream<Char, CharTraits>& os, const T& x) { + TypeWithoutFormatter<T, + (internal::IsAProtocolMessage<T>::value ? kProtobuf : + internal::ImplicitlyConvertible<const T&, internal::BiggestInt>::value ? + kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + return os; +} + +} // namespace internal2 +} // namespace testing + +// This namespace MUST NOT BE NESTED IN ::testing, or the name look-up +// magic needed for implementing UniversalPrinter won't work. +namespace testing_internal { + +// Used to print a value that is not an STL-style container when the +// user doesn't define PrintTo() for it. +template <typename T> +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT + + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; +} + +} // namespace testing_internal + +namespace testing { +namespace internal { + +// UniversalPrinter<T>::Print(value, ostream_ptr) prints the given +// value to the given ostream. The caller must ensure that +// 'ostream_ptr' is not NULL, or the behavior is undefined. +// +// We define UniversalPrinter as a class template (as opposed to a +// function template), as we need to partially specialize it for +// reference types, which cannot be done with function templates. +template <typename T> +class UniversalPrinter; + +template <typename T> +void UniversalPrint(const T& value, ::std::ostream* os); + +// Used to print an STL-style container when the user doesn't define +// a PrintTo() for it. +template <typename C> +void DefaultPrintTo(IsContainer /* dummy */, + false_type /* is not a pointer */, + const C& container, ::std::ostream* os) { + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) { + if (count > 0) { + *os << ','; + if (count == kMaxCount) { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } + + if (count > 0) { + *os << ' '; + } + *os << '}'; +} + +// Used to print a pointer that is neither a char pointer nor a member +// pointer, when the user doesn't define PrintTo() for it. (A member +// variable pointer or member function pointer doesn't really point to +// a location in the address space. Their representation is +// implementation-defined. Therefore they will be printed as raw +// bytes.) +template <typename T> +void DefaultPrintTo(IsNotContainer /* dummy */, + true_type /* is a pointer */, + T* p, ::std::ostream* os) { + if (p == NULL) { + *os << "NULL"; + } else { + // C++ doesn't allow casting from a function pointer to any object + // pointer. + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible<T*, const void*>::value)) { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } else { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. However, we cannot cast it to const void* directly, + // even using reinterpret_cast, as earlier versions of gcc + // (e.g. 3.4.5) cannot compile the cast when p is a function + // pointer. Casting to UInt64 first solves the problem. + *os << reinterpret_cast<const void*>( + reinterpret_cast<internal::UInt64>(p)); + } + } +} + +// Used to print a non-container, non-pointer value when the user +// doesn't define PrintTo() for it. +template <typename T> +void DefaultPrintTo(IsNotContainer /* dummy */, + false_type /* is not a pointer */, + const T& value, ::std::ostream* os) { + ::testing_internal::DefaultPrintNonContainerTo(value, os); +} + +// Prints the given value using the << operator if it has one; +// otherwise prints the bytes in it. This is what +// UniversalPrinter<T>::Print() does when PrintTo() is not specialized +// or overloaded for type T. +// +// A user can override this behavior for a class type Foo by defining +// an overload of PrintTo() in the namespace where Foo is defined. We +// give the user this option as sometimes defining a << operator for +// Foo is not desirable (e.g. the coding style may prevent doing it, +// or there is already a << operator but it doesn't do what the user +// wants). +template <typename T> +void PrintTo(const T& value, ::std::ostream* os) { + // DefaultPrintTo() is overloaded. The type of its first two + // arguments determine which version will be picked. If T is an + // STL-style container, the version for container will be called; if + // T is a pointer, the pointer version will be called; otherwise the + // generic version will be called. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // The second argument of DefaultPrintTo() is needed to bypass a bug + // in Symbian's C++ compiler that prevents it from picking the right + // overload between: + // + // PrintTo(const T& x, ...); + // PrintTo(T* x, ...); + DefaultPrintTo(IsContainerTest<T>(0), is_pointer<T>(), value, os); +} + +// The following list of PrintTo() overloads tells +// UniversalPrinter<T>::Print() how to print standard types (built-in +// types, strings, plain arrays, and pointers). + +// Overloads for various char types. +GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); +GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); +inline void PrintTo(char c, ::std::ostream* os) { + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast<unsigned char>(c), os); +} + +// Overloads for other simple built-in types. +inline void PrintTo(bool x, ::std::ostream* os) { + *os << (x ? "true" : "false"); +} + +// Overload for wchar_t type. +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its decimal code (except for L'\0'). +// The L'\0' char is printed as "L'\\0'". The decimal code is printed +// as signed integer when wchar_t is implemented by the compiler +// as a signed type and is printed as an unsigned integer when wchar_t +// is implemented as an unsigned type. +GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); + +// Overloads for C strings. +GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); +inline void PrintTo(char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_<const char*>(s), os); +} + +// signed/unsigned char is often used for representing binary data, so +// we print pointers to it as void* to be safe. +inline void PrintTo(const signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_<const void*>(s), os); +} +inline void PrintTo(signed char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_<const void*>(s), os); +} +inline void PrintTo(const unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_<const void*>(s), os); +} +inline void PrintTo(unsigned char* s, ::std::ostream* os) { + PrintTo(ImplicitCast_<const void*>(s), os); +} + +// MSVC can be configured to define wchar_t as a typedef of unsigned +// short. It defines _NATIVE_WCHAR_T_DEFINED when wchar_t is a native +// type. When wchar_t is a typedef, defining an overload for const +// wchar_t* would cause unsigned short* be printed as a wide string, +// possibly causing invalid memory accesses. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Overloads for wide C strings +GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) { + PrintTo(ImplicitCast_<const wchar_t*>(s), os); +} +#endif + +// Overload for C arrays. Multi-dimensional arrays are printed +// properly. + +// Prints the given number of elements in an array, without printing +// the curly braces. +template <typename T> +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) { + *os << ", "; + UniversalPrint(a[i], os); + } +} + +// Overloads for ::string and ::std::string. +#if GTEST_HAS_GLOBAL_STRING +GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); +inline void PrintTo(const ::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) { + PrintStringTo(s, os); +} + +// Overloads for ::wstring and ::std::wstring. +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { + PrintWideStringTo(s, os); +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_TR1_TUPLE +// Overload for ::std::tr1::tuple. Needed for printing function arguments, +// which are packed as tuples. + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template <typename T> +void PrintTupleTo(const T& t, ::std::ostream* os); + +// Overloaded PrintTo() for tuples of various arities. We support +// tuples of up-to 10 fields. The following implementation works +// regardless of whether tr1::tuple is implemented using the +// non-standard variadic template feature or not. + +inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1> +void PrintTo(const ::std::tr1::tuple<T1>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2> +void PrintTo(const ::std::tr1::tuple<T1, T2>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3> +void PrintTo(const ::std::tr1::tuple<T1, T2, T3>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3, typename T4> +void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4>& t, ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5>& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6>& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7>& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8>& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +void PrintTo(const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9>& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +void PrintTo( + const ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>& t, + ::std::ostream* os) { + PrintTupleTo(t, os); +} +#endif // GTEST_HAS_TR1_TUPLE + +// Overload for std::pair. +template <typename T1, typename T2> +void PrintTo(const ::std::pair<T1, T2>& value, ::std::ostream* os) { + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter<T1>::Print(value.first, os); + *os << ", "; + UniversalPrinter<T2>::Print(value.second, os); + *os << ')'; +} + +// Implements printing a non-reference type T by letting the compiler +// pick the right overload of PrintTo() for T. +template <typename T> +class UniversalPrinter { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// UniversalPrintArray(begin, len, os) prints an array of 'len' +// elements, starting at address 'begin'. +template <typename T> +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { + if (len == 0) { + *os << "{}"; + } else { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + // TODO(wan@google.com): let the user control the threshold using a flag. + if (len <= kThreshold) { + PrintRawArrayTo(begin, len, os); + } else { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } +} +// This overload prints a (const) char array compactly. +GTEST_API_ void UniversalPrintArray(const char* begin, + size_t len, + ::std::ostream* os); + +// Implements printing an array type T[N]. +template <typename T, size_t N> +class UniversalPrinter<T[N]> { + public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) { + UniversalPrintArray(a, N, os); + } +}; + +// Implements printing a reference type T&. +template <typename T> +class UniversalPrinter<T&> { + public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4180) // Temporarily disables warning 4180. +#endif // _MSC_VER + + static void Print(const T& value, ::std::ostream* os) { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast<const void*>(&value) << " "; + + // Then prints the value itself. + UniversalPrint(value, os); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER +}; + +// Prints a value tersely: for a reference type, the referenced value +// (but not the address) is printed; for a (const) char pointer, the +// NUL-terminated string (but not the pointer) is printed. +template <typename T> +void UniversalTersePrint(const T& value, ::std::ostream* os) { + UniversalPrint(value, os); +} +inline void UniversalTersePrint(const char* str, ::std::ostream* os) { + if (str == NULL) { + *os << "NULL"; + } else { + UniversalPrint(string(str), os); + } +} +inline void UniversalTersePrint(char* str, ::std::ostream* os) { + UniversalTersePrint(static_cast<const char*>(str), os); +} + +// Prints a value using the type inferred by the compiler. The +// difference between this and UniversalTersePrint() is that for a +// (const) char pointer, this prints both the pointer and the +// NUL-terminated string. +template <typename T> +void UniversalPrint(const T& value, ::std::ostream* os) { + UniversalPrinter<T>::Print(value, os); +} + +#if GTEST_HAS_TR1_TUPLE +typedef ::std::vector<string> Strings; + +// This helper template allows PrintTo() for tuples and +// UniversalTersePrintTupleFieldsToStrings() to be defined by +// induction on the number of tuple fields. The idea is that +// TuplePrefixPrinter<N>::PrintPrefixTo(t, os) prints the first N +// fields in tuple t, and can be defined in terms of +// TuplePrefixPrinter<N - 1>. + +// The inductive case. +template <size_t N> +struct TuplePrefixPrinter { + // Prints the first N fields of a tuple. + template <typename Tuple> + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + TuplePrefixPrinter<N - 1>::PrintPrefixTo(t, os); + *os << ", "; + UniversalPrinter<typename ::std::tr1::tuple_element<N - 1, Tuple>::type> + ::Print(::std::tr1::get<N - 1>(t), os); + } + + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. + template <typename Tuple> + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + TuplePrefixPrinter<N - 1>::TersePrintPrefixToStrings(t, strings); + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<N - 1>(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Base cases. +template <> +struct TuplePrefixPrinter<0> { + template <typename Tuple> + static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} + + template <typename Tuple> + static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} +}; +// We have to specialize the entire TuplePrefixPrinter<> class +// template here, even though the definition of +// TersePrintPrefixToStrings() is the same as the generic version, as +// Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't +// support specializing a method template of a class template. +template <> +struct TuplePrefixPrinter<1> { + template <typename Tuple> + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { + UniversalPrinter<typename ::std::tr1::tuple_element<0, Tuple>::type>:: + Print(::std::tr1::get<0>(t), os); + } + + template <typename Tuple> + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<0>(t), &ss); + strings->push_back(ss.str()); + } +}; + +// Helper function for printing a tuple. T must be instantiated with +// a tuple type. +template <typename T> +void PrintTupleTo(const T& t, ::std::ostream* os) { + *os << "("; + TuplePrefixPrinter< ::std::tr1::tuple_size<T>::value>:: + PrintPrefixTo(t, os); + *os << ")"; +} + +// Prints the fields of a tuple tersely to a string vector, one +// element for each field. See the comment before +// UniversalTersePrint() for how we define "tersely". +template <typename Tuple> +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { + Strings result; + TuplePrefixPrinter< ::std::tr1::tuple_size<Tuple>::value>:: + TersePrintPrefixToStrings(value, &result); + return result; +} +#endif // GTEST_HAS_TR1_TUPLE + +} // namespace internal + +template <typename T> +::std::string PrintToString(const T& value) { + ::std::stringstream ss; + internal::UniversalTersePrint(value, &ss); + return ss.str(); +} + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ diff --git a/lib/gtest/include/gtest/gtest-spi.h b/lib/gtest/include/gtest/gtest-spi.h new file mode 100644 index 0000000..b226e55 --- /dev/null +++ b/lib/gtest/include/gtest/gtest-spi.h @@ -0,0 +1,232 @@ +// Copyright 2007, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Utilities for testing Google Test itself and code that uses Google Test +// (e.g. frameworks built on top of Google Test). + +#ifndef GTEST_INCLUDE_GTEST_GTEST_SPI_H_ +#define GTEST_INCLUDE_GTEST_GTEST_SPI_H_ + +#include "gtest/gtest.h" + +namespace testing { + +// This helper class can be used to mock out Google Test failure reporting +// so that we can test Google Test or code that builds on Google Test. +// +// An object of this class appends a TestPartResult object to the +// TestPartResultArray object given in the constructor whenever a Google Test +// failure is reported. It can either intercept only failures that are +// generated in the same thread that created this object or it can intercept +// all generated failures. The scope of this mock object can be controlled with +// the second argument to the two arguments constructor. +class GTEST_API_ ScopedFakeTestPartResultReporter + : public TestPartResultReporterInterface { + public: + // The two possible mocking modes of this object. + enum InterceptMode { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; + + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); + + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); + + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); + private: + void Init(); + + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); +}; + +namespace internal { + +// A helper class for implementing EXPECT_FATAL_FAILURE() and +// EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +class GTEST_API_ SingleFailureChecker { + public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr); + ~SingleFailureChecker(); + private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +}; + +} // namespace internal + +} // namespace testing + +// A set of macros for testing Google Test assertions or code that's expected +// to generate Google Test fatal failures. It verifies that the given +// statement will cause exactly one fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_FATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_FATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - 'statement' cannot reference local non-static variables or +// non-static members of the current object. +// - 'statement' cannot return a value. +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. The AcceptsMacroThatExpandsToUnprotectedComma test in +// gtest_unittest.cc will fail to compile if we do that. +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do { \ + class GTestExpectFatalFailureHelper {\ + public:\ + static void Execute() { statement; }\ + };\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, >est_failures);\ + GTestExpectFatalFailureHelper::Execute();\ + }\ + } while (::testing::internal::AlwaysFalse()) + +// A macro for testing Google Test assertions or code that's expected to +// generate Google Test non-fatal failures. It asserts that the given +// statement will cause exactly one non-fatal Google Test failure with 'substr' +// being part of the failure message. +// +// There are two different versions of this macro. EXPECT_NONFATAL_FAILURE only +// affects and considers failures generated in the current thread and +// EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS does the same but for all threads. +// +// 'statement' is allowed to reference local variables and members of +// the current object. +// +// The verification of the assertion is done correctly even when the statement +// throws an exception or aborts the current function. +// +// Known restrictions: +// - You cannot stream a failure message to this macro. +// +// Note that even though the implementations of the following two +// macros are much alike, we cannot refactor them to use a common +// helper macro, due to some peculiarity in how the preprocessor +// works. If we do that, the code won't compile when the user gives +// EXPECT_NONFATAL_FAILURE() a statement that contains a macro that +// expands to code containing an unprotected comma. The +// AcceptsMacroThatExpandsToUnprotectedComma test in gtest_unittest.cc +// catches that. +// +// For the same reason, we have to write +// if (::testing::internal::AlwaysTrue()) { statement; } +// instead of +// GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +// to avoid an MSVC warning on unreachable code. +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do {\ + ::testing::TestPartResultArray gtest_failures;\ + ::testing::internal::SingleFailureChecker gtest_checker(\ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr));\ + {\ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS,\ + >est_failures);\ + if (::testing::internal::AlwaysTrue()) { statement; }\ + }\ + } while (::testing::internal::AlwaysFalse()) + +#endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/lib/gtest/include/gtest/gtest-test-part.h b/lib/gtest/include/gtest/gtest-test-part.h new file mode 100644 index 0000000..8aeea14 --- /dev/null +++ b/lib/gtest/include/gtest/gtest-test-part.h @@ -0,0 +1,176 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: mheule@google.com (Markus Heule) +// + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ + +#include <iosfwd> +#include <vector> +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +namespace testing { + +// A copyable object representing the result of a test part (i.e. an +// assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). +// +// Don't inherit from TestPartResult as its destructor is not virtual. +class GTEST_API_ TestPartResult { + public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; + + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) { + } + + // Gets the outcome of the test part. + Type type() const { return type_; } + + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const { return file_name_.c_str(); } + + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } + + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } + + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } + + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } + + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } + + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } + private: + Type type_; + + // Gets the summary of the failure message by omitting the stack + // trace in it. + static internal::String ExtractSummary(const char* message); + + // The name of the source file where the test part took place, or + // NULL if the source file is unknown. + internal::String file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + internal::String summary_; // The test failure summary. + internal::String message_; // The test failure message. +}; + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result); + +// An array of TestPartResult objects. +// +// Don't inherit from TestPartResultArray as its destructor is not +// virtual. +class GTEST_API_ TestPartResultArray { + public: + TestPartResultArray() {} + + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); + + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; + + // Returns the number of TestPartResult objects in the array. + int size() const; + + private: + std::vector<TestPartResult> array_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); +}; + +// This interface knows how to report a test part result. +class TestPartResultReporterInterface { + public: + virtual ~TestPartResultReporterInterface() {} + + virtual void ReportTestPartResult(const TestPartResult& result) = 0; +}; + +namespace internal { + +// This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a +// statement generates new fatal failures. To do so it registers itself as the +// current test part result reporter. Besides checking if fatal failures were +// reported, it only delegates the reporting to the former result reporter. +// The original result reporter is restored in the destructor. +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +class GTEST_API_ HasNewFatalFailureHelper + : public TestPartResultReporterInterface { + public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } + private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +}; + +} // namespace internal + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ diff --git a/lib/gtest/include/gtest/gtest-typed-test.h b/lib/gtest/include/gtest/gtest-typed-test.h new file mode 100644 index 0000000..fe1e83b --- /dev/null +++ b/lib/gtest/include/gtest/gtest-typed-test.h @@ -0,0 +1,259 @@ +// Copyright 2008 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#ifndef GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ + +// This header implements typed tests and type-parameterized tests. + +// Typed (aka type-driven) tests repeat the same test for types in a +// list. You must know which types you want to test with when writing +// typed tests. Here's how you do it: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template <typename T> +class FooTest : public testing::Test { + public: + ... + typedef std::list<T> List; + static T shared_; + T value_; +}; + +// Next, associate a list of types with the test case, which will be +// repeated for each type in the list. The typedef is necessary for +// the macro to parse correctly. +typedef testing::Types<char, int, unsigned int> MyTypes; +TYPED_TEST_CASE(FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// TYPED_TEST_CASE(FooTest, int); + +// Then, use TYPED_TEST() instead of TEST_F() to define as many typed +// tests for this test case as you want. +TYPED_TEST(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + // Since we are inside a derived class template, C++ requires use to + // visit the members of FooTest via 'this'. + TypeParam n = this->value_; + + // To visit static members of the fixture, add the TestFixture:: + // prefix. + n += TestFixture::shared_; + + // To refer to typedefs in the fixture, add the "typename + // TestFixture::" prefix. + typename TestFixture::List values; + values.push_back(n); + ... +} + +TYPED_TEST(FooTest, HasPropertyA) { ... } + +#endif // 0 + +// Type-parameterized tests are abstract test patterns parameterized +// by a type. Compared with typed tests, type-parameterized tests +// allow you to define the test pattern without knowing what the type +// parameters are. The defined pattern can be instantiated with +// different types any number of times, in any number of translation +// units. +// +// If you are designing an interface or concept, you can define a +// suite of type-parameterized tests to verify properties that any +// valid implementation of the interface/concept should have. Then, +// each implementation can easily instantiate the test suite to verify +// that it conforms to the requirements, without having to write +// similar tests repeatedly. Here's an example: + +#if 0 + +// First, define a fixture class template. It should be parameterized +// by a type. Remember to derive it from testing::Test. +template <typename T> +class FooTest : public testing::Test { + ... +}; + +// Next, declare that you will define a type-parameterized test case +// (the _P suffix is for "parameterized" or "pattern", whichever you +// prefer): +TYPED_TEST_CASE_P(FooTest); + +// Then, use TYPED_TEST_P() to define as many type-parameterized tests +// for this type-parameterized test case as you want. +TYPED_TEST_P(FooTest, DoesBlah) { + // Inside a test, refer to TypeParam to get the type parameter. + TypeParam n = 0; + ... +} + +TYPED_TEST_P(FooTest, HasPropertyA) { ... } + +// Now the tricky part: you need to register all test patterns before +// you can instantiate them. The first argument of the macro is the +// test case name; the rest are the names of the tests in this test +// case. +REGISTER_TYPED_TEST_CASE_P(FooTest, + DoesBlah, HasPropertyA); + +// Finally, you are free to instantiate the pattern with the types you +// want. If you put the above code in a header file, you can #include +// it in multiple C++ source files and instantiate it multiple times. +// +// To distinguish different instances of the pattern, the first +// argument to the INSTANTIATE_* macro is a prefix that will be added +// to the actual test case name. Remember to pick unique prefixes for +// different instances. +typedef testing::Types<char, int, unsigned int> MyTypes; +INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); + +// If the type list contains only one type, you can write that type +// directly without Types<...>: +// INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int); + +#endif // 0 + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-type-util.h" + +// Implements typed tests. + +#if GTEST_HAS_TYPED_TEST + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the typedef for the type parameters of the +// given test case. +# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types<int>) +# define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList< Types >::type \ + GTEST_TYPE_PARAMS_(CaseName) + +# define TYPED_TEST(CaseName, TestName) \ + template <typename gtest_TypeParam_> \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName<gtest_TypeParam_> { \ + private: \ + typedef CaseName<gtest_TypeParam_> TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register(\ + "", #CaseName, #TestName, 0); \ + template <typename gtest_TypeParam_> \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)<gtest_TypeParam_>::TestBody() + +#endif // GTEST_HAS_TYPED_TEST + +// Implements type-parameterized tests. + +#if GTEST_HAS_TYPED_TEST_P + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the namespace name that the type-parameterized tests for +// the given type-parameterized test case are defined in. The exact +// name of the namespace is subject to change without notice. +# define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Expands to the name of the variable used to remember the names of +// the defined tests in the given test case. +# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. +// +// Expands to the name of the variable used to remember the names of +// the registered tests in the given test case. +# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ + +// The variables defined in the type-parameterized test macros are +// static as typically these macros are used in a .h file that can be +// #included in multiple translation units linked together. +# define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) + +# define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + template <typename gtest_TypeParam_> \ + class TestName : public CaseName<gtest_TypeParam_> { \ + private: \ + typedef CaseName<gtest_TypeParam_> TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template <typename gtest_TypeParam_> \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName<gtest_TypeParam_>::TestBody() + +# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ + __FILE__, __LINE__, #__VA_ARGS__) + +// The 'Types' template argument below must have spaces around it +// since some compilers may choke on '>>' when passing a template +// instance (e.g. Types<int>) +# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestCase<CaseName, \ + GTEST_CASE_NAMESPACE_(CaseName)::gtest_AllTests_, \ + ::testing::internal::TypeList< Types >::type>::Register(\ + #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + +#endif // GTEST_HAS_TYPED_TEST_P + +#endif // GTEST_INCLUDE_GTEST_GTEST_TYPED_TEST_H_ diff --git a/lib/gtest/include/gtest/gtest.h b/lib/gtest/include/gtest/gtest.h new file mode 100644 index 0000000..cd01c7b --- /dev/null +++ b/lib/gtest/include/gtest/gtest.h @@ -0,0 +1,2155 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the public API for Google Test. It should be +// included by any test program that uses Google Test. +// +// IMPORTANT NOTE: Due to limitation of the C++ language, we have to +// leave some internal implementation details in this header file. +// They are clearly marked by comments like this: +// +// // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +// +// Such code is NOT meant to be used by a user directly, and is subject +// to CHANGE WITHOUT NOTICE. Therefore DO NOT DEPEND ON IT in a user +// program! +// +// Acknowledgment: Google Test borrowed the idea of automatic test +// registration from Barthelemy Dagenais' (barthelemy@prologique.com) +// easyUnit framework. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +#define GTEST_INCLUDE_GTEST_GTEST_H_ + +#include <limits> +#include <vector> + +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" +#include "gtest/gtest-death-test.h" +#include "gtest/gtest-message.h" +#include "gtest/gtest-param-test.h" +#include "gtest/gtest-printers.h" +#include "gtest/gtest_prod.h" +#include "gtest/gtest-test-part.h" +#include "gtest/gtest-typed-test.h" + +// Depending on the platform, different string classes are available. +// On Linux, in addition to ::std::string, Google also makes use of +// class ::string, which has the same interface as ::std::string, but +// has a different implementation. +// +// The user can define GTEST_HAS_GLOBAL_STRING to 1 to indicate that +// ::string is available AND is a distinct type to ::std::string, or +// define it to 0 to indicate otherwise. +// +// If the user's ::std::string and ::string are the same class due to +// aliasing, he should define GTEST_HAS_GLOBAL_STRING to 0. +// +// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// heuristically. + +namespace testing { + +// Declares the flags. + +// This flag temporary enables the disabled tests. +GTEST_DECLARE_bool_(also_run_disabled_tests); + +// This flag brings the debugger on an assertion failure. +GTEST_DECLARE_bool_(break_on_failure); + +// This flag controls whether Google Test catches all test-thrown exceptions +// and logs them as failures. +GTEST_DECLARE_bool_(catch_exceptions); + +// This flag enables using colors in terminal output. Available values are +// "yes" to enable colors, "no" (disable colors), or "auto" (the default) +// to let Google Test decide. +GTEST_DECLARE_string_(color); + +// This flag sets up the filter to select by name using a glob pattern +// the tests to run. If the filter is not given all tests are executed. +GTEST_DECLARE_string_(filter); + +// This flag causes the Google Test to list tests. None of the tests listed +// are actually run if the flag is provided. +GTEST_DECLARE_bool_(list_tests); + +// This flag controls whether Google Test emits a detailed XML report to a file +// in addition to its normal textual output. +GTEST_DECLARE_string_(output); + +// This flags control whether Google Test prints the elapsed time for each +// test. +GTEST_DECLARE_bool_(print_time); + +// This flag specifies the random number seed. +GTEST_DECLARE_int32_(random_seed); + +// This flag sets how many times the tests are repeated. The default value +// is 1. If the value is -1 the tests are repeating forever. +GTEST_DECLARE_int32_(repeat); + +// This flag controls whether Google Test includes Google Test internal +// stack frames in failure stack traces. +GTEST_DECLARE_bool_(show_internal_stack_frames); + +// When this flag is specified, tests' order is randomized on every iteration. +GTEST_DECLARE_bool_(shuffle); + +// This flag specifies the maximum number of stack frames to be +// printed in a failure message. +GTEST_DECLARE_int32_(stack_trace_depth); + +// When this flag is specified, a failed assertion will throw an +// exception if exceptions are enabled, or exit the program with a +// non-zero code otherwise. +GTEST_DECLARE_bool_(throw_on_failure); + +// When this flag is set with a "host:port" string, on supported +// platforms test results are streamed to the specified port on +// the specified host machine. +GTEST_DECLARE_string_(stream_result_to); + +// The upper limit for valid stack trace depths. +const int kMaxStackTraceDepth = 100; + +namespace internal { + +class AssertHelper; +class DefaultGlobalTestPartResultReporter; +class ExecDeathTest; +class NoExecDeathTest; +class FinalSuccessChecker; +class GTestFlagSaver; +class TestResultAccessor; +class TestEventListenersAccessor; +class TestEventRepeater; +class WindowsDeathTest; +class UnitTestImpl* GetUnitTestImpl(); +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message); + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared in gtest-internal.h but defined here, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable) { + return (Message() << streamable).GetString(); +} + +} // namespace internal + +// The friend relationship of some of these classes is cyclic. +// If we don't forward declare them the compiler might confuse the classes +// in friendship clauses with same named classes on the scope. +class Test; +class TestCase; +class TestInfo; +class UnitTest; + +// A class for indicating whether an assertion was successful. When +// the assertion wasn't successful, the AssertionResult object +// remembers a non-empty message that describes how it failed. +// +// To create an instance of this class, use one of the factory functions +// (AssertionSuccess() and AssertionFailure()). +// +// This class is useful for two purposes: +// 1. Defining predicate functions to be used with Boolean test assertions +// EXPECT_TRUE/EXPECT_FALSE and their ASSERT_ counterparts +// 2. Defining predicate-format functions to be +// used with predicate assertions (ASSERT_PRED_FORMAT*, etc). +// +// For example, if you define IsEven predicate: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then the failed expectation EXPECT_TRUE(IsEven(Fib(5))) +// will print the message +// +// Value of: IsEven(Fib(5)) +// Actual: false (5 is odd) +// Expected: true +// +// instead of a more opaque +// +// Value of: IsEven(Fib(5)) +// Actual: false +// Expected: true +// +// in case IsEven is a simple Boolean predicate. +// +// If you expect your predicate to be reused and want to support informative +// messages in EXPECT_FALSE and ASSERT_FALSE (negative assertions show up +// about half as often as positive ones in our tests), supply messages for +// both success and failure cases: +// +// testing::AssertionResult IsEven(int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess() << n << " is even"; +// else +// return testing::AssertionFailure() << n << " is odd"; +// } +// +// Then a statement EXPECT_FALSE(IsEven(Fib(6))) will print +// +// Value of: IsEven(Fib(6)) +// Actual: true (8 is even) +// Expected: false +// +// NB: Predicates that support negative Boolean assertions have reduced +// performance in positive ones so be careful not to use them in tests +// that have lots (tens of thousands) of positive Boolean assertions. +// +// To use this class with EXPECT_PRED_FORMAT assertions such as: +// +// // Verifies that Foo() returns an even number. +// EXPECT_PRED_FORMAT1(IsEven, Foo()); +// +// you need to define: +// +// testing::AssertionResult IsEven(const char* expr, int n) { +// if ((n % 2) == 0) +// return testing::AssertionSuccess(); +// else +// return testing::AssertionFailure() +// << "Expected: " << expr << " is even\n Actual: it's " << n; +// } +// +// If Foo() returns 5, you will see the following message: +// +// Expected: Foo() is even +// Actual: it's 5 +// +class GTEST_API_ AssertionResult { + public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} + + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT + + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; + + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const { + return message_.get() != NULL ? message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } + + // Streams a custom failure message into this object. + template <typename T> AssertionResult& operator<<(const T& value) { + AppendMessage(Message() << value); + return *this; + } + + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { + AppendMessage(Message() << basic_manipulator); + return *this; + } + + private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) { + if (message_.get() == NULL) + message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } + + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr< ::std::string> message_; + + GTEST_DISALLOW_ASSIGN_(AssertionResult); +}; + +// Makes a successful assertion result. +GTEST_API_ AssertionResult AssertionSuccess(); + +// Makes a failed assertion result. +GTEST_API_ AssertionResult AssertionFailure(); + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << msg. +GTEST_API_ AssertionResult AssertionFailure(const Message& msg); + +// The abstract class that all tests inherit from. +// +// In Google Test, a unit test program contains one or many TestCases, and +// each TestCase contains one or many Tests. +// +// When you define a test using the TEST macro, you don't need to +// explicitly derive from Test - the TEST macro automatically does +// this for you. +// +// The only time you derive from Test is when defining a test fixture +// to be used a TEST_F. For example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { ... } +// virtual void TearDown() { ... } +// ... +// }; +// +// TEST_F(FooTest, Bar) { ... } +// TEST_F(FooTest, Baz) { ... } +// +// Test is not copyable. +class GTEST_API_ Test { + public: + friend class TestInfo; + + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); + + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} + + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} + + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); + + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); + + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + + // Logs a property for the current test. Only the last value for a given + // key is remembered. + // These are public static so they can be called from utility functions + // that are not members of the test fixture. + // The arguments are const char* instead strings, as Google Test is used + // on platforms where string doesn't compile. + // + // Note that a driving consideration for these RecordProperty methods + // was to produce xml output suited to the Greenspan charting utility, + // which at present will only chart values that fit in a 32-bit int. It + // is the user's responsibility to restrict their values to 32-bit ints + // if they intend them to be used with Greenspan. + static void RecordProperty(const char* key, const char* value); + static void RecordProperty(const char* key, int value); + + protected: + // Creates a Test object. + Test(); + + // Sets up the test fixture. + virtual void SetUp(); + + // Tears down the test fixture. + virtual void TearDown(); + + private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); + + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; + + // Sets up, executes, and tears down the test. + void Run(); + + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } + + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; + + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); +}; + +typedef internal::TimeInMillis TimeInMillis; + +// A copyable object representing a user specified test property which can be +// output as a key/value string pair. +// +// Don't inherit from TestProperty as its destructor is not virtual. +class TestProperty { + public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const char* a_key, const char* a_value) : + key_(a_key), value_(a_value) { + } + + // Gets the user supplied key. + const char* key() const { + return key_.c_str(); + } + + // Gets the user supplied value. + const char* value() const { + return value_.c_str(); + } + + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const char* new_value) { + value_ = new_value; + } + + private: + // The key supplied by the user. + internal::String key_; + // The value supplied by the user. + internal::String value_; +}; + +// The result of a single Test. This includes a list of +// TestPartResults, a list of TestProperties, a count of how many +// death tests there are in the Test, and how much time it took to run +// the Test. +// +// TestResult is not copyable. +class GTEST_API_ TestResult { + public: + // Creates an empty TestResult. + TestResult(); + + // D'tor. Do not inherit from TestResult. + ~TestResult(); + + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; + + // Returns the number of the test properties. + int test_property_count() const; + + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } + + // Returns true iff the test failed. + bool Failed() const; + + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; + + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; + + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; + + private: + friend class TestInfo; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; + + // Gets the vector of TestPartResults. + const std::vector<TestPartResult>& test_part_results() const { + return test_part_results_; + } + + // Gets the vector of TestProperties. + const std::vector<TestProperty>& test_properties() const { + return test_properties_; + } + + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. + void RecordProperty(const TestProperty& test_property); + + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const TestProperty& test_property); + + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); + + // Returns the death test count. + int death_test_count() const { return death_test_count_; } + + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } + + // Clears the test part results. + void ClearTestPartResults(); + + // Clears the object. + void Clear(); + + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; + + // The vector of TestPartResults + std::vector<TestPartResult> test_part_results_; + // The vector of TestProperties + std::vector<TestProperty> test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); +}; // class TestResult + +// A TestInfo object stores the following information about a test: +// +// Test case name +// Test name +// Whether the test should be run +// A function pointer that creates the test object when invoked +// Test result +// +// The constructor of TestInfo registers itself with the UnitTest +// singleton such that the RUN_ALL_TESTS() macro knows which tests to +// run. +class GTEST_API_ TestInfo { + public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); + + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } + + // Returns the test name. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const { + if (value_param_.get() != NULL) + return value_param_->c_str(); + return NULL; + } + + // Returns true if this test should run, that is if the test is not disabled + // (or it is disabled but the also_run_disabled_tests flag has been specified) + // and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const { return should_run_; } + + // Returns the result of the test. + const TestResult* result() const { return &result_; } + + private: + +#if GTEST_HAS_DEATH_TEST + friend class internal::DefaultDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + friend class Test; + friend class TestCase; + friend class internal::UnitTestImpl; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); + + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const char* test_case_name, const char* name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); + + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() { + return result_.increment_death_test_count(); + } + + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); + + static void ClearTestResult(TestInfo* test_info) { + test_info->result_.Clear(); + } + + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr<const ::std::string> type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const internal::scoped_ptr<const ::std::string> value_param_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object + + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); +}; + +// A test case, which consists of a vector of TestInfos. +// +// TestCase is not copyable. +class GTEST_API_ TestCase { + public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Destructor of TestCase. + virtual ~TestCase(); + + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } + + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test case. + const char* type_param() const { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } + + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } + + // Gets the number of successful tests in this test case. + int successful_test_count() const; + + // Gets the number of failed tests in this test case. + int failed_test_count() const; + + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; + + // Get the number of tests in this test case that should run. + int test_to_run_count() const; + + // Gets the number of all tests in this test case. + int total_test_count() const; + + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } + + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } + + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; + + private: + friend class Test; + friend class internal::UnitTestImpl; + + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector<TestInfo*>& test_info_list() { return test_info_list_; } + + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector<TestInfo*>& test_info_list() const { + return test_info_list_; + } + + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); + + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } + + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo * test_info); + + // Clears the results of all tests in this test case. + void ClearResult(); + + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) { + test_case->ClearResult(); + } + + // Runs every test in this TestCase. + void Run(); + + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } + + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } + + // Returns true iff test passed. + static bool TestPassed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Passed(); + } + + // Returns true iff test failed. + static bool TestFailed(const TestInfo* test_info) { + return test_info->should_run() && test_info->result()->Failed(); + } + + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo* test_info) { + return test_info->is_disabled_; + } + + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo* test_info) { + return test_info->should_run(); + } + + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); + + // Restores the test order to before the first shuffle. + void UnshuffleTests(); + + // Name of the test case. + internal::String name_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr<const ::std::string> type_param_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector<TestInfo*> test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector<int> test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); +}; + +// An Environment object is capable of setting up and tearing down an +// environment. The user should subclass this to define his own +// environment(s). +// +// An Environment object does the set-up and tear-down in virtual +// methods SetUp() and TearDown() instead of the constructor and the +// destructor, as: +// +// 1. You cannot safely throw from a destructor. This is a problem +// as in some cases Google Test is used where exceptions are enabled, and +// we may want to implement ASSERT_* using exceptions where they are +// available. +// 2. You cannot use ASSERT_* directly in a constructor or +// destructor. +class Environment { + public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} + + // Override this to define how to set up the environment. + virtual void SetUp() {} + + // Override this to define how to tear down the environment. + virtual void TearDown() {} + private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp {}; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } +}; + +// The interface for tracing execution of tests. The methods are organized in +// the order the corresponding events are fired. +class TestEventListener { + public: + virtual ~TestEventListener() {} + + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; + + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; + + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; + + // Fired after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; + + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; + + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; +}; + +// The convenience class for users who need to override just one or two +// methods and are not concerned that a possible change to a signature of +// the methods they override will not be caught during the build. For +// comments about each method please see the definition of TestEventListener +// above. +class EmptyTestEventListener : public TestEventListener { + public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +}; + +// TestEventListeners lets users add listeners to track events in Google Test. +class GTEST_API_ TestEventListeners { + public: + TestEventListeners(); + ~TestEventListeners(); + + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); + + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); + + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const { + return default_result_printer_; + } + + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const { + return default_xml_generator_; + } + + private: + friend class TestCase; + friend class TestInfo; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::UnitTestImpl; + + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); + + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); + + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); + + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); + + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; + + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); +}; + +// A UnitTest consists of a vector of TestCases. +// +// This is a singleton class. The only instance of UnitTest is +// created when UnitTest::GetInstance() is first called. This +// instance is never deleted. +// +// UnitTest is not copyable. +// +// This class is thread-safe as long as the methods are called +// according to their specification. +class GTEST_API_ UnitTest { + public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); + + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; + + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; + + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const; + + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const; + + // Returns the random seed used at the start of the current test run. + int random_seed() const; + +#if GTEST_HAS_PARAM_TEST + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry(); +#endif // GTEST_HAS_PARAM_TEST + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; + + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); + + private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); + + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace); + + // Adds a TestProperty to the current TestResult object. If the result already + // contains a property with the same key, the value will be updated. + void RecordPropertyForCurrentTest(const char* key, const char* value); + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); + + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } + + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const internal::String& message); + + // Creates an empty UnitTest. + UnitTest(); + + // D'tor + virtual ~UnitTest(); + + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace); + + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace(); + + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; + + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; + + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); +}; + +// A convenient wrapper for adding an environment for the test +// program. +// +// You should call this before RUN_ALL_TESTS() is called, probably in +// main(). If you use gtest_main, you need to call this before main() +// starts for it to take effect. For example, you can define a global +// variable like this: +// +// testing::Environment* const foo_env = +// testing::AddGlobalTestEnvironment(new FooEnvironment); +// +// However, we strongly recommend you to write your own main() and +// call AddGlobalTestEnvironment() there, as relying on initialization +// of global variables makes the code harder to read and may cause +// problems when you register multiple environments from different +// translation units and the environments have dependencies among them +// (remember that the compiler doesn't guarantee the order in which +// global variables from different translation units are initialized). +inline Environment* AddGlobalTestEnvironment(Environment* env) { + return UnitTest::GetInstance()->AddEnvironment(env); +} + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +GTEST_API_ void InitGoogleTest(int* argc, char** argv); + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); + +namespace internal { + +// Formats a comparison assertion (e.g. ASSERT_EQ, EXPECT_LT, and etc) +// operand to be used in a failure message. The type (but not value) +// of the other operand may affect the format. This allows us to +// print a char* as a raw pointer when it is compared against another +// char*, and print it as a C string when it is compared against an +// std::string object, for example. +// +// The default implementation ignores the type of the other operand. +// Some specialized versions are used to handle formatting wide or +// narrow C strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template <typename T1, typename T2> +String FormatForComparisonFailureMessage(const T1& value, + const T2& /* other_operand */) { + // C++Builder compiles this incorrectly if the namespace isn't explicitly + // given. + return ::testing::PrintToString(value); +} + +// The helper function for {ASSERT|EXPECT}_EQ. +template <typename T1, typename T2> +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4389) // Temporarily disables warning on + // signed/unsigned mismatch. +#endif + + if (expected == actual) { + return AssertionSuccess(); + } + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// With this overloaded version, we allow anonymous enums to be used +// in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums +// can be implicitly cast to BiggestInt. +GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); + +// The helper class for {ASSERT|EXPECT}_EQ. The template argument +// lhs_is_null_literal is true iff the first argument to ASSERT_EQ() +// is a null pointer literal. The following default implementation is +// for lhs_is_null_literal being false. +template <bool lhs_is_null_literal> +class EqHelper { + public: + // This templatized version is for the general case. + template <typename T1, typename T2> + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } +}; + +// This specialization is used when the first argument to ASSERT_EQ() +// is a null pointer literal, like NULL, false, or 0. +template <> +class EqHelper<true> { + public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template <typename T1, typename T2> + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual, + // The following line prevents this overload from being considered if T2 + // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) + // expands to Compare("", "", NULL, my_ptr), which requires a conversion + // to match the Secret* in the other overload, which would otherwise make + // this template match better. + typename EnableIf<!is_pointer<T2>::value>::type* = 0) { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } + + // This version will be picked when the second argument to ASSERT_EQ() is a + // pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template <typename T> + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + // We used to have a second template parameter instead of Secret*. That + // template parameter would deduce to 'long', making this a better match + // than the first overload even without the first overload's EnableIf. + // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to + // non-pointer argument" (even a deduced integral argument), so the old + // implementation caused warnings in user code. + Secret* /* expected (NULL) */, + T* actual) { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast<T*>(NULL), actual); + } +}; + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_??. It is here just to avoid copy-and-paste +// of similar code. +// +// For each templatized helper function, we also define an overloaded +// version for BiggestInt in order to reduce code bloat and allow +// anonymous enums to be used with {ASSERT|EXPECT}_?? when compiled +// with gcc 4. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +template <typename T1, typename T2>\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +}\ +GTEST_API_ AssertionResult CmpHelper##op_name(\ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) + +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + +// Implements the helper function for {ASSERT|EXPECT}_NE +GTEST_IMPL_CMP_HELPER_(NE, !=); +// Implements the helper function for {ASSERT|EXPECT}_LE +GTEST_IMPL_CMP_HELPER_(LE, <=); +// Implements the helper function for {ASSERT|EXPECT}_LT +GTEST_IMPL_CMP_HELPER_(LT, < ); +// Implements the helper function for {ASSERT|EXPECT}_GE +GTEST_IMPL_CMP_HELPER_(GE, >=); +// Implements the helper function for {ASSERT|EXPECT}_GT +GTEST_IMPL_CMP_HELPER_(GT, > ); + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual); + +// The helper function for {ASSERT|EXPECT}_STRNE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2); + + +// Helper function for *_STREQ on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); + +// Helper function for *_STRNE on wide strings. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); + +} // namespace internal + +// IsSubstring() and IsNotSubstring() are intended to be used as the +// first argument to {EXPECT,ASSERT}_PRED_FORMAT2(), not by +// themselves. They check whether needle is a substring of haystack +// (NULL is considered a substring of itself only), and return an +// appropriate error message when they fail. +// +// The {needle,haystack}_expr arguments are the stringified +// expressions that generated the two real arguments. +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); + +#if GTEST_HAS_STD_WSTRING +GTEST_API_ AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +GTEST_API_ AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +// Helper template function for comparing floating-points. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +template <typename RawType> +AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, + const char* actual_expression, + RawType expected, + RawType actual) { + const FloatingPoint<RawType> lhs(expected), rhs(actual); + + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + ::std::stringstream expected_ss; + expected_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << expected; + + ::std::stringstream actual_ss; + actual_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << actual; + + return EqFailure(expected_expression, + actual_expression, + StringStreamToString(&expected_ss), + StringStreamToString(&actual_ss), + false); +} + +// Helper function for implementing ASSERT_NEAR. +// +// INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. +GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// A class that enables one to stream messages to assertion macros +class GTEST_API_ AssertHelper { + public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); + + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; + + private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) { } + + TestPartResult::Type const type; + const char* const file; + int const line; + String const message; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; + + AssertHelperData* const data_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); +}; + +} // namespace internal + +#if GTEST_HAS_PARAM_TEST +// The pure interface class that all value-parameterized tests inherit from. +// A value-parameterized class must inherit from both ::testing::Test and +// ::testing::WithParamInterface. In most cases that just means inheriting +// from ::testing::TestWithParam, but more complicated test hierarchies +// may need to inherit from Test and WithParamInterface at different levels. +// +// This interface has support for accessing the test parameter value via +// the GetParam() method. +// +// Use it with one of the parameter generator defining functions, like Range(), +// Values(), ValuesIn(), Bool(), and Combine(). +// +// class FooTest : public ::testing::TestWithParam<int> { +// protected: +// FooTest() { +// // Can use GetParam() here. +// } +// virtual ~FooTest() { +// // Can use GetParam() here. +// } +// virtual void SetUp() { +// // Can use GetParam() here. +// } +// virtual void TearDown { +// // Can use GetParam() here. +// } +// }; +// TEST_P(FooTest, DoesBar) { +// // Can use GetParam() method here. +// Foo foo; +// ASSERT_TRUE(foo.DoesBar(GetParam())); +// } +// INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); + +template <typename T> +class WithParamInterface { + public: + typedef T ParamType; + virtual ~WithParamInterface() {} + + // The current parameter value. Is also available in the test fixture's + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface<bool>::GetParam()' for a test that + // uses a fixture whose parameter type is int. + const ParamType& GetParam() const { return *parameter_; } + + private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) { + parameter_ = parameter; + } + + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; + + // TestClass must be a subclass of WithParamInterface<T> and Test. + template <class TestClass> friend class internal::ParameterizedTestFactory; +}; + +template <typename T> +const T* WithParamInterface<T>::parameter_ = NULL; + +// Most value-parameterized classes can ignore the existence of +// WithParamInterface, and can just inherit from ::testing::TestWithParam. + +template <typename T> +class TestWithParam : public Test, public WithParamInterface<T> { +}; + +#endif // GTEST_HAS_PARAM_TEST + +// Macros for indicating success/failure in test code. + +// ADD_FAILURE unconditionally adds a failure to the current test. +// SUCCEED generates a success - it doesn't automatically make the +// current test successful, as a test is only successful when it has +// no failure. +// +// EXPECT_* verifies that a certain condition is satisfied. If not, +// it behaves like ADD_FAILURE. In particular: +// +// EXPECT_TRUE verifies that a Boolean condition is true. +// EXPECT_FALSE verifies that a Boolean condition is false. +// +// FAIL and ASSERT_* are similar to ADD_FAILURE and EXPECT_*, except +// that they will also abort the current function on failure. People +// usually want the fail-fast behavior of FAIL and ASSERT_*, but those +// writing data-driven tests often find themselves using ADD_FAILURE +// and EXPECT_* more. +// +// Examples: +// +// EXPECT_TRUE(server.StatusIsOK()); +// ASSERT_FALSE(server.HasPendingRequest(port)) +// << "There are still pending requests " << "on port " << port; + +// Generates a nonfatal failure with a generic message. +#define ADD_FAILURE() GTEST_NONFATAL_FAILURE_("Failed") + +// Generates a nonfatal failure at the given source file location with +// a generic message. +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) + +// Generates a fatal failure with a generic message. +#define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") + +// Define this macro to 1 to omit the definition of FAIL(), which is a +// generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_FAIL +# define FAIL() GTEST_FAIL() +#endif + +// Generates a success with a generic message. +#define GTEST_SUCCEED() GTEST_SUCCESS_("Succeeded") + +// Define this macro to 1 to omit the definition of SUCCEED(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_SUCCEED +# define SUCCEED() GTEST_SUCCEED() +#endif + +// Macros for testing exceptions. +// +// * {ASSERT|EXPECT}_THROW(statement, expected_exception): +// Tests that the statement throws the expected exception. +// * {ASSERT|EXPECT}_NO_THROW(statement): +// Tests that the statement doesn't throw any exception. +// * {ASSERT|EXPECT}_ANY_THROW(statement): +// Tests that the statement throws an exception. + +#define EXPECT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) +#define EXPECT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define EXPECT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) +#define ASSERT_THROW(statement, expected_exception) \ + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) +#define ASSERT_NO_THROW(statement) \ + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) +#define ASSERT_ANY_THROW(statement) \ + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + +// Boolean assertions. Condition can be either a Boolean expression or an +// AssertionResult. For more information on how to use AssertionResult with +// these macros see comments on that class. +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) + +// Includes the auto-generated header that implements a family of +// generic predicate assertion macros. +#include "gtest/gtest_pred_impl.h" + +// Macros for testing equalities and inequalities. +// +// * {ASSERT|EXPECT}_EQ(expected, actual): Tests that expected == actual +// * {ASSERT|EXPECT}_NE(v1, v2): Tests that v1 != v2 +// * {ASSERT|EXPECT}_LT(v1, v2): Tests that v1 < v2 +// * {ASSERT|EXPECT}_LE(v1, v2): Tests that v1 <= v2 +// * {ASSERT|EXPECT}_GT(v1, v2): Tests that v1 > v2 +// * {ASSERT|EXPECT}_GE(v1, v2): Tests that v1 >= v2 +// +// When they are not, Google Test prints both the tested expressions and +// their actual values. The values must be compatible built-in types, +// or you will get a compiler error. By "compatible" we mean that the +// values can be compared by the respective operator. +// +// Note: +// +// 1. It is possible to make a user-defined type work with +// {ASSERT|EXPECT}_??(), but that requires overloading the +// comparison operators and is thus discouraged by the Google C++ +// Usage Guide. Therefore, you are advised to use the +// {ASSERT|EXPECT}_TRUE() macro to assert that two objects are +// equal. +// +// 2. The {ASSERT|EXPECT}_??() macros do pointer comparisons on +// pointers (in particular, C strings). Therefore, if you use it +// with two C strings, you are testing how their locations in memory +// are related, not how their content is related. To compare two C +// strings by content, use {ASSERT|EXPECT}_STR*(). +// +// 3. {ASSERT|EXPECT}_EQ(expected, actual) is preferred to +// {ASSERT|EXPECT}_TRUE(expected == actual), as the former tells you +// what the actual value is when it fails, and similarly for the +// other comparisons. +// +// 4. Do not depend on the order in which {ASSERT|EXPECT}_??() +// evaluate their arguments, which is undefined. +// +// 5. These macros evaluate their arguments exactly once. +// +// Examples: +// +// EXPECT_NE(5, Foo()); +// EXPECT_EQ(NULL, a_pointer); +// ASSERT_LT(i, array_size); +// ASSERT_GT(records.size(), 0) << "There is no record left."; + +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \ + expected, actual) +#define EXPECT_NE(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) +#define EXPECT_LE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define EXPECT_LT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define EXPECT_GE(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define EXPECT_GT(val1, val2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +#define GTEST_ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper<GTEST_IS_NULL_LITERAL_(expected)>::Compare, \ + expected, actual) +#define GTEST_ASSERT_NE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) +#define GTEST_ASSERT_LE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) +#define GTEST_ASSERT_LT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) +#define GTEST_ASSERT_GE(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) +#define GTEST_ASSERT_GT(val1, val2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + +// Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of +// ASSERT_XY(), which clashes with some users' own code. + +#if !GTEST_DONT_DEFINE_ASSERT_EQ +# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_NE +# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LE +# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_LT +# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GE +# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#endif + +#if !GTEST_DONT_DEFINE_ASSERT_GT +# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#endif + +// C String Comparisons. All tests treat NULL and any non-NULL string +// as different. Two NULLs are equal. +// +// * {ASSERT|EXPECT}_STREQ(s1, s2): Tests that s1 == s2 +// * {ASSERT|EXPECT}_STRNE(s1, s2): Tests that s1 != s2 +// * {ASSERT|EXPECT}_STRCASEEQ(s1, s2): Tests that s1 == s2, ignoring case +// * {ASSERT|EXPECT}_STRCASENE(s1, s2): Tests that s1 != s2, ignoring case +// +// For wide or narrow string objects, you can use the +// {ASSERT|EXPECT}_??() macros. +// +// Don't depend on the order in which the arguments are evaluated, +// which is undefined. +// +// These macros evaluate their arguments exactly once. + +#define EXPECT_STREQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define EXPECT_STRNE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define EXPECT_STRCASEEQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +#define ASSERT_STREQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) +#define ASSERT_STRNE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) +#define ASSERT_STRCASEEQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + +// Macros for comparing floating-point numbers. +// +// * {ASSERT|EXPECT}_FLOAT_EQ(expected, actual): +// Tests that two float values are almost equal. +// * {ASSERT|EXPECT}_DOUBLE_EQ(expected, actual): +// Tests that two double values are almost equal. +// * {ASSERT|EXPECT}_NEAR(v1, v2, abs_error): +// Tests that v1 and v2 are within the given distance to each other. +// +// Google Test uses ULP-based comparison to automatically pick a default +// error bound that is appropriate for the operands. See the +// FloatingPoint template class in gtest-internal.h if you are +// interested in the implementation details. + +#define EXPECT_FLOAT_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ + expected, actual) + +#define EXPECT_DOUBLE_EQ(expected, actual)\ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ + expected, actual) + +#define ASSERT_FLOAT_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<float>, \ + expected, actual) + +#define ASSERT_DOUBLE_EQ(expected, actual)\ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ<double>, \ + expected, actual) + +#define EXPECT_NEAR(val1, val2, abs_error)\ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +#define ASSERT_NEAR(val1, val2, abs_error)\ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) + +// These predicate format functions work on floating-point values, and +// can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. +// +// EXPECT_PRED_FORMAT2(testing::DoubleLE, Foo(), 5.0); + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2); +GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2); + + +#if GTEST_OS_WINDOWS + +// Macros that test for HRESULT failure and success, these are only useful +// on Windows, and rely on Windows SDK macros and APIs to compile. +// +// * {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED}(expr) +// +// When expr unexpectedly fails or succeeds, Google Test prints the +// expected result and the actual result with both a human-readable +// string representation of the error, if available, as well as the +// hex result code. +# define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) + +# define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +# define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) + +#endif // GTEST_OS_WINDOWS + +// Macros that execute statement and check that it doesn't generate new fatal +// failures in the current thread. +// +// * {ASSERT|EXPECT}_NO_FATAL_FAILURE(statement); +// +// Examples: +// +// EXPECT_NO_FATAL_FAILURE(Process()); +// ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; +// +#define ASSERT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) +#define EXPECT_NO_FATAL_FAILURE(statement) \ + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + +// Causes a trace (including the source file path, the current line +// number, and the given message) to be included in every test failure +// message generated by code in the current scope. The effect is +// undone when the control leaves the current scope. +// +// The message argument can be anything streamable to std::ostream. +// +// In the implementation, we include the current line number as part +// of the dummy variable name, thus allowing multiple SCOPED_TRACE()s +// to appear in the same block - as long as they are on different +// lines. +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ + __FILE__, __LINE__, ::testing::Message() << (message)) + +// Compile-time assertion for type equality. +// StaticAssertTypeEq<type1, type2>() compiles iff type1 and type2 are +// the same type. The value it returns is not interesting. +// +// Instead of making StaticAssertTypeEq a class template, we make it a +// function template that invokes a helper class template. This +// prevents a user from misusing StaticAssertTypeEq<T1, T2> by +// defining objects of that type. +// +// CAVEAT: +// +// When used inside a method of a class template, +// StaticAssertTypeEq<T1, T2>() is effective ONLY IF the method is +// instantiated. For example, given: +// +// template <typename T> class Foo { +// public: +// void Bar() { testing::StaticAssertTypeEq<int, T>(); } +// }; +// +// the code: +// +// void Test1() { Foo<bool> foo; } +// +// will NOT generate a compiler error, as Foo<bool>::Bar() is never +// actually instantiated. Instead, you need: +// +// void Test2() { Foo<bool> foo; foo.Bar(); } +// +// to cause a compiler error. +template <typename T1, typename T2> +bool StaticAssertTypeEq() { + (void)internal::StaticAssertTypeEqHelper<T1, T2>(); + return true; +} + +// Defines a test. +// +// The first parameter is the name of the test case, and the second +// parameter is the name of the test within the test case. +// +// The convention is to end the test case name with "Test". For +// example, a test case for the Foo class can be named FooTest. +// +// The user should put his test code between braces after using this +// macro. Example: +// +// TEST(FooTest, InitializesCorrectly) { +// Foo foo; +// EXPECT_TRUE(foo.StatusIsOK()); +// } + +// Note that we call GetTestTypeId() instead of GetTypeId< +// ::testing::Test>() here to get the type ID of testing::Test. This +// is to work around a suspected linker bug when using Google Test as +// a framework on Mac OS X. The bug causes GetTypeId< +// ::testing::Test>() to return different values depending on whether +// the call is from the Google Test framework itself or from user test +// code. GetTestTypeId() is guaranteed to always return the same +// value, as it always calls GetTypeId<>() from the Google Test +// framework. +#define GTEST_TEST(test_case_name, test_name)\ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) + +// Define this macro to 1 to omit the definition of TEST(), which +// is a generic name and clashes with some other libraries. +#if !GTEST_DONT_DEFINE_TEST +# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#endif + +// Defines a test that uses a test fixture. +// +// The first parameter is the name of the test fixture class, which +// also doubles as the test case name. The second parameter is the +// name of the test within the test case. +// +// A test fixture class must be declared earlier. The user should put +// his test code between braces after using this macro. Example: +// +// class FooTest : public testing::Test { +// protected: +// virtual void SetUp() { b_.AddElement(3); } +// +// Foo a_; +// Foo b_; +// }; +// +// TEST_F(FooTest, InitializesCorrectly) { +// EXPECT_TRUE(a_.StatusIsOK()); +// } +// +// TEST_F(FooTest, ReturnsElementCountCorrectly) { +// EXPECT_EQ(0, a_.size()); +// EXPECT_EQ(1, b_.size()); +// } + +#define TEST_F(test_fixture, test_name)\ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId<test_fixture>()) + +// Use this macro in main() to run all tests. It returns 0 if all +// tests are successful, or 1 otherwise. +// +// RUN_ALL_TESTS() should be invoked after the command line has been +// parsed by InitGoogleTest(). + +#define RUN_ALL_TESTS()\ + (::testing::UnitTest::GetInstance()->Run()) + +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/lib/gtest/include/gtest/gtest_pred_impl.h b/lib/gtest/include/gtest/gtest_pred_impl.h new file mode 100644 index 0000000..3805f85 --- /dev/null +++ b/lib/gtest/include/gtest/gtest_pred_impl.h @@ -0,0 +1,358 @@ +// Copyright 2006, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. + +// This file is AUTOMATICALLY GENERATED on 09/24/2010 by command +// 'gen_gtest_pred_impl.py 5'. DO NOT EDIT BY HAND! +// +// Implements a family of generic predicate assertion macros. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ + +// Makes sure this header is not included before gtest.h. +#ifndef GTEST_INCLUDE_GTEST_GTEST_H_ +# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#endif // GTEST_INCLUDE_GTEST_GTEST_H_ + +// This header implements a family of generic predicate assertion +// macros: +// +// ASSERT_PRED_FORMAT1(pred_format, v1) +// ASSERT_PRED_FORMAT2(pred_format, v1, v2) +// ... +// +// where pred_format is a function or functor that takes n (in the +// case of ASSERT_PRED_FORMATn) values and their source expression +// text, and returns a testing::AssertionResult. See the definition +// of ASSERT_EQ in gtest.h for an example. +// +// If you don't care about formatting, you can use the more +// restrictive version: +// +// ASSERT_PRED1(pred, v1) +// ASSERT_PRED2(pred, v1, v2) +// ... +// +// where pred is an n-ary function or functor that returns bool, +// and the values v1, v2, ..., must support the << operator for +// streaming to std::ostream. +// +// We also define the EXPECT_* variations. +// +// For now we only support predicates whose arity is at most 5. +// Please email googletestframework@googlegroups.com if you need +// support for higher arities. + +// GTEST_ASSERT_ is the basic statement to which all of the assertions +// in this file reduce. Don't use this in your code. + +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) + + +// Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +template <typename Pred, + typename T1> +AssertionResult AssertPred1Helper(const char* pred_text, + const char* e1, + Pred pred, + const T1& v1) { + if (pred(v1)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. +// Don't use this in your code. +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, v1),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use +// this in your code. +#define GTEST_PRED1_(pred, v1, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), on_failure) + +// Unary predicate assertion macros. +#define EXPECT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT1(pred_format, v1) \ + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED1(pred, v1) \ + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2> +AssertionResult AssertPred2Helper(const char* pred_text, + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) { + if (pred(v1, v2)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. +// Don't use this in your code. +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use +// this in your code. +#define GTEST_PRED2_(pred, v1, v2, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), on_failure) + +// Binary predicate assertion macros. +#define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED2(pred, v1, v2) \ + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2, + typename T3> +AssertionResult AssertPred3Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) { + if (pred(v1, v2, v3)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. +// Don't use this in your code. +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use +// this in your code. +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), on_failure) + +// Ternary predicate assertion macros. +#define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED3(pred, v1, v2, v3) \ + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2, + typename T3, + typename T4> +AssertionResult AssertPred4Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) { + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. +// Don't use this in your code. +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use +// this in your code. +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), on_failure) + +// 4-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED4(pred, v1, v2, v3, v4) \ + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + + + +// Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +template <typename Pred, + typename T1, + typename T2, + typename T3, + typename T4, + typename T5> +AssertionResult AssertPred5Helper(const char* pred_text, + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) { + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" << e1 << " evaluates to " << v1 + << "\n" << e2 << " evaluates to " << v2 + << "\n" << e3 << " evaluates to " << v3 + << "\n" << e4 << " evaluates to " << v4 + << "\n" << e5 << " evaluates to " << v5; +} + +// Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. +// Don't use this in your code. +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5),\ + on_failure) + +// Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use +// this in your code. +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), on_failure) + +// 5-ary predicate assertion macros. +#define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) +#define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) +#define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + + + +#endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/lib/gtest/include/gtest/gtest_prod.h b/lib/gtest/include/gtest/gtest_prod.h new file mode 100644 index 0000000..da80ddc --- /dev/null +++ b/lib/gtest/include/gtest/gtest_prod.h @@ -0,0 +1,58 @@ +// Copyright 2006, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// Google C++ Testing Framework definitions useful in production code. + +#ifndef GTEST_INCLUDE_GTEST_GTEST_PROD_H_ +#define GTEST_INCLUDE_GTEST_GTEST_PROD_H_ + +// When you need to test the private or protected members of a class, +// use the FRIEND_TEST macro to declare your tests as friends of the +// class. For example: +// +// class MyClass { +// private: +// void MyMethod(); +// FRIEND_TEST(MyClassTest, MyMethod); +// }; +// +// class MyClassTest : public testing::Test { +// // ... +// }; +// +// TEST_F(MyClassTest, MyMethod) { +// // Can call MyClass::MyMethod() here. +// } + +#define FRIEND_TEST(test_case_name, test_name)\ +friend class test_case_name##_##test_name##_Test + +#endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-death-test-internal.h b/lib/gtest/include/gtest/internal/gtest-death-test-internal.h new file mode 100644 index 0000000..1d9f83b --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-death-test-internal.h @@ -0,0 +1,308 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines internal utilities needed for implementing +// death tests. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ + +#include "gtest/internal/gtest-internal.h" + +#include <stdio.h> + +namespace testing { +namespace internal { + +GTEST_DECLARE_string_(internal_run_death_test); + +// Names of the flags (needed for parsing Google Test flags). +const char kDeathTestStyleFlag[] = "death_test_style"; +const char kDeathTestUseFork[] = "death_test_use_fork"; +const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; + +#if GTEST_HAS_DEATH_TEST + +// DeathTest is a class that hides much of the complexity of the +// GTEST_DEATH_TEST_ macro. It is abstract; its static Create method +// returns a concrete class that depends on the prevailing death test +// style, as defined by the --gtest_death_test_style and/or +// --gtest_internal_run_death_test flags. + +// In describing the results of death tests, these terms are used with +// the corresponding definitions: +// +// exit status: The integer exit information in the format specified +// by wait(2) +// exit code: The integer code passed to exit(3), _exit(2), or +// returned from main() +class GTEST_API_ DeathTest { + public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() { } + + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) { } + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; + + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; + + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; + + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; + + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; + + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; + + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); + + static void set_last_death_test_message(const String& message); + + private: + // A string containing a description of the outcome of the last death test. + static String last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +}; + +// Factory interface for death tests. May be mocked out for testing. +class DeathTestFactory { + public: + virtual ~DeathTestFactory() { } + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; +}; + +// A concrete DeathTestFactory implementation for normal use. +class DefaultDeathTestFactory : public DeathTestFactory { + public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); +}; + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +GTEST_API_ bool ExitedUnsuccessfully(int exit_status); + +// Traps C++ exceptions escaping statement and reports them as test +// failures. Note that trapping SEH exceptions is not implemented here. +# if GTEST_HAS_EXCEPTIONS +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } catch (const ::std::exception& gtest_exception) { \ + fprintf(\ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } catch (...) { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } + +# else +# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) + +# endif + +// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, +// ASSERT_EXIT*, and EXPECT_EXIT*. +# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + default: \ + break; \ + } \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ + fail(::testing::internal::DeathTest::LastMessage()) +// The symbol "fail" here expands to something into which a message +// can be streamed. + +// A class representing the parsed contents of the +// --gtest_internal_run_death_test flag, as it existed when +// RUN_ALL_TESTS was called. +class InternalRunDeathTestFlag { + public: + InternalRunDeathTestFlag(const String& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), + write_fd_(a_write_fd) {} + + ~InternalRunDeathTestFlag() { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } + + String file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } + + private: + String file_; + int line_; + int index_; + int write_fd_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); +}; + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); + +#else // GTEST_HAS_DEATH_TEST + +// This macro is used for implementing macros such as +// EXPECT_DEATH_IF_SUPPORTED and ASSERT_DEATH_IF_SUPPORTED on systems where +// death tests are not supported. Those macros must compile on such systems +// iff EXPECT_DEATH and ASSERT_DEATH compile with the same parameters on +// systems that support death tests. This allows one to write such a macro +// on a system that does not support death tests and be sure that it will +// compile on a death-test supporting system. +// +// Parameters: +// statement - A statement that a macro such as EXPECT_DEATH would test +// for program termination. This macro has to make sure this +// statement is compiled but not executed, to ensure that +// EXPECT_DEATH_IF_SUPPORTED compiles with a certain +// parameter iff EXPECT_DEATH compiles with it. +// regex - A regex that a macro such as EXPECT_DEATH would use to test +// the output of statement. This parameter has to be +// compiled but not evaluated by this macro, to ensure that +// this macro only accepts expressions that a macro such as +// EXPECT_DEATH would accept. +// terminator - Must be an empty statement for EXPECT_DEATH_IF_SUPPORTED +// and a return statement for ASSERT_DEATH_IF_SUPPORTED. +// This ensures that ASSERT_DEATH_IF_SUPPORTED will not +// compile inside functions where ASSERT_DEATH doesn't +// compile. +// +// The branch that has an always false condition is used to ensure that +// statement and regex are compiled (and thus syntactically correct) but +// never executed. The unreachable code macro protects the terminator +// statement from generating an 'unreachable code' warning in case +// statement unconditionally returns or throws. The Message constructor at +// the end allows the syntax of streaming additional messages into the +// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. +# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } else if (::testing::internal::AlwaysFalse()) { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } else \ + ::testing::Message() + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_DEATH_TEST_INTERNAL_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-filepath.h b/lib/gtest/include/gtest/internal/gtest-filepath.h new file mode 100644 index 0000000..b36b3cf --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-filepath.h @@ -0,0 +1,210 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: keith.ray@gmail.com (Keith Ray) +// +// Google Test filepath utilities +// +// This header file declares classes and functions used internally by +// Google Test. They are subject to change without notice. +// +// This file is #included in <gtest/internal/gtest-internal.h>. +// Do not include this header file separately! + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ + +#include "gtest/internal/gtest-string.h" + +namespace testing { +namespace internal { + +// FilePath - a class for file and directory pathname manipulation which +// handles platform-specific conventions (like the pathname separator). +// Used for helper functions for naming files in a directory for xml output. +// Except for Set methods, all methods are const or static, which provides an +// "immutable value object" -- useful for peace of mind. +// A FilePath with a value ending in a path separator ("like/this/") represents +// a directory, otherwise it is assumed to represent a file. In either case, +// it may or may not represent an actual file or directory in the file system. +// Names are NOT checked for syntax correctness -- no checking for illegal +// characters, malformed paths, etc. + +class GTEST_API_ FilePath { + public: + FilePath() : pathname_("") { } + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } + + explicit FilePath(const char* pathname) : pathname_(pathname) { + Normalize(); + } + + explicit FilePath(const String& pathname) : pathname_(pathname) { + Normalize(); + } + + FilePath& operator=(const FilePath& rhs) { + Set(rhs); + return *this; + } + + void Set(const FilePath& rhs) { + pathname_ = rhs.pathname_; + } + + String ToString() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } + + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); + + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); + + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); + + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_<number>.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); + + // Returns true iff the path is NULL or "". + bool IsEmpty() const { return c_str() == NULL || *c_str() == '\0'; } + + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; + + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; + + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; + + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; + + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; + + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; + + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; + + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; + + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; + + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; + + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; + + private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". + + void Normalize(); + + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; + + String pathname_; +}; // class FilePath + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-internal.h b/lib/gtest/include/gtest/internal/gtest-internal.h new file mode 100644 index 0000000..7aa1197 --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-internal.h @@ -0,0 +1,1226 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares functions and macros used internally by +// Google Test. They are subject to change without notice. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_LINUX +# include <stdlib.h> +# include <sys/types.h> +# include <sys/wait.h> +# include <unistd.h> +#endif // GTEST_OS_LINUX + +#include <ctype.h> +#include <string.h> +#include <iomanip> +#include <limits> +#include <set> + +#include "gtest/internal/gtest-string.h" +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-type-util.h" + +// Due to C++ preprocessor weirdness, we need double indirection to +// concatenate two tokens when one of them is __LINE__. Writing +// +// foo ## __LINE__ +// +// will result in the token foo__LINE__, instead of foo followed by +// the current line number. For more details, see +// http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 +#define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar + +// Google Test defines the testing::Message class to allow construction of +// test messages via the << operator. The idea is that anything +// streamable to std::ostream can be streamed to a testing::Message. +// This allows a user to use his own types in Google Test assertions by +// overloading the << operator. +// +// util/gtl/stl_logging-inl.h overloads << for STL containers. These +// overloads cannot be defined in the std namespace, as that will be +// undefined behavior. Therefore, they are defined in the global +// namespace instead. +// +// C++'s symbol lookup rule (i.e. Koenig lookup) says that these +// overloads are visible in either the std namespace or the global +// namespace, but not other namespaces, including the testing +// namespace which Google Test's Message class is in. +// +// To allow STL containers (and other types that has a << operator +// defined in the global namespace) to be used in Google Test assertions, +// testing::Message must access the custom << operator from the global +// namespace. Hence this helper function. +// +// Note: Jeffrey Yasskin suggested an alternative fix by "using +// ::operator<<;" in the definition of Message's operator<<. That fix +// doesn't require a helper function, but unfortunately doesn't +// compile with MSVC. +template <typename T> +inline void GTestStreamToHelper(std::ostream* os, const T& val) { + *os << val; +} + +class ProtocolMessage; +namespace proto2 { class Message; } + +namespace testing { + +// Forward declarations. + +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. + +template <typename T> +::std::string PrintToString(const T& value); + +namespace internal { + +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest + +// How many times InitGoogleTest() has been called. +extern int g_init_gtest_count; + +// The text used in failure messages to indicate the start of the +// stack trace. +GTEST_API_ extern const char kStackTraceMarker[]; + +// A secret type that Google Test users don't know about. It has no +// definition on purpose. Therefore it's impossible to create a +// Secret object, which is what we want. +class Secret; + +// Two overloaded helpers for checking at compile time whether an +// expression is a null pointer literal (i.e. NULL or any 0-valued +// compile-time integral constant). Their return values have +// different sizes, so we can use sizeof() to test which version is +// picked by the compiler. These helpers have no implementations, as +// we only need their signatures. +// +// Given IsNullLiteralHelper(x), the compiler will pick the first +// version if x can be implicitly converted to Secret*, and pick the +// second version otherwise. Since Secret is a secret and incomplete +// type, the only expression a user can write that has type Secret* is +// a null pointer literal. Therefore, we know that x is a null +// pointer literal if and only if the first version is picked by the +// compiler. +char IsNullLiteralHelper(Secret* p); +char (&IsNullLiteralHelper(...))[2]; // NOLINT + +// A compile-time bool constant that is true if and only if x is a +// null pointer literal (i.e. NULL or any 0-valued compile-time +// integral constant). +#ifdef GTEST_ELLIPSIS_NEEDS_POD_ +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_IS_NULL_LITERAL_(x) false +#else +# define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#endif // GTEST_ELLIPSIS_NEEDS_POD_ + +// Appends the user-supplied message to the Google-Test-generated message. +GTEST_API_ String AppendUserMessage(const String& gtest_msg, + const Message& user_msg); + +// A helper class for creating scoped traces in user programs. +class GTEST_API_ ScopedTrace { + public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); + + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable); + +// The Symbian compiler has a bug that prevents it from selecting the +// correct overload of FormatForComparisonFailureMessage (see below) +// unless we pass the first argument by reference. If we do that, +// however, Visual Age C++ 10.1 generates a compiler error. Therefore +// we only apply the work-around for Symbian. +#if defined(__SYMBIAN32__) +# define GTEST_CREF_WORKAROUND_ const& +#else +# define GTEST_CREF_WORKAROUND_ +#endif + +// When this operand is a const char* or char*, if the other operand +// is a ::std::string or ::string, we print this operand as a C string +// rather than a pointer (we do the same for wide strings); otherwise +// we print it as a pointer to be safe. + +// This internal macro is used to avoid duplicated code. +#define GTEST_FORMAT_IMPL_(operand2_type, operand1_printer)\ +inline String FormatForComparisonFailureMessage(\ + operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \ + const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +}\ +inline String FormatForComparisonFailureMessage(\ + const operand2_type::value_type* GTEST_CREF_WORKAROUND_ str, \ + const operand2_type& /*operand2*/) {\ + return operand1_printer(str);\ +} + +GTEST_FORMAT_IMPL_(::std::string, String::ShowCStringQuoted) +#if GTEST_HAS_STD_WSTRING +GTEST_FORMAT_IMPL_(::std::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_STRING +GTEST_FORMAT_IMPL_(::string, String::ShowCStringQuoted) +#endif // GTEST_HAS_GLOBAL_STRING +#if GTEST_HAS_GLOBAL_WSTRING +GTEST_FORMAT_IMPL_(::wstring, String::ShowWideCStringQuoted) +#endif // GTEST_HAS_GLOBAL_WSTRING + +#undef GTEST_FORMAT_IMPL_ + +// The next four overloads handle the case where the operand being +// printed is a char/wchar_t pointer and the other operand is not a +// string/wstring object. In such cases, we just print the operand as +// a pointer to be safe. +#define GTEST_FORMAT_CHAR_PTR_IMPL_(CharType) \ + template <typename T> \ + String FormatForComparisonFailureMessage(CharType* GTEST_CREF_WORKAROUND_ p, \ + const T&) { \ + return PrintToString(static_cast<const void*>(p)); \ + } + +GTEST_FORMAT_CHAR_PTR_IMPL_(char) +GTEST_FORMAT_CHAR_PTR_IMPL_(const char) +GTEST_FORMAT_CHAR_PTR_IMPL_(wchar_t) +GTEST_FORMAT_CHAR_PTR_IMPL_(const wchar_t) + +#undef GTEST_FORMAT_CHAR_PTR_IMPL_ + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +GTEST_API_ AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case); + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +GTEST_API_ String GetBoolAssertionFailureMessage( + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); + +// This template class represents an IEEE floating-point number +// (either single-precision or double-precision, depending on the +// template parameters). +// +// The purpose of this class is to do more sophisticated number +// comparison. (Due to round-off error, etc, it's very unlikely that +// two floating-points will be equal exactly. Hence a naive +// comparison by the == operation often doesn't work.) +// +// Format of IEEE floating-point: +// +// The most-significant bit being the leftmost, an IEEE +// floating-point looks like +// +// sign_bit exponent_bits fraction_bits +// +// Here, sign_bit is a single bit that designates the sign of the +// number. +// +// For float, there are 8 exponent bits and 23 fraction bits. +// +// For double, there are 11 exponent bits and 52 fraction bits. +// +// More details can be found at +// http://en.wikipedia.org/wiki/IEEE_floating-point_standard. +// +// Template parameter: +// +// RawType: the raw floating-point type (either float or double) +template <typename RawType> +class FloatingPoint { + public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize<sizeof(RawType)>::UInt Bits; + + // Constants. + + // # of bits in a number. + static const size_t kBitCount = 8*sizeof(RawType); + + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits<RawType>::digits - 1; + + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast<Bits>(1) << (kBitCount - 1); + + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast<Bits>(0) >> (kExponentBitCount + 1); + + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm. + static const size_t kMaxUlps = 4; + + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + + // Static methods + + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } + + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() { + return ReinterpretBits(kExponentBitMask); + } + + // Non-static methods + + // Returns the bits that represents this number. + const Bits &bits() const { return u_.bits_; } + + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } + + // Returns true iff this is NAN (not a number). + bool is_nan() const { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } + + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; + + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) + <= kMaxUlps; + } + + private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; + + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits &sam) { + if (kSignBitMask & sam) { + // sam represents a negative number. + return ~sam + 1; + } else { + // sam represents a positive number. + return kSignBitMask | sam; + } + } + + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, + const Bits &sam2) { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } + + FloatingPointUnion u_; +}; + +// Typedefs the instances of the FloatingPoint template class that we +// care to use. +typedef FloatingPoint<float> Float; +typedef FloatingPoint<double> Double; + +// In order to catch the mistake of putting tests that use different +// test fixture classes in the same test case, we need to assign +// unique IDs to fixture classes and compare them. The TypeId type is +// used to hold such IDs. The user should treat TypeId as an opaque +// type: the only operation allowed on TypeId values is to compare +// them for equality using the == operator. +typedef const void* TypeId; + +template <typename T> +class TypeIdHelper { + public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper<T>::dummy_ for different Ts as an "optimization". + static bool dummy_; +}; + +template <typename T> +bool TypeIdHelper<T>::dummy_ = false; + +// GetTypeId<T>() returns the ID of type T. Different values will be +// returned for different types. Calling the function twice with the +// same type argument is guaranteed to return the same ID. +template <typename T> +TypeId GetTypeId() { + // The compiler is required to allocate a different + // TypeIdHelper<T>::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper<T>::dummy_); +} + +// Returns the type ID of ::testing::Test. Always call this instead +// of GetTypeId< ::testing::Test>() to get the type ID of +// ::testing::Test, as the latter may give the wrong result due to a +// suspected linker bug when compiling Google Test as a Mac OS X +// framework. +GTEST_API_ TypeId GetTestTypeId(); + +// Defines the abstract factory interface that creates instances +// of a Test object. +class TestFactoryBase { + public: + virtual ~TestFactoryBase() {} + + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; + + protected: + TestFactoryBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +}; + +// This class provides implementation of TeastFactoryBase interface. +// It is used in TEST and TEST_F macros. +template <class TestClass> +class TestFactoryImpl : public TestFactoryBase { + public: + virtual Test* CreateTest() { return new TestClass; } +}; + +#if GTEST_OS_WINDOWS + +// Predicate-formatters for implementing the HRESULT checking macros +// {ASSERT|EXPECT}_HRESULT_{SUCCEEDED|FAILED} +// We pass a long instead of HRESULT to avoid causing an +// include dependency for the HRESULT type. +GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, + long hr); // NOLINT +GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, + long hr); // NOLINT + +#endif // GTEST_OS_WINDOWS + +// Types of SetUpTestCase() and TearDownTestCase() functions. +typedef void (*SetUpTestCaseFunc)(); +typedef void (*TearDownTestCaseFunc)(); + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param text representation of the test's value parameter, +// or NULL if this is not a type-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +GTEST_API_ TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// State of the definition of a type-parameterized test case. +class GTEST_API_ TypedTestCasePState { + public: + TypedTestCasePState() : registered_(false) {} + + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) { + if (registered_) { + fprintf(stderr, "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } + + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); + + private: + bool registered_; + ::std::set<const char*> defined_test_names_; +}; + +// Skips to the first non-space char after the first comma in 'str'; +// returns NULL if no comma is found in 'str'. +inline const char* SkipComma(const char* str) { + const char* comma = strchr(str, ','); + if (comma == NULL) { + return NULL; + } + while (IsSpace(*(++comma))) {} + return comma; +} + +// Returns the prefix of 'str' before the first comma in it; returns +// the entire string if it contains no comma. +inline String GetPrefixUntilComma(const char* str) { + const char* comma = strchr(str, ','); + return comma == NULL ? String(str) : String(str, comma - str); +} + +// TypeParameterizedTest<Fixture, TestSel, Types>::Register() +// registers a list of type-parameterized tests with Google Test. The +// return value is insignificant - we just need to return something +// such that we can call this function in a namespace scope. +// +// Implementation note: The GTEST_TEMPLATE_ macro declares a template +// template parameter. It's defined in gtest-type-util.h. +template <GTEST_TEMPLATE_ Fixture, class TestSel, typename Types> +class TypeParameterizedTest { + public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) { + typedef typename Types::Head Type; + typedef Fixture<Type> FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; + + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + String::Format("%s%s%s/%d", prefix, prefix[0] == '\0' ? "" : "/", + case_name, index).c_str(), + GetPrefixUntilComma(test_names).c_str(), + GetTypeName<Type>().c_str(), + NULL, // No value parameter. + GetTypeId<FixtureClass>(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl<TestClass>); + + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest<Fixture, TestSel, typename Types::Tail> + ::Register(prefix, case_name, test_names, index + 1); + } +}; + +// The base case for the compile time recursion. +template <GTEST_TEMPLATE_ Fixture, class TestSel> +class TypeParameterizedTest<Fixture, TestSel, Types0> { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) { + return true; + } +}; + +// TypeParameterizedTestCase<Fixture, Tests, Types>::Register() +// registers *all combinations* of 'Tests' and 'Types' with Google +// Test. The return value is insignificant - we just need to return +// something such that we can call this function in a namespace scope. +template <GTEST_TEMPLATE_ Fixture, typename Tests, typename Types> +class TypeParameterizedTestCase { + public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) { + typedef typename Tests::Head Head; + + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest<Fixture, Head, Types>::Register( + prefix, case_name, test_names, 0); + + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase<Fixture, typename Tests::Tail, Types> + ::Register(prefix, case_name, SkipComma(test_names)); + } +}; + +// The base case for the compile time recursion. +template <GTEST_TEMPLATE_ Fixture, typename Types> +class TypeParameterizedTestCase<Fixture, Templates0, Types> { + public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) { + return true; + } +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +GTEST_API_ String GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, + int skip_count); + +// Helpers for suppressing warnings on unreachable code or constant +// condition. + +// Always returns true. +GTEST_API_ bool AlwaysTrue(); + +// Always returns false. +inline bool AlwaysFalse() { return !AlwaysTrue(); } + +// Helper for suppressing false warning from Clang on a const char* +// variable declared in a conditional expression always being NULL in +// the else branch. +struct GTEST_API_ ConstCharPtr { + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; +}; + +// A simple Linear Congruential Generator for generating random +// numbers with a uniform distribution. Unlike rand() and srand(), it +// doesn't use global state (and therefore can't interfere with user +// code). Unlike rand_r(), it's portable. An LCG isn't very random, +// but it's good enough for our purposes. +class GTEST_API_ Random { + public: + static const UInt32 kMaxRange = 1u << 31; + + explicit Random(UInt32 seed) : state_(seed) {} + + void Reseed(UInt32 seed) { state_ = seed; } + + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); + + private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +}; + +// Defining a variable of type CompileAssertTypesEqual<T1, T2> will cause a +// compiler error iff T1 and T2 are different types. +template <typename T1, typename T2> +struct CompileAssertTypesEqual; + +template <typename T> +struct CompileAssertTypesEqual<T, T> { +}; + +// Removes the reference from a type if it is a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::remove_reference, which is not widely available yet. +template <typename T> +struct RemoveReference { typedef T type; }; // NOLINT +template <typename T> +struct RemoveReference<T&> { typedef T type; }; // NOLINT + +// A handy wrapper around RemoveReference that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_REFERENCE_(T) \ + typename ::testing::internal::RemoveReference<T>::type + +// Removes const from a type if it is a const type, otherwise leaves +// it unchanged. This is the same as tr1::remove_const, which is not +// widely available yet. +template <typename T> +struct RemoveConst { typedef T type; }; // NOLINT +template <typename T> +struct RemoveConst<const T> { typedef T type; }; // NOLINT + +// MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above +// definition to fail to remove the const in 'const int[3]' and 'const +// char[3][4]'. The following specialization works around the bug. +// However, it causes trouble with GCC and thus needs to be +// conditionally compiled. +#if defined(_MSC_VER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) +template <typename T, size_t N> +struct RemoveConst<const T[N]> { + typedef typename RemoveConst<T>::type type[N]; +}; +#endif + +// A handy wrapper around RemoveConst that works when the argument +// T depends on template parameters. +#define GTEST_REMOVE_CONST_(T) \ + typename ::testing::internal::RemoveConst<T>::type + +// Turns const U&, U&, const U, and U all into U. +#define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ + GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) + +// Adds reference to a type if it is not a reference type, +// otherwise leaves it unchanged. This is the same as +// tr1::add_reference, which is not widely available yet. +template <typename T> +struct AddReference { typedef T& type; }; // NOLINT +template <typename T> +struct AddReference<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper around AddReference that works when the argument T +// depends on template parameters. +#define GTEST_ADD_REFERENCE_(T) \ + typename ::testing::internal::AddReference<T>::type + +// Adds a reference to const on top of T as necessary. For example, +// it transforms +// +// char ==> const char& +// const char ==> const char& +// char& ==> const char& +// const char& ==> const char& +// +// The argument T must depend on some template parameters. +#define GTEST_REFERENCE_TO_CONST_(T) \ + GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) + +// ImplicitlyConvertible<From, To>::value is a compile-time bool +// constant that's true iff type From can be implicitly converted to +// type To. +template <typename From, typename To> +class ImplicitlyConvertible { + private: + // We need the following helper functions only for their types. + // They have no implementations. + + // MakeFrom() is an expression whose type is From. We cannot simply + // use From(), as the type From may not have a public default + // constructor. + static From MakeFrom(); + + // These two functions are overloaded. Given an expression + // Helper(x), the compiler will pick the first version if x can be + // implicitly converted to type To; otherwise it will pick the + // second version. + // + // The first version returns a value of size 1, and the second + // version returns a value of size 2. Therefore, by checking the + // size of Helper(x), which can be done at compile time, we can tell + // which version of Helper() is used, and hence whether x can be + // implicitly converted to type To. + static char Helper(To); + static char (&Helper(...))[2]; // NOLINT + + // We have to put the 'public' section after the 'private' section, + // or MSVC refuses to compile the code. + public: + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4244) // Temporarily disables warning 4244. + + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +# pragma warning(pop) // Restores the warning state. +#elif defined(__BORLANDC__) + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); +#else + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +#endif // _MSV_VER +}; +template <typename From, typename To> +const bool ImplicitlyConvertible<From, To>::value; + +// IsAProtocolMessage<T>::value is a compile-time bool constant that's +// true iff T is type ProtocolMessage, proto2::Message, or a subclass +// of those. +template <typename T> +struct IsAProtocolMessage + : public bool_constant< + ImplicitlyConvertible<const T*, const ::ProtocolMessage*>::value || + ImplicitlyConvertible<const T*, const ::proto2::Message*>::value> { +}; + +// When the compiler sees expression IsContainerTest<C>(0), if C is an +// STL-style container class, the first overload of IsContainerTest +// will be viable (since both C::iterator* and C::const_iterator* are +// valid types and NULL can be implicitly converted to them). It will +// be picked over the second overload as 'int' is a perfect match for +// the type of argument 0. If C::iterator or C::const_iterator is not +// a valid type, the first overload is not viable, and the second +// overload will be picked. Therefore, we can determine whether C is +// a container class by checking the type of IsContainerTest<C>(0). +// The value of the expression is insignificant. +// +// Note that we look for both C::iterator and C::const_iterator. The +// reason is that C++ injects the name of a class as a member of the +// class itself (e.g. you can refer to class iterator as either +// 'iterator' or 'iterator::iterator'). If we look for C::iterator +// only, for example, we would mistakenly think that a class named +// iterator is an STL container. +// +// Also note that the simpler approach of overloading +// IsContainerTest(typename C::const_iterator*) and +// IsContainerTest(...) doesn't work with Visual Age C++ and Sun C++. +typedef int IsContainer; +template <class C> +IsContainer IsContainerTest(int /* dummy */, + typename C::iterator* /* it */ = NULL, + typename C::const_iterator* /* const_it */ = NULL) { + return 0; +} + +typedef char IsNotContainer; +template <class C> +IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } + +// EnableIf<condition>::type is void when 'Cond' is true, and +// undefined when 'Cond' is false. To use SFINAE to make a function +// overload only apply when a particular expression is true, add +// "typename EnableIf<expression>::type* = 0" as the last parameter. +template<bool> struct EnableIf; +template<> struct EnableIf<true> { typedef void type; }; // NOLINT + +// Utilities for native arrays. + +// ArrayEq() compares two k-dimensional native arrays using the +// elements' operator==, where k can be any integer >= 0. When k is +// 0, ArrayEq() degenerates into comparing a single pair of values. + +template <typename T, typename U> +bool ArrayEq(const T* lhs, size_t size, const U* rhs); + +// This generic version is used when k is 0. +template <typename T, typename U> +inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } + +// This overload is used when k >= 1. +template <typename T, typename U, size_t N> +inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { + return internal::ArrayEq(lhs, N, rhs); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous ArrayEq() function, arrays with different sizes would +// lead to different copies of the template code. +template <typename T, typename U> +bool ArrayEq(const T* lhs, size_t size, const U* rhs) { + for (size_t i = 0; i != size; i++) { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; +} + +// Finds the first element in the iterator range [begin, end) that +// equals elem. Element may be a native array type itself. +template <typename Iter, typename Element> +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { + for (Iter it = begin; it != end; ++it) { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; +} + +// CopyArray() copies a k-dimensional native array using the elements' +// operator=, where k can be any integer >= 0. When k is 0, +// CopyArray() degenerates into copying a single value. + +template <typename T, typename U> +void CopyArray(const T* from, size_t size, U* to); + +// This generic version is used when k is 0. +template <typename T, typename U> +inline void CopyArray(const T& from, U* to) { *to = from; } + +// This overload is used when k >= 1. +template <typename T, typename U, size_t N> +inline void CopyArray(const T(&from)[N], U(*to)[N]) { + internal::CopyArray(from, N, *to); +} + +// This helper reduces code bloat. If we instead put its logic inside +// the previous CopyArray() function, arrays with different sizes +// would lead to different copies of the template code. +template <typename T, typename U> +void CopyArray(const T* from, size_t size, U* to) { + for (size_t i = 0; i != size; i++) { + internal::CopyArray(from[i], to + i); + } +} + +// The relation between an NativeArray object (see below) and the +// native array it represents. +enum RelationToSource { + kReference, // The NativeArray references the native array. + kCopy // The NativeArray makes a copy of the native array and + // owns the copy. +}; + +// Adapts a native array to a read-only STL-style container. Instead +// of the complete STL container concept, this adaptor only implements +// members useful for Google Mock's container matchers. New members +// should be added as needed. To simplify the implementation, we only +// support Element being a raw type (i.e. having no top-level const or +// reference modifier). It's the client's responsibility to satisfy +// this requirement. Element can be an array type itself (hence +// multi-dimensional arrays are supported). +template <typename Element> +class NativeArray { + public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; + + // Constructs from a native array. + NativeArray(const Element* array, size_t count, RelationToSource relation) { + Init(array, count, relation); + } + + // Copy constructor. + NativeArray(const NativeArray& rhs) { + Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + } + + ~NativeArray() { + // Ensures that the user doesn't instantiate NativeArray with a + // const or reference type. + static_cast<void>(StaticAssertTypeEqHelper<Element, + GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>()); + if (relation_to_source_ == kCopy) + delete[] array_; + } + + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } + + private: + // Initializes this object; makes a copy of the input array if + // 'relation' is kCopy. + void Init(const Element* array, size_t a_size, RelationToSource relation) { + if (relation == kReference) { + array_ = array; + } else { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + } + size_ = a_size; + relation_to_source_ = relation; + } + + const Element* array_; + size_t size_; + RelationToSource relation_to_source_; + + GTEST_DISALLOW_ASSIGN_(NativeArray); +}; + +} // namespace internal +} // namespace testing + +#define GTEST_MESSAGE_AT_(file, line, message, result_type) \ + ::testing::internal::AssertHelper(result_type, file, line, message) \ + = ::testing::Message() + +#define GTEST_MESSAGE_(message, result_type) \ + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + +#define GTEST_FATAL_FAILURE_(message) \ + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + +#define GTEST_NONFATAL_FAILURE_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + +#define GTEST_SUCCESS_(message) \ + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + +// Suppresses MSVC warnings 4072 (unreachable code) for the code following +// statement if it returns or throws (or doesn't return or throw in some +// situations). +#define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ + if (::testing::internal::AlwaysTrue()) { statement; } + +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") { \ + bool gtest_caught_expected = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) { \ + gtest_caught_expected = true; \ + } \ + catch (...) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " \ + #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ + fail(gtest_msg.value) + +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ + fail("Expected: " #statement " doesn't throw an exception.\n" \ + " Actual: it throws.") + +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + bool gtest_caught_any = false; \ + try { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ + fail("Expected: " #statement " throws an exception.\n" \ + " Actual: it doesn't.") + + +// Implements Boolean test assertions such as EXPECT_TRUE. expression can be +// either a boolean expression or an AssertionResult. text is a textual +// represenation of expression as it was passed into the EXPECT_TRUE. +#define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage(\ + gtest_ar_, text, #actual, #expected).c_str()) + +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ + fail("Expected: " #statement " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") + +// Expands to the name of the class that implements the given test. +#define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + test_case_name##_##test_name##_Test + +// Helper macro for defining tests. +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ +class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ + public:\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ + private:\ + virtual void TestBody();\ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ + GTEST_DISALLOW_COPY_AND_ASSIGN_(\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ +};\ +\ +::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ + ::test_info_ =\ + ::testing::internal::MakeAndRegisterTestInfo(\ + #test_case_name, #test_name, NULL, NULL, \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl<\ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ +void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-linked_ptr.h b/lib/gtest/include/gtest/internal/gtest-linked_ptr.h new file mode 100644 index 0000000..57147b4 --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-linked_ptr.h @@ -0,0 +1,233 @@ +// Copyright 2003 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: Dan Egnor (egnor@google.com) +// +// A "smart" pointer type with reference tracking. Every pointer to a +// particular object is kept on a circular linked list. When the last pointer +// to an object is destroyed or reassigned, the object is deleted. +// +// Used properly, this deletes the object when the last reference goes away. +// There are several caveats: +// - Like all reference counting schemes, cycles lead to leaks. +// - Each smart pointer is actually two pointers (8 bytes instead of 4). +// - Every time a pointer is assigned, the entire list of pointers to that +// object is traversed. This class is therefore NOT SUITABLE when there +// will often be more than two or three pointers to a particular object. +// - References are only tracked as long as linked_ptr<> objects are copied. +// If a linked_ptr<> is converted to a raw pointer and back, BAD THINGS +// will happen (double deletion). +// +// A good use of this class is storing object references in STL containers. +// You can safely put linked_ptr<> in a vector<>. +// Other uses may not be as good. +// +// Note: If you use an incomplete type with linked_ptr<>, the class +// *containing* linked_ptr<> must have a constructor and destructor (even +// if they do nothing!). +// +// Bill Gibbons suggested we use something like this. +// +// Thread Safety: +// Unlike other linked_ptr implementations, in this implementation +// a linked_ptr object is thread-safe in the sense that: +// - it's safe to copy linked_ptr objects concurrently, +// - it's safe to copy *from* a linked_ptr and read its underlying +// raw pointer (e.g. via get()) concurrently, and +// - it's safe to write to two linked_ptrs that point to the same +// shared object concurrently. +// TODO(wan@google.com): rename this to safe_linked_ptr to avoid +// confusion with normal linked_ptr. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ + +#include <stdlib.h> +#include <assert.h> + +#include "gtest/internal/gtest-port.h" + +namespace testing { +namespace internal { + +// Protects copying of all linked_ptr objects. +GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// This is used internally by all instances of linked_ptr<>. It needs to be +// a non-template class because different types of linked_ptr<> can refer to +// the same object (linked_ptr<Superclass>(obj) vs linked_ptr<Subclass>(obj)). +// So, it needs to be possible for different types of linked_ptr to participate +// in the same circular linked list, so we need a single class type here. +// +// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>. +class linked_ptr_internal { + public: + // Create a new circle that includes only this instance. + void join_new() { + next_ = this; + } + + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and + // linked_ptr<Derived2>). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. + + // Join an existing circle. + // L < g_linked_ptr_mutex + void join(linked_ptr_internal const* ptr) { + MutexLock lock(&g_linked_ptr_mutex); + + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } + + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + // L < g_linked_ptr_mutex + bool depart() { + MutexLock lock(&g_linked_ptr_mutex); + + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } + + private: + mutable linked_ptr_internal const* next_; +}; + +template <typename T> +class linked_ptr { + public: + typedef T element_type; + + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } + + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); } + linked_ptr(linked_ptr const& ptr) { // NOLINT + assert(&ptr != this); + copy(&ptr); + } + + // Assignment releases the old value and acquires the new. + template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) { + depart(); + copy(&ptr); + return *this; + } + + linked_ptr& operator=(linked_ptr const& ptr) { + if (&ptr != this) { + depart(); + copy(&ptr); + } + return *this; + } + + // Smart pointer members. + void reset(T* ptr = NULL) { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } + + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template <typename U> + bool operator==(linked_ptr<U> const& ptr) const { + return value_ == ptr.get(); + } + template <typename U> + bool operator!=(linked_ptr<U> const& ptr) const { + return value_ != ptr.get(); + } + + private: + template <typename U> + friend class linked_ptr; + + T* value_; + linked_ptr_internal link_; + + void depart() { + if (link_.depart()) delete value_; + } + + void capture(T* ptr) { + value_ = ptr; + link_.join_new(); + } + + template <typename U> void copy(linked_ptr<U> const* ptr) { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } +}; + +template<typename T> inline +bool operator==(T* ptr, const linked_ptr<T>& x) { + return ptr == x.get(); +} + +template<typename T> inline +bool operator!=(T* ptr, const linked_ptr<T>& x) { + return ptr != x.get(); +} + +// A function to convert T* into linked_ptr<T> +// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation +// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg)) +template <typename T> +linked_ptr<T> make_linked_ptr(T* ptr) { + return linked_ptr<T>(ptr); +} + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_LINKED_PTR_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-param-util-generated.h b/lib/gtest/include/gtest/internal/gtest-param-util-generated.h new file mode 100644 index 0000000..2582675 --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-param-util-generated.h @@ -0,0 +1,4822 @@ +// This file was GENERATED by command: +// pump.py gtest-param-util-generated.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most 50 arguments in Values, +// and at most 10 arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at 10. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template <typename ForwardIterator> +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]); + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template <typename T1> +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template <typename T> + operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +template <typename T1, typename T2> +class ValueArray2 { + public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); + + const T1 v1_; + const T2 v2_; +}; + +template <typename T1, typename T2, typename T3> +class ValueArray3 { + public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; +}; + +template <typename T1, typename T2, typename T3, typename T4> +class ValueArray4 { + public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +class ValueArray5 { + public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +class ValueArray6 { + public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +class ValueArray7 { + public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +class ValueArray8 { + public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +class ValueArray9 { + public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +class ValueArray10 { + public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +class ValueArray11 { + public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +class ValueArray12 { + public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +class ValueArray13 { + public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +class ValueArray14 { + public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +class ValueArray15 { + public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +class ValueArray16 { + public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +class ValueArray17 { + public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +class ValueArray18 { + public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +class ValueArray19 { + public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +class ValueArray20 { + public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +class ValueArray21 { + public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +class ValueArray22 { + public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +class ValueArray23 { + public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, + v23_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +class ValueArray24 { + public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +class ValueArray25 { + public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +class ValueArray26 { + public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +class ValueArray27 { + public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +class ValueArray28 { + public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +class ValueArray29 { + public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +class ValueArray30 { + public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +class ValueArray31 { + public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +class ValueArray32 { + public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +class ValueArray33 { + public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +class ValueArray34 { + public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +class ValueArray35 { + public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, + v35_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +class ValueArray36 { + public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +class ValueArray37 { + public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +class ValueArray38 { + public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +class ValueArray39 { + public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +class ValueArray40 { + public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +class ValueArray41 { + public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +class ValueArray42 { + public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +class ValueArray43 { + public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), + v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), + v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), + v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), + v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), + v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), + v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +class ValueArray44 { + public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), + v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), + v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), + v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), + v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), + v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), + v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), + v43_(v43), v44_(v44) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +class ValueArray45 { + public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), + v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), + v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), + v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), + v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), + v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), + v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), + v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +class ValueArray46 { + public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), + v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +class ValueArray47 { + public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), + v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), + v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), + v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), + v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), + v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), + v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), + v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), + v47_(v47) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, + v47_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +class ValueArray48 { + public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), + v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), + v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), + v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), + v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), + v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), + v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), + v46_(v46), v47_(v47), v48_(v48) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +class ValueArray49 { + public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +class ValueArray50 { + public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), + v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), + v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), + v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), + v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), + v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), + v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), + v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {v1_, v2_, v3_, v4_, v5_, v6_, v7_, v8_, v9_, v10_, v11_, + v12_, v13_, v14_, v15_, v16_, v17_, v18_, v19_, v20_, v21_, v22_, v23_, + v24_, v25_, v26_, v27_, v28_, v29_, v30_, v31_, v32_, v33_, v34_, v35_, + v36_, v37_, v38_, v39_, v40_, v41_, v42_, v43_, v44_, v45_, v46_, v47_, + v48_, v49_, v50_}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); + + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; +}; + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +template <typename T1, typename T2> +class CartesianProductGenerator2 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2> > { + public: + typedef ::std::tr1::tuple<T1, T2> ParamType; + + CartesianProductGenerator2(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; +}; // class CartesianProductGenerator2 + + +template <typename T1, typename T2, typename T3> +class CartesianProductGenerator3 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3> ParamType; + + CartesianProductGenerator3(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; +}; // class CartesianProductGenerator3 + + +template <typename T1, typename T2, typename T3, typename T4> +class CartesianProductGenerator4 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4> ParamType; + + CartesianProductGenerator4(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; +}; // class CartesianProductGenerator4 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +class CartesianProductGenerator5 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5> ParamType; + + CartesianProductGenerator5(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; +}; // class CartesianProductGenerator5 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +class CartesianProductGenerator6 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, + T6> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> ParamType; + + CartesianProductGenerator6(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; +}; // class CartesianProductGenerator6 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +class CartesianProductGenerator7 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> ParamType; + + CartesianProductGenerator7(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; +}; // class CartesianProductGenerator7 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +class CartesianProductGenerator8 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7, T8> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> ParamType; + + CartesianProductGenerator8(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, + const ParamGenerator<T8>& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + virtual ~CartesianProductGenerator8() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7, + const ParamGenerator<T8>& g8, + const typename ParamGenerator<T8>::iterator& current8) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + const typename ParamGenerator<T8>::iterator begin8_; + const typename ParamGenerator<T8>::iterator end8_; + typename ParamGenerator<T8>::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; + const ParamGenerator<T8> g8_; +}; // class CartesianProductGenerator8 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +class CartesianProductGenerator9 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7, T8, T9> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9> ParamType; + + CartesianProductGenerator9(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, + const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + virtual ~CartesianProductGenerator9() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7, + const ParamGenerator<T8>& g8, + const typename ParamGenerator<T8>::iterator& current8, + const ParamGenerator<T9>& g9, + const typename ParamGenerator<T9>::iterator& current9) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + const typename ParamGenerator<T8>::iterator begin8_; + const typename ParamGenerator<T8>::iterator end8_; + typename ParamGenerator<T8>::iterator current8_; + const typename ParamGenerator<T9>::iterator begin9_; + const typename ParamGenerator<T9>::iterator end9_; + typename ParamGenerator<T9>::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; + const ParamGenerator<T8> g8_; + const ParamGenerator<T9> g9_; +}; // class CartesianProductGenerator9 + + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +class CartesianProductGenerator10 + : public ParamGeneratorInterface< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7, T8, T9, T10> > { + public: + typedef ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ParamType; + + CartesianProductGenerator10(const ParamGenerator<T1>& g1, + const ParamGenerator<T2>& g2, const ParamGenerator<T3>& g3, + const ParamGenerator<T4>& g4, const ParamGenerator<T5>& g5, + const ParamGenerator<T6>& g6, const ParamGenerator<T7>& g7, + const ParamGenerator<T8>& g8, const ParamGenerator<T9>& g9, + const ParamGenerator<T10>& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, + const ParamGenerator<T1>& g1, + const typename ParamGenerator<T1>::iterator& current1, + const ParamGenerator<T2>& g2, + const typename ParamGenerator<T2>::iterator& current2, + const ParamGenerator<T3>& g3, + const typename ParamGenerator<T3>::iterator& current3, + const ParamGenerator<T4>& g4, + const typename ParamGenerator<T4>::iterator& current4, + const ParamGenerator<T5>& g5, + const typename ParamGenerator<T5>::iterator& current5, + const ParamGenerator<T6>& g6, + const typename ParamGenerator<T6>::iterator& current6, + const ParamGenerator<T7>& g7, + const typename ParamGenerator<T7>::iterator& current7, + const ParamGenerator<T8>& g8, + const typename ParamGenerator<T8>::iterator& current8, + const ParamGenerator<T9>& g9, + const typename ParamGenerator<T9>::iterator& current9, + const ParamGenerator<T10>& g10, + const typename ParamGenerator<T10>::iterator& current10) + : base_(base), + begin1_(g1.begin()), end1_(g1.end()), current1_(current1), + begin2_(g2.begin()), end2_(g2.end()), current2_(current2), + begin3_(g3.begin()), end3_(g3.end()), current3_(current3), + begin4_(g4.begin()), end4_(g4.end()), current4_(current4), + begin5_(g5.begin()), end5_(g5.end()), current5_(current5), + begin6_(g6.begin()), end6_(g6.end()), current6_(current6), + begin7_(g7.begin()), end7_(g7.end()), current7_(current7), + begin8_(g8.begin()), end8_(g8.end()), current8_(current8), + begin9_(g9.begin()), end9_(g9.end()), current9_(current9), + begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ( + current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return + current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator<T1>::iterator begin1_; + const typename ParamGenerator<T1>::iterator end1_; + typename ParamGenerator<T1>::iterator current1_; + const typename ParamGenerator<T2>::iterator begin2_; + const typename ParamGenerator<T2>::iterator end2_; + typename ParamGenerator<T2>::iterator current2_; + const typename ParamGenerator<T3>::iterator begin3_; + const typename ParamGenerator<T3>::iterator end3_; + typename ParamGenerator<T3>::iterator current3_; + const typename ParamGenerator<T4>::iterator begin4_; + const typename ParamGenerator<T4>::iterator end4_; + typename ParamGenerator<T4>::iterator current4_; + const typename ParamGenerator<T5>::iterator begin5_; + const typename ParamGenerator<T5>::iterator end5_; + typename ParamGenerator<T5>::iterator current5_; + const typename ParamGenerator<T6>::iterator begin6_; + const typename ParamGenerator<T6>::iterator end6_; + typename ParamGenerator<T6>::iterator current6_; + const typename ParamGenerator<T7>::iterator begin7_; + const typename ParamGenerator<T7>::iterator end7_; + typename ParamGenerator<T7>::iterator current7_; + const typename ParamGenerator<T8>::iterator begin8_; + const typename ParamGenerator<T8>::iterator end8_; + typename ParamGenerator<T8>::iterator current8_; + const typename ParamGenerator<T9>::iterator begin9_; + const typename ParamGenerator<T9>::iterator end9_; + typename ParamGenerator<T9>::iterator current9_; + const typename ParamGenerator<T10>::iterator begin10_; + const typename ParamGenerator<T10>::iterator end10_; + typename ParamGenerator<T10>::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); + + const ParamGenerator<T1> g1_; + const ParamGenerator<T2> g2_; + const ParamGenerator<T3> g3_; + const ParamGenerator<T4> g4_; + const ParamGenerator<T5> g5_; + const ParamGenerator<T6> g6_; + const ParamGenerator<T7> g7_; + const ParamGenerator<T8> g8_; + const ParamGenerator<T9> g9_; + const ParamGenerator<T10> g10_; +}; // class CartesianProductGenerator10 + + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is +// convertible to U. +// +template <class Generator1, class Generator2> +class CartesianProductHolder2 { + public: +CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template <typename T1, typename T2> + operator ParamGenerator< ::std::tr1::tuple<T1, T2> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2> >( + new CartesianProductGenerator2<T1, T2>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); + + const Generator1 g1_; + const Generator2 g2_; +}; // class CartesianProductHolder2 + +template <class Generator1, class Generator2, class Generator3> +class CartesianProductHolder3 { + public: +CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template <typename T1, typename T2, typename T3> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3> >( + new CartesianProductGenerator3<T1, T2, T3>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; +}; // class CartesianProductHolder3 + +template <class Generator1, class Generator2, class Generator3, + class Generator4> +class CartesianProductHolder4 { + public: +CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template <typename T1, typename T2, typename T3, typename T4> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4> >( + new CartesianProductGenerator4<T1, T2, T3, T4>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; +}; // class CartesianProductHolder4 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5> +class CartesianProductHolder5 { + public: +CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5> >( + new CartesianProductGenerator5<T1, T2, T3, T4, T5>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; +}; // class CartesianProductHolder5 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6> +class CartesianProductHolder6 { + public: +CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6> >( + new CartesianProductGenerator6<T1, T2, T3, T4, T5, T6>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; +}; // class CartesianProductHolder6 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7> +class CartesianProductHolder7 { + public: +CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, + T7> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7> >( + new CartesianProductGenerator7<T1, T2, T3, T4, T5, T6, T7>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; +}; // class CartesianProductHolder7 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8> +class CartesianProductHolder8 { + public: +CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), + g8_(g8) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, + T8> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8> >( + new CartesianProductGenerator8<T1, T2, T3, T4, T5, T6, T7, T8>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_), + static_cast<ParamGenerator<T8> >(g8_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; +}; // class CartesianProductHolder8 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8, class Generator9> +class CartesianProductHolder9 { + public: +CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9> >( + new CartesianProductGenerator9<T1, T2, T3, T4, T5, T6, T7, T8, T9>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_), + static_cast<ParamGenerator<T8> >(g8_), + static_cast<ParamGenerator<T9> >(g9_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; +}; // class CartesianProductHolder9 + +template <class Generator1, class Generator2, class Generator3, + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8, class Generator9, class Generator10> +class CartesianProductHolder10 { + public: +CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), + g9_(g9), g10_(g10) {} + template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> + operator ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9, T10> >() const { + return ParamGenerator< ::std::tr1::tuple<T1, T2, T3, T4, T5, T6, T7, T8, + T9, T10> >( + new CartesianProductGenerator10<T1, T2, T3, T4, T5, T6, T7, T8, T9, + T10>( + static_cast<ParamGenerator<T1> >(g1_), + static_cast<ParamGenerator<T2> >(g2_), + static_cast<ParamGenerator<T3> >(g3_), + static_cast<ParamGenerator<T4> >(g4_), + static_cast<ParamGenerator<T5> >(g5_), + static_cast<ParamGenerator<T6> >(g6_), + static_cast<ParamGenerator<T7> >(g7_), + static_cast<ParamGenerator<T8> >(g8_), + static_cast<ParamGenerator<T9> >(g9_), + static_cast<ParamGenerator<T10> >(g10_))); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); + + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; +}; // class CartesianProductHolder10 + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-param-util-generated.h.pump b/lib/gtest/include/gtest/internal/gtest-param-util-generated.h.pump new file mode 100644 index 0000000..dbe9386 --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-param-util-generated.h.pump @@ -0,0 +1,301 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of Values arguments we want to support. +$var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. +// Copyright 2008 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. +// This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently Google Test supports at most $n arguments in Values, +// and at most $maxtuple arguments in Combine. Please contact +// googletestframework@googlegroups.com if you need more. +// Please note that the number of arguments to Combine is limited +// by the maximum arity of the implementation of tr1::tuple which is +// currently set at $maxtuple. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-param-util.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { + +// Forward declarations of ValuesIn(), which is implemented in +// include/gtest/gtest-param-test.h. +template <typename ForwardIterator> +internal::ParamGenerator< + typename ::testing::internal::IteratorTraits<ForwardIterator>::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end); + +template <typename T, size_t N> +internal::ParamGenerator<T> ValuesIn(const T (&array)[N]); + +template <class Container> +internal::ParamGenerator<typename Container::value_type> ValuesIn( + const Container& container); + +namespace internal { + +// Used in the Values() function to provide polymorphic capabilities. +template <typename T1> +class ValueArray1 { + public: + explicit ValueArray1(T1 v1) : v1_(v1) {} + + template <typename T> + operator ParamGenerator<T>() const { return ValuesIn(&v1_, &v1_ + 1); } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); + + const T1 v1_; +}; + +$range i 2..n +$for i [[ +$range j 1..i + +template <$for j, [[typename T$j]]> +class ValueArray$i { + public: + ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {} + + template <typename T> + operator ParamGenerator<T>() const { + const T array[] = {$for j, [[v$(j)_]]}; + return ValuesIn(array); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray$i& other); + +$for j [[ + + const T$j v$(j)_; +]] + +}; + +]] + +# if GTEST_HAS_COMBINE +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Generates values from the Cartesian product of values produced +// by the argument generators. +// +$range i 2..maxtuple +$for i [[ +$range j 1..i +$range k 2..i + +template <$for j, [[typename T$j]]> +class CartesianProductGenerator$i + : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > { + public: + typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType; + + CartesianProductGenerator$i($for j, [[const ParamGenerator<T$j>& g$j]]) + : $for j, [[g$(j)_(g$j)]] {} + virtual ~CartesianProductGenerator$i() {} + + virtual ParamIteratorInterface<ParamType>* Begin() const { + return new Iterator(this, $for j, [[g$(j)_, g$(j)_.begin()]]); + } + virtual ParamIteratorInterface<ParamType>* End() const { + return new Iterator(this, $for j, [[g$(j)_, g$(j)_.end()]]); + } + + private: + class Iterator : public ParamIteratorInterface<ParamType> { + public: + Iterator(const ParamGeneratorInterface<ParamType>* base, $for j, [[ + + const ParamGenerator<T$j>& g$j, + const typename ParamGenerator<T$j>::iterator& current$(j)]]) + : base_(base), +$for j, [[ + + begin$(j)_(g$j.begin()), end$(j)_(g$j.end()), current$(j)_(current$j) +]] { + ComputeCurrentValue(); + } + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<ParamType>* BaseGenerator() const { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() { + assert(!AtEnd()); + ++current$(i)_; + +$for k [[ + if (current$(i+2-k)_ == end$(i+2-k)_) { + current$(i+2-k)_ = begin$(i+2-k)_; + ++current$(i+2-k-1)_; + } + +]] + ComputeCurrentValue(); + } + virtual ParamIteratorInterface<ParamType>* Clone() const { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface<ParamType>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType<const Iterator>(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + ($for j && [[ + + current$(j)_ == typed_other->current$(j)_ +]]); + } + + private: + Iterator(const Iterator& other) + : base_(other.base_), $for j, [[ + + begin$(j)_(other.begin$(j)_), + end$(j)_(other.end$(j)_), + current$(j)_(other.current$(j)_) +]] { + ComputeCurrentValue(); + } + + void ComputeCurrentValue() { + if (!AtEnd()) + current_value_ = ParamType($for j, [[*current$(j)_]]); + } + bool AtEnd() const { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return +$for j || [[ + + current$(j)_ == end$(j)_ +]]; + } + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<ParamType>* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. +$for j [[ + + const typename ParamGenerator<T$j>::iterator begin$(j)_; + const typename ParamGenerator<T$j>::iterator end$(j)_; + typename ParamGenerator<T$j>::iterator current$(j)_; +]] + + ParamType current_value_; + }; // class CartesianProductGenerator$i::Iterator + + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator$i& other); + + +$for j [[ + const ParamGenerator<T$j> g$(j)_; + +]] +}; // class CartesianProductGenerator$i + + +]] + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Helper classes providing Combine() with polymorphic features. They allow +// casting CartesianProductGeneratorN<T> to ParamGenerator<U> if T is +// convertible to U. +// +$range i 2..maxtuple +$for i [[ +$range j 1..i + +template <$for j, [[class Generator$j]]> +class CartesianProductHolder$i { + public: +CartesianProductHolder$i($for j, [[const Generator$j& g$j]]) + : $for j, [[g$(j)_(g$j)]] {} + template <$for j, [[typename T$j]]> + operator ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >() const { + return ParamGenerator< ::std::tr1::tuple<$for j, [[T$j]]> >( + new CartesianProductGenerator$i<$for j, [[T$j]]>( +$for j,[[ + + static_cast<ParamGenerator<T$j> >(g$(j)_) +]])); + } + + private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder$i& other); + + +$for j [[ + const Generator$j g$(j)_; + +]] +}; // class CartesianProductHolder$i + +]] + +# endif // GTEST_HAS_COMBINE + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-param-util.h b/lib/gtest/include/gtest/internal/gtest-param-util.h new file mode 100644 index 0000000..0ef9718 --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-param-util.h @@ -0,0 +1,619 @@ +// Copyright 2008 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: vladl@google.com (Vlad Losev) + +// Type and function utilities for implementing parameterized tests. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ + +#include <iterator> +#include <utility> +#include <vector> + +// scripts/fuse_gtest.py depends on gtest's own header being #included +// *unconditionally*. Therefore these #includes cannot be moved +// inside #if GTEST_HAS_PARAM_TEST. +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-linked_ptr.h" +#include "gtest/internal/gtest-port.h" +#include "gtest/gtest-printers.h" + +#if GTEST_HAS_PARAM_TEST + +namespace testing { +namespace internal { + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Outputs a message explaining invalid registration of different +// fixture class for the same test case. This may happen when +// TEST_P macro is used to define two tests with the same name +// but in different namespaces. +GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line); + +template <typename> class ParamGeneratorInterface; +template <typename> class ParamGenerator; + +// Interface for iterating over elements provided by an implementation +// of ParamGeneratorInterface<T>. +template <typename T> +class ParamIteratorInterface { + public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface<T>* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator<T>. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator<T>::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator<T>::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; +}; + +// Class iterating over elements provided by an implementation of +// ParamGeneratorInterface<T>. It wraps ParamIteratorInterface<T> +// and implements the const forward iterator concept. +template <typename T> +class ParamIterator { + public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; + + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } + + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) { + ParamIteratorInterface<T>* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const { + return !(*this == other); + } + + private: + friend class ParamGenerator<T>; + explicit ParamIterator(ParamIteratorInterface<T>* impl) : impl_(impl) {} + scoped_ptr<ParamIteratorInterface<T> > impl_; +}; + +// ParamGeneratorInterface<T> is the binary interface to access generators +// defined in other translation units. +template <typename T> +class ParamGeneratorInterface { + public: + typedef T ParamType; + + virtual ~ParamGeneratorInterface() {} + + // Generator interface definition + virtual ParamIteratorInterface<T>* Begin() const = 0; + virtual ParamIteratorInterface<T>* End() const = 0; +}; + +// Wraps ParamGeneratorInterface<T> and provides general generator syntax +// compatible with the STL Container concept. +// This class implements copy initialization semantics and the contained +// ParamGeneratorInterface<T> instance is shared among all copies +// of the original object. This is possible because that instance is immutable. +template<typename T> +class ParamGenerator { + public: + typedef ParamIterator<T> iterator; + + explicit ParamGenerator(ParamGeneratorInterface<T>* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + + ParamGenerator& operator=(const ParamGenerator& other) { + impl_ = other.impl_; + return *this; + } + + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } + + private: + linked_ptr<const ParamGeneratorInterface<T> > impl_; +}; + +// Generates values from a range of two comparable values. Can be used to +// generate sequences of user-defined types that implement operator+() and +// operator<(). +// This class is used in the Range() function. +template <typename T, typename IncrementT> +class RangeGenerator : public ParamGeneratorInterface<T> { + public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), + step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} + + virtual ParamIteratorInterface<T>* Begin() const { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface<T>* End() const { + return new Iterator(this, end_, end_index_, step_); + } + + private: + class Iterator : public ParamIteratorInterface<T> { + public: + Iterator(const ParamGeneratorInterface<T>* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<T>* BaseGenerator() const { + return base_; + } + virtual void Advance() { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface<T>* Clone() const { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface<T>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType<const Iterator>(&other)->index_; + return index_ == other_index; + } + + private: + Iterator(const Iterator& other) + : ParamIteratorInterface<T>(), + base_(other.base_), value_(other.value_), index_(other.index_), + step_(other.step_) {} + + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); + + const ParamGeneratorInterface<T>* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator + + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } + + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); + + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; +}; // class RangeGenerator + + +// Generates values from a pair of STL-style iterators. Used in the +// ValuesIn() function. The elements are copied from the source range +// since the source can be located on the stack, and the generator +// is likely to persist beyond that stack frame. +template <typename T> +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface<T> { + public: + template <typename ForwardIterator> + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) {} + virtual ~ValuesInIteratorRangeGenerator() {} + + virtual ParamIteratorInterface<T>* Begin() const { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface<T>* End() const { + return new Iterator(this, container_.end()); + } + + private: + typedef typename ::std::vector<T> ContainerType; + + class Iterator : public ParamIteratorInterface<T> { + public: + Iterator(const ParamGeneratorInterface<T>* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} + + virtual const ParamGeneratorInterface<T>* BaseGenerator() const { + return base_; + } + virtual void Advance() { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface<T>* Clone() const { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface<T>& other) const { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType<const Iterator>(&other)->iterator_; + } + + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface<T>(), + base_(other.base_), + iterator_(other.iterator_) {} + + const ParamGeneratorInterface<T>* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr<const T> value_; + }; // class ValuesInIteratorRangeGenerator::Iterator + + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); + + const ContainerType container_; +}; // class ValuesInIteratorRangeGenerator + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Stores a parameter value and later creates tests parameterized with that +// value. +template <class TestClass> +class ParameterizedTestFactory : public TestFactoryBase { + public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : + parameter_(parameter) {} + virtual Test* CreateTest() { + TestClass::SetParam(¶meter_); + return new TestClass(); + } + + private: + const ParamType parameter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactoryBase is a base class for meta-factories that create +// test factories for passing into MakeAndRegisterTestInfo function. +template <class ParamType> +class TestMetaFactoryBase { + public: + virtual ~TestMetaFactoryBase() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// TestMetaFactory creates test factories for passing into +// MakeAndRegisterTestInfo function. Since MakeAndRegisterTestInfo receives +// ownership of test factory pointer, same factory object cannot be passed +// into that method twice. But ParameterizedTestCaseInfo is going to call +// it for each Test/Parameter value combination. Thus it needs meta factory +// creator class. +template <class TestCase> +class TestMetaFactory + : public TestMetaFactoryBase<typename TestCase::ParamType> { + public: + typedef typename TestCase::ParamType ParamType; + + TestMetaFactory() {} + + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { + return new ParameterizedTestFactory<TestCase>(parameter); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfoBase is a generic interface +// to ParameterizedTestCaseInfo classes. ParameterizedTestCaseInfoBase +// accumulates test information provided by TEST_P macro invocations +// and generators provided by INSTANTIATE_TEST_CASE_P macro invocations +// and uses that information to register all resulting test instances +// in RegisterTests method. The ParameterizeTestCaseRegistry class holds +// a collection of pointers to the ParameterizedTestCaseInfo objects +// and calls RegisterTests() on each of them when asked. +class ParameterizedTestCaseInfoBase { + public: + virtual ~ParameterizedTestCaseInfoBase() {} + + // Base part of test case name for display purposes. + virtual const string& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; + + protected: + ParameterizedTestCaseInfoBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +}; + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseInfo accumulates tests obtained from TEST_P +// macro invocations for a particular test case and generators +// obtained from INSTANTIATE_TEST_CASE_P macro invocations for that +// test case. It registers tests with all values generated by all +// generators when asked. +template <class TestCase> +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { + public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator<ParamType>(GeneratorCreationFunc)(); + + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} + + // Test case base name for display purposes. + virtual const string& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId<TestCase>(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase<ParamType>* meta_factory) { + tests_.push_back(linked_ptr<TestInfo>(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const string& instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) { + linked_ptr<TestInfo> test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); gen_it != instantiations_.end(); + ++gen_it) { + const string& instantiation_name = gen_it->first; + ParamGenerator<ParamType> generator((*gen_it->second)()); + + Message test_case_name_stream; + if ( !instantiation_name.empty() ) + test_case_name_stream << instantiation_name << "/"; + test_case_name_stream << test_info->test_case_base_name; + + int i = 0; + for (typename ParamGenerator<ParamType>::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) { + Message test_name_stream; + test_name_stream << test_info->test_base_name << "/" << i; + MakeAndRegisterTestInfo( + test_case_name_stream.GetString().c_str(), + test_name_stream.GetString().c_str(), + NULL, // No type parameter. + PrintToString(*param_it).c_str(), + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests + + private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase<ParamType>* a_test_meta_factory) : + test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} + + const string test_case_base_name; + const string test_base_name; + const scoped_ptr<TestMetaFactoryBase<ParamType> > test_meta_factory; + }; + typedef ::std::vector<linked_ptr<TestInfo> > TestInfoContainer; + // Keeps pairs of <Instantiation name, Sequence generator creation function> + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector<std::pair<string, GeneratorCreationFunc*> > + InstantiationContainer; + + const string test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); +}; // class ParameterizedTestCaseInfo + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// ParameterizedTestCaseRegistry contains a map of ParameterizedTestCaseInfoBase +// classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P +// macros use it to locate their corresponding ParameterizedTestCaseInfo +// descriptors. +class ParameterizedTestCaseRegistry { + public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + delete *it; + } + } + + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template <class TestCase> + ParameterizedTestCaseInfo<TestCase>* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) { + ParameterizedTestCaseInfo<TestCase>* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + if ((*it)->GetTestCaseName() == test_case_name) { + if ((*it)->GetTestCaseTypeId() != GetTypeId<TestCase>()) { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + posix::Abort(); + } else { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo<TestCase> >(*it); + } + break; + } + } + if (typed_test_info == NULL) { + typed_test_info = new ParameterizedTestCaseInfo<TestCase>(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) { + (*it)->RegisterTests(); + } + } + + private: + typedef ::std::vector<ParameterizedTestCaseInfoBase*> TestCaseInfoContainer; + + TestCaseInfoContainer test_case_infos_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_HAS_PARAM_TEST + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-port.h b/lib/gtest/include/gtest/internal/gtest-port.h new file mode 100644 index 0000000..157b47f --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-port.h @@ -0,0 +1,1775 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: wan@google.com (Zhanyong Wan) +// +// Low-level types and utilities for porting Google Test to various +// platforms. They are subject to change without notice. DO NOT USE +// THEM IN USER CODE. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + +// The user can define the following macros in the build script to +// control Google Test's behavior. If the user doesn't define a macro +// in this list, Google Test will define it. +// +// GTEST_HAS_CLONE - Define it to 1/0 to indicate that clone(2) +// is/isn't available. +// GTEST_HAS_EXCEPTIONS - Define it to 1/0 to indicate that exceptions +// are enabled. +// GTEST_HAS_GLOBAL_STRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::string, which is different to std::string). +// GTEST_HAS_GLOBAL_WSTRING - Define it to 1/0 to indicate that ::string +// is/isn't available (some systems define +// ::wstring, which is different to std::wstring). +// GTEST_HAS_POSIX_RE - Define it to 1/0 to indicate that POSIX regular +// expressions are/aren't available. +// GTEST_HAS_PTHREAD - Define it to 1/0 to indicate that <pthread.h> +// is/isn't available. +// GTEST_HAS_RTTI - Define it to 1/0 to indicate that RTTI is/isn't +// enabled. +// GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that +// std::wstring does/doesn't work (Google Test can +// be used where std::wstring is unavailable). +// GTEST_HAS_TR1_TUPLE - Define it to 1/0 to indicate tr1::tuple +// is/isn't available. +// GTEST_HAS_SEH - Define it to 1/0 to indicate whether the +// compiler supports Microsoft's "Structured +// Exception Handling". +// GTEST_HAS_STREAM_REDIRECTION +// - Define it to 1/0 to indicate whether the +// platform supports I/O stream redirection using +// dup() and dup2(). +// GTEST_USE_OWN_TR1_TUPLE - Define it to 1/0 to indicate whether Google +// Test's own tr1 tuple implementation should be +// used. Unused when the user sets +// GTEST_HAS_TR1_TUPLE to 0. +// GTEST_LINKED_AS_SHARED_LIBRARY +// - Define to 1 when compiling tests that use +// Google Test as a shared library (known as +// DLL on Windows). +// GTEST_CREATE_SHARED_LIBRARY +// - Define to 1 when compiling Google Test itself +// as a shared library. + +// This header defines the following utilities: +// +// Macros indicating the current platform (defined to 1 if compiled on +// the given platform; otherwise undefined): +// GTEST_OS_AIX - IBM AIX +// GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_HPUX - HP-UX +// GTEST_OS_LINUX - Linux +// GTEST_OS_LINUX_ANDROID - Google Android +// GTEST_OS_MAC - Mac OS X +// GTEST_OS_NACL - Google Native Client (NaCl) +// GTEST_OS_SOLARIS - Sun Solaris +// GTEST_OS_SYMBIAN - Symbian +// GTEST_OS_WINDOWS - Windows (Desktop, MinGW, or Mobile) +// GTEST_OS_WINDOWS_DESKTOP - Windows Desktop +// GTEST_OS_WINDOWS_MINGW - MinGW +// GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_ZOS - z/OS +// +// Among the platforms, Cygwin, Linux, Max OS X, and Windows have the +// most stable support. Since core members of the Google Test project +// don't have access to other platforms, support for them may be less +// stable. If you notice any problems on your platform, please notify +// googletestframework@googlegroups.com (patches for fixing them are +// even more welcome!). +// +// Note that it is possible that none of the GTEST_OS_* macros are defined. +// +// Macros indicating available Google Test features (defined to 1 if +// the corresponding feature is supported; otherwise undefined): +// GTEST_HAS_COMBINE - the Combine() function (for value-parameterized +// tests) +// GTEST_HAS_DEATH_TEST - death tests +// GTEST_HAS_PARAM_TEST - value-parameterized tests +// GTEST_HAS_TYPED_TEST - typed tests +// GTEST_HAS_TYPED_TEST_P - type-parameterized tests +// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with +// GTEST_HAS_POSIX_RE (see above) which users can +// define themselves. +// GTEST_USES_SIMPLE_RE - our own simple regex is used; +// the above two are mutually exclusive. +// GTEST_CAN_COMPARE_NULL - accepts untyped NULL in EXPECT_EQ(). +// +// Macros for basic C++ coding: +// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning. +// GTEST_ATTRIBUTE_UNUSED_ - declares that a class' instances or a +// variable don't have to be used. +// GTEST_DISALLOW_ASSIGN_ - disables operator=. +// GTEST_DISALLOW_COPY_AND_ASSIGN_ - disables copy ctor and operator=. +// GTEST_MUST_USE_RESULT_ - declares that a function's result must be used. +// +// Synchronization: +// Mutex, MutexLock, ThreadLocal, GetThreadCount() +// - synchronization primitives. +// GTEST_IS_THREADSAFE - defined to 1 to indicate that the above +// synchronization primitives have real implementations +// and Google Test is thread-safe; or 0 otherwise. +// +// Template meta programming: +// is_pointer - as in TR1; needed on Symbian and IBM XL C/C++ only. +// IteratorTraits - partial implementation of std::iterator_traits, which +// is not available in libCstd when compiled with Sun C++. +// +// Smart pointers: +// scoped_ptr - as in TR2. +// +// Regular expressions: +// RE - a simple regular expression class using the POSIX +// Extended Regular Expression syntax on UNIX-like +// platforms, or a reduced regular exception syntax on +// other platforms, including Windows. +// +// Logging: +// GTEST_LOG_() - logs messages at the specified severity level. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. +// +// Stdout and stderr capturing: +// CaptureStdout() - starts capturing stdout. +// GetCapturedStdout() - stops capturing stdout and returns the captured +// string. +// CaptureStderr() - starts capturing stderr. +// GetCapturedStderr() - stops capturing stderr and returns the captured +// string. +// +// Integer types: +// TypeWithSize - maps an integer to a int type. +// Int32, UInt32, Int64, UInt64, TimeInMillis +// - integers of known sizes. +// BiggestInt - the biggest signed integer type. +// +// Command-line utilities: +// GTEST_FLAG() - references a flag. +// GTEST_DECLARE_*() - declares a flag. +// GTEST_DEFINE_*() - defines a flag. +// GetArgvs() - returns the command line as a vector of strings. +// +// Environment variable utilities: +// GetEnv() - gets the value of an environment variable. +// BoolFromGTestEnv() - parses a bool environment variable. +// Int32FromGTestEnv() - parses an Int32 environment variable. +// StringFromGTestEnv() - parses a string environment variable. + +#include <ctype.h> // for isspace, etc +#include <stddef.h> // for ptrdiff_t +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#ifndef _WIN32_WCE +# include <sys/types.h> +# include <sys/stat.h> +#endif // !_WIN32_WCE + +#include <iostream> // NOLINT +#include <sstream> // NOLINT +#include <string> // NOLINT + +#define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" +#define GTEST_FLAG_PREFIX_ "gtest_" +#define GTEST_FLAG_PREFIX_DASH_ "gtest-" +#define GTEST_FLAG_PREFIX_UPPER_ "GTEST_" +#define GTEST_NAME_ "Google Test" +#define GTEST_PROJECT_URL_ "http://code.google.com/p/googletest/" + +// Determines the version of gcc that is used to compile this. +#ifdef __GNUC__ +// 40302 means version 4.3.2. +# define GTEST_GCC_VER_ \ + (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#endif // __GNUC__ + +// Determines the platform on which Google Test is compiled. +#ifdef __CYGWIN__ +# define GTEST_OS_CYGWIN 1 +#elif defined __SYMBIAN32__ +# define GTEST_OS_SYMBIAN 1 +#elif defined _WIN32 +# define GTEST_OS_WINDOWS 1 +# ifdef _WIN32_WCE +# define GTEST_OS_WINDOWS_MOBILE 1 +# elif defined(__MINGW__) || defined(__MINGW32__) +# define GTEST_OS_WINDOWS_MINGW 1 +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE +#elif defined __APPLE__ +# define GTEST_OS_MAC 1 +#elif defined __linux__ +# define GTEST_OS_LINUX 1 +# ifdef ANDROID +# define GTEST_OS_LINUX_ANDROID 1 +# endif // ANDROID +#elif defined __MVS__ +# define GTEST_OS_ZOS 1 +#elif defined(__sun) && defined(__SVR4) +# define GTEST_OS_SOLARIS 1 +#elif defined(_AIX) +# define GTEST_OS_AIX 1 +#elif defined(__hpux) +# define GTEST_OS_HPUX 1 +#elif defined __native_client__ +# define GTEST_OS_NACL 1 +#endif // __CYGWIN__ + +// Brings in definitions for functions used in the testing::internal::posix +// namespace (read, write, close, chdir, isatty, stat). We do not currently +// use them on Windows Mobile. +#if !GTEST_OS_WINDOWS +// This assumes that non-Windows OSes provide unistd.h. For OSes where this +// is not the case, we need to include headers that provide the functions +// mentioned above. +# include <unistd.h> +# if !GTEST_OS_NACL +// TODO(vladl@google.com): Remove this condition when Native Client SDK adds +// strings.h (tracked in +// http://code.google.com/p/nativeclient/issues/detail?id=1175). +# include <strings.h> // Native Client doesn't provide strings.h. +# endif +#elif !GTEST_OS_WINDOWS_MOBILE +# include <direct.h> +# include <io.h> +#endif + +// Defines this to true iff Google Test can use POSIX regular expressions. +#ifndef GTEST_HAS_POSIX_RE +# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +#endif + +#if GTEST_HAS_POSIX_RE + +// On some platforms, <regex.h> needs someone to define size_t, and +// won't compile otherwise. We can #include it here as we already +// included <stdlib.h>, which is guaranteed to define size_t through +// <stddef.h>. +# include <regex.h> // NOLINT + +# define GTEST_USES_POSIX_RE 1 + +#elif GTEST_OS_WINDOWS + +// <regex.h> is not available on Windows. Use our own simple regex +// implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#else + +// <regex.h> may not be available on this platform. Use our own +// simple regex implementation instead. +# define GTEST_USES_SIMPLE_RE 1 + +#endif // GTEST_HAS_POSIX_RE + +#ifndef GTEST_HAS_EXCEPTIONS +// The user didn't tell us whether exceptions are enabled, so we need +// to figure it out. +# if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS +// macro to enable exceptions, so we'll do the same. +// Assumes that exceptions are enabled by default. +# ifndef _HAS_EXCEPTIONS +# define _HAS_EXCEPTIONS 1 +# endif // _HAS_EXCEPTIONS +# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__GNUC__) && __EXCEPTIONS +// gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__SUNPRO_CC) +// Sun Pro CC supports exceptions. However, there is no compile-time way of +// detecting whether they are enabled or not. Therefore, we assume that +// they are enabled unless the user tells us otherwise. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__IBMCPP__) && __EXCEPTIONS +// xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. +# define GTEST_HAS_EXCEPTIONS 1 +# elif defined(__HP_aCC) +// Exception handling is in effect by default in HP aCC compiler. It has to +// be turned of by +noeh compiler option if desired. +# define GTEST_HAS_EXCEPTIONS 1 +# else +// For other compilers, we assume exceptions are disabled to be +// conservative. +# define GTEST_HAS_EXCEPTIONS 0 +# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#endif // GTEST_HAS_EXCEPTIONS + +#if !defined(GTEST_HAS_STD_STRING) +// Even though we don't use this macro any longer, we keep it in case +// some clients still depend on it. +# define GTEST_HAS_STD_STRING 1 +#elif !GTEST_HAS_STD_STRING +// The user told us that ::std::string isn't available. +# error "Google Test cannot be used where ::std::string isn't available." +#endif // !defined(GTEST_HAS_STD_STRING) + +#ifndef GTEST_HAS_GLOBAL_STRING +// The user didn't tell us whether ::string is available, so we need +// to figure it out. + +# define GTEST_HAS_GLOBAL_STRING 0 + +#endif // GTEST_HAS_GLOBAL_STRING + +#ifndef GTEST_HAS_STD_WSTRING +// The user didn't tell us whether ::std::wstring is available, so we need +// to figure it out. +// TODO(wan@google.com): uses autoconf to detect whether ::std::wstring +// is available. + +// Cygwin 1.7 and below doesn't support ::std::wstring. +// Solaris' libc++ doesn't support it either. Android has +// no support for it at least as recent as Froyo (2.2). +# define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) + +#endif // GTEST_HAS_STD_WSTRING + +#ifndef GTEST_HAS_GLOBAL_WSTRING +// The user didn't tell us whether ::wstring is available, so we need +// to figure it out. +# define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#endif // GTEST_HAS_GLOBAL_WSTRING + +// Determines whether RTTI is available. +#ifndef GTEST_HAS_RTTI +// The user didn't tell us whether RTTI is enabled, so we need to +// figure it out. + +# ifdef _MSC_VER + +# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +// Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) + +# ifdef __GXX_RTTI +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif // __GXX_RTTI + +// Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if +// both the typeid and dynamic_cast features are present. +# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) + +# ifdef __RTTI_ALL__ +# define GTEST_HAS_RTTI 1 +# else +# define GTEST_HAS_RTTI 0 +# endif + +# else + +// For all other compilers, we assume RTTI is enabled. +# define GTEST_HAS_RTTI 1 + +# endif // _MSC_VER + +#endif // GTEST_HAS_RTTI + +// It's this header's responsibility to #include <typeinfo> when RTTI +// is enabled. +#if GTEST_HAS_RTTI +# include <typeinfo> +#endif + +// Determines whether Google Test can use the pthreads library. +#ifndef GTEST_HAS_PTHREAD +// The user didn't tell us explicitly, so we assume pthreads support is +// available on Linux and Mac. +// +// To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 +// to your compiler flags. +# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX) +#endif // GTEST_HAS_PTHREAD + +#if GTEST_HAS_PTHREAD +// gtest-port.h guarantees to #include <pthread.h> when GTEST_HAS_PTHREAD is +// true. +# include <pthread.h> // NOLINT + +// For timespec and nanosleep, used below. +# include <time.h> // NOLINT +#endif + +// Determines whether Google Test can use tr1/tuple. You can define +// this macro to 0 to prevent Google Test from using tuple (any +// feature depending on tuple with be disabled in this mode). +#ifndef GTEST_HAS_TR1_TUPLE +// The user didn't tell us not to do it, so we assume it's OK. +# define GTEST_HAS_TR1_TUPLE 1 +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether Google Test's own tr1 tuple implementation +// should be used. +#ifndef GTEST_USE_OWN_TR1_TUPLE +// The user didn't tell us, so we need to figure it out. + +// We use our own TR1 tuple if we aren't sure the user has an +// implementation of it already. At this time, GCC 4.0.0+ and MSVC +// 2010 are the only mainstream compilers that come with a TR1 tuple +// implementation. NVIDIA's CUDA NVCC compiler pretends to be GCC by +// defining __GNUC__ and friends, but cannot compile GCC's tuple +// implementation. MSVC 2008 (9.0) provides TR1 tuple in a 323 MB +// Feature Pack download, which we cannot assume the user has. +# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000)) \ + || _MSC_VER >= 1600 +# define GTEST_USE_OWN_TR1_TUPLE 0 +# else +# define GTEST_USE_OWN_TR1_TUPLE 1 +# endif + +#endif // GTEST_USE_OWN_TR1_TUPLE + +// To avoid conditional compilation everywhere, we make it +// gtest-port.h's responsibility to #include the header implementing +// tr1/tuple. +#if GTEST_HAS_TR1_TUPLE + +# if GTEST_USE_OWN_TR1_TUPLE +# include "gtest/internal/gtest-tuple.h" +# elif GTEST_OS_SYMBIAN + +// On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to +// use STLport's tuple implementation, which unfortunately doesn't +// work as the copy of STLport distributed with Symbian is incomplete. +// By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to +// use its own tuple implementation. +# ifdef BOOST_HAS_TR1_TUPLE +# undef BOOST_HAS_TR1_TUPLE +# endif // BOOST_HAS_TR1_TUPLE + +// This prevents <boost/tr1/detail/config.hpp>, which defines +// BOOST_HAS_TR1_TUPLE, from being #included by Boost's <tuple>. +# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +# include <tuple> + +# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +// GCC 4.0+ implements tr1/tuple in the <tr1/tuple> header. This does +// not conform to the TR1 spec, which requires the header to be <tuple>. + +# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +// Until version 4.3.2, gcc has a bug that causes <tr1/functional>, +// which is #included by <tr1/tuple>, to not compile when RTTI is +// disabled. _TR1_FUNCTIONAL is the header guard for +// <tr1/functional>. Hence the following #define is a hack to prevent +// <tr1/functional> from being included. +# define _TR1_FUNCTIONAL 1 +# include <tr1/tuple> +# undef _TR1_FUNCTIONAL // Allows the user to #include + // <tr1/functional> if he chooses to. +# else +# include <tr1/tuple> // NOLINT +# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 + +# else +// If the compiler is not GCC 4.0+, we assume the user is using a +// spec-conforming TR1 implementation. +# include <tuple> // NOLINT +# endif // GTEST_USE_OWN_TR1_TUPLE + +#endif // GTEST_HAS_TR1_TUPLE + +// Determines whether clone(2) is supported. +// Usually it will only be available on Linux, excluding +// Linux on the Itanium architecture. +// Also see http://linux.die.net/man/2/clone. +#ifndef GTEST_HAS_CLONE +// The user didn't tell us, so we need to figure it out. + +# if GTEST_OS_LINUX && !defined(__ia64__) +# define GTEST_HAS_CLONE 1 +# else +# define GTEST_HAS_CLONE 0 +# endif // GTEST_OS_LINUX && !defined(__ia64__) + +#endif // GTEST_HAS_CLONE + +// Determines whether to support stream redirection. This is used to test +// output correctness and to implement death tests. +#ifndef GTEST_HAS_STREAM_REDIRECTION +// By default, we assume that stream redirection is supported on all +// platforms except known mobile ones. +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN +# define GTEST_HAS_STREAM_REDIRECTION 0 +# else +# define GTEST_HAS_STREAM_REDIRECTION 1 +# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#endif // GTEST_HAS_STREAM_REDIRECTION + +// Determines whether to support death tests. +// Google Test does not support death tests for VC 7.1 and earlier as +// abort() in a VC 7.1 application compiled as GUI in debug config +// pops up a dialog window that cannot be suppressed programmatically. +#if (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX) +# define GTEST_HAS_DEATH_TEST 1 +# include <vector> // NOLINT +#endif + +// We don't support MSVC 7.1 with exceptions disabled now. Therefore +// all the compilers we care about are adequate for supporting +// value-parameterized tests. +#define GTEST_HAS_PARAM_TEST 1 + +// Determines whether to support type-driven tests. + +// Typed tests need <typeinfo> and variadic macros, which GCC, VC++ 8.0, +// Sun Pro CC, IBM Visual Age, and HP aCC support. +#if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ + defined(__IBMCPP__) || defined(__HP_aCC) +# define GTEST_HAS_TYPED_TEST 1 +# define GTEST_HAS_TYPED_TEST_P 1 +#endif + +// Determines whether to support Combine(). This only makes sense when +// value-parameterized tests are enabled. The implementation doesn't +// work on Sun Studio since it doesn't understand templated conversion +// operators. +#if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) +# define GTEST_HAS_COMBINE 1 +#endif + +// Determines whether the system compiler uses UTF-16 for encoding wide strings. +#define GTEST_WIDE_STRING_USES_UTF16_ \ + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + +// Determines whether test results can be streamed to a socket. +#if GTEST_OS_LINUX +# define GTEST_CAN_STREAM_RESULTS_ 1 +#endif + +// Defines some utility macros. + +// The GNU compiler emits a warning if nested "if" statements are followed by +// an "else" statement and braces are not used to explicitly disambiguate the +// "else" binding. This leads to problems with code like: +// +// if (gate) +// ASSERT_*(condition) << "Some message"; +// +// The "switch (0) case 0:" idiom is used to suppress this. +#ifdef __INTEL_COMPILER +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#else +# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#endif + +// Use this annotation at the end of a struct/class definition to +// prevent the compiler from optimizing away instances that are never +// used. This is useful when all interesting logic happens inside the +// c'tor and / or d'tor. Example: +// +// struct Foo { +// Foo() { ... } +// } GTEST_ATTRIBUTE_UNUSED_; +// +// Also use it after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +#if defined(__GNUC__) && !defined(COMPILER_ICC) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#else +# define GTEST_ATTRIBUTE_UNUSED_ +#endif + +// A macro to disallow operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_ASSIGN_(type)\ + void operator=(type const &) + +// A macro to disallow copy constructor and operator= +// This should be used in the private: declarations for a class. +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ + type(type const &);\ + GTEST_DISALLOW_ASSIGN_(type) + +// Tell the compiler to warn about unused return values for functions declared +// with this macro. The macro should be used on function declarations +// following the argument list: +// +// Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; +#if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) +# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#else +# define GTEST_MUST_USE_RESULT_ +#endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC + +// Determine whether the compiler supports Microsoft's Structured Exception +// Handling. This is supported by several Windows compilers but generally +// does not exist on any other system. +#ifndef GTEST_HAS_SEH +// The user didn't tell us, so we need to figure it out. + +# if defined(_MSC_VER) || defined(__BORLANDC__) +// These two compilers are known to support SEH. +# define GTEST_HAS_SEH 1 +# else +// Assume no SEH. +# define GTEST_HAS_SEH 0 +# endif + +#endif // GTEST_HAS_SEH + +#ifdef _MSC_VER + +# if GTEST_LINKED_AS_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllimport) +# elif GTEST_CREATE_SHARED_LIBRARY +# define GTEST_API_ __declspec(dllexport) +# endif + +#endif // _MSC_VER + +#ifndef GTEST_API_ +# define GTEST_API_ +#endif + +#ifdef __GNUC__ +// Ask the compiler to never inline a given function. +# define GTEST_NO_INLINE_ __attribute__((noinline)) +#else +# define GTEST_NO_INLINE_ +#endif + +namespace testing { + +class Message; + +namespace internal { + +class String; + +// The GTEST_COMPILE_ASSERT_ macro can be used to verify that a compile time +// expression is true. For example, you could use it to verify the +// size of a static array: +// +// GTEST_COMPILE_ASSERT_(ARRAYSIZE(content_type_names) == CONTENT_NUM_TYPES, +// content_type_names_incorrect_size); +// +// or to make sure a struct is smaller than a certain size: +// +// GTEST_COMPILE_ASSERT_(sizeof(foo) < 128, foo_too_large); +// +// The second argument to the macro is the name of the variable. If +// the expression is false, most compilers will issue a warning/error +// containing the name of the variable. + +template <bool> +struct CompileAssert { +}; + +#define GTEST_COMPILE_ASSERT_(expr, msg) \ + typedef ::testing::internal::CompileAssert<(bool(expr))> \ + msg[bool(expr) ? 1 : -1] + +// Implementation details of GTEST_COMPILE_ASSERT_: +// +// - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 +// elements (and thus is invalid) when the expression is false. +// +// - The simpler definition +// +// #define GTEST_COMPILE_ASSERT_(expr, msg) typedef char msg[(expr) ? 1 : -1] +// +// does not work, as gcc supports variable-length arrays whose sizes +// are determined at run-time (this is gcc's extension and not part +// of the C++ standard). As a result, gcc fails to reject the +// following code with the simple definition: +// +// int foo; +// GTEST_COMPILE_ASSERT_(foo, msg); // not supposed to compile as foo is +// // not a compile-time constant. +// +// - By using the type CompileAssert<(bool(expr))>, we ensures that +// expr is a compile-time constant. (Template arguments must be +// determined at compile-time.) +// +// - The outter parentheses in CompileAssert<(bool(expr))> are necessary +// to work around a bug in gcc 3.4.4 and 4.0.1. If we had written +// +// CompileAssert<bool(expr)> +// +// instead, these compilers will refuse to compile +// +// GTEST_COMPILE_ASSERT_(5 > 0, some_message); +// +// (They seem to think the ">" in "5 > 0" marks the end of the +// template argument list.) +// +// - The array size is (bool(expr) ? 1 : -1), instead of simply +// +// ((expr) ? 1 : -1). +// +// This is to avoid running into a bug in MS VC 7.1, which +// causes ((0.0) ? 1 : -1) to incorrectly evaluate to 1. + +// StaticAssertTypeEqHelper is used by StaticAssertTypeEq defined in gtest.h. +// +// This template is declared, but intentionally undefined. +template <typename T1, typename T2> +struct StaticAssertTypeEqHelper; + +template <typename T> +struct StaticAssertTypeEqHelper<T, T> {}; + +#if GTEST_HAS_GLOBAL_STRING +typedef ::string string; +#else +typedef ::std::string string; +#endif // GTEST_HAS_GLOBAL_STRING + +#if GTEST_HAS_GLOBAL_WSTRING +typedef ::wstring wstring; +#elif GTEST_HAS_STD_WSTRING +typedef ::std::wstring wstring; +#endif // GTEST_HAS_GLOBAL_WSTRING + +// A helper for suppressing warnings on constant condition. It just +// returns 'condition'. +GTEST_API_ bool IsTrue(bool condition); + +// Defines scoped_ptr. + +// This implementation of scoped_ptr is PARTIAL - it only contains +// enough stuff to satisfy Google Test's need. +template <typename T> +class scoped_ptr { + public: + typedef T element_type; + + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } + + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } + + T* release() { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } + + void reset(T* p = NULL) { + if (p != ptr_) { + if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } + private: + T* ptr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); +}; + +// Defines RE. + +// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended +// Regular Expression syntax. +class GTEST_API_ RE { + public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } + + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + +#if GTEST_HAS_GLOBAL_STRING + + RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT + +#endif // GTEST_HAS_GLOBAL_STRING + + RE(const char* regex) { Init(regex); } // NOLINT + ~RE(); + + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } + + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#if GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const ::string& str, const RE& re) { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) { + return PartialMatch(str.c_str(), re); + } + +#endif // GTEST_HAS_GLOBAL_STRING + + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); + + private: + void Init(const char* regex); + + // We use a const char* instead of a string, as Google Test may be used + // where string is not available. We also do not use Google Test's own + // String type here, in order to simplify dependencies between the + // files. + const char* pattern_; + bool is_valid_; + +#if GTEST_USES_POSIX_RE + + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). + +#else // GTEST_USES_SIMPLE_RE + + const char* full_pattern_; // For FullMatch(); + +#endif + + GTEST_DISALLOW_ASSIGN_(RE); +}; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + +// Defines logging utilities: +// GTEST_LOG_(severity) - logs messages at the specified severity level. The +// message itself is streamed into the macro. +// LogToStderr() - directs all log messages to stderr. +// FlushInfoLog() - flushes informational log messages. + +enum GTestLogSeverity { + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL +}; + +// Formats log entry severity, provides a stream object for streaming the +// log message, and terminates the message with a newline when going out of +// scope. +class GTEST_API_ GTestLog { + public: + GTestLog(GTestLogSeverity severity, const char* file, int line); + + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); + + ::std::ostream& GetStream() { return ::std::cerr; } + + private: + const GTestLogSeverity severity_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); +}; + +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__).GetStream() + +inline void LogToStderr() {} +inline void FlushInfoLog() { fflush(NULL); } + +// INTERNAL IMPLEMENTATION - DO NOT USE. +// +// GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition +// is not satisfied. +// Synopsys: +// GTEST_CHECK_(boolean_condition); +// or +// GTEST_CHECK_(boolean_condition) << "Additional message"; +// +// This checks the condition and if the condition is not satisfied +// it prints message about the condition violation, including the +// condition itself, plus additional message streamed into it, if any, +// and then it aborts the program. It aborts the program irrespective of +// whether it is built in the debug mode or not. +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " + +// An all-mode assert to verify that the given POSIX-style function +// call returns 0 (indicating success). Known limitation: this +// doesn't expand to a balanced 'if' statement, so enclose the macro +// in {} if you need to use it as the only statement in an 'if' +// branch. +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error + +// INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. +// +// Use ImplicitCast_ as a safe version of static_cast for upcasting in +// the type hierarchy (e.g. casting a Foo* to a SuperclassOfFoo* or a +// const Foo*). When you use ImplicitCast_, the compiler checks that +// the cast is safe. Such explicit ImplicitCast_s are necessary in +// surprisingly many situations where C++ demands an exact type match +// instead of an argument type convertable to a target type. +// +// The syntax for using ImplicitCast_ is the same as for static_cast: +// +// ImplicitCast_<ToType>(expr) +// +// ImplicitCast_ would have been part of the C++ standard library, +// but the proposal was submitted too late. It will probably make +// its way into the language in the future. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., implicit_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template<typename To> +inline To ImplicitCast_(To x) { return x; } + +// When you upcast (that is, cast a pointer from type Foo to type +// SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts +// always succeed. When you downcast (that is, cast a pointer from +// type Foo to type SubclassOfFoo), static_cast<> isn't safe, because +// how do you know the pointer is really of type SubclassOfFoo? It +// could be a bare Foo, or of type DifferentSubclassOfFoo. Thus, +// when you downcast, you should use this macro. In debug mode, we +// use dynamic_cast<> to double-check the downcast is legal (we die +// if it's not). In normal mode, we do the efficient static_cast<> +// instead. Thus, it's important to test in debug mode to make sure +// the cast is legal! +// This is the only place in the code we should use dynamic_cast<>. +// In particular, you SHOULDN'T be using dynamic_cast<> in order to +// do RTTI (eg code like this: +// if (dynamic_cast<Subclass1>(foo)) HandleASubclass1Object(foo); +// if (dynamic_cast<Subclass2>(foo)) HandleASubclass2Object(foo); +// You should design the code some other way not to need this. +// +// This relatively ugly name is intentional. It prevents clashes with +// similar functions users may have (e.g., down_cast). The internal +// namespace alone is not enough because the function can be found by ADL. +template<typename To, typename From> // use like this: DownCast_<T*>(foo); +inline To DownCast_(From* f) { // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) { + const To to = NULL; + ::testing::internal::ImplicitCast_<From*>(to); + } + +#if GTEST_HAS_RTTI + // RTTI: debug mode only! + GTEST_CHECK_(f == NULL || dynamic_cast<To>(f) != NULL); +#endif + return static_cast<To>(f); +} + +// Downcasts the pointer of type Base to Derived. +// Derived must be a subclass of Base. The parameter MUST +// point to a class of type Derived, not any subclass of it. +// When RTTI is available, the function performs a runtime +// check to enforce this. +template <class Derived, class Base> +Derived* CheckedDowncastToActualType(Base* base) { +#if GTEST_HAS_RTTI + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast<Derived*>(base); // NOLINT +#else + return static_cast<Derived*>(base); // Poor man's downcast. +#endif +} + +#if GTEST_HAS_STREAM_REDIRECTION + +// Defines the stderr capturer: +// CaptureStdout - starts capturing stdout. +// GetCapturedStdout - stops capturing stdout and returns the captured string. +// CaptureStderr - starts capturing stderr. +// GetCapturedStderr - stops capturing stderr and returns the captured string. +// +GTEST_API_ void CaptureStdout(); +GTEST_API_ String GetCapturedStdout(); +GTEST_API_ void CaptureStderr(); +GTEST_API_ String GetCapturedStderr(); + +#endif // GTEST_HAS_STREAM_REDIRECTION + + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +extern ::std::vector<String> g_argvs; + +// GTEST_HAS_DEATH_TEST implies we have ::std::string. +const ::std::vector<String>& GetArgvs(); + +#endif // GTEST_HAS_DEATH_TEST + +// Defines synchronization primitives. + +#if GTEST_HAS_PTHREAD + +// Sleeps for (roughly) n milli-seconds. This function is only for +// testing Google Test's own constructs. Don't use it in user tests, +// either directly or indirectly. +inline void SleepMilliseconds(int n) { + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); +} + +// Allows a controller thread to pause execution of newly created +// threads until notified. Instances of this class must be created +// and destroyed in the controller thread. +// +// This class is only for testing Google Test's own constructs. Do not +// use it in user tests, either directly or indirectly. +class Notification { + public: + Notification() : notified_(false) {} + + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() { notified_ = true; } + + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() { + while(!notified_) { + SleepMilliseconds(10); + } + } + + private: + volatile bool notified_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; + +// As a C-function, ThreadFuncWithCLinkage cannot be templated itself. +// Consequently, it cannot select a correct instantiation of ThreadWithParam +// in order to call its Run(). Introducing ThreadWithParamBase as a +// non-templated base class for ThreadWithParam allows us to bypass this +// problem. +class ThreadWithParamBase { + public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; +}; + +// pthread_create() accepts a pointer to a function type with the C linkage. +// According to the Standard (7.5/1), function types with different linkages +// are different even if they are otherwise identical. Some compilers (for +// example, SunStudio) treat them as different types. Since class methods +// cannot be defined with C-linkage we need to define a free C-function to +// pass into pthread_create(). +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { + static_cast<ThreadWithParamBase*>(thread)->Run(); + return NULL; +} + +// Helper class for testing Google Test's multi-threading constructs. +// To use it, write: +// +// void ThreadFunc(int param) { /* Do things with param */ } +// Notification thread_can_start; +// ... +// // The thread_can_start parameter is optional; you can supply NULL. +// ThreadWithParam<int> thread(&ThreadFunc, 5, &thread_can_start); +// thread_can_start.Notify(); +// +// These classes are only for testing Google Test's own constructs. Do +// not use them in user tests, either directly or indirectly. +template <typename T> +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void (*UserThreadFunc)(T); + + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } + + void Join() { + if (!finished_) { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } + + virtual void Run() { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } + + private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// MutexBase and Mutex implement mutex on pthreads-based platforms. They +// are used in conjunction with class MutexLock: +// +// Mutex mutex; +// ... +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the end +// // of the current scope. +// +// MutexBase implements behavior for both statically and dynamically +// allocated mutexes. Do not use MutexBase directly. Instead, write +// the following to define a static mutex: +// +// GTEST_DEFINE_STATIC_MUTEX_(g_some_mutex); +// +// You can forward declare a static mutex like this: +// +// GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); +// +// To create a dynamic mutex, just define an object of type Mutex. +class MutexBase { + public: + // Acquires this mutex. + void Lock() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + } + + // Releases this mutex. + void Unlock() { + // We don't protect writing to owner_ here, as it's the caller's + // responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_ = 0; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const { + GTEST_CHECK_(owner_ == pthread_self()) + << "The current thread is not holding the mutex @" << this; + } + + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. + public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + pthread_t owner_; // The thread holding the mutex; 0 means no one holds it. +}; + +// Forward-declares a static mutex. +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex + +// Defines and statically (i.e. at link time) initializes a static mutex. +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, 0 } + +// The Mutex class can only be used for mutexes created at runtime. It +// shares its API with MutexBase otherwise. +class Mutex : public MutexBase { + public: + Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + owner_ = 0; + } + ~Mutex() { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +// We cannot name this class MutexLock as the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + MutexBase* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Helpers for ThreadLocal. + +// pthread_key_create() requires DeleteThreadLocalValue() to have +// C-linkage. Therefore it cannot be templatized to access +// ThreadLocal<T>. Hence the need for class +// ThreadLocalValueHolderBase. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Called by pthread to delete thread-local data stored by +// pthread_setspecific(). +extern "C" inline void DeleteThreadLocalValue(void* value_holder) { + delete static_cast<ThreadLocalValueHolderBase*>(value_holder); +} + +// Implements thread-local storage on pthreads-based systems. +// +// // Thread 1 +// ThreadLocal<int> tl(100); // 100 is the default value for each thread. +// +// // Thread 2 +// tl.set(150); // Changes the value for thread 2 only. +// EXPECT_EQ(150, tl.get()); +// +// // Thread 1 +// EXPECT_EQ(100, tl.get()); // In thread 1, tl has the original value. +// tl.set(200); +// EXPECT_EQ(200, tl.get()); +// +// The template type argument T must have a public copy constructor. +// In addition, the default ThreadLocal constructor requires T to have +// a public default constructor. +// +// An object managed for a thread by a ThreadLocal instance is deleted +// when the thread exits. Or, if the ThreadLocal instance dies in +// that thread, when the ThreadLocal dies. It's the user's +// responsibility to ensure that all other threads using a ThreadLocal +// have exited when it dies, or the per-thread objects for those +// threads will not be deleted. +// +// Google Test only uses global ThreadLocal objects. That means they +// will die after main() has returned. Therefore, no per-thread +// object managed by Google Test will be leaked as long as all threads +// using Google Test have exited when main() returns. +template <typename T> +class ThreadLocal { + public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} + + ~ThreadLocal() { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); + + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } + + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } + + private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + static pthread_key_t CreateKey() { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } + + T* GetOrCreateValue() const { + ThreadLocalValueHolderBase* const holder = + static_cast<ThreadLocalValueHolderBase*>(pthread_getspecific(key_)); + if (holder != NULL) { + return CheckedDowncastToActualType<ValueHolder>(holder)->pointer(); + } + + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } + + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# define GTEST_IS_THREADSAFE 1 + +#else // GTEST_HAS_PTHREAD + +// A dummy implementation of synchronization primitives (mutex, lock, +// and thread-local variable). Necessary for compiling Google Test where +// mutex is not supported - using Google Test in multiple threads is not +// supported on such platforms. + +class Mutex { + public: + Mutex() {} + void AssertHeld() const {} +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex + +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex*) {} // NOLINT +}; + +typedef GTestMutexLock MutexLock; + +template <typename T> +class ThreadLocal { + public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + private: + T value_; +}; + +// The above synchronization primitives have dummy implementations. +// Therefore Google Test is not thread-safe. +# define GTEST_IS_THREADSAFE 0 + +#endif // GTEST_HAS_PTHREAD + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +GTEST_API_ size_t GetThreadCount(); + +// Passing non-POD classes through ellipsis (...) crashes the ARM +// compiler and generates a warning in Sun Studio. The Nokia Symbian +// and the IBM XL C/C++ compiler try to instantiate a copy constructor +// for objects passed through ellipsis (...), failing for uncopyable +// objects. We define this to ensure that only POD is passed through +// ellipsis on these systems. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) +// We lose support for NULL detection where the compiler doesn't like +// passing non-POD classes through ellipsis (...). +# define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#else +# define GTEST_CAN_COMPARE_NULL 1 +#endif + +// The Nokia Symbian and IBM XL C/C++ compilers cannot decide between +// const T& and const T* in a function template. These compilers +// _can_ decide between class template specializations for T and T*, +// so a tr1::type_traits-like is_pointer works. +#if defined(__SYMBIAN32__) || defined(__IBMCPP__) +# define GTEST_NEEDS_IS_POINTER_ 1 +#endif + +template <bool bool_value> +struct bool_constant { + typedef bool_constant<bool_value> type; + static const bool value = bool_value; +}; +template <bool bool_value> const bool bool_constant<bool_value>::value; + +typedef bool_constant<false> false_type; +typedef bool_constant<true> true_type; + +template <typename T> +struct is_pointer : public false_type {}; + +template <typename T> +struct is_pointer<T*> : public true_type {}; + +template <typename Iterator> +struct IteratorTraits { + typedef typename Iterator::value_type value_type; +}; + +template <typename T> +struct IteratorTraits<T*> { + typedef T value_type; +}; + +template <typename T> +struct IteratorTraits<const T*> { + typedef T value_type; +}; + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_SEP_ "\\" +# define GTEST_HAS_ALT_PATH_SEP_ 1 +// The biggest signed integer type the compiler supports. +typedef __int64 BiggestInt; +#else +# define GTEST_PATH_SEP_ "/" +# define GTEST_HAS_ALT_PATH_SEP_ 0 +typedef long long BiggestInt; // NOLINT +#endif // GTEST_OS_WINDOWS + +// Utilities for char. + +// isspace(int ch) and friends accept an unsigned char or EOF. char +// may be signed, depending on the compiler (or compiler flags). +// Therefore we need to cast a char to unsigned char before calling +// isspace(), etc. + +inline bool IsAlpha(char ch) { + return isalpha(static_cast<unsigned char>(ch)) != 0; +} +inline bool IsAlNum(char ch) { + return isalnum(static_cast<unsigned char>(ch)) != 0; +} +inline bool IsDigit(char ch) { + return isdigit(static_cast<unsigned char>(ch)) != 0; +} +inline bool IsLower(char ch) { + return islower(static_cast<unsigned char>(ch)) != 0; +} +inline bool IsSpace(char ch) { + return isspace(static_cast<unsigned char>(ch)) != 0; +} +inline bool IsUpper(char ch) { + return isupper(static_cast<unsigned char>(ch)) != 0; +} +inline bool IsXDigit(char ch) { + return isxdigit(static_cast<unsigned char>(ch)) != 0; +} + +inline char ToLower(char ch) { + return static_cast<char>(tolower(static_cast<unsigned char>(ch))); +} +inline char ToUpper(char ch) { + return static_cast<char>(toupper(static_cast<unsigned char>(ch))); +} + +// The testing::internal::posix namespace holds wrappers for common +// POSIX functions. These wrappers hide the differences between +// Windows/MSVC and POSIX systems. Since some compilers define these +// standard functions as macros, the wrapper cannot have the same name +// as the wrapped function. + +namespace posix { + +// Functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + +typedef struct _stat StatStruct; + +# ifdef __BORLANDC__ +inline int IsATTY(int fd) { return isatty(fd); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +# else // !__BORLANDC__ +# if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) { return 0; } +# else +inline int IsATTY(int fd) { return _isatty(fd); } +# endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) { + return _stricmp(s1, s2); +} +inline char* StrDup(const char* src) { return _strdup(src); } +# endif // __BORLANDC__ + +# if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast<int>(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +# else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { + return (_S_IFDIR & st.st_mode) != 0; +} +# endif // GTEST_OS_WINDOWS_MOBILE + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int IsATTY(int fd) { return isatty(fd); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +inline int StrCaseCmp(const char* s1, const char* s2) { + return strcasecmp(s1, s2); +} +inline char* StrDup(const char* src) { return strdup(src); } +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS + +// Functions deprecated by MSVC 8.0. + +#ifdef _MSC_VER +// Temporarily disable warning 4996 (deprecated function). +# pragma warning(push) +# pragma warning(disable:4996) +#endif + +inline const char* StrNCpy(char* dest, const char* src, size_t n) { + return strncpy(dest, src, n); +} + +// ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and +// StrError() aren't needed on Windows CE at this time and thus not +// defined there. + +#if !GTEST_OS_WINDOWS_MOBILE +inline int ChDir(const char* dir) { return chdir(dir); } +#endif +inline FILE* FOpen(const char* path, const char* mode) { + return fopen(path, mode); +} +#if !GTEST_OS_WINDOWS_MOBILE +inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { + return freopen(path, mode, stream); +} +inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } +#endif +inline int FClose(FILE* fp) { return fclose(fp); } +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) { + return static_cast<int>(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) { + return static_cast<int>(write(fd, buf, count)); +} +inline int Close(int fd) { return close(fd); } +inline const char* StrError(int errnum) { return strerror(errnum); } +#endif +inline const char* GetEnv(const char* name) { +#if GTEST_OS_WINDOWS_MOBILE + // We are on Windows CE, which has no environment variables. + return NULL; +#elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; +#else + return getenv(name); +#endif +} + +#ifdef _MSC_VER +# pragma warning(pop) // Restores the warning state. +#endif + +#if GTEST_OS_WINDOWS_MOBILE +// Windows CE has no C library. The abort() function is used in +// several places in Google Test. This implementation provides a reasonable +// imitation of standard behaviour. +void Abort(); +#else +inline void Abort() { abort(); } +#endif // GTEST_OS_WINDOWS_MOBILE + +} // namespace posix + +// The maximum number a BiggestInt can represent. This definition +// works no matter BiggestInt is represented in one's complement or +// two's complement. +// +// We cannot rely on numeric_limits in STL, as __int64 and long long +// are not part of standard C++ and numeric_limits doesn't need to be +// defined for them. +const BiggestInt kMaxBiggestInt = + ~(static_cast<BiggestInt>(1) << (8*sizeof(BiggestInt) - 1)); + +// This template class serves as a compile-time function from size to +// type. It maps a size in bytes to a primitive type with that +// size. e.g. +// +// TypeWithSize<4>::UInt +// +// is typedef-ed to be unsigned int (unsigned integer made up of 4 +// bytes). +// +// Such functionality should belong to STL, but I cannot find it +// there. +// +// Google Test uses this class in the implementation of floating-point +// comparison. +// +// For now it only handles UInt (unsigned int) as that's all Google Test +// needs. Other types can be easily added in the future if need +// arises. +template <size_t size> +class TypeWithSize { + public: + // This prevents the user from using TypeWithSize<N> with incorrect + // values of N. + typedef void UInt; +}; + +// The specialization for size 4. +template <> +class TypeWithSize<4> { + public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; +}; + +// The specialization for size 8. +template <> +class TypeWithSize<8> { + public: + +#if GTEST_OS_WINDOWS + typedef __int64 Int; + typedef unsigned __int64 UInt; +#else + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT +#endif // GTEST_OS_WINDOWS +}; + +// Integer types of known sizes. +typedef TypeWithSize<4>::Int Int32; +typedef TypeWithSize<4>::UInt UInt32; +typedef TypeWithSize<8>::Int Int64; +typedef TypeWithSize<8>::UInt UInt64; +typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. + +// Utilities for command line flags and environment variables. + +// Macro for referencing flags. +#define GTEST_FLAG(name) FLAGS_gtest_##name + +// Macros for declaring flags. +#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) +#define GTEST_DECLARE_int32_(name) \ + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) +#define GTEST_DECLARE_string_(name) \ + GTEST_API_ extern ::testing::internal::String GTEST_FLAG(name) + +// Macros for defining flags. +#define GTEST_DEFINE_bool_(name, default_val, doc) \ + GTEST_API_ bool GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_int32_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) +#define GTEST_DEFINE_string_(name, default_val, doc) \ + GTEST_API_ ::testing::internal::String GTEST_FLAG(name) = (default_val) + +// Parses 'str' for a 32-bit signed integer. If successful, writes the result +// to *value and returns true; otherwise leaves *value unchanged and returns +// false. +// TODO(chandlerc): Find a better way to refactor flag and environment parsing +// out of both gtest-port.cc and gtest.cc to avoid exporting this utility +// function. +bool ParseInt32(const Message& src_text, const char* str, Int32* value); + +// Parses a bool/Int32/string from the environment variable +// corresponding to the given Google Test flag. +bool BoolFromGTestEnv(const char* flag, bool default_val); +GTEST_API_ Int32 Int32FromGTestEnv(const char* flag, Int32 default_val); +const char* StringFromGTestEnv(const char* flag, const char* default_val); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-string.h b/lib/gtest/include/gtest/internal/gtest-string.h new file mode 100644 index 0000000..dc3a07b --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-string.h @@ -0,0 +1,350 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: wan@google.com (Zhanyong Wan), eefacm@gmail.com (Sean Mcafee) +// +// The Google C++ Testing Framework (Google Test) +// +// This header file declares the String class and functions used internally by +// Google Test. They are subject to change without notice. They should not used +// by code external to Google Test. +// +// This header file is #included by <gtest/internal/gtest-internal.h>. +// It should not be #included by other files. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ + +#ifdef __BORLANDC__ +// string.h is not guaranteed to provide strcpy on C++ Builder. +# include <mem.h> +#endif + +#include <string.h> +#include "gtest/internal/gtest-port.h" + +#include <string> + +namespace testing { +namespace internal { + +// String - a UTF-8 string class. +// +// For historic reasons, we don't use std::string. +// +// TODO(wan@google.com): replace this class with std::string or +// implement it in terms of the latter. +// +// Note that String can represent both NULL and the empty string, +// while std::string cannot represent NULL. +// +// NULL and the empty string are considered different. NULL is less +// than anything (including the empty string) except itself. +// +// This class only provides minimum functionality necessary for +// implementing Google Test. We do not intend to implement a full-fledged +// string class here. +// +// Since the purpose of this class is to provide a substitute for +// std::string on platforms where it cannot be used, we define a copy +// constructor and assignment operators such that we don't need +// conditional compilation in a lot of places. +// +// In order to make the representation efficient, the d'tor of String +// is not virtual. Therefore DO NOT INHERIT FROM String. +class GTEST_API_ String { + public: + // Static utility methods + + // Returns the input enclosed in double quotes if it's not NULL; + // otherwise returns "(null)". For example, "\"Hello\"" is returned + // for input "Hello". + // + // This is useful for printing a C string in the syntax of a literal. + // + // Known issue: escape sequences are not handled yet. + static String ShowCStringQuoted(const char* c_str); + + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); + +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. + + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); + + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); +#endif + + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); + + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static String ShowWideCString(const wchar_t* wide_c_str); + + // Similar to ShowWideCString(), except that this function encloses + // the converted string in double quotes. + static String ShowWideCStringQuoted(const wchar_t* wide_c_str); + + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); + + // Formats a list of arguments to a String, using the same format + // spec string as for printf. + // + // We do not use the StringPrintf class as it is not universally + // available. + // + // The result is limited to 4096 characters (including the tailing + // 0). If 4096 characters are not enough to format the input, + // "<buffer exceeded>" is returned. + static String Format(const char* format, ...); + + // C'tors + + // The default c'tor constructs a NULL string. + String() : c_str_(NULL), length_(0) {} + + // Constructs a String by cloning a 0-terminated C string. + String(const char* a_c_str) { // NOLINT + if (a_c_str == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(a_c_str, strlen(a_c_str)); + } + } + + // Constructs a String by copying a given number of chars from a + // buffer. E.g. String("hello", 3) creates the string "hel", + // String("a\0bcd", 4) creates "a\0bc", String(NULL, 0) creates "", + // and String(NULL, 1) results in access violation. + String(const char* buffer, size_t a_length) { + ConstructNonNull(buffer, a_length); + } + + // The copy c'tor creates a new copy of the string. The two + // String objects do not share content. + String(const String& str) : c_str_(NULL), length_(0) { *this = str; } + + // D'tor. String is intended to be a final class, so the d'tor + // doesn't need to be virtual. + ~String() { delete[] c_str_; } + + // Allows a String to be implicitly converted to an ::std::string or + // ::string, and vice versa. Converting a String containing a NULL + // pointer to ::std::string or ::string is undefined behavior. + // Converting a ::std::string or ::string containing an embedded NUL + // character to a String will result in the prefix up to the first + // NUL character. + String(const ::std::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::std::string() const { return ::std::string(c_str(), length()); } + +#if GTEST_HAS_GLOBAL_STRING + String(const ::string& str) { + ConstructNonNull(str.c_str(), str.length()); + } + + operator ::string() const { return ::string(c_str(), length()); } +#endif // GTEST_HAS_GLOBAL_STRING + + // Returns true iff this is an empty string (i.e. ""). + bool empty() const { return (c_str() != NULL) && (length() == 0); } + + // Compares this with another String. + // Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 + // if this is greater than rhs. + int Compare(const String& rhs) const; + + // Returns true iff this String equals the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator==(const char* a_c_str) const { return Compare(a_c_str) == 0; } + + // Returns true iff this String is less than the given String. A + // NULL string is considered less than "". + bool operator<(const String& rhs) const { return Compare(rhs) < 0; } + + // Returns true iff this String doesn't equal the given C string. A NULL + // string and a non-NULL string are considered not equal. + bool operator!=(const char* a_c_str) const { return !(*this == a_c_str); } + + // Returns true iff this String ends with the given suffix. *Any* + // String is considered to end with a NULL or empty suffix. + bool EndsWith(const char* suffix) const; + + // Returns true iff this String ends with the given suffix, not considering + // case. Any String is considered to end with a NULL or empty suffix. + bool EndsWithCaseInsensitive(const char* suffix) const; + + // Returns the length of the encapsulated string, or 0 if the + // string is NULL. + size_t length() const { return length_; } + + // Gets the 0-terminated C string this String object represents. + // The String object still owns the string. Therefore the caller + // should NOT delete the return value. + const char* c_str() const { return c_str_; } + + // Assigns a C string to this object. Self-assignment works. + const String& operator=(const char* a_c_str) { + return *this = String(a_c_str); + } + + // Assigns a String object to this object. Self-assignment works. + const String& operator=(const String& rhs) { + if (this != &rhs) { + delete[] c_str_; + if (rhs.c_str() == NULL) { + c_str_ = NULL; + length_ = 0; + } else { + ConstructNonNull(rhs.c_str(), rhs.length()); + } + } + + return *this; + } + + private: + // Constructs a non-NULL String from the given content. This + // function can only be called when c_str_ has not been allocated. + // ConstructNonNull(NULL, 0) results in an empty string (""). + // ConstructNonNull(NULL, non_zero) is undefined behavior. + void ConstructNonNull(const char* buffer, size_t a_length) { + char* const str = new char[a_length + 1]; + memcpy(str, buffer, a_length); + str[a_length] = '\0'; + c_str_ = str; + length_ = a_length; + } + + const char* c_str_; + size_t length_; +}; // class String + +// Streams a String to an ostream. Each '\0' character in the String +// is replaced with "\\0". +inline ::std::ostream& operator<<(::std::ostream& os, const String& str) { + if (str.c_str() == NULL) { + os << "(null)"; + } else { + const char* const c_str = str.c_str(); + for (size_t i = 0; i != str.length(); i++) { + if (c_str[i] == '\0') { + os << "\\0"; + } else { + os << c_str[i]; + } + } + } + return os; +} + +// Gets the content of the stringstream's buffer as a String. Each '\0' +// character in the buffer is replaced with "\\0". +GTEST_API_ String StringStreamToString(::std::stringstream* stream); + +// Converts a streamable value to a String. A NULL pointer is +// converted to "(null)". When the input value is a ::string, +// ::std::string, ::wstring, or ::std::wstring object, each NUL +// character in it is replaced with "\\0". + +// Declared here but defined in gtest.h, so that it has access +// to the definition of the Message class, required by the ARM +// compiler. +template <typename T> +String StreamableToString(const T& streamable); + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_STRING_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-tuple.h b/lib/gtest/include/gtest/internal/gtest-tuple.h new file mode 100644 index 0000000..d1af50e --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-tuple.h @@ -0,0 +1,968 @@ +// This file was GENERATED by a script. DO NOT EDIT BY HAND!!! + +// Copyright 2009 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include <utility> // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template <GTEST_10_TYPENAMES_(U)> friend class tuple; \ + private: +#endif + +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> +#define GTEST_1_TUPLE_(T) tuple<T##0, void, void, void, void, void, void, \ + void, void, void> +#define GTEST_2_TUPLE_(T) tuple<T##0, T##1, void, void, void, void, void, \ + void, void, void> +#define GTEST_3_TUPLE_(T) tuple<T##0, T##1, T##2, void, void, void, void, \ + void, void, void> +#define GTEST_4_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, void, void, void, \ + void, void, void> +#define GTEST_5_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, void, void, \ + void, void, void> +#define GTEST_6_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, void, \ + void, void, void> +#define GTEST_7_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + void, void, void> +#define GTEST_8_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, void, void> +#define GTEST_9_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, T##8, void> +#define GTEST_10_TUPLE_(T) tuple<T##0, T##1, T##2, T##3, T##4, T##5, T##6, \ + T##7, T##8, T##9> + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. +#define GTEST_0_TYPENAMES_(T) +#define GTEST_1_TYPENAMES_(T) typename T##0 +#define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 +#define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 +#define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3 +#define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4 +#define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5 +#define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6 +#define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template <typename T0 = void, typename T1 = void, typename T2 = void, + typename T3 = void, typename T4 = void, typename T5 = void, + typename T6 = void, typename T7 = void, typename T8 = void, + typename T9 = void> +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef<T>::type is T if T is a reference; otherwise it's const T&. +template <typename T> +struct ByRef { typedef const T& type; }; // NOLINT +template <typename T> +struct ByRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type + +// AddRef<T>::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference<T>::type. +template <typename T> +struct AddRef { typedef T& type; }; // NOLINT +template <typename T> +struct AddRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type + +// A helper for implementing get<k>(). +template <int k> class Get; + +// A helper for implementing tuple_element<k, T>. kIndexValid is true +// iff k < the number of fields in tuple type T. +template <bool kIndexValid, int kIndex, class Tuple> +struct TupleElement; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 0, GTEST_10_TUPLE_(T)> { typedef T0 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 1, GTEST_10_TUPLE_(T)> { typedef T1 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 2, GTEST_10_TUPLE_(T)> { typedef T2 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 3, GTEST_10_TUPLE_(T)> { typedef T3 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 4, GTEST_10_TUPLE_(T)> { typedef T4 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 5, GTEST_10_TUPLE_(T)> { typedef T5 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 6, GTEST_10_TUPLE_(T)> { typedef T6 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 7, GTEST_10_TUPLE_(T)> { typedef T7 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 8, GTEST_10_TUPLE_(T)> { typedef T8 type; }; + +template <GTEST_10_TYPENAMES_(T)> +struct TupleElement<true, 9, GTEST_10_TUPLE_(T)> { typedef T9 type; }; + +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + +template <GTEST_1_TYPENAMES_(T)> +class GTEST_1_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + + tuple(const tuple& t) : f0_(t.f0_) {} + + template <GTEST_1_TYPENAMES_(U)> + tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_1_TYPENAMES_(U)> + tuple& operator=(const GTEST_1_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_1_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { + f0_ = t.f0_; + return *this; + } + + T0 f0_; +}; + +template <GTEST_2_TYPENAMES_(T)> +class GTEST_2_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + + template <GTEST_2_TYPENAMES_(U)> + tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} + template <typename U0, typename U1> + tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_2_TYPENAMES_(U)> + tuple& operator=(const GTEST_2_TUPLE_(U)& t) { + return CopyFrom(t); + } + template <typename U0, typename U1> + tuple& operator=(const ::std::pair<U0, U1>& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_2_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } + + T0 f0_; + T1 f1_; +}; + +template <GTEST_3_TYPENAMES_(T)> +class GTEST_3_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + template <GTEST_3_TYPENAMES_(U)> + tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_3_TYPENAMES_(U)> + tuple& operator=(const GTEST_3_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_3_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; +}; + +template <GTEST_4_TYPENAMES_(T)> +class GTEST_4_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + + template <GTEST_4_TYPENAMES_(U)> + tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_4_TYPENAMES_(U)> + tuple& operator=(const GTEST_4_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_4_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; +}; + +template <GTEST_5_TYPENAMES_(T)> +class GTEST_5_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_) {} + + template <GTEST_5_TYPENAMES_(U)> + tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_5_TYPENAMES_(U)> + tuple& operator=(const GTEST_5_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_5_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; +}; + +template <GTEST_6_TYPENAMES_(T)> +class GTEST_6_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_) {} + + template <GTEST_6_TYPENAMES_(U)> + tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_6_TYPENAMES_(U)> + tuple& operator=(const GTEST_6_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_6_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; +}; + +template <GTEST_7_TYPENAMES_(T)> +class GTEST_7_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + template <GTEST_7_TYPENAMES_(U)> + tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_7_TYPENAMES_(U)> + tuple& operator=(const GTEST_7_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_7_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; +}; + +template <GTEST_8_TYPENAMES_(T)> +class GTEST_8_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + template <GTEST_8_TYPENAMES_(U)> + tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_8_TYPENAMES_(U)> + tuple& operator=(const GTEST_8_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_8_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; +}; + +template <GTEST_9_TYPENAMES_(T)> +class GTEST_9_TUPLE_(T) { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), + f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + template <GTEST_9_TYPENAMES_(U)> + tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_9_TYPENAMES_(U)> + tuple& operator=(const GTEST_9_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_9_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; +}; + +template <GTEST_10_TYPENAMES_(T)> +class tuple { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), + f9_() {} + + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), + f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), + f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + + template <GTEST_10_TYPENAMES_(U)> + tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), + f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), + f9_(t.f9_) {} + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_10_TYPENAMES_(U)> + tuple& operator=(const GTEST_10_TUPLE_(U)& t) { + return CopyFrom(t); + } + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_10_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } + + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; +}; + +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper<T> to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +template <GTEST_1_TYPENAMES_(T)> +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { + return GTEST_1_TUPLE_(T)(f0); +} + +template <GTEST_2_TYPENAMES_(T)> +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { + return GTEST_2_TUPLE_(T)(f0, f1); +} + +template <GTEST_3_TYPENAMES_(T)> +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { + return GTEST_3_TUPLE_(T)(f0, f1, f2); +} + +template <GTEST_4_TYPENAMES_(T)> +inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3) { + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); +} + +template <GTEST_5_TYPENAMES_(T)> +inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4) { + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); +} + +template <GTEST_6_TYPENAMES_(T)> +inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5) { + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); +} + +template <GTEST_7_TYPENAMES_(T)> +inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6) { + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); +} + +template <GTEST_8_TYPENAMES_(T)> +inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); +} + +template <GTEST_9_TYPENAMES_(T)> +inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) { + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); +} + +template <GTEST_10_TYPENAMES_(T)> +inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) { + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); +} + +// 6.1.3.3 Tuple helper classes. + +template <typename Tuple> struct tuple_size; + +template <GTEST_0_TYPENAMES_(T)> +struct tuple_size<GTEST_0_TUPLE_(T)> { static const int value = 0; }; + +template <GTEST_1_TYPENAMES_(T)> +struct tuple_size<GTEST_1_TUPLE_(T)> { static const int value = 1; }; + +template <GTEST_2_TYPENAMES_(T)> +struct tuple_size<GTEST_2_TUPLE_(T)> { static const int value = 2; }; + +template <GTEST_3_TYPENAMES_(T)> +struct tuple_size<GTEST_3_TUPLE_(T)> { static const int value = 3; }; + +template <GTEST_4_TYPENAMES_(T)> +struct tuple_size<GTEST_4_TUPLE_(T)> { static const int value = 4; }; + +template <GTEST_5_TYPENAMES_(T)> +struct tuple_size<GTEST_5_TUPLE_(T)> { static const int value = 5; }; + +template <GTEST_6_TYPENAMES_(T)> +struct tuple_size<GTEST_6_TUPLE_(T)> { static const int value = 6; }; + +template <GTEST_7_TYPENAMES_(T)> +struct tuple_size<GTEST_7_TUPLE_(T)> { static const int value = 7; }; + +template <GTEST_8_TYPENAMES_(T)> +struct tuple_size<GTEST_8_TUPLE_(T)> { static const int value = 8; }; + +template <GTEST_9_TYPENAMES_(T)> +struct tuple_size<GTEST_9_TUPLE_(T)> { static const int value = 9; }; + +template <GTEST_10_TYPENAMES_(T)> +struct tuple_size<GTEST_10_TUPLE_(T)> { static const int value = 10; }; + +template <int k, class Tuple> +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size<Tuple>::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + +template <> +class Get<0> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) { return t.f0_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) { return t.f0_; } +}; + +template <> +class Get<1> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) { return t.f1_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) { return t.f1_; } +}; + +template <> +class Get<2> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) { return t.f2_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) { return t.f2_; } +}; + +template <> +class Get<3> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) { return t.f3_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) { return t.f3_; } +}; + +template <> +class Get<4> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) { return t.f4_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) { return t.f4_; } +}; + +template <> +class Get<5> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) { return t.f5_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) { return t.f5_; } +}; + +template <> +class Get<6> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) { return t.f6_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) { return t.f6_; } +}; + +template <> +class Get<7> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) { return t.f7_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) { return t.f7_; } +}; + +template <> +class Get<8> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) { return t.f8_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) { return t.f8_; } +}; + +template <> +class Get<9> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) { return t.f9_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) { return t.f9_; } +}; + +} // namespace gtest_internal + +template <int k, GTEST_10_TYPENAMES_(T)> +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get<k>::Field(t); +} + +template <int k, GTEST_10_TYPENAMES_(T)> +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T)& t) { + return gtest_internal::Get<k>::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template <int kSize1, int kSize2> +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template <int k> +struct SameSizeTuplePrefixComparator<k, k> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) && + ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2); + } +}; + +} // namespace gtest_internal + +template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)> +inline bool operator==(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size<GTEST_10_TUPLE_(T)>::value, + tuple_size<GTEST_10_TUPLE_(U)>::value>::Eq(t, u); +} + +template <GTEST_10_TYPENAMES_(T), GTEST_10_TYPENAMES_(U)> +inline bool operator!=(const GTEST_10_TUPLE_(T)& t, + const GTEST_10_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + +#undef GTEST_0_TUPLE_ +#undef GTEST_1_TUPLE_ +#undef GTEST_2_TUPLE_ +#undef GTEST_3_TUPLE_ +#undef GTEST_4_TUPLE_ +#undef GTEST_5_TUPLE_ +#undef GTEST_6_TUPLE_ +#undef GTEST_7_TUPLE_ +#undef GTEST_8_TUPLE_ +#undef GTEST_9_TUPLE_ +#undef GTEST_10_TUPLE_ + +#undef GTEST_0_TYPENAMES_ +#undef GTEST_1_TYPENAMES_ +#undef GTEST_2_TYPENAMES_ +#undef GTEST_3_TYPENAMES_ +#undef GTEST_4_TYPENAMES_ +#undef GTEST_5_TYPENAMES_ +#undef GTEST_6_TYPENAMES_ +#undef GTEST_7_TYPENAMES_ +#undef GTEST_8_TYPENAMES_ +#undef GTEST_9_TYPENAMES_ +#undef GTEST_10_TYPENAMES_ + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-tuple.h.pump b/lib/gtest/include/gtest/internal/gtest-tuple.h.pump new file mode 100644 index 0000000..ef51909 --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-tuple.h.pump @@ -0,0 +1,336 @@ +$$ -*- mode: c++; -*- +$var n = 10 $$ Maximum number of tuple fields we want to support. +$$ This meta comment fixes auto-indentation in Emacs. }} +// Copyright 2009 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Implements a subset of TR1 tuple needed by Google Test and Google Mock. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ + +#include <utility> // For ::std::pair. + +// The compiler used in Symbian has a bug that prevents us from declaring the +// tuple template as a friend (it complains that tuple is redefined). This +// hack bypasses the bug by declaring the members that should otherwise be +// private as public. +// Sun Studio versions < 12 also have the above bug. +#if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#else +# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template <GTEST_$(n)_TYPENAMES_(U)> friend class tuple; \ + private: +#endif + + +$range i 0..n-1 +$range j 0..n +$range k 1..n +// GTEST_n_TUPLE_(T) is the type of an n-tuple. +#define GTEST_0_TUPLE_(T) tuple<> + +$for k [[ +$range m 0..k-1 +$range m2 k..n-1 +#define GTEST_$(k)_TUPLE_(T) tuple<$for m, [[T##$m]]$for m2 [[, void]]> + +]] + +// GTEST_n_TYPENAMES_(T) declares a list of n typenames. + +$for j [[ +$range m 0..j-1 +#define GTEST_$(j)_TYPENAMES_(T) $for m, [[typename T##$m]] + + +]] + +// In theory, defining stuff in the ::std namespace is undefined +// behavior. We can do this as we are playing the role of a standard +// library vendor. +namespace std { +namespace tr1 { + +template <$for i, [[typename T$i = void]]> +class tuple; + +// Anything in namespace gtest_internal is Google Test's INTERNAL +// IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. +namespace gtest_internal { + +// ByRef<T>::type is T if T is a reference; otherwise it's const T&. +template <typename T> +struct ByRef { typedef const T& type; }; // NOLINT +template <typename T> +struct ByRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for ByRef. +#define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef<T>::type + +// AddRef<T>::type is T if T is a reference; otherwise it's T&. This +// is the same as tr1::add_reference<T>::type. +template <typename T> +struct AddRef { typedef T& type; }; // NOLINT +template <typename T> +struct AddRef<T&> { typedef T& type; }; // NOLINT + +// A handy wrapper for AddRef. +#define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef<T>::type + +// A helper for implementing get<k>(). +template <int k> class Get; + +// A helper for implementing tuple_element<k, T>. kIndexValid is true +// iff k < the number of fields in tuple type T. +template <bool kIndexValid, int kIndex, class Tuple> +struct TupleElement; + + +$for i [[ +template <GTEST_$(n)_TYPENAMES_(T)> +struct TupleElement<true, $i, GTEST_$(n)_TUPLE_(T)> [[]] +{ typedef T$i type; }; + + +]] +} // namespace gtest_internal + +template <> +class tuple<> { + public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } +}; + + +$for k [[ +$range m 0..k-1 +template <GTEST_$(k)_TYPENAMES_(T)> +class $if k < n [[GTEST_$(k)_TUPLE_(T)]] $else [[tuple]] { + public: + template <int k> friend class gtest_internal::Get; + + tuple() : $for m, [[f$(m)_()]] {} + + explicit tuple($for m, [[GTEST_BY_REF_(T$m) f$m]]) : [[]] +$for m, [[f$(m)_(f$m)]] {} + + tuple(const tuple& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} + + template <GTEST_$(k)_TYPENAMES_(U)> + tuple(const GTEST_$(k)_TUPLE_(U)& t) : $for m, [[f$(m)_(t.f$(m)_)]] {} + +$if k == 2 [[ + template <typename U0, typename U1> + tuple(const ::std::pair<U0, U1>& p) : f0_(p.first), f1_(p.second) {} + +]] + + tuple& operator=(const tuple& t) { return CopyFrom(t); } + + template <GTEST_$(k)_TYPENAMES_(U)> + tuple& operator=(const GTEST_$(k)_TUPLE_(U)& t) { + return CopyFrom(t); + } + +$if k == 2 [[ + template <typename U0, typename U1> + tuple& operator=(const ::std::pair<U0, U1>& p) { + f0_ = p.first; + f1_ = p.second; + return *this; + } + +]] + + GTEST_DECLARE_TUPLE_AS_FRIEND_ + + template <GTEST_$(k)_TYPENAMES_(U)> + tuple& CopyFrom(const GTEST_$(k)_TUPLE_(U)& t) { + +$for m [[ + f$(m)_ = t.f$(m)_; + +]] + return *this; + } + + +$for m [[ + T$m f$(m)_; + +]] +}; + + +]] +// 6.1.3.2 Tuple creation functions. + +// Known limitations: we don't support passing an +// std::tr1::reference_wrapper<T> to make_tuple(). And we don't +// implement tie(). + +inline tuple<> make_tuple() { return tuple<>(); } + +$for k [[ +$range m 0..k-1 + +template <GTEST_$(k)_TYPENAMES_(T)> +inline GTEST_$(k)_TUPLE_(T) make_tuple($for m, [[const T$m& f$m]]) { + return GTEST_$(k)_TUPLE_(T)($for m, [[f$m]]); +} + +]] + +// 6.1.3.3 Tuple helper classes. + +template <typename Tuple> struct tuple_size; + + +$for j [[ +template <GTEST_$(j)_TYPENAMES_(T)> +struct tuple_size<GTEST_$(j)_TUPLE_(T)> { static const int value = $j; }; + + +]] +template <int k, class Tuple> +struct tuple_element { + typedef typename gtest_internal::TupleElement< + k < (tuple_size<Tuple>::value), k, Tuple>::type type; +}; + +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element<k, Tuple >::type + +// 6.1.3.4 Element access. + +namespace gtest_internal { + + +$for i [[ +template <> +class Get<$i> { + public: + template <class Tuple> + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) + Field(Tuple& t) { return t.f$(i)_; } // NOLINT + + template <class Tuple> + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_($i, Tuple)) + ConstField(const Tuple& t) { return t.f$(i)_; } +}; + + +]] +} // namespace gtest_internal + +template <int k, GTEST_$(n)_TYPENAMES_(T)> +GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) +get(GTEST_$(n)_TUPLE_(T)& t) { + return gtest_internal::Get<k>::Field(t); +} + +template <int k, GTEST_$(n)_TYPENAMES_(T)> +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_$(n)_TUPLE_(T))) +get(const GTEST_$(n)_TUPLE_(T)& t) { + return gtest_internal::Get<k>::ConstField(t); +} + +// 6.1.3.5 Relational operators + +// We only implement == and !=, as we don't have a need for the rest yet. + +namespace gtest_internal { + +// SameSizeTuplePrefixComparator<k, k>::Eq(t1, t2) returns true if the +// first k fields of t1 equals the first k fields of t2. +// SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if +// k1 != k2. +template <int kSize1, int kSize2> +struct SameSizeTuplePrefixComparator; + +template <> +struct SameSizeTuplePrefixComparator<0, 0> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { + return true; + } +}; + +template <int k> +struct SameSizeTuplePrefixComparator<k, k> { + template <class Tuple1, class Tuple2> + static bool Eq(const Tuple1& t1, const Tuple2& t2) { + return SameSizeTuplePrefixComparator<k - 1, k - 1>::Eq(t1, t2) && + ::std::tr1::get<k - 1>(t1) == ::std::tr1::get<k - 1>(t2); + } +}; + +} // namespace gtest_internal + +template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)> +inline bool operator==(const GTEST_$(n)_TUPLE_(T)& t, + const GTEST_$(n)_TUPLE_(U)& u) { + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size<GTEST_$(n)_TUPLE_(T)>::value, + tuple_size<GTEST_$(n)_TUPLE_(U)>::value>::Eq(t, u); +} + +template <GTEST_$(n)_TYPENAMES_(T), GTEST_$(n)_TYPENAMES_(U)> +inline bool operator!=(const GTEST_$(n)_TUPLE_(T)& t, + const GTEST_$(n)_TUPLE_(U)& u) { return !(t == u); } + +// 6.1.4 Pairs. +// Unimplemented. + +} // namespace tr1 +} // namespace std + + +$for j [[ +#undef GTEST_$(j)_TUPLE_ + +]] + + +$for j [[ +#undef GTEST_$(j)_TYPENAMES_ + +]] + +#undef GTEST_DECLARE_TUPLE_AS_FRIEND_ +#undef GTEST_BY_REF_ +#undef GTEST_ADD_REF_ +#undef GTEST_TUPLE_ELEMENT_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TUPLE_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-type-util.h b/lib/gtest/include/gtest/internal/gtest-type-util.h new file mode 100644 index 0000000..b7b01b0 --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-type-util.h @@ -0,0 +1,3330 @@ +// This file was GENERATED by command: +// pump.py gtest-type-util.h.pump +// DO NOT EDIT BY HAND!!! + +// Copyright 2008 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most 50 types in a list, and at most 50 +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-string.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# ifdef __GLIBCXX__ +# include <cxxabi.h> +# elif defined(__HP_aCC) +# include <acxx_demangle.h> +# endif // __GLIBCXX__ + +namespace testing { +namespace internal { + +// GetTypeName<T>() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template <typename T> +String GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if defined(__GLIBCXX__) || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# ifdef __GLIBCXX__ + using abi::__cxa_demangle; +# endif // __GLIBCXX__ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const String name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // __GLIBCXX__ || __HP_aCC + +# else + + return "<type>"; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template <typename T1, typename T2> +struct AssertTypeEq; + +template <typename T> +struct AssertTypeEq<T, T> { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN<T1, T2, ..., TN> +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template <typename T1> +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; +template <typename T1, typename T2> +struct Types2 { + typedef T1 Head; + typedef Types1<T2> Tail; +}; + +template <typename T1, typename T2, typename T3> +struct Types3 { + typedef T1 Head; + typedef Types2<T2, T3> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4> +struct Types4 { + typedef T1 Head; + typedef Types3<T2, T3, T4> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5> +struct Types5 { + typedef T1 Head; + typedef Types4<T2, T3, T4, T5> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +struct Types6 { + typedef T1 Head; + typedef Types5<T2, T3, T4, T5, T6> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +struct Types7 { + typedef T1 Head; + typedef Types6<T2, T3, T4, T5, T6, T7> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +struct Types8 { + typedef T1 Head; + typedef Types7<T2, T3, T4, T5, T6, T7, T8> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +struct Types9 { + typedef T1 Head; + typedef Types8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +struct Types10 { + typedef T1 Head; + typedef Types9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +struct Types11 { + typedef T1 Head; + typedef Types10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +struct Types12 { + typedef T1 Head; + typedef Types11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +struct Types13 { + typedef T1 Head; + typedef Types12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +struct Types14 { + typedef T1 Head; + typedef Types13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +struct Types15 { + typedef T1 Head; + typedef Types14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +struct Types16 { + typedef T1 Head; + typedef Types15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +struct Types17 { + typedef T1 Head; + typedef Types16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +struct Types18 { + typedef T1 Head; + typedef Types17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +struct Types19 { + typedef T1 Head; + typedef Types18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +struct Types20 { + typedef T1 Head; + typedef Types19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +struct Types21 { + typedef T1 Head; + typedef Types20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +struct Types22 { + typedef T1 Head; + typedef Types21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +struct Types23 { + typedef T1 Head; + typedef Types22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +struct Types24 { + typedef T1 Head; + typedef Types23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +struct Types25 { + typedef T1 Head; + typedef Types24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +struct Types26 { + typedef T1 Head; + typedef Types25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +struct Types27 { + typedef T1 Head; + typedef Types26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +struct Types28 { + typedef T1 Head; + typedef Types27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +struct Types29 { + typedef T1 Head; + typedef Types28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +struct Types30 { + typedef T1 Head; + typedef Types29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +struct Types31 { + typedef T1 Head; + typedef Types30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +struct Types32 { + typedef T1 Head; + typedef Types31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +struct Types33 { + typedef T1 Head; + typedef Types32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +struct Types34 { + typedef T1 Head; + typedef Types33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +struct Types35 { + typedef T1 Head; + typedef Types34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +struct Types36 { + typedef T1 Head; + typedef Types35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +struct Types37 { + typedef T1 Head; + typedef Types36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +struct Types38 { + typedef T1 Head; + typedef Types37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +struct Types39 { + typedef T1 Head; + typedef Types38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +struct Types40 { + typedef T1 Head; + typedef Types39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +struct Types41 { + typedef T1 Head; + typedef Types40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +struct Types42 { + typedef T1 Head; + typedef Types41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +struct Types43 { + typedef T1 Head; + typedef Types42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +struct Types44 { + typedef T1 Head; + typedef Types43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +struct Types45 { + typedef T1 Head; + typedef Types44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +struct Types46 { + typedef T1 Head; + typedef Types45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +struct Types47 { + typedef T1 Head; + typedef Types46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +struct Types48 { + typedef T1 Head; + typedef Types47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +struct Types49 { + typedef T1 Head; + typedef Types48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49> Tail; +}; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +struct Types50 { + typedef T1 Head; + typedef Types49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> Tail; +}; + + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types<int> +// will appear as Types<int, None, None, ..., None> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types<T1, ..., TN>, and Google Test will translate +// that to TypesN<T1, ..., TN> internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. +template <typename T1 = internal::None, typename T2 = internal::None, + typename T3 = internal::None, typename T4 = internal::None, + typename T5 = internal::None, typename T6 = internal::None, + typename T7 = internal::None, typename T8 = internal::None, + typename T9 = internal::None, typename T10 = internal::None, + typename T11 = internal::None, typename T12 = internal::None, + typename T13 = internal::None, typename T14 = internal::None, + typename T15 = internal::None, typename T16 = internal::None, + typename T17 = internal::None, typename T18 = internal::None, + typename T19 = internal::None, typename T20 = internal::None, + typename T21 = internal::None, typename T22 = internal::None, + typename T23 = internal::None, typename T24 = internal::None, + typename T25 = internal::None, typename T26 = internal::None, + typename T27 = internal::None, typename T28 = internal::None, + typename T29 = internal::None, typename T30 = internal::None, + typename T31 = internal::None, typename T32 = internal::None, + typename T33 = internal::None, typename T34 = internal::None, + typename T35 = internal::None, typename T36 = internal::None, + typename T37 = internal::None, typename T38 = internal::None, + typename T39 = internal::None, typename T40 = internal::None, + typename T41 = internal::None, typename T42 = internal::None, + typename T43 = internal::None, typename T44 = internal::None, + typename T45 = internal::None, typename T46 = internal::None, + typename T47 = internal::None, typename T48 = internal::None, + typename T49 = internal::None, typename T50 = internal::None> +struct Types { + typedef internal::Types50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48, T49, T50> type; +}; + +template <> +struct Types<internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types0 type; +}; +template <typename T1> +struct Types<T1, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types1<T1> type; +}; +template <typename T1, typename T2> +struct Types<T1, T2, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types2<T1, T2> type; +}; +template <typename T1, typename T2, typename T3> +struct Types<T1, T2, T3, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types3<T1, T2, T3> type; +}; +template <typename T1, typename T2, typename T3, typename T4> +struct Types<T1, T2, T3, T4, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types4<T1, T2, T3, T4> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5> +struct Types<T1, T2, T3, T4, T5, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types5<T1, T2, T3, T4, T5> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6> +struct Types<T1, T2, T3, T4, T5, T6, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types6<T1, T2, T3, T4, T5, T6> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7> +struct Types<T1, T2, T3, T4, T5, T6, T7, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types7<T1, T2, T3, T4, T5, T6, T7> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types8<T1, T2, T3, T4, T5, T6, T7, T8> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, + T12> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, + T40> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> { + typedef internal::Types43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> { + typedef internal::Types44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + internal::None, internal::None, internal::None, internal::None, + internal::None> { + typedef internal::Types45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, internal::None, internal::None, internal::None, internal::None> { + typedef internal::Types46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, internal::None, internal::None, internal::None> { + typedef internal::Types47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, T48, internal::None, internal::None> { + typedef internal::Types48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48> type; +}; +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +struct Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, T48, T49, internal::None> { + typedef internal::Types49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48, T49> type; +}; + +namespace internal { + +# define GTEST_TEMPLATE_ template <typename T> class + +// The template "selector" struct TemplateSel<Tmpl> is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined +// as the type Tmpl<T>. This allows us to actually instantiate the +// template "selected" by TemplateSel<Tmpl>. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template <GTEST_TEMPLATE_ Tmpl> +struct TemplateSel { + template <typename T> + struct Bind { + typedef Tmpl<T> type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind<T>::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates<int>, Templates<int, double>, +// and etc), which C++ doesn't support directly. +template <typename T> +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN<T1, T2, ..., +// TN> represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template <GTEST_TEMPLATE_ T1> +struct Templates1 { + typedef TemplateSel<T1> Head; + typedef Templates0 Tail; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> +struct Templates2 { + typedef TemplateSel<T1> Head; + typedef Templates1<T2> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> +struct Templates3 { + typedef TemplateSel<T1> Head; + typedef Templates2<T2, T3> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4> +struct Templates4 { + typedef TemplateSel<T1> Head; + typedef Templates3<T2, T3, T4> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> +struct Templates5 { + typedef TemplateSel<T1> Head; + typedef Templates4<T2, T3, T4, T5> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> +struct Templates6 { + typedef TemplateSel<T1> Head; + typedef Templates5<T2, T3, T4, T5, T6> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7> +struct Templates7 { + typedef TemplateSel<T1> Head; + typedef Templates6<T2, T3, T4, T5, T6, T7> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> +struct Templates8 { + typedef TemplateSel<T1> Head; + typedef Templates7<T2, T3, T4, T5, T6, T7, T8> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> +struct Templates9 { + typedef TemplateSel<T1> Head; + typedef Templates8<T2, T3, T4, T5, T6, T7, T8, T9> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10> +struct Templates10 { + typedef TemplateSel<T1> Head; + typedef Templates9<T2, T3, T4, T5, T6, T7, T8, T9, T10> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> +struct Templates11 { + typedef TemplateSel<T1> Head; + typedef Templates10<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> +struct Templates12 { + typedef TemplateSel<T1> Head; + typedef Templates11<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13> +struct Templates13 { + typedef TemplateSel<T1> Head; + typedef Templates12<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> +struct Templates14 { + typedef TemplateSel<T1> Head; + typedef Templates13<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> +struct Templates15 { + typedef TemplateSel<T1> Head; + typedef Templates14<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16> +struct Templates16 { + typedef TemplateSel<T1> Head; + typedef Templates15<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> +struct Templates17 { + typedef TemplateSel<T1> Head; + typedef Templates16<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> +struct Templates18 { + typedef TemplateSel<T1> Head; + typedef Templates17<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19> +struct Templates19 { + typedef TemplateSel<T1> Head; + typedef Templates18<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> +struct Templates20 { + typedef TemplateSel<T1> Head; + typedef Templates19<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> +struct Templates21 { + typedef TemplateSel<T1> Head; + typedef Templates20<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22> +struct Templates22 { + typedef TemplateSel<T1> Head; + typedef Templates21<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> +struct Templates23 { + typedef TemplateSel<T1> Head; + typedef Templates22<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> +struct Templates24 { + typedef TemplateSel<T1> Head; + typedef Templates23<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25> +struct Templates25 { + typedef TemplateSel<T1> Head; + typedef Templates24<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> +struct Templates26 { + typedef TemplateSel<T1> Head; + typedef Templates25<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> +struct Templates27 { + typedef TemplateSel<T1> Head; + typedef Templates26<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28> +struct Templates28 { + typedef TemplateSel<T1> Head; + typedef Templates27<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> +struct Templates29 { + typedef TemplateSel<T1> Head; + typedef Templates28<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> +struct Templates30 { + typedef TemplateSel<T1> Head; + typedef Templates29<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31> +struct Templates31 { + typedef TemplateSel<T1> Head; + typedef Templates30<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> +struct Templates32 { + typedef TemplateSel<T1> Head; + typedef Templates31<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> +struct Templates33 { + typedef TemplateSel<T1> Head; + typedef Templates32<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34> +struct Templates34 { + typedef TemplateSel<T1> Head; + typedef Templates33<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> +struct Templates35 { + typedef TemplateSel<T1> Head; + typedef Templates34<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> +struct Templates36 { + typedef TemplateSel<T1> Head; + typedef Templates35<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37> +struct Templates37 { + typedef TemplateSel<T1> Head; + typedef Templates36<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> +struct Templates38 { + typedef TemplateSel<T1> Head; + typedef Templates37<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> +struct Templates39 { + typedef TemplateSel<T1> Head; + typedef Templates38<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40> +struct Templates40 { + typedef TemplateSel<T1> Head; + typedef Templates39<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> +struct Templates41 { + typedef TemplateSel<T1> Head; + typedef Templates40<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> +struct Templates42 { + typedef TemplateSel<T1> Head; + typedef Templates41<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43> +struct Templates43 { + typedef TemplateSel<T1> Head; + typedef Templates42<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> +struct Templates44 { + typedef TemplateSel<T1> Head; + typedef Templates43<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> +struct Templates45 { + typedef TemplateSel<T1> Head; + typedef Templates44<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46> +struct Templates46 { + typedef TemplateSel<T1> Head; + typedef Templates45<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> +struct Templates47 { + typedef TemplateSel<T1> Head; + typedef Templates46<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> +struct Templates48 { + typedef TemplateSel<T1> Head; + typedef Templates47<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47, T48> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49> +struct Templates49 { + typedef TemplateSel<T1> Head; + typedef Templates48<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47, T48, T49> Tail; +}; + +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50> +struct Templates50 { + typedef TemplateSel<T1> Head; + typedef Templates49<T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43, T44, T45, T46, T47, T48, T49, T50> Tail; +}; + + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates<list> +// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates<T1, ..., TN>, and Google Test will translate +// that to TemplatesN<T1, ..., TN> internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. +template <GTEST_TEMPLATE_ T1 = NoneT, GTEST_TEMPLATE_ T2 = NoneT, + GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT, + GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT, + GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT, + GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT, + GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT, + GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT, + GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT, + GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT, + GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT, + GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT, + GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT, + GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT, + GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT, + GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT, + GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT, + GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT, + GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT, + GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT, + GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT, + GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT, + GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT, + GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT, + GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT, + GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT> +struct Templates { + typedef Templates50<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47, T48, T49, T50> type; +}; + +template <> +struct Templates<NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates0 type; +}; +template <GTEST_TEMPLATE_ T1> +struct Templates<T1, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates1<T1> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2> +struct Templates<T1, T2, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates2<T1, T2> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3> +struct Templates<T1, T2, T3, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates3<T1, T2, T3> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4> +struct Templates<T1, T2, T3, T4, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates4<T1, T2, T3, T4> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> +struct Templates<T1, T2, T3, T4, T5, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates5<T1, T2, T3, T4, T5> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> +struct Templates<T1, T2, T3, T4, T5, T6, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates6<T1, T2, T3, T4, T5, T6> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7> +struct Templates<T1, T2, T3, T4, T5, T6, T7, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates7<T1, T2, T3, T4, T5, T6, T7> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates8<T1, T2, T3, T4, T5, T6, T7, T8> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates9<T1, T2, T3, T4, T5, T6, T7, T8, T9> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> { + typedef Templates21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> { + typedef Templates22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> { + typedef Templates23<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> { + typedef Templates24<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates25<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates26<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates27<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> { + typedef Templates28<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> { + typedef Templates29<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates30<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates31<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates32<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates33<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates34<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates35<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates36<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates37<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates38<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates39<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates40<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates41<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates42<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates43<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates44<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, NoneT, NoneT, NoneT, NoneT, NoneT> { + typedef Templates45<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, NoneT, NoneT, NoneT, NoneT> { + typedef Templates46<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, NoneT, NoneT, NoneT> { + typedef Templates47<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, T48, NoneT, NoneT> { + typedef Templates48<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47, T48> type; +}; +template <GTEST_TEMPLATE_ T1, GTEST_TEMPLATE_ T2, GTEST_TEMPLATE_ T3, + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49> +struct Templates<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, T48, T49, NoneT> { + typedef Templates49<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42, T43, T44, T45, T46, T47, T48, T49> type; +}; + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template <typename T> +struct TypeList { typedef Types1<T> type; }; + +template <typename T1, typename T2, typename T3, typename T4, typename T5, + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +struct TypeList<Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> > { + typedef typename Types<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, + T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27, T28, T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41, T42, T43, T44, T45, T46, T47, T48, T49, T50>::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/lib/gtest/include/gtest/internal/gtest-type-util.h.pump b/lib/gtest/include/gtest/internal/gtest-type-util.h.pump new file mode 100644 index 0000000..27f331d --- /dev/null +++ b/lib/gtest/include/gtest/internal/gtest-type-util.h.pump @@ -0,0 +1,296 @@ +$$ -*- mode: c++; -*- +$var n = 50 $$ Maximum length of type lists we want to support. +// Copyright 2008 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Type utilities needed for implementing typed and type-parameterized +// tests. This file is generated by a SCRIPT. DO NOT EDIT BY HAND! +// +// Currently we support at most $n types in a list, and at most $n +// type-parameterized tests in one type-parameterized test case. +// Please contact googletestframework@googlegroups.com if you need +// more. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ + +#include "gtest/internal/gtest-port.h" +#include "gtest/internal/gtest-string.h" + +// #ifdef __GNUC__ is too general here. It is possible to use gcc without using +// libstdc++ (which is where cxxabi.h comes from). +# ifdef __GLIBCXX__ +# include <cxxabi.h> +# elif defined(__HP_aCC) +# include <acxx_demangle.h> +# endif // __GLIBCXX__ + +namespace testing { +namespace internal { + +// GetTypeName<T>() returns a human-readable name of type T. +// NB: This function is also used in Google Mock, so don't move it inside of +// the typed-test-only section below. +template <typename T> +String GetTypeName() { +# if GTEST_HAS_RTTI + + const char* const name = typeid(T).name(); +# if defined(__GLIBCXX__) || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +# ifdef __GLIBCXX__ + using abi::__cxa_demangle; +# endif // __GLIBCXX__ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const String name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +# else + return name; +# endif // __GLIBCXX__ || __HP_aCC + +# else + + return "<type>"; + +# endif // GTEST_HAS_RTTI +} + +#if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +// AssertyTypeEq<T1, T2>::type is defined iff T1 and T2 are the same +// type. This can be used as a compile-time assertion to ensure that +// two types are equal. + +template <typename T1, typename T2> +struct AssertTypeEq; + +template <typename T> +struct AssertTypeEq<T, T> { + typedef bool type; +}; + +// A unique type used as the default value for the arguments of class +// template Types. This allows us to simulate variadic templates +// (e.g. Types<int>, Type<int, double>, and etc), which C++ doesn't +// support directly. +struct None {}; + +// The following family of struct and struct templates are used to +// represent type lists. In particular, TypesN<T1, T2, ..., TN> +// represents a type list with N types (T1, T2, ..., and TN) in it. +// Except for Types0, every struct in the family has two member types: +// Head for the first type in the list, and Tail for the rest of the +// list. + +// The empty type list. +struct Types0 {}; + +// Type lists of length 1, 2, 3, and so on. + +template <typename T1> +struct Types1 { + typedef T1 Head; + typedef Types0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[typename T$j]]> +struct Types$i { + typedef T1 Head; + typedef Types$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +} // namespace internal + +// We don't want to require the users to write TypesN<...> directly, +// as that would require them to count the length. Types<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Types<int> +// will appear as Types<int, None, None, ..., None> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Types<T1, ..., TN>, and Google Test will translate +// that to TypesN<T1, ..., TN> internally to make error messages +// readable. The translation is done by the 'type' member of the +// Types template. + +$range i 1..n +template <$for i, [[typename T$i = internal::None]]> +struct Types { + typedef internal::Types$n<$for i, [[T$i]]> type; +}; + +template <> +struct Types<$for i, [[internal::None]]> { + typedef internal::Types0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[typename T$j]]> +struct Types<$for j, [[T$j]]$for k[[, internal::None]]> { + typedef internal::Types$i<$for j, [[T$j]]> type; +}; + +]] + +namespace internal { + +# define GTEST_TEMPLATE_ template <typename T> class + +// The template "selector" struct TemplateSel<Tmpl> is used to +// represent Tmpl, which must be a class template with one type +// parameter, as a type. TemplateSel<Tmpl>::Bind<T>::type is defined +// as the type Tmpl<T>. This allows us to actually instantiate the +// template "selected" by TemplateSel<Tmpl>. +// +// This trick is necessary for simulating typedef for class templates, +// which C++ doesn't support directly. +template <GTEST_TEMPLATE_ Tmpl> +struct TemplateSel { + template <typename T> + struct Bind { + typedef Tmpl<T> type; + }; +}; + +# define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind<T>::type + +// A unique struct template used as the default value for the +// arguments of class template Templates. This allows us to simulate +// variadic templates (e.g. Templates<int>, Templates<int, double>, +// and etc), which C++ doesn't support directly. +template <typename T> +struct NoneT {}; + +// The following family of struct and struct templates are used to +// represent template lists. In particular, TemplatesN<T1, T2, ..., +// TN> represents a list of N templates (T1, T2, ..., and TN). Except +// for Templates0, every struct in the family has two member types: +// Head for the selector of the first template in the list, and Tail +// for the rest of the list. + +// The empty template list. +struct Templates0 {}; + +// Template lists of length 1, 2, 3, and so on. + +template <GTEST_TEMPLATE_ T1> +struct Templates1 { + typedef TemplateSel<T1> Head; + typedef Templates0 Tail; +}; + +$range i 2..n + +$for i [[ +$range j 1..i +$range k 2..i +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates$i { + typedef TemplateSel<T1> Head; + typedef Templates$(i-1)<$for k, [[T$k]]> Tail; +}; + + +]] + +// We don't want to require the users to write TemplatesN<...> directly, +// as that would require them to count the length. Templates<...> is much +// easier to write, but generates horrible messages when there is a +// compiler error, as gcc insists on printing out each template +// argument, even if it has the default value (this means Templates<list> +// will appear as Templates<list, NoneT, NoneT, ..., NoneT> in the compiler +// errors). +// +// Our solution is to combine the best part of the two approaches: a +// user would write Templates<T1, ..., TN>, and Google Test will translate +// that to TemplatesN<T1, ..., TN> internally to make error messages +// readable. The translation is done by the 'type' member of the +// Templates template. + +$range i 1..n +template <$for i, [[GTEST_TEMPLATE_ T$i = NoneT]]> +struct Templates { + typedef Templates$n<$for i, [[T$i]]> type; +}; + +template <> +struct Templates<$for i, [[NoneT]]> { + typedef Templates0 type; +}; + +$range i 1..n-1 +$for i [[ +$range j 1..i +$range k i+1..n +template <$for j, [[GTEST_TEMPLATE_ T$j]]> +struct Templates<$for j, [[T$j]]$for k[[, NoneT]]> { + typedef Templates$i<$for j, [[T$j]]> type; +}; + +]] + +// The TypeList template makes it possible to use either a single type +// or a Types<...> list in TYPED_TEST_CASE() and +// INSTANTIATE_TYPED_TEST_CASE_P(). + +template <typename T> +struct TypeList { typedef Types1<T> type; }; + + +$range i 1..n +template <$for i, [[typename T$i]]> +struct TypeList<Types<$for i, [[T$i]]> > { + typedef typename Types<$for i, [[T$i]]>::type type; +}; + +#endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ diff --git a/lib/gtest/src/gtest-all.cc b/lib/gtest/src/gtest-all.cc new file mode 100644 index 0000000..0a9cee5 --- /dev/null +++ b/lib/gtest/src/gtest-all.cc @@ -0,0 +1,48 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: mheule@google.com (Markus Heule) +// +// Google C++ Testing Framework (Google Test) +// +// Sometimes it's desirable to build Google Test by compiling a single file. +// This file serves this purpose. + +// This line ensures that gtest.h can be compiled on its own, even +// when it's fused. +#include "gtest/gtest.h" + +// The following lines pull in the real gtest *.cc files. +#include "src/gtest.cc" +#include "src/gtest-death-test.cc" +#include "src/gtest-filepath.cc" +#include "src/gtest-port.cc" +#include "src/gtest-printers.cc" +#include "src/gtest-test-part.cc" +#include "src/gtest-typed-test.cc" diff --git a/lib/gtest/src/gtest-death-test.cc b/lib/gtest/src/gtest-death-test.cc new file mode 100644 index 0000000..8b2e413 --- /dev/null +++ b/lib/gtest/src/gtest-death-test.cc @@ -0,0 +1,1234 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan), vladl@google.com (Vlad Losev) +// +// This file implements death tests. + +#include "gtest/gtest-death-test.h" +#include "gtest/internal/gtest-port.h" + +#if GTEST_HAS_DEATH_TEST + +# if GTEST_OS_MAC +# include <crt_externs.h> +# endif // GTEST_OS_MAC + +# include <errno.h> +# include <fcntl.h> +# include <limits.h> +# include <stdarg.h> + +# if GTEST_OS_WINDOWS +# include <windows.h> +# else +# include <sys/mman.h> +# include <sys/wait.h> +# endif // GTEST_OS_WINDOWS + +#endif // GTEST_HAS_DEATH_TEST + +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +// Constants. + +// The default death test style. +static const char kDefaultDeathTestStyle[] = "fast"; + +GTEST_DEFINE_string_( + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); + +GTEST_DEFINE_bool_( + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); + +namespace internal { +GTEST_DEFINE_string_( + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "colons. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); +} // namespace internal + +#if GTEST_HAS_DEATH_TEST + +// ExitedWithCode constructor. +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +} + +// ExitedWithCode function-call operator. +bool ExitedWithCode::operator()(int exit_status) const { +# if GTEST_OS_WINDOWS + + return exit_status == exit_code_; + +# else + + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + +# endif // GTEST_OS_WINDOWS +} + +# if !GTEST_OS_WINDOWS +// KilledBySignal constructor. +KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +} + +// KilledBySignal function-call operator. +bool KilledBySignal::operator()(int exit_status) const { + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +} +# endif // !GTEST_OS_WINDOWS + +namespace internal { + +// Utilities needed for death tests. + +// Generates a textual description of a given exit code, in the format +// specified by wait(2). +static String ExitSummary(int exit_code) { + Message m; + +# if GTEST_OS_WINDOWS + + m << "Exited with exit status " << exit_code; + +# else + + if (WIFEXITED(exit_code)) { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } else if (WIFSIGNALED(exit_code)) { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +# ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) { + m << " (core dumped)"; + } +# endif +# endif // GTEST_OS_WINDOWS + + return m.GetString(); +} + +// Returns true if exit_status describes a process that was terminated +// by a signal, or exited normally with a nonzero exit code. +bool ExitedUnsuccessfully(int exit_status) { + return !ExitedWithCode(0)(exit_status); +} + +# if !GTEST_OS_WINDOWS +// Generates a textual failure message when a death test finds more than +// one thread running, or cannot determine the number of threads, prior +// to executing the given statement. It is the responsibility of the +// caller not to pass a thread_count of 1. +static String DeathTestThreadWarning(size_t thread_count) { + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); +} +# endif // !GTEST_OS_WINDOWS + +// Flag characters for reporting a death test that did not die. +static const char kDeathTestLived = 'L'; +static const char kDeathTestReturned = 'R'; +static const char kDeathTestThrew = 'T'; +static const char kDeathTestInternalError = 'I'; + +// An enumeration describing all of the possible ways that a death test can +// conclude. DIED means that the process died while executing the test +// code; LIVED means that process lived beyond the end of the test code; +// RETURNED means that the test statement attempted to execute a return +// statement, which is not allowed; THREW means that the test statement +// returned control by throwing an exception. IN_PROGRESS means the test +// has not yet concluded. +// TODO(vladl@google.com): Unify names and possibly values for +// AbortReason, DeathTestOutcome, and flag characters above. +enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; + +// Routine for aborting the program which is safe to call from an +// exec-style death test child process, in which case the error +// message is propagated back to the parent process. Otherwise, the +// message is simply printed to stderr. In either case, the program +// then exits with status 1. +void DeathTestAbort(const String& message) { + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } else { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } +} + +// A replacement for CHECK that calls DeathTestAbort if the assertion +// fails. +# define GTEST_DEATH_TEST_CHECK_(expression) \ + do { \ + if (!::testing::internal::IsTrue(expression)) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for +// evaluating any system call that fulfills two conditions: it must return +// -1 on failure, and set errno to EINTR when it is interrupted and +// should be tried again. The macro expands to a loop that repeatedly +// evaluates the expression as long as it evaluates to -1 and sets +// errno to EINTR. If the expression evaluates to -1 but errno is +// something other than EINTR, DeathTestAbort is called. +# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do { \ + int gtest_retval; \ + do { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) { \ + DeathTestAbort(::testing::internal::String::Format( \ + "CHECK failed: File %s, line %d: %s != -1", \ + __FILE__, __LINE__, #expression)); \ + } \ + } while (::testing::internal::AlwaysFalse()) + +// Returns the message describing the last system error in errno. +String GetLastErrnoDescription() { + return String(errno == 0 ? "" : posix::StrError(errno)); +} + +// This is called from a death test parent process to read a failure +// message from the death test child process and log it with the FATAL +// severity. On Windows, the message is read from a pipe handle. On other +// platforms, it is read from a file descriptor. +static void FailFromInternalError(int fd) { + Message error; + char buffer[256]; + int num_read; + + do { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); + + if (num_read == 0) { + GTEST_LOG_(FATAL) << error.GetString(); + } else { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } +} + +// Death test constructor. Increments the running death test count +// for the current test. +DeathTest::DeathTest() { + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) { + DeathTestAbort("Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } +} + +// Creates and returns a death test by dispatching to the current +// death test factory. +bool DeathTest::Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) { + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); +} + +const char* DeathTest::LastMessage() { + return last_death_test_message_.c_str(); +} + +void DeathTest::set_last_death_test_message(const String& message) { + last_death_test_message_ = message; +} + +String DeathTest::last_death_test_message_; + +// Provides cross platform implementation for some death functionality. +class DeathTestImpl : public DeathTest { + protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} + + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); + + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } + + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); + + private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; +}; + +// Called in the parent process only. Reads the result code of the death +// test child process via a pipe, interprets it to set the outcome_ +// member, and closes read_fd_. Outputs diagnostics and terminates in +// case of unexpected codes. +void DeathTestImpl::ReadAndInterpretStatusByte() { + char flag; + int bytes_read; + + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); + + if (bytes_read == 0) { + set_outcome(DIED); + } else if (bytes_read == 1) { + switch (flag) { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast<unsigned int>(flag) << ")"; + } + } else { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); +} + +// Signals that the death test code which should have exited, didn't. +// Should be called only in a death test child process. +// Writes a status byte to the child's status file descriptor, then +// calls _exit(1). +void DeathTestImpl::Abort(AbortReason reason) { + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : + reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; + + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) +} + +// Returns an indented copy of stderr output for a death test. +// This makes distinguishing death test output lines from regular log lines +// much easier. +static ::std::string FormatDeathTestOutput(const ::std::string& output) { + ::std::string ret; + for (size_t at = 0; ; ) { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; +} + +// Assesses the success or failure of a death test, using both private +// members which have previously been set, and one argument: +// +// Private data members: +// outcome: An enumeration describing how the death test +// concluded: DIED, LIVED, THREW, or RETURNED. The death test +// fails in the latter three cases. +// status: The exit status of the child process. On *nix, it is in the +// in the format specified by wait(2). On Windows, this is the +// value supplied to the ExitProcess() API or a numeric code +// of the exception that terminated the program. +// regex: A regular expression object to be applied to +// the test's captured standard error output; the death test +// fails if it does not match. +// +// Argument: +// status_ok: true if exit_status is acceptable in the context of +// this particular death test, which fails if it is false +// +// Returns true iff all of the above conditions are met. Otherwise, the +// first failing condition, in the order given above, is the one that is +// reported. Also sets the last death test message string. +bool DeathTestImpl::Passed(bool status_ok) { + if (!spawned()) + return false; + + const String error_message = GetCapturedStderr(); + + bool success = false; + Message buffer; + + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) { + success = true; + } else { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + } else { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } + + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; +} + +# if GTEST_OS_WINDOWS +// WindowsDeathTest implements death tests on Windows. Due to the +// specifics of starting new processes on Windows, death tests there are +// always threadsafe, and Google Test considers the +// --gtest_death_test_style=fast setting to be equivalent to +// --gtest_death_test_style=threadsafe there. +// +// A few implementation notes: Like the Linux version, the Windows +// implementation uses pipes for child-to-parent communication. But due to +// the specifics of pipes on Windows, some extra steps are required: +// +// 1. The parent creates a communication pipe and stores handles to both +// ends of it. +// 2. The parent starts the child and provides it with the information +// necessary to acquire the handle to the write end of the pipe. +// 3. The child acquires the write end of the pipe and signals the parent +// using a Windows event. +// 4. Now the parent can release the write end of the pipe on its side. If +// this is done before step 3, the object's reference count goes down to +// 0 and it is destroyed, preventing the child from acquiring it. The +// parent now has to release it, or read operations on the read end of +// the pipe will not return when the child terminates. +// 5. The parent reads child's output through the pipe (outcome code and +// any possible error messages) from the pipe, and its stderr and then +// determines whether to fail the test. +// +// Note: to distinguish Win32 API calls from the local method and function +// calls, the former are explicitly resolved in the global namespace. +// +class WindowsDeathTest : public DeathTestImpl { + public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); + + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; +}; + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int WindowsDeathTest::Wait() { + if (!spawned()) + return 0; + + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } + + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); + + ReadAndInterpretStatusByte(); + + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast<int>(status_code)); + return status(); +} + +// The AssumeRole process for a Windows death test. It creates a child +// process with the same executable as the current process to run the +// death test. The child process is given the --gtest_filter and +// --gtest_internal_run_death_test flags such that it knows to run the +// current death test only. +DeathTest::TestRole WindowsDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast<intptr_t>(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const String filter_flag = String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), + info->name()); + const String internal_flag = String::Format( + "--%s%s=%s|%d|%d|%u|%Iu|%Iu", + GTEST_FLAG_PREFIX_, + kInternalRunDeathTestFlag, + file_, line_, + death_test_index, + static_cast<unsigned int>(::GetCurrentProcessId()), + // size_t has the same with as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + reinterpret_cast<size_t>(write_handle), + reinterpret_cast<size_t>(event_handle_.Get())); + + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); + + String command_line = String::Format("%s %s \"%s\"", + ::GetCommandLineA(), + filter_flag.c_str(), + internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); + + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast<char*>(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; +} +# else // We are not on Windows. + +// ForkingDeathTest provides implementations for most of the abstract +// methods of the DeathTest interface. Only the AssumeRole method is +// left undefined. +class ForkingDeathTest : public DeathTestImpl { + public: + ForkingDeathTest(const char* statement, const RE* regex); + + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + + protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } + + private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; +}; + +// Constructs a ForkingDeathTest. +ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} + +// Waits for the child in a death test to exit, returning its exit +// status, or 0 if no child process exists. As a side effect, sets the +// outcome data member. +int ForkingDeathTest::Wait() { + if (!spawned()) + return 0; + + ReadAndInterpretStatusByte(); + + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; +} + +// A concrete death test class that forks, then immediately runs the test +// in the child process. +class NoExecDeathTest : public ForkingDeathTest { + public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : + ForkingDeathTest(a_statement, a_regex) { } + virtual TestRole AssumeRole(); +}; + +// The AssumeRole process for a fork-and-run death test. It implements a +// straightforward fork, with a simple pipe to transmit the status byte. +DeathTest::TestRole NoExecDeathTest::AssumeRole() { + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); + + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + return EXECUTE_TEST; + } else { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } +} + +// A concrete death test class that forks and re-executes the main +// program from the beginning, with command-line flags set that cause +// only this specific death test to be run. +class ExecDeathTest : public ForkingDeathTest { + public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : + ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } + virtual TestRole AssumeRole(); + private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; +}; + +// Utility class for accumulating command-line arguments. +class Arguments { + public: + Arguments() { + args_.push_back(NULL); + } + + ~Arguments() { + for (std::vector<char*>::iterator i = args_.begin(); i != args_.end(); + ++i) { + free(*i); + } + } + void AddArgument(const char* argument) { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } + + template <typename Str> + void AddArguments(const ::std::vector<Str>& arguments) { + for (typename ::std::vector<Str>::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() { + return &args_[0]; + } + private: + std::vector<char*> args_; +}; + +// A struct that encompasses the arguments to the child process of a +// threadsafe-style death test process. +struct ExecDeathTestArgs { + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe +}; + +# if GTEST_OS_MAC +inline char** GetEnviron() { + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); +} +# else +// Some POSIX platforms expect you to declare environ. extern "C" makes +// it reside in the global namespace. +extern "C" char** environ; +inline char** GetEnviron() { return environ; } +# endif // GTEST_OS_MAC + +// The main function for a threadsafe-style death test child process. +// This function is called in a clone()-ed process and thus must avoid +// any potentially unsafe operations like malloc or libc functions. +static int ExecDeathTestChildMain(void* child_arg) { + ExecDeathTestArgs* const args = static_cast<ExecDeathTestArgs*>(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); + + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) { + DeathTestAbort(String::Format("chdir(\"%s\") failed: %s", + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; + } + + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(String::Format("execve(%s, ...) in %s failed: %s", + args->argv[0], + original_dir, + GetLastErrnoDescription().c_str())); + return EXIT_FAILURE; +} + +// Two utility routines that together determine the direction the stack +// grows. +// This could be accomplished more elegantly by a single recursive +// function, but we want to guard against the unlikely possibility of +// a smart compiler optimizing the recursion away. +// +// GTEST_NO_INLINE_ is required to prevent GCC 4.6 from inlining +// StackLowerThanAddress into StackGrowsDown, which then doesn't give +// correct answer. +bool StackLowerThanAddress(const void* ptr) GTEST_NO_INLINE_; +bool StackLowerThanAddress(const void* ptr) { + int dummy; + return &dummy < ptr; +} + +bool StackGrowsDown() { + int dummy; + return StackLowerThanAddress(&dummy); +} + +// A threadsafe implementation of fork(2) for threadsafe-style death tests +// that uses clone(2). It dies with an error message if anything goes +// wrong. +static pid_t ExecDeathTestFork(char* const* argv, int close_fd) { + ExecDeathTestArgs args = { argv, close_fd }; + pid_t child_pid = -1; + +# if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); + + if (!use_fork) { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + void* const stack_top = + static_cast<char*>(stack) + (stack_grows_down ? stack_size : 0); + + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +# else + const bool use_fork = true; +# endif // GTEST_HAS_CLONE + + if (use_fork && (child_pid = fork()) == 0) { + ExecDeathTestChildMain(&args); + _exit(0); + } + + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; +} + +// The AssumeRole process for a fork-and-exec death test. It re-executes the +// main program from the beginning, setting the --gtest_filter +// and --gtest_internal_run_death_test flags to cause only the current +// death test to be re-run. +DeathTest::TestRole ExecDeathTest::AssumeRole() { + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); + + if (flag != NULL) { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } + + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + + const String filter_flag = + String::Format("--%s%s=%s.%s", + GTEST_FLAG_PREFIX_, kFilterFlag, + info->test_case_name(), info->name()); + const String internal_flag = + String::Format("--%s%s=%s|%d|%d|%d", + GTEST_FLAG_PREFIX_, kInternalRunDeathTestFlag, + file_, line_, death_test_index, pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvs()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); + + DeathTest::set_last_death_test_message(""); + + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); + + const pid_t child_pid = ExecDeathTestFork(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; +} + +# endif // !GTEST_OS_WINDOWS + +// Creates a concrete DeathTest-derived class that depends on the +// --gtest_death_test_style flag, and sets the pointer pointed to +// by the "test" argument to its address. If the test should be +// skipped, sets that pointer to NULL. Returns true, unless the +// flag is set to an invalid value. +bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, + const char* file, int line, + DeathTest** test) { + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); + + if (flag != NULL) { + if (death_test_index > flag->index()) { + DeathTest::set_last_death_test_message(String::Format( + "Death test count (%d) somehow exceeded expected maximum (%d)", + death_test_index, flag->index())); + return false; + } + + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) { + *test = NULL; + return true; + } + } + +# if GTEST_OS_WINDOWS + + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") { + *test = new WindowsDeathTest(statement, regex, file, line); + } + +# else + + if (GTEST_FLAG(death_test_style) == "threadsafe") { + *test = new ExecDeathTest(statement, regex, file, line); + } else if (GTEST_FLAG(death_test_style) == "fast") { + *test = new NoExecDeathTest(statement, regex); + } + +# endif // GTEST_OS_WINDOWS + + else { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message(String::Format( + "Unknown death test style \"%s\" encountered", + GTEST_FLAG(death_test_style).c_str())); + return false; + } + + return true; +} + +// Splits a given string on a given delimiter, populating a given +// vector with the fields. GTEST_HAS_DEATH_TEST implies that we have +// ::std::string, so we can use it here. +static void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest) { + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) { + parsed.push_back(str.substr(pos)); + break; + } else { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); +} + +# if GTEST_OS_WINDOWS +// Recreates the pipe and event handles from the provided parameters, +// signals the event, and returns a file descriptor wrapped around the pipe +// handle. This function is called in the child process only. +int GetStatusFileDescriptor(unsigned int parent_process_id, + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) { + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { + DeathTestAbort(String::Format("Unable to open parent process %u", + parent_process_id)); + } + + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + + const HANDLE write_handle = + reinterpret_cast<HANDLE>(write_handle_as_size_t); + HANDLE dup_write_handle; + + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the pipe handle %Iu from the parent process %u", + write_handle_as_size_t, parent_process_id)); + } + + const HANDLE event_handle = reinterpret_cast<HANDLE>(event_handle_as_size_t); + HANDLE dup_event_handle; + + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) { + DeathTestAbort(String::Format( + "Unable to duplicate the event handle %Iu from the parent process %u", + event_handle_as_size_t, parent_process_id)); + } + + const int write_fd = + ::_open_osfhandle(reinterpret_cast<intptr_t>(dup_write_handle), O_APPEND); + if (write_fd == -1) { + DeathTestAbort(String::Format( + "Unable to convert pipe handle %Iu to a file descriptor", + write_handle_as_size_t)); + } + + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); + + return write_fd; +} +# endif // GTEST_OS_WINDOWS + +// Returns a newly created InternalRunDeathTestFlag object with fields +// initialized from the GTEST_FLAG(internal_run_death_test) flag if +// the flag is specified; otherwise returns NULL. +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; + + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; + +# if GTEST_OS_WINDOWS + + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; + + if (fields.size() != 6 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &parent_process_id) + || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) + || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +# else + + if (fields.size() != 4 + || !ParseNaturalNumber(fields[1], &line) + || !ParseNaturalNumber(fields[2], &index) + || !ParseNaturalNumber(fields[3], &write_fd)) { + DeathTestAbort(String::Format( + "Bad --gtest_internal_run_death_test flag: %s", + GTEST_FLAG(internal_run_death_test).c_str())); + } + +# endif // GTEST_OS_WINDOWS + + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); +} + +} // namespace internal + +#endif // GTEST_HAS_DEATH_TEST + +} // namespace testing diff --git a/lib/gtest/src/gtest-filepath.cc b/lib/gtest/src/gtest-filepath.cc new file mode 100644 index 0000000..91b2571 --- /dev/null +++ b/lib/gtest/src/gtest-filepath.cc @@ -0,0 +1,380 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Authors: keith.ray@gmail.com (Keith Ray) + +#include "gtest/internal/gtest-filepath.h" +#include "gtest/internal/gtest-port.h" + +#include <stdlib.h> + +#if GTEST_OS_WINDOWS_MOBILE +# include <windows.h> +#elif GTEST_OS_WINDOWS +# include <direct.h> +# include <io.h> +#elif GTEST_OS_SYMBIAN || GTEST_OS_NACL +// Symbian OpenC and NaCl have PATH_MAX in sys/syslimits.h +# include <sys/syslimits.h> +#else +# include <limits.h> +# include <climits> // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_WINDOWS +# define GTEST_PATH_MAX_ _MAX_PATH +#elif defined(PATH_MAX) +# define GTEST_PATH_MAX_ PATH_MAX +#elif defined(_XOPEN_PATH_MAX) +# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#else +# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#endif // GTEST_OS_WINDOWS + +#include "gtest/internal/gtest-string.h" + +namespace testing { +namespace internal { + +#if GTEST_OS_WINDOWS +// On Windows, '\\' is the standard path separator, but many tools and the +// Windows API also accept '/' as an alternate path separator. Unless otherwise +// noted, a file path can contain either kind of path separators, or a mixture +// of them. +const char kPathSeparator = '\\'; +const char kAlternatePathSeparator = '/'; +const char kPathSeparatorString[] = "\\"; +const char kAlternatePathSeparatorString[] = "/"; +# if GTEST_OS_WINDOWS_MOBILE +// Windows CE doesn't have a current directory. You should not use +// the current directory in tests on Windows CE, but this at least +// provides a reasonable fallback. +const char kCurrentDirectoryString[] = "\\"; +// Windows CE doesn't define INVALID_FILE_ATTRIBUTES +const DWORD kInvalidFileAttributes = 0xffffffff; +# else +const char kCurrentDirectoryString[] = ".\\"; +# endif // GTEST_OS_WINDOWS_MOBILE +#else +const char kPathSeparator = '/'; +const char kPathSeparatorString[] = "/"; +const char kCurrentDirectoryString[] = "./"; +#endif // GTEST_OS_WINDOWS + +// Returns whether the given character is a valid path separator. +static bool IsPathSeparator(char c) { +#if GTEST_HAS_ALT_PATH_SEP_ + return (c == kPathSeparator) || (c == kAlternatePathSeparator); +#else + return c == kPathSeparator; +#endif +} + +// Returns the current working directory, or "" if unsuccessful. +FilePath FilePath::GetCurrentDir() { +#if GTEST_OS_WINDOWS_MOBILE + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); +#elif GTEST_OS_WINDOWS + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#else + char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns a copy of the FilePath with the case-insensitive extension removed. +// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns +// FilePath("dir/file"). If a case-insensitive extension is not +// found, returns a copy of the original FilePath. +FilePath FilePath::RemoveExtension(const char* extension) const { + String dot_extension(String::Format(".%s", extension)); + if (pathname_.EndsWithCaseInsensitive(dot_extension.c_str())) { + return FilePath(String(pathname_.c_str(), pathname_.length() - 4)); + } + return *this; +} + +// Returns a pointer to the last occurence of a valid path separator in +// the FilePath. On Windows, for example, both '/' and '\' are valid path +// separators. Returns NULL if no path separator was found. +const char* FilePath::FindLastPathSeparator() const { + const char* const last_sep = strrchr(c_str(), kPathSeparator); +#if GTEST_HAS_ALT_PATH_SEP_ + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) { + return last_alt_sep; + } +#endif + return last_sep; +} + +// Returns a copy of the FilePath with the directory part removed. +// Example: FilePath("path/to/file").RemoveDirectoryName() returns +// FilePath("file"). If there is no directory part ("just_a_file"), it returns +// the FilePath unmodified. If there is no file part ("just_a_dir/") it +// returns an empty FilePath (""). +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveDirectoryName() const { + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(String(last_sep + 1)) : *this; +} + +// RemoveFileName returns the directory path with the filename removed. +// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". +// If the FilePath is "a_file" or "/a_file", RemoveFileName returns +// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does +// not have a file, like "just/a/dir/", it returns the FilePath unmodified. +// On Windows platform, '\' is the path separator, otherwise it is '/'. +FilePath FilePath::RemoveFileName() const { + const char* const last_sep = FindLastPathSeparator(); + String dir; + if (last_sep) { + dir = String(c_str(), last_sep + 1 - c_str()); + } else { + dir = kCurrentDirectoryString; + } + return FilePath(dir); +} + +// Helper functions for naming files in a directory for xml output. + +// Given directory = "dir", base_name = "test", number = 0, +// extension = "xml", returns "dir/test.xml". If number is greater +// than zero (e.g., 12), returns "dir/test_12.xml". +// On Windows platform, uses \ as the separator rather than /. +FilePath FilePath::MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension) { + String file; + if (number == 0) { + file = String::Format("%s.%s", base_name.c_str(), extension); + } else { + file = String::Format("%s_%d.%s", base_name.c_str(), number, extension); + } + return ConcatPaths(directory, FilePath(file)); +} + +// Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". +// On Windows, uses \ as the separator rather than /. +FilePath FilePath::ConcatPaths(const FilePath& directory, + const FilePath& relative_path) { + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(String::Format("%s%c%s", dir.c_str(), kPathSeparator, + relative_path.c_str())); +} + +// Returns true if pathname describes something findable in the file-system, +// either a file, directory, or whatever. +bool FilePath::FileOrDirectoryExists() const { +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + return attributes != kInvalidFileAttributes; +#else + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +// Returns true if pathname describes a directory in the file-system +// that exists. +bool FilePath::DirectoryExists() const { + bool result = false; +#if GTEST_OS_WINDOWS + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : + RemoveTrailingPathSeparator()); +#else + const FilePath& path(*this); +#endif + +#if GTEST_OS_WINDOWS_MOBILE + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete [] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) { + result = true; + } +#else + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); +#endif // GTEST_OS_WINDOWS_MOBILE + + return result; +} + +// Returns true if pathname describes a root directory. (Windows has one +// root directory per disk drive.) +bool FilePath::IsRootDirectory() const { +#if GTEST_OS_WINDOWS + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); +#else + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); +#endif +} + +// Returns true if pathname describes an absolute path. +bool FilePath::IsAbsolutePath() const { + const char* const name = pathname_.c_str(); +#if GTEST_OS_WINDOWS + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); +#else + return IsPathSeparator(name[0]); +#endif +} + +// Returns a pathname for a file that does not currently exist. The pathname +// will be directory/base_name.extension or +// directory/base_name_<number>.extension if directory/base_name.extension +// already exists. The number will be incremented until a pathname is found +// that does not already exist. +// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. +// There could be a race condition if two or more processes are calling this +// function at the same time -- they could both pick the same filename. +FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension) { + FilePath full_pathname; + int number = 0; + do { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; +} + +// Returns true if FilePath ends with a path separator, which indicates that +// it is intended to represent a directory. Returns false otherwise. +// This does NOT check that a directory (or file) actually exists. +bool FilePath::IsDirectory() const { + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +} + +// Create directories so that path exists. Returns true if successful or if +// the directories already exist; returns false if unable to create directories +// for any reason. +bool FilePath::CreateDirectoriesRecursively() const { + if (!this->IsDirectory()) { + return false; + } + + if (pathname_.length() == 0 || this->DirectoryExists()) { + return true; + } + + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); +} + +// Create the directory so that path exists. Returns true if successful or +// if the directory already exists; returns false if unable to create the +// directory for any reason, including if the parent directory does not +// exist. Not named "CreateDirectory" because that's a macro on Windows. +bool FilePath::CreateFolder() const { +#if GTEST_OS_WINDOWS_MOBILE + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete [] unicode; +#elif GTEST_OS_WINDOWS + int result = _mkdir(pathname_.c_str()); +#else + int result = mkdir(pathname_.c_str(), 0777); +#endif // GTEST_OS_WINDOWS_MOBILE + + if (result == -1) { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. +} + +// If input name has a trailing separator character, remove it and return the +// name, otherwise return the name string unmodified. +// On Windows platform, uses \ as the separator, other platforms use /. +FilePath FilePath::RemoveTrailingPathSeparator() const { + return IsDirectory() + ? FilePath(String(pathname_.c_str(), pathname_.length() - 1)) + : *this; +} + +// Removes any redundant separators that might be in the pathname. +// For example, "bar///foo" becomes "bar/foo". Does not eliminate other +// redundancies that might be in a pathname involving "." or "..". +// TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). +void FilePath::Normalize() { + if (pathname_.c_str() == NULL) { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); + + while (*src != '\0') { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) { + src++; + } else { +#if GTEST_HAS_ALT_PATH_SEP_ + if (*dest_ptr == kAlternatePathSeparator) { + *dest_ptr = kPathSeparator; + } +#endif + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; +} + +} // namespace internal +} // namespace testing diff --git a/lib/gtest/src/gtest-internal-inl.h b/lib/gtest/src/gtest-internal-inl.h new file mode 100644 index 0000000..65a2101 --- /dev/null +++ b/lib/gtest/src/gtest-internal-inl.h @@ -0,0 +1,1038 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. + +// Utility functions and classes used by the Google C++ testing framework. +// +// Author: wan@google.com (Zhanyong Wan) +// +// This file contains purely Google Test's internal implementation. Please +// DO NOT #INCLUDE IT IN A USER PROGRAM. + +#ifndef GTEST_SRC_GTEST_INTERNAL_INL_H_ +#define GTEST_SRC_GTEST_INTERNAL_INL_H_ + +// GTEST_IMPLEMENTATION_ is defined to 1 iff the current translation unit is +// part of Google Test's implementation; otherwise it's undefined. +#if !GTEST_IMPLEMENTATION_ +// A user is trying to include this from his code - just say no. +# error "gtest-internal-inl.h is part of Google Test's internal implementation." +# error "It must not be included except by Google Test itself." +#endif // GTEST_IMPLEMENTATION_ + +#ifndef _WIN32_WCE +# include <errno.h> +#endif // !_WIN32_WCE +#include <stddef.h> +#include <stdlib.h> // For strtoll/_strtoul64/malloc/free. +#include <string.h> // For memmove. + +#include <algorithm> +#include <string> +#include <vector> + +#include "gtest/internal/gtest-port.h" + +#if GTEST_OS_WINDOWS +# include <windows.h> // NOLINT +#endif // GTEST_OS_WINDOWS + +#include "gtest/gtest.h" // NOLINT +#include "gtest/gtest-spi.h" + +namespace testing { + +// Declares the flags. +// +// We don't want the users to modify this flag in the code, but want +// Google Test's own unit tests to be able to access it. Therefore we +// declare it here as opposed to in gtest.h. +GTEST_DECLARE_bool_(death_test_use_fork); + +namespace internal { + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; + +// Names of the flags (needed for parsing Google Test flags). +const char kAlsoRunDisabledTestsFlag[] = "also_run_disabled_tests"; +const char kBreakOnFailureFlag[] = "break_on_failure"; +const char kCatchExceptionsFlag[] = "catch_exceptions"; +const char kColorFlag[] = "color"; +const char kFilterFlag[] = "filter"; +const char kListTestsFlag[] = "list_tests"; +const char kOutputFlag[] = "output"; +const char kPrintTimeFlag[] = "print_time"; +const char kRandomSeedFlag[] = "random_seed"; +const char kRepeatFlag[] = "repeat"; +const char kShuffleFlag[] = "shuffle"; +const char kStackTraceDepthFlag[] = "stack_trace_depth"; +const char kStreamResultToFlag[] = "stream_result_to"; +const char kThrowOnFailureFlag[] = "throw_on_failure"; + +// A valid random seed must be in [1, kMaxRandomSeed]. +const int kMaxRandomSeed = 99999; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +GTEST_API_ extern bool g_help_flag; + +// Returns the current time in milliseconds. +GTEST_API_ TimeInMillis GetTimeInMillis(); + +// Returns true iff Google Test should use colors in the output. +GTEST_API_ bool ShouldUseColor(bool stdout_is_tty); + +// Formats the given time in milliseconds as seconds. +GTEST_API_ std::string FormatTimeInMillisAsSeconds(TimeInMillis ms); + +// Parses a string for an Int32 flag, in the form of "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +GTEST_API_ bool ParseInt32Flag( + const char* str, const char* flag, Int32* value); + +// Returns a random seed in range [1, kMaxRandomSeed] based on the +// given --gtest_random_seed flag value. +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { + const unsigned int raw_seed = (random_seed_flag == 0) ? + static_cast<unsigned int>(GetTimeInMillis()) : + static_cast<unsigned int>(random_seed_flag); + + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast<int>((raw_seed - 1U) % + static_cast<unsigned int>(kMaxRandomSeed)) + 1; + return normalized_seed; +} + +// Returns the first valid random seed after 'seed'. The behavior is +// undefined if 'seed' is invalid. The seed after kMaxRandomSeed is +// considered to be 1. +inline int GetNextRandomSeed(int seed) { + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +} + +// This class saves the values of all Google Test flags in its c'tor, and +// restores them in its d'tor. +class GTestFlagSaver { + public: + // The c'tor. + GTestFlagSaver() { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } + + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } + private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + String color_; + String death_test_style_; + bool death_test_use_fork_; + String filter_; + String internal_run_death_test_; + bool list_tests_; + String output_; + bool print_time_; + bool pretty_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + String stream_result_to_; + bool throw_on_failure_; +} GTEST_ATTRIBUTE_UNUSED_; + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +GTEST_API_ char* CodePointToUtf8(UInt32 code_point, char* str); + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +GTEST_API_ String WideStringToUtf8(const wchar_t* str, int num_chars); + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded(); + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (e.g., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +GTEST_API_ bool ShouldShard(const char* total_shards_str, + const char* shard_index_str, + bool in_subprocess_for_death_test); + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error and +// and aborts. +GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +GTEST_API_ bool ShouldRunTestOnShard( + int total_shards, int shard_index, int test_id); + +// STL container utilities. + +// Returns the number of elements in the given container that satisfy +// the given predicate. +template <class Container, typename Predicate> +inline int CountIf(const Container& c, Predicate predicate) { + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { + if (predicate(*it)) + ++count; + } + return count; +} + +// Applies a function/functor to each element in the container. +template <class Container, typename Functor> +void ForEach(const Container& c, Functor functor) { + std::for_each(c.begin(), c.end(), functor); +} + +// Returns the i-th element of the vector, or default_value if i is not +// in range [0, v.size()). +template <typename E> +inline E GetElementOr(const std::vector<E>& v, int i, E default_value) { + return (i < 0 || i >= static_cast<int>(v.size())) ? default_value : v[i]; +} + +// Performs an in-place shuffle of a range of the vector's elements. +// 'begin' and 'end' are element indices as an STL-style range; +// i.e. [begin, end) are shuffled, where 'end' == size() means to +// shuffle to the end of the vector. +template <typename E> +void ShuffleRange(internal::Random* random, int begin, int end, + std::vector<E>* v) { + const int size = static_cast<int>(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; + + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } +} + +// Performs an in-place shuffle of the vector's elements. +template <typename E> +inline void Shuffle(internal::Random* random, std::vector<E>* v) { + ShuffleRange(random, 0, static_cast<int>(v->size()), v); +} + +// A function for deleting an object. Handy for being used as a +// functor. +template <typename T> +static void Delete(T* x) { + delete x; +} + +// A predicate that checks the key of a TestProperty against a known key. +// +// TestPropertyKeyIs is copyable. +class TestPropertyKeyIs { + public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const char* key) + : key_(key) {} + + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const { + return String(test_property.key()).Compare(key_) == 0; + } + + private: + String key_; +}; + +// Class UnitTestOptions. +// +// This class contains functions for processing options the user +// specifies when running the tests. It has only static members. +// +// In most cases, the user can specify an option using either an +// environment variable or a command line flag. E.g. you can set the +// test filter using either GTEST_FILTER or --gtest_filter. If both +// the variable and the flag are present, the latter overrides the +// former. +class GTEST_API_ UnitTestOptions { + public: + // Functions for processing the gtest_output flag. + + // Returns the output format, or "" for normal printed output. + static String GetOutputFormat(); + + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static String GetAbsolutePathToOutputFile(); + + // Functions for processing the gtest_filter flag. + + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char *pattern, const char *str); + + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const String &test_case_name, + const String &test_name); + +#if GTEST_OS_WINDOWS + // Function for supporting the gtest_catch_exception flag. + + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); +#endif // GTEST_OS_WINDOWS + + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const String& name, const char* filter); +}; + +// Returns the current application's name, removing directory path if that +// is present. Used by UnitTestOptions::GetOutputFile. +GTEST_API_ FilePath GetCurrentExecutableName(); + +// The role interface for getting the OS stack trace as a string. +class OsStackTraceGetterInterface { + public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} + + // Returns the current OS stack trace as a String. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual String CurrentStackTrace(int max_depth, int skip_count) = 0; + + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +}; + +// A working implementation of the OsStackTraceGetterInterface interface. +class OsStackTraceGetter : public OsStackTraceGetterInterface { + public: + OsStackTraceGetter() : caller_frame_(NULL) {} + virtual String CurrentStackTrace(int max_depth, int skip_count); + virtual void UponLeavingGTest(); + + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + + private: + Mutex mutex_; // protects all internal state + + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); +}; + +// Information about a Google Test trace point. +struct TraceInfo { + const char* file; + int line; + String message; +}; + +// This is the default global test part result reporter used in UnitTestImpl. +// This class should only be used by UnitTestImpl. +class DefaultGlobalTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); +}; + +// This is the default per thread test part result reporter used in +// UnitTestImpl. This class should only be used by UnitTestImpl. +class DefaultPerThreadTestPartResultReporter + : public TestPartResultReporterInterface { + public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); + + private: + UnitTestImpl* const unit_test_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); +}; + +// The private implementation of the UnitTest class. We don't protect +// the methods under a mutex, as this class is not accessible by a +// user and the UnitTest class that delegates work to this class does +// proper locking. +class GTEST_API_ UnitTestImpl { + public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); + + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. + + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); + + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); + + // Gets the number of successful test cases. + int successful_test_case_count() const; + + // Gets the number of failed test cases. + int failed_test_case_count() const; + + // Gets the number of all test cases. + int total_test_case_count() const; + + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; + + // Gets the number of successful tests. + int successful_test_count() const; + + // Gets the number of failed tests. + int failed_test_count() const; + + // Gets the number of disabled tests. + int disabled_test_count() const; + + // Gets the number of all tests. + int total_test_count() const; + + // Gets the number of tests that should run. + int test_to_run_count() const; + + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } + + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } + + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } + + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } + + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } + + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); + + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); + + // Returns the current OS stack trace as a String. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + String CurrentOsStackTraceExceptTop(int skip_count); + + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); + + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } + + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc)->AddTestInfo(test_info); + } + +#if GTEST_HAS_PARAM_TEST + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { + return parameterized_test_registry_; + } +#endif // GTEST_HAS_PARAM_TEST + + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) { + current_test_case_ = a_current_test_case; + } + + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) { + current_test_info_ = a_current_test_info; + } + + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); + + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); + + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } + + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() { + ad_hoc_test_result_.Clear(); + } + + enum ReactionToSharding { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; + + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); + + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); + + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } + + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector<Environment*>& environments() { return environments_; } + + // Getters for the per-thread Google Test trace stack. + std::vector<TraceInfo>& gtest_trace_stack() { + return *(gtest_trace_stack_.pointer()); + } + const std::vector<TraceInfo>& gtest_trace_stack() const { + return gtest_trace_stack_.get(); + } + +#if GTEST_HAS_DEATH_TEST + void InitDeathTestSubprocessControlInfo() { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const { + return internal_run_death_test_flag_.get(); + } + + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() { + return death_test_factory_.get(); + } + + void SuppressTestEventsIfInSubprocess(); + + friend class ReplaceDeathTestFactory; +#endif // GTEST_HAS_DEATH_TEST + + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); +#endif + + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); + + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } + + // Gets the random number generator. + internal::Random* random() { return &random_; } + + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); + + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); + + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } + + private: + friend class ::testing::UnitTest; + + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; + + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; + + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; + + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; + + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; + + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal<TestPartResultReporterInterface*> + per_thread_test_part_result_reporter_; + + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector<Environment*> environments_; + + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector<TestCase*> test_cases_; + + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector<int> test_case_indices_; + +#if GTEST_HAS_PARAM_TEST + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; +#endif // GTEST_HAS_PARAM_TEST + + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; + + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; + + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; + + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; + + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; + + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; + + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; + + // The random number seed used at the beginning of the test run. + int random_seed_; + + // Our random number generator. + internal::Random random_; + + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; + +#if GTEST_HAS_DEATH_TEST + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr<InternalRunDeathTestFlag> internal_run_death_test_flag_; + internal::scoped_ptr<internal::DeathTestFactory> death_test_factory_; +#endif // GTEST_HAS_DEATH_TEST + + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal<std::vector<TraceInfo> > gtest_trace_stack_; + + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); +}; // class UnitTestImpl + +// Convenience function for accessing the global UnitTest +// implementation object. +inline UnitTestImpl* GetUnitTestImpl() { + return UnitTest::GetInstance()->impl(); +} + +#if GTEST_USES_SIMPLE_RE + +// Internal helper functions for implementing the simple regular +// expression matcher. +GTEST_API_ bool IsInSet(char ch, const char* str); +GTEST_API_ bool IsAsciiDigit(char ch); +GTEST_API_ bool IsAsciiPunct(char ch); +GTEST_API_ bool IsRepeat(char ch); +GTEST_API_ bool IsAsciiWhiteSpace(char ch); +GTEST_API_ bool IsAsciiWordChar(char ch); +GTEST_API_ bool IsValidEscape(char ch); +GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); +GTEST_API_ bool ValidateRegex(const char* regex); +GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); +GTEST_API_ bool MatchRepetitionAndRegexAtHead( + bool escaped, char ch, char repeat, const char* regex, const char* str); +GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); + +#endif // GTEST_USES_SIMPLE_RE + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, char** argv); +GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); + +#if GTEST_HAS_DEATH_TEST + +// Returns the message describing the last system error, regardless of the +// platform. +GTEST_API_ String GetLastErrnoDescription(); + +# if GTEST_OS_WINDOWS +// Provides leak-safe Windows kernel handle ownership. +class AutoHandle { + public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} + + ~AutoHandle() { Reset(); } + + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) { + if (handle != handle_) { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } + + private: + HANDLE handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; +# endif // GTEST_OS_WINDOWS + +// Attempts to parse a string into a positive integer pointed to by the +// number parameter. Returns true if that is possible. +// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use +// it here. +template <typename Integer> +bool ParseNaturalNumber(const ::std::string& str, Integer* number) { + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) { + return false; + } + errno = 0; + + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. + +# if GTEST_OS_WINDOWS && !defined(__GNUC__) + + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + +# else + + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + +# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) + + const bool parse_success = *end == '\0' && errno == 0; + + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + + const Integer result = static_cast<Integer>(parsed); + if (parse_success && static_cast<BiggestConvertible>(result) == parsed) { + *number = result; + return true; + } + return false; +} +#endif // GTEST_HAS_DEATH_TEST + +// TestResult contains some private methods that should be hidden from +// Google Test user but are required for testing. This class allow our tests +// to access them. +// +// This class is supplied only for the purpose of testing Google Test's own +// constructs. Do not use it in user tests, either directly or indirectly. +class TestResultAccessor { + public: + static void RecordProperty(TestResult* test_result, + const TestProperty& property) { + test_result->RecordProperty(property); + } + + static void ClearTestPartResults(TestResult* test_result) { + test_result->ClearTestPartResults(); + } + + static const std::vector<testing::TestPartResult>& test_part_results( + const TestResult& test_result) { + return test_result.test_part_results(); + } +}; + +} // namespace internal +} // namespace testing + +#endif // GTEST_SRC_GTEST_INTERNAL_INL_H_ diff --git a/lib/gtest/src/gtest-port.cc b/lib/gtest/src/gtest-port.cc new file mode 100644 index 0000000..b860d48 --- /dev/null +++ b/lib/gtest/src/gtest-port.cc @@ -0,0 +1,746 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/internal/gtest-port.h" + +#include <limits.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#if GTEST_OS_WINDOWS_MOBILE +# include <windows.h> // For TerminateProcess() +#elif GTEST_OS_WINDOWS +# include <io.h> +# include <sys/stat.h> +#else +# include <unistd.h> +#endif // GTEST_OS_WINDOWS_MOBILE + +#if GTEST_OS_MAC +# include <mach/mach_init.h> +# include <mach/task.h> +# include <mach/vm_map.h> +#endif // GTEST_OS_MAC + +#include "gtest/gtest-spi.h" +#include "gtest/gtest-message.h" +#include "gtest/internal/gtest-internal.h" +#include "gtest/internal/gtest-string.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { +namespace internal { + +#if defined(_MSC_VER) || defined(__BORLANDC__) +// MSVC and C++Builder do not provide a definition of STDERR_FILENO. +const int kStdOutFileno = 1; +const int kStdErrFileno = 2; +#else +const int kStdOutFileno = STDOUT_FILENO; +const int kStdErrFileno = STDERR_FILENO; +#endif // _MSC_VER + +#if GTEST_OS_MAC + +// Returns the number of threads running in the process, or 0 to indicate that +// we cannot detect it. +size_t GetThreadCount() { + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast<vm_address_t>(thread_list), + sizeof(thread_t) * thread_count); + return static_cast<size_t>(thread_count); + } else { + return 0; + } +} + +#else + +size_t GetThreadCount() { + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; +} + +#endif // GTEST_OS_MAC + +#if GTEST_USES_POSIX_RE + +// Implements RE. Currently only needed for death tests. + +RE::~RE() { + if (is_valid_) { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast<char*>(pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + if (!re.is_valid_) return false; + + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = posix::StrDup(regex); + + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; + + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; + + delete[] full_pattern; +} + +#elif GTEST_USES_SIMPLE_RE + +// Returns true iff ch appears anywhere in str (excluding the +// terminating '\0' character). +bool IsInSet(char ch, const char* str) { + return ch != '\0' && strchr(str, ch) != NULL; +} + +// Returns true iff ch belongs to the given classification. Unlike +// similar functions in <ctype.h>, these aren't affected by the +// current locale. +bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } +bool IsAsciiPunct(char ch) { + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +} +bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } +bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } +bool IsAsciiWordChar(char ch) { + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; +} + +// Returns true iff "\\c" is a supported escape sequence. +bool IsValidEscape(char c) { + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +} + +// Returns true iff the given atom (specified by escaped and pattern) +// matches ch. The result is undefined if the atom is invalid. +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { + if (escaped) { // "\\p" where p is pattern_char. + switch (pattern_char) { + case 'd': return IsAsciiDigit(ch); + case 'D': return !IsAsciiDigit(ch); + case 'f': return ch == '\f'; + case 'n': return ch == '\n'; + case 'r': return ch == '\r'; + case 's': return IsAsciiWhiteSpace(ch); + case 'S': return !IsAsciiWhiteSpace(ch); + case 't': return ch == '\t'; + case 'v': return ch == '\v'; + case 'w': return IsAsciiWordChar(ch); + case 'W': return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } + + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; +} + +// Helper function used by ValidateRegex() to format error messages. +String FormatRegexSyntaxError(const char* regex, int index) { + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ").GetString(); +} + +// Generates non-fatal failures and returns false if regex is invalid; +// otherwise returns true. +bool ValidateRegex(const char* regex) { + if (regex == NULL) { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } + + bool is_valid = true; + + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) { + if (regex[i] == '\\') { // An escape sequence + i++; + if (regex[i] == '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } + + if (!IsValidEscape(regex[i])) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } else { // Not an escape sequence. + const char ch = regex[i]; + + if (ch == '^' && i > 0) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } else if (ch == '$' && regex[i + 1] != '\0') { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } else if (IsInSet(ch, "()[]{}|")) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } else if (IsRepeat(ch) && !prev_repeatable) { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } + + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } + + return is_valid; +} + +// Matches a repeated regex atom followed by a valid simple regular +// expression. The regex atom is defined as c if escaped is false, +// or \c otherwise. repeat is the repetition meta character (?, *, +// or +). The behavior is undefined if str contains too many +// characters to be indexable by size_t, in which case the test will +// probably time out anyway. We are fine with this limitation as +// std::string has it too. +bool MatchRepetitionAndRegexAtHead( + bool escaped, char c, char repeat, const char* regex, + const char* str) { + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : + static_cast<size_t>(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. + + for (size_t i = 0; i <= max_count; ++i) { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; +} + +// Returns true iff regex matches a prefix of str. regex must be a +// valid simple regular expression and not start with "^", or the +// result is undefined. +bool MatchRegexAtHead(const char* regex, const char* str) { + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; + + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; + + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } else { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } +} + +// Returns true iff regex matches any substring of str. regex must be +// a valid simple regular expression, or the result is undefined. +// +// The algorithm is recursive, but the recursion depth doesn't exceed +// the regex length, so we won't need to worry about running out of +// stack space normally. In rare cases the time complexity can be +// exponential with respect to the regex length + the string length, +// but usually it's must faster (often close to linear). +bool MatchRegexAnywhere(const char* regex, const char* str) { + if (regex == NULL || str == NULL) + return false; + + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); + + // A successful match can be anywhere in str. + do { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; +} + +// Implements the RE class. + +RE::~RE() { + free(const_cast<char*>(pattern_)); + free(const_cast<char*>(full_pattern_)); +} + +// Returns true iff regular expression re matches the entire str. +bool RE::FullMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +} + +// Returns true iff regular expression re matches a substring of str +// (including str itself). +bool RE::PartialMatch(const char* str, const RE& re) { + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +} + +// Initializes an RE from its string representation. +void RE::Init(const char* regex) { + pattern_ = full_pattern_ = NULL; + if (regex != NULL) { + pattern_ = posix::StrDup(regex); + } + + is_valid_ = ValidateRegex(regex); + if (!is_valid_) { + // No need to calculate the full pattern when the regex is invalid. + return; + } + + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast<char*>(malloc(len + 3)); + full_pattern_ = buffer; + + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; + + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + + *buffer = '\0'; +} + +#endif // GTEST_USES_POSIX_RE + +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) { + return String::Format("%s:", file_name).c_str(); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line).c_str(); +#else + return String::Format("%s:%d:", file_name, line).c_str(); +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) + return file_name; + else + return String::Format("%s:%d", file_name, line).c_str(); +} + + +GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) + : severity_(severity) { + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : + severity == GTEST_WARNING ? "[WARNING]" : + severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; +} + +// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. +GTestLog::~GTestLog() { + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) { + fflush(stderr); + posix::Abort(); + } +} +// Disable Microsoft deprecation warnings for POSIX functions called from +// this class (creat, dup, dup2, and close) +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable: 4996) +#endif // _MSC_VER + +#if GTEST_HAS_STREAM_REDIRECTION + +// Object that captures an output stream (stdout/stderr). +class CapturedStream { + public: + // The ctor redirects the stream to a temporary file. + CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { + +# if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT + char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT + + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +# else + // There's no guarantee that a test has write access to the + // current directory, so we create the temporary file in the /tmp + // directory instead. + char name_template[] = "/tmp/captured_stream.XXXXXX"; + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +# endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } + + ~CapturedStream() { + remove(filename_.c_str()); + } + + String GetCapturedString() { + if (uncaptured_fd_ != -1) { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } + + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const String content = ReadEntireFile(file); + posix::FClose(file); + return content; + } + + private: + // Reads the entire content of a file as a String. + static String ReadEntireFile(FILE* file); + + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); + + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); +}; + +// Returns the size (in bytes) of a file. +size_t CapturedStream::GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast<size_t>(ftell(file)); +} + +// Reads the entire content of a file as a string. +String CapturedStream::ReadEntireFile(FILE* file) { + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; + + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far + + fseek(file, 0, SEEK_SET); + + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do { + bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); + + const String content(buffer, bytes_read); + delete[] buffer; + + return content; +} + +# ifdef _MSC_VER +# pragma warning(pop) +# endif // _MSC_VER + +static CapturedStream* g_captured_stderr = NULL; +static CapturedStream* g_captured_stdout = NULL; + +// Starts capturing an output stream (stdout/stderr). +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { + if (*stream != NULL) { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); +} + +// Stops capturing the output stream and returns the captured string. +String GetCapturedStream(CapturedStream** captured_stream) { + const String content = (*captured_stream)->GetCapturedString(); + + delete *captured_stream; + *captured_stream = NULL; + + return content; +} + +// Starts capturing stdout. +void CaptureStdout() { + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +} + +// Starts capturing stderr. +void CaptureStderr() { + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +} + +// Stops capturing stdout and returns the captured string. +String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); } + +// Stops capturing stderr and returns the captured string. +String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); } + +#endif // GTEST_HAS_STREAM_REDIRECTION + +#if GTEST_HAS_DEATH_TEST + +// A copy of all command line arguments. Set by InitGoogleTest(). +::std::vector<String> g_argvs; + +// Returns the command line as a vector of strings. +const ::std::vector<String>& GetArgvs() { return g_argvs; } + +#endif // GTEST_HAS_DEATH_TEST + +#if GTEST_OS_WINDOWS_MOBILE +namespace posix { +void Abort() { + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); +} +} // namespace posix +#endif // GTEST_OS_WINDOWS_MOBILE + +// Returns the name of the environment variable corresponding to the +// given flag. For example, FlagToEnvVar("foo") will return +// "GTEST_FOO" in the open-source version. +static String FlagToEnvVar(const char* flag) { + const String full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); + + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) { + env_var << ToUpper(full_flag.c_str()[i]); + } + + return env_var.GetString(); +} + +// Parses 'str' for a 32-bit signed integer. If successful, writes +// the result to *value and returns true; otherwise leaves *value +// unchanged and returns false. +bool ParseInt32(const Message& src_text, const char* str, Int32* value) { + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT + + // Has strtol() consumed all characters in the string? + if (*end != '\0') { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast<Int32>(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } + + *value = result; + return true; +} + +// Reads and returns the Boolean environment variable corresponding to +// the given flag; if it's not set, returns default_value. +// +// The value is considered true iff it's not "0". +bool BoolFromGTestEnv(const char* flag, bool default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? + default_value : strcmp(string_value, "0") != 0; +} + +// Reads and returns a 32-bit integer stored in the environment +// variable corresponding to the given flag; if it isn't set or +// doesn't represent a valid 32-bit integer, returns default_value. +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) { + // The environment variable is not set. + return default_value; + } + + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } + + return result; +} + +// Reads and returns the string environment variable corresponding to +// the given flag; if it's not set, returns default_value. +const char* StringFromGTestEnv(const char* flag, const char* default_value) { + const String env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; +} + +} // namespace internal +} // namespace testing diff --git a/lib/gtest/src/gtest-printers.cc b/lib/gtest/src/gtest-printers.cc new file mode 100644 index 0000000..ed63c7b --- /dev/null +++ b/lib/gtest/src/gtest-printers.cc @@ -0,0 +1,356 @@ +// Copyright 2007, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +// Google Test - The Google C++ Testing Framework +// +// This file implements a universal value printer that can print a +// value of any type T: +// +// void ::testing::internal::UniversalPrinter<T>::Print(value, ostream_ptr); +// +// It uses the << operator when possible, and prints the bytes in the +// object otherwise. A user can override its behavior for a class +// type Foo by defining either operator<<(::std::ostream&, const Foo&) +// or void PrintTo(const Foo&, ::std::ostream*) in the namespace that +// defines Foo. + +#include "gtest/gtest-printers.h" +#include <ctype.h> +#include <stdio.h> +#include <ostream> // NOLINT +#include <string> +#include "gtest/internal/gtest-port.h" + +namespace testing { + +namespace { + +using ::std::ostream; + +#if GTEST_OS_WINDOWS_MOBILE // Windows CE does not define _snprintf_s. +# define snprintf _snprintf +#elif _MSC_VER >= 1400 // VC 8.0 and later deprecate snprintf and _snprintf. +# define snprintf _snprintf_s +#elif _MSC_VER +# define snprintf _snprintf +#endif // GTEST_OS_WINDOWS_MOBILE + +// Prints a segment of bytes in the given object. +void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, + size_t count, ostream* os) { + char text[5] = ""; + for (size_t i = 0; i != count; i++) { + const size_t j = start + i; + if (i != 0) { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + snprintf(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } +} + +// Prints the bytes in the given value to the given ostream. +void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, + ostream* os) { + // Tells the user how big the object is. + *os << count << "-byte object <"; + + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } else { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1)/2*2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; +} + +} // namespace + +namespace internal2 { + +// Delegates to PrintBytesInObjectToImpl() to print the bytes in the +// given object. The delegation simplifies the implementation, which +// uses the << operator and thus is easier done outside of the +// ::testing::internal namespace, which contains a << operator that +// sometimes conflicts with the one in STL. +void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, + ostream* os) { + PrintBytesInObjectToImpl(obj_bytes, count, os); +} + +} // namespace internal2 + +namespace internal { + +// Depending on the value of a char (or wchar_t), we print it in one +// of three formats: +// - as is if it's a printable ASCII (e.g. 'a', '2', ' '), +// - as a hexidecimal escape sequence (e.g. '\x7F'), or +// - as a special escape sequence (e.g. '\r', '\n'). +enum CharFormat { + kAsIs, + kHexEscape, + kSpecialEscape +}; + +// Returns true if c is a printable ASCII character. We test the +// value of c directly instead of calling isprint(), which is buggy on +// Windows Mobile. +inline bool IsPrintableAscii(wchar_t c) { + return 0x20 <= c && c <= 0x7E; +} + +// Prints a wide or narrow char c as a character literal without the +// quotes, escaping it when necessary; returns how c was formatted. +// The template argument UnsignedChar is the unsigned version of Char, +// which is the type of c. +template <typename UnsignedChar, typename Char> +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { + switch (static_cast<wchar_t>(c)) { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) { + *os << static_cast<char>(c); + return kAsIs; + } else { + *os << String::Format("\\x%X", static_cast<UnsignedChar>(c)); + return kHexEscape; + } + } + return kSpecialEscape; +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsWideStringLiteralTo(wchar_t c, ostream* os) { + switch (c) { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo<wchar_t>(c, os); + } +} + +// Prints a char c as if it's part of a string literal, escaping it when +// necessary; returns how c was formatted. +static CharFormat PrintAsNarrowStringLiteralTo(char c, ostream* os) { + return PrintAsWideStringLiteralTo(static_cast<unsigned char>(c), os); +} + +// Prints a wide or narrow character c and its code. '\0' is printed +// as "'\\0'", other unprintable characters are also properly escaped +// using the standard C++ escape sequence. The template argument +// UnsignedChar is the unsigned version of Char, which is the type of c. +template <typename UnsignedChar, typename Char> +void PrintCharAndCodeTo(Char c, ostream* os) { + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo<UnsignedChar>(c, os); + *os << "'"; + + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << String::Format("%d", c).c_str(); + + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) { + // Do nothing. + } else { + *os << String::Format(", 0x%X", + static_cast<UnsignedChar>(c)).c_str(); + } + *os << ")"; +} + +void PrintTo(unsigned char c, ::std::ostream* os) { + PrintCharAndCodeTo<unsigned char>(c, os); +} +void PrintTo(signed char c, ::std::ostream* os) { + PrintCharAndCodeTo<unsigned char>(c, os); +} + +// Prints a wchar_t as a symbol if it is printable or as its internal +// code otherwise and also as its code. L'\0' is printed as "L'\\0'". +void PrintTo(wchar_t wc, ostream* os) { + PrintCharAndCodeTo<wchar_t>(wc, os); +} + +// Prints the given array of characters to the ostream. +// The array starts at *begin, the length is len, it may include '\0' characters +// and may not be null-terminated. +static void PrintCharsAsStringTo(const char* begin, size_t len, ostream* os) { + *os << "\""; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const char cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" \""; + } + is_previous_hex = PrintAsNarrowStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints a (const) char array of 'len' elements, starting at address 'begin'. +void UniversalPrintArray(const char* begin, size_t len, ostream* os) { + PrintCharsAsStringTo(begin, len, os); +} + +// Prints the given array of wide characters to the ostream. +// The array starts at *begin, the length is len, it may include L'\0' +// characters and may not be null-terminated. +static void PrintWideCharsAsStringTo(const wchar_t* begin, size_t len, + ostream* os) { + *os << "L\""; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) { + const wchar_t cur = begin[index]; + if (is_previous_hex && isascii(cur) && IsXDigit(static_cast<char>(cur))) { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" L\""; + } + is_previous_hex = PrintAsWideStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; +} + +// Prints the given C string to the ostream. +void PrintTo(const char* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_<const void*>(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } +} + +// MSVC compiler can be configured to define whar_t as a typedef +// of unsigned short. Defining an overload for const wchar_t* in that case +// would cause pointers to unsigned shorts be printed as wide strings, +// possibly accessing more memory than intended and causing invalid +// memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when +// wchar_t is implemented as a native type. +#if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) +// Prints the given wide C string to the ostream. +void PrintTo(const wchar_t* s, ostream* os) { + if (s == NULL) { + *os << "NULL"; + } else { + *os << ImplicitCast_<const void*>(s) << " pointing to "; + PrintWideCharsAsStringTo(s, wcslen(s), os); + } +} +#endif // wchar_t is native + +// Prints a ::string object. +#if GTEST_HAS_GLOBAL_STRING +void PrintStringTo(const ::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_STRING + +void PrintStringTo(const ::std::string& s, ostream* os) { + PrintCharsAsStringTo(s.data(), s.size(), os); +} + +// Prints a ::wstring object. +#if GTEST_HAS_GLOBAL_WSTRING +void PrintWideStringTo(const ::wstring& s, ostream* os) { + PrintWideCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +#if GTEST_HAS_STD_WSTRING +void PrintWideStringTo(const ::std::wstring& s, ostream* os) { + PrintWideCharsAsStringTo(s.data(), s.size(), os); +} +#endif // GTEST_HAS_STD_WSTRING + +} // namespace internal + +} // namespace testing diff --git a/lib/gtest/src/gtest-test-part.cc b/lib/gtest/src/gtest-test-part.cc new file mode 100644 index 0000000..5ddc67c --- /dev/null +++ b/lib/gtest/src/gtest-test-part.cc @@ -0,0 +1,110 @@ +// Copyright 2008, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: mheule@google.com (Markus Heule) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest-test-part.h" + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +namespace testing { + +using internal::GetUnitTestImpl; + +// Gets the summary of the failure message by omitting the stack trace +// in it. +internal::String TestPartResult::ExtractSummary(const char* message) { + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? internal::String(message) : + internal::String(message, stack_trace - message); +} + +// Prints a TestPartResult object. +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : + result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : + "Non-fatal failure") << ":\n" + << result.message() << std::endl; +} + +// Appends a TestPartResult to the array. +void TestPartResultArray::Append(const TestPartResult& result) { + array_.push_back(result); +} + +// Returns the TestPartResult at the given index (0-based). +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { + if (index < 0 || index >= size()) { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } + + return array_[index]; +} + +// Returns the number of TestPartResult objects in the array. +int TestPartResultArray::size() const { + return static_cast<int>(array_.size()); +} + +namespace internal { + +HasNewFatalFailureHelper::HasNewFatalFailureHelper() + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()-> + GetTestPartResultReporterForCurrentThread()) { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); +} + +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); +} + +void HasNewFatalFailureHelper::ReportTestPartResult( + const TestPartResult& result) { + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); +} + +} // namespace internal + +} // namespace testing diff --git a/lib/gtest/src/gtest-typed-test.cc b/lib/gtest/src/gtest-typed-test.cc new file mode 100644 index 0000000..a5cc88f --- /dev/null +++ b/lib/gtest/src/gtest-typed-test.cc @@ -0,0 +1,110 @@ +// Copyright 2008 Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) + +#include "gtest/gtest-typed-test.h" +#include "gtest/gtest.h" + +namespace testing { +namespace internal { + +#if GTEST_HAS_TYPED_TEST_P + +// Skips to the first non-space char in str. Returns an empty string if str +// contains only whitespace characters. +static const char* SkipSpaces(const char* str) { + while (IsSpace(*str)) + str++; + return str; +} + +// Verifies that registered_tests match the test names in +// defined_test_names_; returns registered_tests if successful, or +// aborts the program otherwise. +const char* TypedTestCasePState::VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests) { + typedef ::std::set<const char*>::const_iterator DefinedTestIter; + registered_ = true; + + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); + + Message errors; + ::std::set<String> tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) { + const String name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } + + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (name == *it) { + found = true; + break; + } + } + + if (found) { + tests.insert(name); + } else { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } + + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) { + if (tests.count(*it) == 0) { + errors << "You forgot to list test " << *it << ".\n"; + } + } + + const String& errors_str = errors.GetString(); + if (errors_str != "") { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } + + return registered_tests; +} + +#endif // GTEST_HAS_TYPED_TEST_P + +} // namespace internal +} // namespace testing diff --git a/lib/gtest/src/gtest.cc b/lib/gtest/src/gtest.cc new file mode 100644 index 0000000..904d9d7 --- /dev/null +++ b/lib/gtest/src/gtest.cc @@ -0,0 +1,4898 @@ +// Copyright 2005, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. +// +// Author: wan@google.com (Zhanyong Wan) +// +// The Google C++ Testing Framework (Google Test) + +#include "gtest/gtest.h" +#include "gtest/gtest-spi.h" + +#include <ctype.h> +#include <math.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <wchar.h> +#include <wctype.h> + +#include <algorithm> +#include <ostream> // NOLINT +#include <sstream> +#include <vector> + +#if GTEST_OS_LINUX + +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +# include <fcntl.h> // NOLINT +# include <limits.h> // NOLINT +# include <sched.h> // NOLINT +// Declares vsnprintf(). This header is not available on Windows. +# include <strings.h> // NOLINT +# include <sys/mman.h> // NOLINT +# include <sys/time.h> // NOLINT +# include <unistd.h> // NOLINT +# include <string> + +#elif GTEST_OS_SYMBIAN +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include <sys/time.h> // NOLINT + +#elif GTEST_OS_ZOS +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include <sys/time.h> // NOLINT + +// On z/OS we additionally need strings.h for strcasecmp. +# include <strings.h> // NOLINT + +#elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. + +# include <windows.h> // NOLINT + +#elif GTEST_OS_WINDOWS // We are on Windows proper. + +# include <io.h> // NOLINT +# include <sys/timeb.h> // NOLINT +# include <sys/types.h> // NOLINT +# include <sys/stat.h> // NOLINT + +# if GTEST_OS_WINDOWS_MINGW +// MinGW has gettimeofday() but not _ftime64(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +// TODO(kenton@google.com): There are other ways to get the time on +// Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW +// supports these. consider using them instead. +# define GTEST_HAS_GETTIMEOFDAY_ 1 +# include <sys/time.h> // NOLINT +# endif // GTEST_OS_WINDOWS_MINGW + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include <windows.h> // NOLINT + +#else + +// Assume other platforms have gettimeofday(). +// TODO(kenton@google.com): Use autoconf to detect availability of +// gettimeofday(). +# define GTEST_HAS_GETTIMEOFDAY_ 1 + +// cpplint thinks that the header is already included, so we want to +// silence it. +# include <sys/time.h> // NOLINT +# include <unistd.h> // NOLINT + +#endif // GTEST_OS_LINUX + +#if GTEST_HAS_EXCEPTIONS +# include <stdexcept> +#endif + +#if GTEST_CAN_STREAM_RESULTS_ +# include <arpa/inet.h> // NOLINT +# include <netdb.h> // NOLINT +#endif + +// Indicates that this translation unit is part of Google Test's +// implementation. It must come before gtest-internal-inl.h is +// included, or there will be a compiler error. This trick is to +// prevent a user from accidentally including gtest-internal-inl.h in +// his code. +#define GTEST_IMPLEMENTATION_ 1 +#include "src/gtest-internal-inl.h" +#undef GTEST_IMPLEMENTATION_ + +#if GTEST_OS_WINDOWS +# define vsnprintf _vsnprintf +#endif // GTEST_OS_WINDOWS + +namespace testing { + +using internal::CountIf; +using internal::ForEach; +using internal::GetElementOr; +using internal::Shuffle; + +// Constants. + +// A test whose test case name or test name matches this filter is +// disabled and not run. +static const char kDisableTestFilter[] = "DISABLED_*:*/DISABLED_*"; + +// A test case whose name matches this filter is considered a death +// test case and will be run before test cases whose name doesn't +// match this filter. +static const char kDeathTestCaseFilter[] = "*DeathTest:*DeathTest/*"; + +// A test filter that matches everything. +static const char kUniversalFilter[] = "*"; + +// The default output file for XML output. +static const char kDefaultOutputFile[] = "test_detail.xml"; + +// The environment variable name for the test shard index. +static const char kTestShardIndex[] = "GTEST_SHARD_INDEX"; +// The environment variable name for the total number of test shards. +static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; +// The environment variable name for the test shard status file. +static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; + +namespace internal { + +// The text used in failure messages to indicate the start of the +// stack trace. +const char kStackTraceMarker[] = "\nStack trace:\n"; + +// g_help_flag is true iff the --help flag or an equivalent form is +// specified on the command line. +bool g_help_flag = false; + +} // namespace internal + +GTEST_DEFINE_bool_( + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); + +GTEST_DEFINE_bool_( + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); + +GTEST_DEFINE_bool_( + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); + +GTEST_DEFINE_string_( + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to xterm, xterm-color, xterm-256color, linux or cygwin."); + +GTEST_DEFINE_string_( + filter, + internal::StringFromGTestEnv("filter", kUniversalFilter), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); + +GTEST_DEFINE_bool_(list_tests, false, + "List all tests without running them."); + +GTEST_DEFINE_string_( + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); + +GTEST_DEFINE_bool_( + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); + +GTEST_DEFINE_int32_( + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); + +GTEST_DEFINE_int32_( + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); + +GTEST_DEFINE_bool_( + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ " should include internal stack frames when " + "printing test failure stack traces."); + +GTEST_DEFINE_bool_( + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); + +GTEST_DEFINE_int32_( + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); + +GTEST_DEFINE_string_( + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); + +GTEST_DEFINE_bool_( + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); + +namespace internal { + +// Generates a random number from [0, range), using a Linear +// Congruential Generator (LCG). Crashes if 'range' is 0 or greater +// than kMaxRange. +UInt32 Random::Generate(UInt32 range) { + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U*state_ + 12345U) % kMaxRange; + + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; + + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; +} + +// GTestIsInitialized() returns true iff the user has initialized +// Google Test. Useful for catching the user mistake of not initializing +// Google Test before calling RUN_ALL_TESTS(). +// +// A user must call testing::InitGoogleTest() to initialize Google +// Test. g_init_gtest_count is set to the number of times +// InitGoogleTest() has been called. We don't protect this variable +// under a mutex as it is only accessed in the main thread. +int g_init_gtest_count = 0; +static bool GTestIsInitialized() { return g_init_gtest_count != 0; } + +// Iterates over a vector of TestCases, keeping a running sum of the +// results of calling a given int-returning method on each. +// Returns the sum. +static int SumOverTestCaseList(const std::vector<TestCase*>& case_list, + int (TestCase::*method)() const) { + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) { + sum += (case_list[i]->*method)(); + } + return sum; +} + +// Returns true iff the test case passed. +static bool TestCasePassed(const TestCase* test_case) { + return test_case->should_run() && test_case->Passed(); +} + +// Returns true iff the test case failed. +static bool TestCaseFailed(const TestCase* test_case) { + return test_case->should_run() && test_case->Failed(); +} + +// Returns true iff test_case contains at least one test that should +// run. +static bool ShouldRunTestCase(const TestCase* test_case) { + return test_case->should_run(); +} + +// AssertHelper constructor. +AssertHelper::AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) { +} + +AssertHelper::~AssertHelper() { + delete data_; +} + +// Message assignment, for assertion streaming support. +void AssertHelper::operator=(const Message& message) const { + UnitTest::GetInstance()-> + AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl() + ->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT +} + +// Mutex for linked pointers. +GTEST_DEFINE_STATIC_MUTEX_(g_linked_ptr_mutex); + +// Application pathname gotten in InitGoogleTest. +String g_executable_path; + +// Returns the current application's name, removing directory path if that +// is present. +FilePath GetCurrentExecutableName() { + FilePath result; + +#if GTEST_OS_WINDOWS + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); +#else + result.Set(FilePath(g_executable_path)); +#endif // GTEST_OS_WINDOWS + + return result.RemoveDirectoryName(); +} + +// Functions for processing the gtest_output flag. + +// Returns the output format, or "" for normal printed output. +String UnitTestOptions::GetOutputFormat() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? + String(gtest_output_flag) : + String(gtest_output_flag, colon - gtest_output_flag); +} + +// Returns the name of the requested output file, or the default if none +// was explicitly specified. +String UnitTestOptions::GetAbsolutePathToOutputFile() { + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return String(""); + + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return String(internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)).ToString() ); + + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); + + if (!output_name.IsDirectory()) + return output_name.ToString(); + + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.ToString(); +} + +// Returns true iff the wildcard pattern matches the string. The +// first ':' or '\0' character in pattern marks the end of it. +// +// This recursive algorithm isn't very efficient, but is clear and +// works well enough for matching test names, which are short. +bool UnitTestOptions::PatternMatchesString(const char *pattern, + const char *str) { + switch (*pattern) { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } +} + +bool UnitTestOptions::MatchesFilter(const String& name, const char* filter) { + const char *cur_pattern = filter; + for (;;) { + if (PatternMatchesString(cur_pattern, name.c_str())) { + return true; + } + + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); + + // Returns if no more pattern can be found. + if (cur_pattern == NULL) { + return false; + } + + // Skips the pattern separater (the ':' character). + cur_pattern++; + } +} + +// TODO(keithray): move String function implementations to gtest-string.cc. + +// Returns true iff the user-specified filter matches the test case +// name and the test name. +bool UnitTestOptions::FilterMatchesTest(const String &test_case_name, + const String &test_name) { + const String& full_name = String::Format("%s.%s", + test_case_name.c_str(), + test_name.c_str()); + + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + String positive; + String negative; + if (dash == NULL) { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = String(""); + } else { + positive = String(p, dash - p); // Everything up to the dash + negative = String(dash+1); // Everything after the dash + if (positive.empty()) { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } + + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); +} + +#if GTEST_HAS_SEH +// Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the +// given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. +// This function is useful as an __except condition. +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; + + bool should_handle = true; + + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; + + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} +#endif // GTEST_HAS_SEH + +} // namespace internal + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. Intercepts only failures from the current thread. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) { + Init(); +} + +// The c'tor sets this object as the test part result reporter used by +// Google Test. The 'result' parameter specifies where to report the +// results. +ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) { + Init(); +} + +void ScopedFakeTestPartResultReporter::Init() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } else { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } +} + +// The d'tor restores the test part result reporter used by Google Test +// before. +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } else { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } +} + +// Increments the test part result count and remembers the result. +// This method is from the TestPartResultReporterInterface interface. +void ScopedFakeTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + result_->Append(result); +} + +namespace internal { + +// Returns the type ID of ::testing::Test. We should always call this +// instead of GetTypeId< ::testing::Test>() to get the type ID of +// testing::Test. This is to work around a suspected linker bug when +// using Google Test as a framework on Mac OS X. The bug causes +// GetTypeId< ::testing::Test>() to return different values depending +// on whether the call is from the Google Test framework itself or +// from user test code. GetTestTypeId() is guaranteed to always +// return the same value, as it always calls GetTypeId<>() from the +// gtest.cc, which is within the Google Test framework. +TypeId GetTestTypeId() { + return GetTypeId<Test>(); +} + +// The value of GetTestTypeId() as seen from within the Google Test +// library. This is solely for testing GetTestTypeId(). +extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); + +// This predicate-formatter checks that 'results' contains a test part +// failure of the given type and that the failure message contains the +// given substring. +AssertionResult HasOneFailure(const char* /* results_expr */, + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) { + const String expected(type == TestPartResult::kFatalFailure ? + "1 fatal failure" : + "1 non-fatal failure"); + Message msg; + if (results.size() != 1) { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) { + msg << "\n" << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } + + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } + + if (strstr(r.message(), substr.c_str()) == NULL) { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } + + return AssertionSuccess(); +} + +// The constructor of SingleFailureChecker remembers where to look up +// test part results, what type of failure we expect, and what +// substring the failure message should contain. +SingleFailureChecker:: SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} + +// The destructor of SingleFailureChecker verifies that the given +// TestPartResultArray contains exactly one failure that has the given +// type and contains the given substring. If that's not the case, a +// non-fatal failure will be generated. +SingleFailureChecker::~SingleFailureChecker() { + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +} + +DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultGlobalTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); +} + +DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( + UnitTestImpl* unit_test) : unit_test_(unit_test) {} + +void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( + const TestPartResult& result) { + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); +} + +// Returns the global test part result reporter. +TestPartResultReporterInterface* +UnitTestImpl::GetGlobalTestPartResultReporter() { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; +} + +// Sets the global test part result reporter. +void UnitTestImpl::SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter) { + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; +} + +// Returns the test part result reporter for the current thread. +TestPartResultReporterInterface* +UnitTestImpl::GetTestPartResultReporterForCurrentThread() { + return per_thread_test_part_result_reporter_.get(); +} + +// Sets the test part result reporter for the current thread. +void UnitTestImpl::SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter) { + per_thread_test_part_result_reporter_.set(reporter); +} + +// Gets the number of successful test cases. +int UnitTestImpl::successful_test_case_count() const { + return CountIf(test_cases_, TestCasePassed); +} + +// Gets the number of failed test cases. +int UnitTestImpl::failed_test_case_count() const { + return CountIf(test_cases_, TestCaseFailed); +} + +// Gets the number of all test cases. +int UnitTestImpl::total_test_case_count() const { + return static_cast<int>(test_cases_.size()); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTestImpl::test_case_to_run_count() const { + return CountIf(test_cases_, ShouldRunTestCase); +} + +// Gets the number of successful tests. +int UnitTestImpl::successful_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +} + +// Gets the number of failed tests. +int UnitTestImpl::failed_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +} + +// Gets the number of disabled tests. +int UnitTestImpl::disabled_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +} + +// Gets the number of all tests. +int UnitTestImpl::total_test_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +} + +// Gets the number of tests that should run. +int UnitTestImpl::test_to_run_count() const { + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// CurrentOsStackTraceExceptTop(1), Foo() will be included in the +// trace but Bar() and CurrentOsStackTraceExceptTop() won't. +String UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { + (void)skip_count; + return String(""); +} + +// Returns the current time in milliseconds. +TimeInMillis GetTimeInMillis() { +#if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast<TimeInMillis>(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; + + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; +#elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ + __timeb64 now; + +# ifdef _MSC_VER + + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + _ftime64(&now); +# pragma warning(pop) // Restores the warning state. +# else + + _ftime64(&now); + +# endif // _MSC_VER + + return static_cast<TimeInMillis>(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast<TimeInMillis>(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +# error "Don't know how to get the current time on your system." +#endif +} + +// Utilities + +// class String + +// Returns the input enclosed in double quotes if it's not NULL; +// otherwise returns "(null)". For example, "\"Hello\"" is returned +// for input "Hello". +// +// This is useful for printing a C string in the syntax of a literal. +// +// Known issue: escape sequences are not handled yet. +String String::ShowCStringQuoted(const char* c_str) { + return c_str ? String::Format("\"%s\"", c_str) : String("(null)"); +} + +// Copies at most length characters from str into a newly-allocated +// piece of memory of size length+1. The memory is allocated with new[]. +// A terminating null byte is written to the memory, and a pointer to it +// is returned. If str is NULL, NULL is returned. +static char* CloneString(const char* str, size_t length) { + if (str == NULL) { + return NULL; + } else { + char* const clone = new char[length + 1]; + posix::StrNCpy(clone, str, length); + clone[length] = '\0'; + return clone; + } +} + +// Clones a 0-terminated C string, allocating memory using new. The +// caller is responsible for deleting[] the return value. Returns the +// cloned string, or NULL if the input is NULL. +const char * String::CloneCString(const char* c_str) { + return (c_str == NULL) ? + NULL : CloneString(c_str, strlen(c_str)); +} + +#if GTEST_OS_WINDOWS_MOBILE +// Creates a UTF-16 wide string from the given ANSI string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the wide string, or NULL if the +// input is NULL. +LPCWSTR String::AnsiToUtf16(const char* ansi) { + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; +} + +// Creates an ANSI string from the given wide string, allocating +// memory using new. The caller is responsible for deleting the return +// value using delete[]. Returns the ANSI string, or NULL if the +// input is NULL. +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; +} + +#endif // GTEST_OS_WINDOWS_MOBILE + +// Compares two C strings. Returns true iff they have the same content. +// +// Unlike strcmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CStringEquals(const char * lhs, const char * rhs) { + if ( lhs == NULL ) return rhs == NULL; + + if ( rhs == NULL ) return false; + + return strcmp(lhs, rhs) == 0; +} + +#if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +// Converts an array of wide chars to a narrow string using the UTF-8 +// encoding, and streams the result to the given Message object. +static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, + Message* msg) { + // TODO(wan): consider allowing a testing::String object to + // contain '\0'. This will make it behave more like std::string, + // and will allow ToUtf8String() to return the correct encoding + // for '\0' s.t. we can get rid of the conditional here (and in + // several other places). + for (size_t i = 0; i != length; ) { // NOLINT + if (wstr[i] != L'\0') { + *msg << WideStringToUtf8(wstr + i, static_cast<int>(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } else { + *msg << '\0'; + i++; + } + } +} + +#endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING + +} // namespace internal + +#if GTEST_HAS_STD_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::std::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_STD_WSTRING + +#if GTEST_HAS_GLOBAL_WSTRING +// Converts the given wide string to a narrow string using the UTF-8 +// encoding, and streams the result to this Message object. +Message& Message::operator <<(const ::wstring& wstr) { + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; +} +#endif // GTEST_HAS_GLOBAL_WSTRING + +// AssertionResult constructors. +// Used in EXPECT_TRUE/FALSE(assertion_result). +AssertionResult::AssertionResult(const AssertionResult& other) + : success_(other.success_), + message_(other.message_.get() != NULL ? + new ::std::string(*other.message_) : + static_cast< ::std::string*>(NULL)) { +} + +// Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. +AssertionResult AssertionResult::operator!() const { + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; +} + +// Makes a successful assertion result. +AssertionResult AssertionSuccess() { + return AssertionResult(true); +} + +// Makes a failed assertion result. +AssertionResult AssertionFailure() { + return AssertionResult(false); +} + +// Makes a failed assertion result with the given failure message. +// Deprecated; use AssertionFailure() << message. +AssertionResult AssertionFailure(const Message& message) { + return AssertionFailure() << message; +} + +namespace internal { + +// Constructs and returns the message for an equality assertion +// (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. +// +// The first four parameters are the expressions used in the assertion +// and their values, as strings. For example, for ASSERT_EQ(foo, bar) +// where foo is 5 and bar is 6, we have: +// +// expected_expression: "foo" +// actual_expression: "bar" +// expected_value: "5" +// actual_value: "6" +// +// The ignoring_case parameter is true iff the assertion is a +// *_STRCASEEQ*. When it's true, the string " (ignoring case)" will +// be inserted into the message. +AssertionResult EqFailure(const char* expected_expression, + const char* actual_expression, + const String& expected_value, + const String& actual_value, + bool ignoring_case) { + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) { + msg << "\n Actual: " << actual_value; + } + + msg << "\nExpected: " << expected_expression; + if (ignoring_case) { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) { + msg << "\nWhich is: " << expected_value; + } + + return AssertionFailure() << msg; +} + +// Constructs a failure message for Boolean assertions such as EXPECT_TRUE. +String GetBoolAssertionFailureMessage(const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) { + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); +} + +// Helper function for implementing ASSERT_NEAR. +AssertionResult DoubleNearPredFormat(const char* expr1, + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) { + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); + + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; +} + + +// Helper template for implementing FloatLE() and DoubleLE(). +template <typename RawType> +AssertionResult FloatingPointLE(const char* expr1, + const char* expr2, + RawType val1, + RawType val2) { + // Returns success if val1 is less than val2, + if (val1 < val2) { + return AssertionSuccess(); + } + + // or if val1 is almost equal to val2. + const FloatingPoint<RawType> lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) { + return AssertionSuccess(); + } + + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. + + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << val1; + + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits<RawType>::digits10 + 2) + << val2; + + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); +} + +} // namespace internal + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult FloatLE(const char* expr1, const char* expr2, + float val1, float val2) { + return internal::FloatingPointLE<float>(expr1, expr2, val1, val2); +} + +// Asserts that val1 is less than, or almost equal to, val2. Fails +// otherwise. In particular, it fails if either val1 or val2 is NaN. +AssertionResult DoubleLE(const char* expr1, const char* expr2, + double val1, double val2) { + return internal::FloatingPointLE<double>(expr1, expr2, val1, val2); +} + +namespace internal { + +// The helper function for {ASSERT|EXPECT}_EQ with int or enum +// arguments. +AssertionResult CmpHelperEQ(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) { + if (expected == actual) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + +// A macro for implementing the helper functions needed to implement +// ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here +// just to avoid copy-and-paste of similar code. +#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ +AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) {\ + if (val1 op val2) {\ + return AssertionSuccess();\ + } else {\ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2\ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ + << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + }\ +} + +// Implements the helper function for {ASSERT|EXPECT}_NE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(NE, !=) +// Implements the helper function for {ASSERT|EXPECT}_LE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LE, <=) +// Implements the helper function for {ASSERT|EXPECT}_LT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(LT, < ) +// Implements the helper function for {ASSERT|EXPECT}_GE with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GE, >=) +// Implements the helper function for {ASSERT|EXPECT}_GT with int or +// enum arguments. +GTEST_IMPL_CMP_HELPER_(GT, > ) + +#undef GTEST_IMPL_CMP_HELPER_ + +// The helper function for {ASSERT|EXPECT}_STREQ. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + false); +} + +// The helper function for {ASSERT|EXPECT}_STRCASEEQ. +AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, + const char* actual_expression, + const char* expected, + const char* actual) { + if (String::CaseInsensitiveCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowCStringQuoted(expected), + String::ShowCStringQuoted(actual), + true); +} + +// The helper function for {ASSERT|EXPECT}_STRNE. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +// The helper function for {ASSERT|EXPECT}_STRCASENE. +AssertionResult CmpHelperSTRCASENE(const char* s1_expression, + const char* s2_expression, + const char* s1, + const char* s2) { + if (!String::CaseInsensitiveCStringEquals(s1, s2)) { + return AssertionSuccess(); + } else { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } +} + +} // namespace internal + +namespace { + +// Helper functions for implementing IsSubString() and IsNotSubstring(). + +// This group of overloaded functions return true iff needle is a +// substring of haystack. NULL is considered a substring of itself +// only. + +bool IsSubstringPred(const char* needle, const char* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return strstr(haystack, needle) != NULL; +} + +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { + if (needle == NULL || haystack == NULL) + return needle == haystack; + + return wcsstr(haystack, needle) != NULL; +} + +// StringType here can be either ::std::string or ::std::wstring. +template <typename StringType> +bool IsSubstringPred(const StringType& needle, + const StringType& haystack) { + return haystack.find(needle) != StringType::npos; +} + +// This function implements either IsSubstring() or IsNotSubstring(), +// depending on the value of the expected_to_be_substring parameter. +// StringType here can be const char*, const wchar_t*, ::std::string, +// or ::std::wstring. +template <typename StringType> +AssertionResult IsSubstringImpl( + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) { + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); + + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; +} + +} // namespace + +// IsSubstring() and IsNotSubstring() check whether needle is a +// substring of haystack (NULL is considered a substring of itself +// only), and return an appropriate error message when they fail. + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} + +#if GTEST_HAS_STD_WSTRING +AssertionResult IsSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); +} + +AssertionResult IsNotSubstring( + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) { + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); +} +#endif // GTEST_HAS_STD_WSTRING + +namespace internal { + +#if GTEST_OS_WINDOWS + +namespace { + +// Helper function for IsHRESULT{SuccessFailure} predicates +AssertionResult HRESULTFailureHelper(const char* expr, + const char* expected, + long hr) { // NOLINT +# if GTEST_OS_WINDOWS_MOBILE + + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; + +# else + + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; // String::Format can't exceed this length. + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = { '\0' }; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing cr-lf) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) { + error_text[message_length - 1] = '\0'; + } + +# endif // GTEST_OS_WINDOWS_MOBILE + + const String error_hex(String::Format("0x%08X ", hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << error_text << "\n"; +} + +} // namespace + +AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT + if (SUCCEEDED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); +} + +AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT + if (FAILED(hr)) { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); +} + +#endif // GTEST_OS_WINDOWS + +// Utility functions for encoding Unicode text (wide strings) in +// UTF-8. + +// A Unicode code-point can have upto 21 bits, and is encoded in UTF-8 +// like this: +// +// Code-point length Encoding +// 0 - 7 bits 0xxxxxxx +// 8 - 11 bits 110xxxxx 10xxxxxx +// 12 - 16 bits 1110xxxx 10xxxxxx 10xxxxxx +// 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx + +// The maximum code-point a one-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint1 = (static_cast<UInt32>(1) << 7) - 1; + +// The maximum code-point a two-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint2 = (static_cast<UInt32>(1) << (5 + 6)) - 1; + +// The maximum code-point a three-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint3 = (static_cast<UInt32>(1) << (4 + 2*6)) - 1; + +// The maximum code-point a four-byte UTF-8 sequence can represent. +const UInt32 kMaxCodePoint4 = (static_cast<UInt32>(1) << (3 + 3*6)) - 1; + +// Chops off the n lowest bits from a bit pattern. Returns the n +// lowest bits. As a side effect, the original bit pattern will be +// shifted to the right by n bits. +inline UInt32 ChopLowBits(UInt32* bits, int n) { + const UInt32 low_bits = *bits & ((static_cast<UInt32>(1) << n) - 1); + *bits >>= n; + return low_bits; +} + +// Converts a Unicode code point to a narrow string in UTF-8 encoding. +// code_point parameter is of type UInt32 because wchar_t may not be +// wide enough to contain a code point. +// The output buffer str must containt at least 32 characters. +// The function returns the address of the output buffer. +// If the code_point is not a valid Unicode code point +// (i.e. outside of Unicode range U+0 to U+10FFFF) it will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. +char* CodePointToUtf8(UInt32 code_point, char* str) { + if (code_point <= kMaxCodePoint1) { + str[1] = '\0'; + str[0] = static_cast<char>(code_point); // 0xxxxxxx + } else if (code_point <= kMaxCodePoint2) { + str[2] = '\0'; + str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast<char>(0xC0 | code_point); // 110xxxxx + } else if (code_point <= kMaxCodePoint3) { + str[3] = '\0'; + str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast<char>(0xE0 | code_point); // 1110xxxx + } else if (code_point <= kMaxCodePoint4) { + str[4] = '\0'; + str[3] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast<char>(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast<char>(0xF0 | code_point); // 11110xxx + } else { + // The longest string String::Format can produce when invoked + // with these parameters is 28 character long (not including + // the terminating nul character). We are asking for 32 character + // buffer just in case. This is also enough for strncpy to + // null-terminate the destination string. + posix::StrNCpy( + str, String::Format("(Invalid Unicode 0x%X)", code_point).c_str(), 32); + str[31] = '\0'; // Makes sure no change in the format to strncpy leaves + // the result unterminated. + } + return str; +} + +// The following two functions only make sense if the the system +// uses UTF-16 for wide string encoding. All supported systems +// with 16 bit wchar_t (Windows, Cygwin, Symbian OS) do use UTF-16. + +// Determines if the arguments constitute UTF-16 surrogate pair +// and thus should be combined into a single Unicode code point +// using CreateCodePointFromUtf16SurrogatePair. +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +} + +// Creates a Unicode code point from UTF16 surrogate pair. +inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, + wchar_t second) { + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? + (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast<UInt32>(first); +} + +// Converts a wide string to a narrow string in UTF-8 encoding. +// The wide string is assumed to have the following encoding: +// UTF-16 if sizeof(wchar_t) == 2 (on Windows, Cygwin, Symbian OS) +// UTF-32 if sizeof(wchar_t) == 4 (on Linux) +// Parameter str points to a null-terminated wide string. +// Parameter num_chars may additionally limit the number +// of wchar_t characters processed. -1 is used when the entire string +// should be processed. +// If the string contains code points that are not valid Unicode code points +// (i.e. outside of Unicode range U+0 to U+10FFFF) they will be output +// as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding +// and contains invalid UTF-16 surrogate pairs, values in those pairs +// will be encoded as individual Unicode characters from Basic Normal Plane. +String WideStringToUtf8(const wchar_t* str, int num_chars) { + if (num_chars == -1) + num_chars = static_cast<int>(wcslen(str)); + + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) { + UInt32 unicode_code_point; + + if (str[i] == L'\0') { + break; + } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } else { + unicode_code_point = static_cast<UInt32>(str[i]); + } + + char buffer[32]; // CodePointToUtf8 requires a buffer this big. + stream << CodePointToUtf8(unicode_code_point, buffer); + } + return StringStreamToString(&stream); +} + +// Converts a wide C string to a String using the UTF-8 encoding. +// NULL will be converted to "(null)". +String String::ShowWideCString(const wchar_t * wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String(internal::WideStringToUtf8(wide_c_str, -1).c_str()); +} + +// Similar to ShowWideCString(), except that this function encloses +// the converted string in double quotes. +String String::ShowWideCStringQuoted(const wchar_t* wide_c_str) { + if (wide_c_str == NULL) return String("(null)"); + + return String::Format("L\"%s\"", + String::ShowWideCString(wide_c_str).c_str()); +} + +// Compares two wide C strings. Returns true iff they have the same +// content. +// +// Unlike wcscmp(), this function can handle NULL argument(s). A NULL +// C string is considered different to any non-NULL C string, +// including the empty string. +bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + + return wcscmp(lhs, rhs) == 0; +} + +// Helper function for *_STREQ on wide strings. +AssertionResult CmpHelperSTREQ(const char* expected_expression, + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) { + if (String::WideCStringEquals(expected, actual)) { + return AssertionSuccess(); + } + + return EqFailure(expected_expression, + actual_expression, + String::ShowWideCStringQuoted(expected), + String::ShowWideCStringQuoted(actual), + false); +} + +// Helper function for *_STRNE on wide strings. +AssertionResult CmpHelperSTRNE(const char* s1_expression, + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) { + if (!String::WideCStringEquals(s1, s2)) { + return AssertionSuccess(); + } + + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << String::ShowWideCStringQuoted(s1) + << " vs " << String::ShowWideCStringQuoted(s2); +} + +// Compares two C strings, ignoring case. Returns true iff they have +// the same content. +// +// Unlike strcasecmp(), this function can handle NULL argument(s). A +// NULL C string is considered different to any non-NULL C string, +// including the empty string. +bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; +} + + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. +bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs) { + if (lhs == NULL) return rhs == NULL; + + if (rhs == NULL) return false; + +#if GTEST_OS_WINDOWS + return _wcsicmp(lhs, rhs) == 0; +#elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID + return wcscasecmp(lhs, rhs) == 0; +#else + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; +#endif // OS selector +} + +// Compares this with another String. +// Returns < 0 if this is less than rhs, 0 if this is equal to rhs, or > 0 +// if this is greater than rhs. +int String::Compare(const String & rhs) const { + const char* const lhs_c_str = c_str(); + const char* const rhs_c_str = rhs.c_str(); + + if (lhs_c_str == NULL) { + return rhs_c_str == NULL ? 0 : -1; // NULL < anything except NULL + } else if (rhs_c_str == NULL) { + return 1; + } + + const size_t shorter_str_len = + length() <= rhs.length() ? length() : rhs.length(); + for (size_t i = 0; i != shorter_str_len; i++) { + if (lhs_c_str[i] < rhs_c_str[i]) { + return -1; + } else if (lhs_c_str[i] > rhs_c_str[i]) { + return 1; + } + } + return (length() < rhs.length()) ? -1 : + (length() > rhs.length()) ? 1 : 0; +} + +// Returns true iff this String ends with the given suffix. *Any* +// String is considered to end with a NULL or empty suffix. +bool String::EndsWith(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Returns true iff this String ends with the given suffix, ignoring case. +// Any String is considered to end with a NULL or empty suffix. +bool String::EndsWithCaseInsensitive(const char* suffix) const { + if (suffix == NULL || CStringEquals(suffix, "")) return true; + + if (c_str() == NULL) return false; + + const size_t this_len = strlen(c_str()); + const size_t suffix_len = strlen(suffix); + return (this_len >= suffix_len) && + CaseInsensitiveCStringEquals(c_str() + this_len - suffix_len, suffix); +} + +// Formats a list of arguments to a String, using the same format +// spec string as for printf. +// +// We do not use the StringPrintf class as it is not universally +// available. +// +// The result is limited to 4096 characters (including the tailing 0). +// If 4096 characters are not enough to format the input, or if +// there's an error, "<formatting error or buffer exceeded>" is +// returned. +String String::Format(const char * format, ...) { + va_list args; + va_start(args, format); + + char buffer[4096]; + const int kBufferSize = sizeof(buffer)/sizeof(buffer[0]); + + // MSVC 8 deprecates vsnprintf(), so we want to suppress warning + // 4996 (deprecated function) there. +#ifdef _MSC_VER // We are using MSVC. +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4996) // Temporarily disables warning 4996. + + const int size = vsnprintf(buffer, kBufferSize, format, args); + +# pragma warning(pop) // Restores the warning state. +#else // We are not using MSVC. + const int size = vsnprintf(buffer, kBufferSize, format, args); +#endif // _MSC_VER + va_end(args); + + // vsnprintf()'s behavior is not portable. When the buffer is not + // big enough, it returns a negative value in MSVC, and returns the + // needed buffer size on Linux. When there is an output error, it + // always returns a negative value. For simplicity, we lump the two + // error cases together. + if (size < 0 || size >= kBufferSize) { + return String("<formatting error or buffer exceeded>"); + } else { + return String(buffer, size); + } +} + +// Converts the buffer in a stringstream to a String, converting NUL +// bytes to "\\0" along the way. +String StringStreamToString(::std::stringstream* ss) { + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); + + // We need to use a helper stringstream to do this transformation + // because String doesn't support push_back(). + ::std::stringstream helper; + for (const char* ch = start; ch != end; ++ch) { + if (*ch == '\0') { + helper << "\\0"; // Replaces NUL with "\\0"; + } else { + helper.put(*ch); + } + } + + return String(helper.str().c_str()); +} + +// Appends the user-supplied message to the Google-Test-generated message. +String AppendUserMessage(const String& gtest_msg, + const Message& user_msg) { + // Appends the user message if it's non-empty. + const String user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) { + return gtest_msg; + } + + Message msg; + msg << gtest_msg << "\n" << user_msg_string; + + return msg.GetString(); +} + +} // namespace internal + +// class TestResult + +// Creates an empty TestResult. +TestResult::TestResult() + : death_test_count_(0), + elapsed_time_(0) { +} + +// D'tor. +TestResult::~TestResult() { +} + +// Returns the i-th test part result among all the results. i can +// range from 0 to total_part_count() - 1. If i is not in that range, +// aborts the program. +const TestPartResult& TestResult::GetTestPartResult(int i) const { + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); +} + +// Returns the i-th test property. i can range from 0 to +// test_property_count() - 1. If i is not in that range, aborts the +// program. +const TestProperty& TestResult::GetTestProperty(int i) const { + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); +} + +// Clears the test part results. +void TestResult::ClearTestPartResults() { + test_part_results_.clear(); +} + +// Adds a test part result to the list. +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { + test_part_results_.push_back(test_part_result); +} + +// Adds a test property to the list. If a property with the same key as the +// supplied property is already represented, the value of this test_property +// replaces the old value for that key. +void TestResult::RecordProperty(const TestProperty& test_property) { + if (!ValidateTestProperty(test_property)) { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector<TestProperty>::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); +} + +// Adds a failure if the key is a reserved attribute of Google Test +// testcase tags. Returns true if the property is valid. +bool TestResult::ValidateTestProperty(const TestProperty& test_property) { + internal::String key(test_property.key()); + if (key == "name" || key == "status" || key == "time" || key == "classname") { + ADD_FAILURE() + << "Reserved key used in RecordProperty(): " + << key + << " ('name', 'status', 'time', and 'classname' are reserved by " + << GTEST_NAME_ << ")"; + return false; + } + return true; +} + +// Clears the object. +void TestResult::Clear() { + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; +} + +// Returns true iff the test failed. +bool TestResult::Failed() const { + for (int i = 0; i < total_part_count(); ++i) { + if (GetTestPartResult(i).failed()) + return true; + } + return false; +} + +// Returns true iff the test part fatally failed. +static bool TestPartFatallyFailed(const TestPartResult& result) { + return result.fatally_failed(); +} + +// Returns true iff the test fatally failed. +bool TestResult::HasFatalFailure() const { + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +} + +// Returns true iff the test part non-fatally failed. +static bool TestPartNonfatallyFailed(const TestPartResult& result) { + return result.nonfatally_failed(); +} + +// Returns true iff the test has a non-fatal failure. +bool TestResult::HasNonfatalFailure() const { + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +} + +// Gets the number of all test parts. This is the sum of the number +// of successful test parts and the number of failed test parts. +int TestResult::total_part_count() const { + return static_cast<int>(test_part_results_.size()); +} + +// Returns the number of the test properties. +int TestResult::test_property_count() const { + return static_cast<int>(test_properties_.size()); +} + +// class Test + +// Creates a Test object. + +// The c'tor saves the values of all Google Test flags. +Test::Test() + : gtest_flag_saver_(new internal::GTestFlagSaver) { +} + +// The d'tor restores the values of all Google Test flags. +Test::~Test() { + delete gtest_flag_saver_; +} + +// Sets up the test fixture. +// +// A sub-class may override this. +void Test::SetUp() { +} + +// Tears down the test fixture. +// +// A sub-class may override this. +void Test::TearDown() { +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, const char* value) { + UnitTest::GetInstance()->RecordPropertyForCurrentTest(key, value); +} + +// Allows user supplied key value pairs to be recorded for later output. +void Test::RecordProperty(const char* key, int value) { + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); +} + +namespace internal { + +void ReportFailureInUnknownLocation(TestPartResult::Type result_type, + const String& message) { + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + String()); // No stack trace, either. +} + +} // namespace internal + +// Google Test requires all tests in the same test case to use the same test +// fixture class. This function checks if the current test has the +// same fixture class as the first test in the current test case. If +// yes, it returns true; otherwise it generates a Google Test failure and +// returns false. +bool Test::HasSameFixtureClass() { + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); + + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); + + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); + + if (this_fixture_id != first_fixture_id) { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + + if (first_is_TEST || this_is_TEST) { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. + + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; + + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } else { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } + + return true; +} + +#if GTEST_HAS_SEH + +// Adds an "exception thrown" fatal failure to the current test. This +// function returns its result via an output parameter pointer because VC++ +// prohibits creation of objects with destructors on stack in functions +// using __try (see error C2712). +static internal::String* FormatSehExceptionMessage(DWORD exception_code, + const char* location) { + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << + exception_code << std::setbase(10) << " thrown in " << location << "."; + + return new internal::String(message.GetString()); +} + +#endif // GTEST_HAS_SEH + +#if GTEST_HAS_EXCEPTIONS + +// Adds an "exception thrown" fatal failure to the current test. +static internal::String FormatCxxExceptionMessage(const char* description, + const char* location) { + Message message; + if (description != NULL) { + message << "C++ exception with description \"" << description << "\""; + } else { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; + + return message.GetString(); +} + +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result); + +// A failed Google Test assertion will throw an exception of this type when +// GTEST_FLAG(throw_on_failure) is true (if exceptions are enabled). We +// derive it from std::runtime_error, which is for errors presumably +// detectable only at run time. Since std::runtime_error inherits from +// std::exception, many testing frameworks know how to extract and print the +// message inside it. +class GoogleTestFailureException : public ::std::runtime_error { + public: + explicit GoogleTestFailureException(const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} +}; +#endif // GTEST_HAS_EXCEPTIONS + +namespace internal { +// We put these helper functions in the internal namespace as IBM's xlC +// compiler rejects the code if they were declared static. + +// Runs the given method and handles SEH exceptions it throws, when +// SEH is supported; returns the 0-value for type Result in case of an +// SEH exception. (Microsoft compilers cannot handle SEH and C++ +// exceptions in the same function. Therefore, we provide a separate +// wrapper function for handling SEH exceptions.) +template <class T, typename Result> +Result HandleSehExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { +#if GTEST_HAS_SEH + __try { + return (object->*method)(); + } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + internal::String* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast<Result>(0); + } +#else + (void)location; + return (object->*method)(); +#endif // GTEST_HAS_SEH +} + +// Runs the given method and catches and reports C++ and/or SEH-style +// exceptions, if they are supported; returns the 0-value for type +// Result in case of an SEH exception. +template <class T, typename Result> +Result HandleExceptionsInMethodIfSupported( + T* object, Result (T::*method)(), const char* location) { + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) { +#if GTEST_HAS_EXCEPTIONS + try { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } catch (const GoogleTestFailureException&) { // NOLINT + // This exception doesn't originate in code under test. It makes no + // sense to report it as a test failure. + throw; + } catch (const std::exception& e) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } catch (...) { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast<Result>(0); +#else + return HandleSehExceptionsInMethodIfSupported(object, method, location); +#endif // GTEST_HAS_EXCEPTIONS + } else { + return (object->*method)(); + } +} + +} // namespace internal + +// Runs the test and updates the test result. +void Test::Run() { + if (!HasSameFixtureClass()) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } + + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); +} + +// Returns true iff the current test has a fatal failure. +bool Test::HasFatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +} + +// Returns true iff the current test has a non-fatal failure. +bool Test::HasNonfatalFailure() { + return internal::GetUnitTestImpl()->current_test_result()-> + HasNonfatalFailure(); +} + +// class TestInfo + +// Constructs a TestInfo object. It assumes ownership of the test factory +// object. +// TODO(vladl@google.com): Make a_test_case_name and a_name const string&'s +// to signify they cannot be NULLs. +TestInfo::TestInfo(const char* a_test_case_name, + const char* a_name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} + +// Destructs a TestInfo object. +TestInfo::~TestInfo() { delete factory_; } + +namespace internal { + +// Creates a new TestInfo object and registers it with Google Test; +// returns the created object. +// +// Arguments: +// +// test_case_name: name of the test case +// name: name of the test +// type_param: the name of the test's type parameter, or NULL if +// this is not a typed or a type-parameterized test. +// value_param: text representation of the test's value parameter, +// or NULL if this is not a value-parameterized test. +// fixture_class_id: ID of the test fixture class +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +// factory: pointer to the factory that creates a test object. +// The newly created TestInfo instance will assume +// ownership of the factory object. +TestInfo* MakeAndRegisterTestInfo( + const char* test_case_name, const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) { + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; +} + +#if GTEST_HAS_PARAM_TEST +void ReportInvalidTestCaseType(const char* test_case_name, + const char* file, int line) { + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; + + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); +} +#endif // GTEST_HAS_PARAM_TEST + +} // namespace internal + +namespace { + +// A predicate that checks the test name of a TestInfo against a known +// value. +// +// This is used for implementation of the TestCase class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestNameIs is copyable. +class TestNameIs { + public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} + + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo * test_info) const { + return test_info && internal::String(test_info->name()).Compare(name_) == 0; + } + + private: + internal::String name_; +}; + +} // namespace + +namespace internal { + +// This method expands all parameterized tests registered with macros TEST_P +// and INSTANTIATE_TEST_CASE_P into regular tests and registers those. +// This will be done just once during the program runtime. +void UnitTestImpl::RegisterParameterizedTests() { +#if GTEST_HAS_PARAM_TEST + if (!parameterized_tests_registered_) { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } +#endif +} + +} // namespace internal + +// Creates the test object, runs it, records its result, and then +// deletes it. +void TestInfo::Run() { + if (!should_run_) return; + + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); + + const TimeInMillis start = internal::GetTimeInMillis(); + + impl->os_stack_trace_getter()->UponLeavingGTest(); + + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); + + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } + + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); + + result_.set_elapsed_time(internal::GetTimeInMillis() - start); + + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); + + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); +} + +// class TestCase + +// Gets the number of successful tests in this test case. +int TestCase::successful_test_count() const { + return CountIf(test_info_list_, TestPassed); +} + +// Gets the number of failed tests in this test case. +int TestCase::failed_test_count() const { + return CountIf(test_info_list_, TestFailed); +} + +int TestCase::disabled_test_count() const { + return CountIf(test_info_list_, TestDisabled); +} + +// Get the number of tests in this test case that should run. +int TestCase::test_to_run_count() const { + return CountIf(test_info_list_, ShouldRunTest); +} + +// Gets the number of all tests. +int TestCase::total_test_count() const { + return static_cast<int>(test_info_list_.size()); +} + +// Creates a TestCase with the given name. +// +// Arguments: +// +// name: name of the test case +// a_type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase::TestCase(const char* a_name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) { +} + +// Destructor of TestCase. +TestCase::~TestCase() { + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete<TestInfo>); +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +const TestInfo* TestCase::GetTestInfo(int i) const { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Returns the i-th test among all the tests. i can range from 0 to +// total_test_count() - 1. If i is not in that range, returns NULL. +TestInfo* TestCase::GetMutableTestInfo(int i) { + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; +} + +// Adds a test to this test case. Will delete the test upon +// destruction of the TestCase object. +void TestCase::AddTestInfo(TestInfo * test_info) { + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast<int>(test_indices_.size())); +} + +// Runs every test in this TestCase. +void TestCase::Run() { + if (!should_run_) return; + + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); + + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; + + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); +} + +// Clears the results of all tests in this test case. +void TestCase::ClearResult() { + ForEach(test_info_list_, TestInfo::ClearTestResult); +} + +// Shuffles the tests in this test case. +void TestCase::ShuffleTests(internal::Random* random) { + Shuffle(random, &test_indices_); +} + +// Restores the test order to before the first shuffle. +void TestCase::UnshuffleTests() { + for (size_t i = 0; i < test_indices_.size(); i++) { + test_indices_[i] = static_cast<int>(i); + } +} + +// Formats a countable noun. Depending on its quantity, either the +// singular form or the plural form is used. e.g. +// +// FormatCountableNoun(1, "formula", "formuli") returns "1 formula". +// FormatCountableNoun(5, "book", "books") returns "5 books". +static internal::String FormatCountableNoun(int count, + const char * singular_form, + const char * plural_form) { + return internal::String::Format("%d %s", count, + count == 1 ? singular_form : plural_form); +} + +// Formats the count of tests. +static internal::String FormatTestCount(int test_count) { + return FormatCountableNoun(test_count, "test", "tests"); +} + +// Formats the count of test cases. +static internal::String FormatTestCaseCount(int test_case_count) { + return FormatCountableNoun(test_case_count, "test case", "test cases"); +} + +// Converts a TestPartResult::Type enum to human-friendly string +// representation. Both kNonFatalFailure and kFatalFailure are translated +// to "Failure", as the user usually doesn't care about the difference +// between the two when viewing the test result. +static const char * TestPartResultTypeToString(TestPartResult::Type type) { + switch (type) { + case TestPartResult::kSuccess: + return "Success"; + + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: +#ifdef _MSC_VER + return "error: "; +#else + return "Failure\n"; +#endif + default: + return "Unknown result type"; + } +} + +// Prints a TestPartResult to a String. +static internal::String PrintTestPartResultToString( + const TestPartResult& test_part_result) { + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()).GetString(); +} + +// Prints a TestPartResult. +static void PrintTestPartResult(const TestPartResult& test_part_result) { + const internal::String& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); +#endif +} + +// class PrettyUnitTestResultPrinter + +namespace internal { + +enum GTestColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GTestColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. COLOR_DEFAULT is +// an invalid input. +const char* GetAnsiColorCode(GTestColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + default: return NULL; + }; +} + +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + +// Returns true iff Google Test should use colors in the output. +bool ShouldUseColor(bool stdout_is_tty) { + const char* const gtest_color = GTEST_FLAG(color).c_str(); + + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { +#if GTEST_OS_WINDOWS + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; +#endif // GTEST_OS_WINDOWS + } + + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. +} + +// Helpers for printing colored strings to stdout. Note that on Windows, we +// cannot simply emit special characters and have the terminal change colors. +// This routine must actually emit the characters rather than return a string +// that would be colored when printed, as can be done on Linux. +void ColoredPrintf(GTestColor color, const char* fmt, ...) { + va_list args; + va_start(args, fmt); + +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + const bool use_color = false; +#else + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); +#endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + + if (!use_color) { + vprintf(fmt, args); + va_end(args); + return; + } + +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); + + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); +#else + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. +#endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE + va_end(args); +} + +void PrintFullTestCommentIfPresent(const TestInfo& test_info) { + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); + + if (type_param != NULL || value_param != NULL) { + printf(", where "); + if (type_param != NULL) { + printf("TypeParam = %s", type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) { + printf("GetParam() = %s", value_param); + } + } +} + +// This class implements the TestEventListener interface. +// +// Class PrettyUnitTestResultPrinter is copyable. +class PrettyUnitTestResultPrinter : public TestEventListener { + public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char * test_case, const char * test) { + printf("%s.%s", test_case, test); + } + + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + + private: + static void PrintFailedTests(const UnitTest& unit_test); + + internal::String test_case_name_; +}; + + // Fired before each iteration of tests starts. +void PrettyUnitTestResultPrinter::OnTestIterationStart( + const UnitTest& unit_test, int iteration) { + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + + const char* const filter = GTEST_FLAG(filter).c_str(); + + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!internal::String::CStringEquals(filter, kUniversalFilter)) { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } + + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast<int>(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } + + if (GTEST_FLAG(shuffle)) { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } + + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case_name_.c_str()); + if (test_case.type_param() == NULL) { + printf("\n"); + } else { + printf(", where TypeParam = %s\n", test_case.type_param()); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_case_name_.c_str(), test_info.name()); + printf("\n"); + fflush(stdout); +} + +// Called after an assertion failure. +void PrettyUnitTestResultPrinter::OnTestPartResult( + const TestPartResult& result) { + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; + + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { + if (test_info.result()->Passed()) { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } else { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_case_name_.c_str(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); + + if (GTEST_FLAG(print_time)) { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()).c_str()); + } else { + printf("\n"); + } + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { + if (!GTEST_FLAG(print_time)) return; + + test_case_name_ = test_case.name(); + const internal::String counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case_name_.c_str(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); +} + +void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( + const UnitTest& /*unit_test*/) { + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); +} + +// Internal helper for printing the list of failed tests. +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) { + return; + } + + for (int i = 0; i < unit_test.total_test_case_count(); ++i) { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } +} + +void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } + + int num_disabled = unit_test.disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { + if (!num_failures) { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); +} + +// End PrettyUnitTestResultPrinter + +// class TestEventRepeater +// +// This class forwards events to other event listeners. +class TestEventRepeater : public TestEventListener { + public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener *listener); + TestEventListener* Release(TestEventListener* listener); + + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); + + private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector<TestEventListener*> listeners_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); +}; + +TestEventRepeater::~TestEventRepeater() { + ForEach(listeners_, Delete<TestEventListener>); +} + +void TestEventRepeater::Append(TestEventListener *listener) { + listeners_.push_back(listener); +} + +// TODO(vladl@google.com): Factor the search functionality into Vector::Find. +TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { + for (size_t i = 0; i < listeners_.size(); ++i) { + if (listeners_[i] == listener) { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } + + return NULL; +} + +// Since most methods are very similar, use macros to reduce boilerplate. +// This defines a member that forwards the call to all listeners. +#define GTEST_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (size_t i = 0; i < listeners_.size(); i++) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} +// This defines a member that forwards the call to all listeners in reverse +// order. +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ +void TestEventRepeater::Name(const Type& parameter) { \ + if (forwarding_enabled_) { \ + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { \ + listeners_[i]->Name(parameter); \ + } \ + } \ +} + +GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) +GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) +GTEST_REPEATER_METHOD_(OnTestCaseStart, TestCase) +GTEST_REPEATER_METHOD_(OnTestStart, TestInfo) +GTEST_REPEATER_METHOD_(OnTestPartResult, TestPartResult) +GTEST_REPEATER_METHOD_(OnEnvironmentsTearDownStart, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsSetUpEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnEnvironmentsTearDownEnd, UnitTest) +GTEST_REVERSE_REPEATER_METHOD_(OnTestEnd, TestInfo) +GTEST_REVERSE_REPEATER_METHOD_(OnTestCaseEnd, TestCase) +GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) + +#undef GTEST_REPEATER_METHOD_ +#undef GTEST_REVERSE_REPEATER_METHOD_ + +void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (size_t i = 0; i < listeners_.size(); i++) { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } +} + +void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, + int iteration) { + if (forwarding_enabled_) { + for (int i = static_cast<int>(listeners_.size()) - 1; i >= 0; i--) { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } +} + +// End TestEventRepeater + +// This class generates an XML output file. +class XmlUnitTestResultPrinter : public EmptyTestEventListener { + public: + explicit XmlUnitTestResultPrinter(const char* output_file); + + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + + private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) { + return c == 0x9 || c == 0xA || c == 0xD; + } + + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) { + return IsNormalizableWhitespace(c) || c >= 0x20; + } + + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static String EscapeXml(const char* str, bool is_attribute); + + // Returns the given string with all characters invalid in XML removed. + static string RemoveInvalidXmlCharacters(const string& str); + + // Convenience wrapper around EscapeXml when str is an attribute value. + static String EscapeXmlAttribute(const char* str) { + return EscapeXml(str, true); + } + + // Convenience wrapper around EscapeXml when str is not an attribute value. + static String EscapeXmlText(const char* str) { return EscapeXml(str, false); } + + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); + + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(FILE* out, const TestCase& test_case); + + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(FILE* out, const UnitTest& unit_test); + + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the String is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static String TestPropertiesAsXmlAttributes(const TestResult& result); + + // The output file. + const String output_file_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); +}; + +// Creates a new XmlUnitTestResultPrinter. +XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) + : output_file_(output_file) { + if (output_file_.c_str() == NULL || output_file_.empty()) { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } +} + +// Called after the unit test ends. +void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, + int /*iteration*/) { + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); + + if (output_dir.CreateDirectoriesRecursively()) { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + PrintXmlUnitTest(xmlout, unit_test); + fclose(xmlout); +} + +// Returns an XML-escaped copy of the input string str. If is_attribute +// is true, the text is meant to appear as an attribute value, and +// normalizable whitespace is preserved by replacing it with character +// references. +// +// Invalid XML characters in str, if any, are stripped from the output. +// It is expected that most, if not all, of the text processed by this +// module will consist of ordinary English text. +// If this module is ever modified to produce version 1.1 XML output, +// most invalid characters can be retained using character references. +// TODO(wan): It might be nice to have a minimally invasive, human-readable +// escaping scheme for invalid characters, rather than dropping them. +String XmlUnitTestResultPrinter::EscapeXml(const char* str, bool is_attribute) { + Message m; + + if (str != NULL) { + for (const char* src = str; *src; ++src) { + switch (*src) { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(*src)) { + if (is_attribute && IsNormalizableWhitespace(*src)) + m << String::Format("&#x%02X;", unsigned(*src)); + else + m << *src; + } + break; + } + } + } + + return m.GetString(); +} + +// Returns the given string with all characters invalid in XML removed. +// Currently invalid characters are dropped from the string. An +// alternative is to replace them with certain characters such as . or ?. +string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters(const string& str) { + string output; + output.reserve(str.size()); + for (string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); + + return output; +} + +// The following routines generate an XML representation of a UnitTest +// object. +// +// This is how Google Test concepts map to the DTD: +// +// <testsuites name="AllTests"> <-- corresponds to a UnitTest object +// <testsuite name="testcase-name"> <-- corresponds to a TestCase object +// <testcase name="test-name"> <-- corresponds to a TestInfo object +// <failure message="...">...</failure> +// <failure message="...">...</failure> +// <failure message="...">...</failure> +// <-- individual assertion failures +// </testcase> +// </testsuite> +// </testsuites> + +// Formats the given time in milliseconds as seconds. +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { + ::std::stringstream ss; + ss << ms/1000.0; + return ss.str(); +} + +// Streams an XML CDATA section, escaping invalid CDATA sequences as needed. +void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, + const char* data) { + const char* segment = data; + *stream << "<![CDATA["; + for (;;) { + const char* const next_segment = strstr(segment, "]]>"); + if (next_segment != NULL) { + stream->write( + segment, static_cast<std::streamsize>(next_segment - segment)); + *stream << "]]>]]><![CDATA["; + segment = next_segment + strlen("]]>"); + } else { + *stream << segment; + break; + } + } + *stream << "]]>"; +} + +// Prints an XML representation of a TestInfo object. +// TODO(wan): There is also value in printing properties with the plain printer. +void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info) { + const TestResult& result = *test_info.result(); + *stream << " <testcase name=\"" + << EscapeXmlAttribute(test_info.name()).c_str() << "\""; + + if (test_info.value_param() != NULL) { + *stream << " value_param=\"" << EscapeXmlAttribute(test_info.value_param()) + << "\""; + } + if (test_info.type_param() != NULL) { + *stream << " type_param=\"" << EscapeXmlAttribute(test_info.type_param()) + << "\""; + } + + *stream << " status=\"" + << (test_info.should_run() ? "run" : "notrun") + << "\" time=\"" + << FormatTimeInMillisAsSeconds(result.elapsed_time()) + << "\" classname=\"" << EscapeXmlAttribute(test_case_name).c_str() + << "\"" << TestPropertiesAsXmlAttributes(result).c_str(); + + int failures = 0; + for (int i = 0; i < result.total_part_count(); ++i) { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.failed()) { + if (++failures == 1) + *stream << ">\n"; + *stream << " <failure message=\"" + << EscapeXmlAttribute(part.summary()).c_str() + << "\" type=\"\">"; + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string message = location + "\n" + part.message(); + OutputXmlCDataSection(stream, + RemoveInvalidXmlCharacters(message).c_str()); + *stream << "</failure>\n"; + } + } + + if (failures == 0) + *stream << " />\n"; + else + *stream << " </testcase>\n"; +} + +// Prints an XML representation of a TestCase object +void XmlUnitTestResultPrinter::PrintXmlTestCase(FILE* out, + const TestCase& test_case) { + fprintf(out, + " <testsuite name=\"%s\" tests=\"%d\" failures=\"%d\" " + "disabled=\"%d\" ", + EscapeXmlAttribute(test_case.name()).c_str(), + test_case.total_test_count(), + test_case.failed_test_count(), + test_case.disabled_test_count()); + fprintf(out, + "errors=\"0\" time=\"%s\">\n", + FormatTimeInMillisAsSeconds(test_case.elapsed_time()).c_str()); + for (int i = 0; i < test_case.total_test_count(); ++i) { + ::std::stringstream stream; + OutputXmlTestInfo(&stream, test_case.name(), *test_case.GetTestInfo(i)); + fprintf(out, "%s", StringStreamToString(&stream).c_str()); + } + fprintf(out, " </testsuite>\n"); +} + +// Prints an XML summary of unit_test to output stream out. +void XmlUnitTestResultPrinter::PrintXmlUnitTest(FILE* out, + const UnitTest& unit_test) { + fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); + fprintf(out, + "<testsuites tests=\"%d\" failures=\"%d\" disabled=\"%d\" " + "errors=\"0\" time=\"%s\" ", + unit_test.total_test_count(), + unit_test.failed_test_count(), + unit_test.disabled_test_count(), + FormatTimeInMillisAsSeconds(unit_test.elapsed_time()).c_str()); + if (GTEST_FLAG(shuffle)) { + fprintf(out, "random_seed=\"%d\" ", unit_test.random_seed()); + } + fprintf(out, "name=\"AllTests\">\n"); + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + PrintXmlTestCase(out, *unit_test.GetTestCase(i)); + fprintf(out, "</testsuites>\n"); +} + +// Produces a string representing the test properties in a result as space +// delimited XML attributes based on the property key="value" pairs. +String XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( + const TestResult& result) { + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); +} + +// End XmlUnitTestResultPrinter + +#if GTEST_CAN_STREAM_RESULTS_ + +// Streams test results to the given port on the given host machine. +class StreamingListener : public EmptyTestEventListener { + public: + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); + + StreamingListener(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) { + MakeConnection(); + Send("gtest_streaming_protocol_version=1.0\n"); + } + + virtual ~StreamingListener() { + if (sockfd_ != -1) + CloseConnection(); + } + + void OnTestProgramStart(const UnitTest& /* unit_test */) { + Send("event=TestProgramStart\n"); + } + + void OnTestProgramEnd(const UnitTest& unit_test) { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + Send(String::Format("event=TestProgramEnd&passed=%d\n", + unit_test.Passed())); + + // Notify the streaming server to stop. + CloseConnection(); + } + + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { + Send(String::Format("event=TestIterationStart&iteration=%d\n", + iteration)); + } + + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { + Send(String::Format("event=TestIterationEnd&passed=%d&elapsed_time=%sms\n", + unit_test.Passed(), + StreamableToString(unit_test.elapsed_time()).c_str())); + } + + void OnTestCaseStart(const TestCase& test_case) { + Send(String::Format("event=TestCaseStart&name=%s\n", test_case.name())); + } + + void OnTestCaseEnd(const TestCase& test_case) { + Send(String::Format("event=TestCaseEnd&passed=%d&elapsed_time=%sms\n", + test_case.Passed(), + StreamableToString(test_case.elapsed_time()).c_str())); + } + + void OnTestStart(const TestInfo& test_info) { + Send(String::Format("event=TestStart&name=%s\n", test_info.name())); + } + + void OnTestEnd(const TestInfo& test_info) { + Send(String::Format( + "event=TestEnd&passed=%d&elapsed_time=%sms\n", + (test_info.result())->Passed(), + StreamableToString((test_info.result())->elapsed_time()).c_str())); + } + + void OnTestPartResult(const TestPartResult& test_part_result) { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + Send(String::Format("event=TestPartResult&file=%s&line=%d&message=", + UrlEncode(file_name).c_str(), + test_part_result.line_number())); + Send(UrlEncode(test_part_result.message()) + "\n"); + } + + private: + // Creates a client socket and connects to the server. + void MakeConnection(); + + // Closes the socket. + void CloseConnection() { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; + + close(sockfd_); + sockfd_ = -1; + } + + // Sends a string to the socket. + void Send(const string& message) { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; + + const int len = static_cast<int>(message.length()); + if (write(sockfd_, message.c_str(), len) != len) { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } + + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); +}; // class StreamingListener + +// Checks if str contains '=', '&', '%' or '\n' characters. If yes, +// replaces them by "%xx" where xx is their hexadecimal value. For +// example, replaces "=" with "%3D". This algorithm is O(strlen(str)) +// in both time and space -- important as the input str may contain an +// arbitrarily long test failure message and stack trace. +string StreamingListener::UrlEncode(const char* str) { + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) { + switch (ch) { + case '%': + case '=': + case '&': + case '\n': + result.append(String::Format("%%%02x", static_cast<unsigned char>(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; +} + +void StreamingListener::MakeConnection() { + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; + + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } + + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { + close(sockfd_); + sockfd_ = -1; + } + } + } + + freeaddrinfo(servinfo); // all done with this structure + + if (sockfd_ == -1) { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } +} + +// End of class Streaming Listener +#endif // GTEST_CAN_STREAM_RESULTS__ + +// Class ScopedTrace + +// Pushes the given source file location and message onto a per-thread +// trace stack maintained by Google Test. +// L < UnitTest::mutex_ +ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) { + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); + + UnitTest::GetInstance()->PushGTestTrace(trace); +} + +// Pops the info pushed by the c'tor. +// L < UnitTest::mutex_ +ScopedTrace::~ScopedTrace() { + UnitTest::GetInstance()->PopGTestTrace(); +} + + +// class OsStackTraceGetter + +// Returns the current OS stack trace as a String. Parameters: +// +// max_depth - the maximum number of stack frames to be included +// in the trace. +// skip_count - the number of top frames to be skipped; doesn't count +// against max_depth. +// +// L < mutex_ +// We use "L < mutex_" to denote that the function may acquire mutex_. +String OsStackTraceGetter::CurrentStackTrace(int, int) { + return String(""); +} + +// L < mutex_ +void OsStackTraceGetter::UponLeavingGTest() { +} + +const char* const +OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +} // namespace internal + +// class TestEventListeners + +TestEventListeners::TestEventListeners() + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) { +} + +TestEventListeners::~TestEventListeners() { delete repeater_; } + +// Returns the standard listener responsible for the default console +// output. Can be removed from the listeners list to shut down default +// console output. Note that removing this object from the listener list +// with Release transfers its ownership to the user. +void TestEventListeners::Append(TestEventListener* listener) { + repeater_->Append(listener); +} + +// Removes the given event listener from the list and returns it. It then +// becomes the caller's responsibility to delete the listener. Returns +// NULL if the listener is not found in the list. +TestEventListener* TestEventListeners::Release(TestEventListener* listener) { + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); +} + +// Returns repeater that broadcasts the TestEventListener events to all +// subscribers. +TestEventListener* TestEventListeners::repeater() { return repeater_; } + +// Sets the default_result_printer attribute to the provided listener. +// The listener is also added to the listener list and previous +// default_result_printer is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { + if (default_result_printer_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Sets the default_xml_generator attribute to the provided listener. The +// listener is also added to the listener list and previous +// default_xml_generator is removed from it and deleted. The listener can +// also be NULL in which case it will not be added to the list. Does +// nothing if the previous and the current listener objects are the same. +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { + if (default_xml_generator_ != listener) { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } +} + +// Controls whether events will be forwarded by the repeater to the +// listeners in the list. +bool TestEventListeners::EventForwardingEnabled() const { + return repeater_->forwarding_enabled(); +} + +void TestEventListeners::SuppressEventForwarding() { + repeater_->set_forwarding_enabled(false); +} + +// class UnitTest + +// Gets the singleton UnitTest object. The first time this method is +// called, a UnitTest object is constructed and returned. Consecutive +// calls will return the same object. +// +// We don't protect this under mutex_ as a user is not supposed to +// call this before main() starts, from which point on the return +// value will never change. +UnitTest * UnitTest::GetInstance() { + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. + + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. + +#if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) + static UnitTest* const instance = new UnitTest; + return instance; +#else + static UnitTest instance; + return &instance; +#endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) +} + +// Gets the number of successful test cases. +int UnitTest::successful_test_case_count() const { + return impl()->successful_test_case_count(); +} + +// Gets the number of failed test cases. +int UnitTest::failed_test_case_count() const { + return impl()->failed_test_case_count(); +} + +// Gets the number of all test cases. +int UnitTest::total_test_case_count() const { + return impl()->total_test_case_count(); +} + +// Gets the number of all test cases that contain at least one test +// that should run. +int UnitTest::test_case_to_run_count() const { + return impl()->test_case_to_run_count(); +} + +// Gets the number of successful tests. +int UnitTest::successful_test_count() const { + return impl()->successful_test_count(); +} + +// Gets the number of failed tests. +int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } + +// Gets the number of disabled tests. +int UnitTest::disabled_test_count() const { + return impl()->disabled_test_count(); +} + +// Gets the number of all tests. +int UnitTest::total_test_count() const { return impl()->total_test_count(); } + +// Gets the number of tests that should run. +int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } + +// Gets the elapsed time, in milliseconds. +internal::TimeInMillis UnitTest::elapsed_time() const { + return impl()->elapsed_time(); +} + +// Returns true iff the unit test passed (i.e. all test cases passed). +bool UnitTest::Passed() const { return impl()->Passed(); } + +// Returns true iff the unit test failed (i.e. some test case failed +// or something outside of all tests failed). +bool UnitTest::Failed() const { return impl()->Failed(); } + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +const TestCase* UnitTest::GetTestCase(int i) const { + return impl()->GetTestCase(i); +} + +// Gets the i-th test case among all the test cases. i can range from 0 to +// total_test_case_count() - 1. If i is not in that range, returns NULL. +TestCase* UnitTest::GetMutableTestCase(int i) { + return impl()->GetMutableTestCase(i); +} + +// Returns the list of event listeners that can be used to track events +// inside Google Test. +TestEventListeners& UnitTest::listeners() { + return *impl()->listeners(); +} + +// Registers and returns a global test environment. When a test +// program is run, all global test environments will be set-up in the +// order they were registered. After all tests in the program have +// finished, all global test environments will be torn-down in the +// *reverse* order they were registered. +// +// The UnitTest object takes ownership of the given environment. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +Environment* UnitTest::AddEnvironment(Environment* env) { + if (env == NULL) { + return NULL; + } + + impl_->environments().push_back(env); + return env; +} + +// Adds a TestPartResult to the current TestResult object. All Google Test +// assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) eventually call +// this to report their results. The user code should use the +// assertion macros instead of calling this directly. +// L < mutex_ +void UnitTest::AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const internal::String& message, + const internal::String& os_stack_trace) { + Message msg; + msg << message; + + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) { + msg << "\n" << GTEST_NAME_ << " trace:"; + + for (int i = static_cast<int>(impl_->gtest_trace_stack().size()); + i > 0; --i) { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } + + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { + msg << internal::kStackTraceMarker << os_stack_trace; + } + + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()-> + ReportTestPartResult(result); + + if (result_type != TestPartResult::kSuccess) { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) { +#if GTEST_OS_WINDOWS + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); +#else + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast<volatile int*>(NULL) = 1; +#endif // GTEST_OS_WINDOWS + } else if (GTEST_FLAG(throw_on_failure)) { +#if GTEST_HAS_EXCEPTIONS + throw GoogleTestFailureException(result); +#else + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); +#endif + } + } +} + +// Creates and adds a property to the current TestResult. If a property matching +// the supplied value already exists, updates its value instead. +void UnitTest::RecordPropertyForCurrentTest(const char* key, + const char* value) { + const TestProperty test_property(key, value); + impl_->current_test_result()->RecordProperty(test_property); +} + +// Runs all tests in this UnitTest object and prints the result. +// Returns 0 if successful, or 1 otherwise. +// +// We don't protect this under mutex_, as we only support calling it +// from the main thread. +int UnitTest::Run() { + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + +#if GTEST_HAS_SEH + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; + + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) { + +# if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +# endif // !GTEST_OS_WINDOWS_MOBILE + +# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +# endif + +# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +# endif + + } +#endif // GTEST_HAS_SEH + + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") ? 0 : 1; +} + +// Returns the working directory when the first TEST() or TEST_F() was +// executed. +const char* UnitTest::original_working_dir() const { + return impl_->original_working_dir_.c_str(); +} + +// Returns the TestCase object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestCase* UnitTest::current_test_case() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); +} + +// Returns the TestInfo object for the test that's currently running, +// or NULL if no test is running. +// L < mutex_ +const TestInfo* UnitTest::current_test_info() const { + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); +} + +// Returns the random seed used at the start of the current test run. +int UnitTest::random_seed() const { return impl_->random_seed(); } + +#if GTEST_HAS_PARAM_TEST +// Returns ParameterizedTestCaseRegistry object used to keep track of +// value-parameterized tests and instantiate and register them. +// L < mutex_ +internal::ParameterizedTestCaseRegistry& + UnitTest::parameterized_test_registry() { + return impl_->parameterized_test_registry(); +} +#endif // GTEST_HAS_PARAM_TEST + +// Creates an empty UnitTest. +UnitTest::UnitTest() { + impl_ = new internal::UnitTestImpl(this); +} + +// Destructor of UnitTest. +UnitTest::~UnitTest() { + delete impl_; +} + +// Pushes a trace defined by SCOPED_TRACE() on to the per-thread +// Google Test trace stack. +// L < mutex_ +void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); +} + +// Pops a trace from the per-thread Google Test trace stack. +// L < mutex_ +void UnitTest::PopGTestTrace() { + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); +} + +namespace internal { + +UnitTestImpl::UnitTestImpl(UnitTest* parent) + : parent_(parent), +#ifdef _MSC_VER +# pragma warning(push) // Saves the current warning state. +# pragma warning(disable:4355) // Temporarily disables warning 4355 + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +# pragma warning(pop) // Restores the warning state again. +#else + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#endif // _MSC_VER + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), +#if GTEST_HAS_PARAM_TEST + parameterized_test_registry_(), + parameterized_tests_registered_(false), +#endif // GTEST_HAS_PARAM_TEST + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + elapsed_time_(0), +#if GTEST_HAS_DEATH_TEST + internal_run_death_test_flag_(NULL), + death_test_factory_(new DefaultDeathTestFactory), +#endif + // Will be overridden by the flag before first use. + catch_exceptions_(false) { + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); +} + +UnitTestImpl::~UnitTestImpl() { + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete<TestCase>); + + // Deletes every Environment. + ForEach(environments_, internal::Delete<Environment>); + + delete os_stack_trace_getter_; +} + +#if GTEST_HAS_DEATH_TEST +// Disables event forwarding if the control is currently in a death test +// subprocess. Must not be called before InitGoogleTest. +void UnitTestImpl::SuppressTestEventsIfInSubprocess() { + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); +} +#endif // GTEST_HAS_DEATH_TEST + +// Initializes event listeners performing XML output as specified by +// UnitTestOptions. Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureXmlOutput() { + const String& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } else if (output_format != "") { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } +} + +#if GTEST_CAN_STREAM_RESULTS_ +// Initializes event listeners for streaming test results in String form. +// Must not be called before InitGoogleTest. +void UnitTestImpl::ConfigureStreamingOutput() { + const string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) { + const size_t pos = target.find(':'); + if (pos != string::npos) { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos+1))); + } else { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } +} +#endif // GTEST_CAN_STREAM_RESULTS_ + +// Performs initialization dependent upon flag values obtained in +// ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to +// ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest +// this function is also called from RunAllTests. Since this function can be +// called more than once, it has to be idempotent. +void UnitTestImpl::PostFlagParsingInit() { + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) { + post_flag_parse_init_performed_ = true; + +#if GTEST_HAS_DEATH_TEST + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); +#endif // GTEST_HAS_DEATH_TEST + + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); + + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); + +#if GTEST_CAN_STREAM_RESULTS_ + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); +#endif // GTEST_CAN_STREAM_RESULTS_ + } +} + +// A predicate that checks the name of a TestCase against a known +// value. +// +// This is used for implementation of the UnitTest class only. We put +// it in the anonymous namespace to prevent polluting the outer +// namespace. +// +// TestCaseNameIs is copyable. +class TestCaseNameIs { + public: + // Constructor. + explicit TestCaseNameIs(const String& name) + : name_(name) {} + + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } + + private: + String name_; +}; + +// Finds and returns a TestCase with the given name. If one doesn't +// exist, creates one and returns it. It's the CALLER'S +// RESPONSIBILITY to ensure that this function is only called WHEN THE +// TESTS ARE NOT SHUFFLED. +// +// Arguments: +// +// test_case_name: name of the test case +// type_param: the name of the test case's type parameter, or NULL if +// this is not a typed or a type-parameterized test case. +// set_up_tc: pointer to the function that sets up the test case +// tear_down_tc: pointer to the function that tears down the test case +TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) { + // Can we find a TestCase with the given name? + const std::vector<TestCase*>::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); + + if (test_case != test_cases_.end()) + return *test_case; + + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(String(test_case_name), + kDeathTestCaseFilter)) { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } else { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } + + test_case_indices_.push_back(static_cast<int>(test_case_indices_.size())); + return new_test_case; +} + +// Helpers for setting up / tearing down the given environment. They +// are for use in the ForEach() function. +static void SetUpEnvironment(Environment* env) { env->SetUp(); } +static void TearDownEnvironment(Environment* env) { env->TearDown(); } + +// Runs all tests in this UnitTest object, prints the result, and +// returns true if all tests are successful. If any exception is +// thrown during a test, the test is considered to be failed, but the +// rest of the tests will still be run. +// +// When parameterized tests are enabled, it expands and registers +// parameterized tests first in RegisterParameterizedTests(). +// All other functions called from RunAllTests() may safely assume that +// parameterized tests are ready to be counted and run. +bool UnitTestImpl::RunAllTests() { + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } + + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; + + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); + + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); + + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; + +#if GTEST_HAS_DEATH_TEST + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); +#endif // GTEST_HAS_DEATH_TEST + + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); + + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; + + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } + + random_seed_ = GTEST_FLAG(shuffle) ? + GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + + // True iff at least one test has failed. + bool failed = false; + + TestEventListener* repeater = listeners()->repeater(); + + repeater->OnTestProgramStart(*parent_); + + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); + + const TimeInMillis start = GetTimeInMillis(); + + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } + + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); + + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); + + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) { + GetMutableTestCase(test_index)->Run(); + } + } + + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } + + elapsed_time_ = GetTimeInMillis() - start; + + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); + + // Gets the result and clears it. + if (!Passed()) { + failed = true; + } + + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); + + if (GTEST_FLAG(shuffle)) { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } + + repeater->OnTestProgramEnd(*parent_); + + return !failed; +} + +// Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file +// if the variable is present. If a file already exists at this location, this +// function will write over it. If the variable is present, but the file cannot +// be created, prints an error and exits. +void WriteToShardStatusFileIfNeeded() { + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } +} + +// Checks whether sharding is enabled by examining the relevant +// environment variable values. If the variables are present, +// but inconsistent (i.e., shard_index >= total_shards), prints +// an error and exits. If in_subprocess_for_death_test, sharding is +// disabled because it must only be applied to the original test +// process. Otherwise, we could filter out death tests we intended to execute. +bool ShouldShard(const char* total_shards_env, + const char* shard_index_env, + bool in_subprocess_for_death_test) { + if (in_subprocess_for_death_test) { + return false; + } + + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + + if (total_shards == -1 && shard_index == -1) { + return false; + } else if (total_shards == -1 && shard_index != -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (total_shards != -1 && shard_index == -1) { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } else if (shard_index < 0 || shard_index >= total_shards) { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + + return total_shards > 1; +} + +// Parses the environment variable var as an Int32. If it is unset, +// returns default_val. If it is not an Int32, prints an error +// and aborts. +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) { + return default_val; + } + + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) { + exit(EXIT_FAILURE); + } + return result; +} + +// Given the total number of shards, the shard index, and the test id, +// returns true iff the test should be run on this shard. The test id is +// some arbitrary but unique non-negative integer assigned to each test +// method. Assumes that 0 <= shard_index < total_shards. +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { + return (test_id % total_shards) == shard_index; +} + +// Compares the name of each test with the user-specified filter to +// decide whether the test should be run, then records the result in +// each TestCase and TestInfo object. +// If shard_tests == true, further filters tests based on sharding +// variables in the environment - see +// http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. +// Returns the number of tests that should run. +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? + Int32FromEnvOrDie(kTestShardIndex, -1) : -1; + + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) { + TestCase* const test_case = test_cases_[i]; + const String &test_case_name = test_case->name(); + test_case->set_should_run(false); + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + TestInfo* const test_info = test_case->test_info_list()[j]; + const String test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; + + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; + + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; + + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); + + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; + + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; +} + +// Prints the names of the tests matching the user-specified filter flag. +void UnitTestImpl::ListTestsMatchingFilter() { + for (size_t i = 0; i < test_cases_.size(); i++) { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; + + for (size_t j = 0; j < test_case->test_info_list().size(); j++) { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) { + if (!printed_test_case_name) { + printed_test_case_name = true; + printf("%s.\n", test_case->name()); + } + printf(" %s\n", test_info->name()); + } + } + } + fflush(stdout); +} + +// Sets the OS stack trace getter. +// +// Does nothing if the input and the current OS stack trace getter are +// the same; otherwise, deletes the old getter and makes the input the +// current getter. +void UnitTestImpl::set_os_stack_trace_getter( + OsStackTraceGetterInterface* getter) { + if (os_stack_trace_getter_ != getter) { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } +} + +// Returns the current OS stack trace getter if it is not NULL; +// otherwise, creates an OsStackTraceGetter, makes it the current +// getter, and returns it. +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { + if (os_stack_trace_getter_ == NULL) { + os_stack_trace_getter_ = new OsStackTraceGetter; + } + + return os_stack_trace_getter_; +} + +// Returns the TestResult for the test that's currently running, or +// the TestResult for the ad hoc test if no test is running. +TestResult* UnitTestImpl::current_test_result() { + return current_test_info_ ? + &(current_test_info_->result_) : &ad_hoc_test_result_; +} + +// Shuffles all test cases, and the tests within each test case, +// making sure that death tests are still run first. +void UnitTestImpl::ShuffleTests() { + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); + + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast<int>(test_cases_.size()), &test_case_indices_); + + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) { + test_cases_[i]->ShuffleTests(random()); + } +} + +// Restores the test cases and tests to their order before the first shuffle. +void UnitTestImpl::UnshuffleTests() { + for (size_t i = 0; i < test_cases_.size(); i++) { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast<int>(i); + } +} + +// Returns the current OS stack trace as a String. +// +// The maximum number of stack frames to be included is specified by +// the gtest_stack_trace_depth flag. The skip_count parameter +// specifies the number of top frames to be skipped, which doesn't +// count against the number of frames to be included. +// +// For example, if Foo() calls Bar(), which in turn calls +// GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in +// the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. +String GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, + int skip_count) { + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); +} + +// Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to +// suppress unreachable code warnings. +namespace { +class ClassUniqueToAlwaysTrue {}; +} + +bool IsTrue(bool condition) { return condition; } + +bool AlwaysTrue() { +#if GTEST_HAS_EXCEPTIONS + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); +#endif // GTEST_HAS_EXCEPTIONS + return true; +} + +// If *pstr starts with the given prefix, modifies *pstr to be right +// past the prefix and returns true; otherwise leaves *pstr unchanged +// and returns false. None of pstr, *pstr, and prefix can be NULL. +bool SkipPrefix(const char* prefix, const char** pstr) { + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) { + *pstr += prefix_len; + return true; + } + return false; +} + +// Parses a string as a command line flag. The string should have +// the format "--flag=value". When def_optional is true, the "=value" +// part can be omitted. +// +// Returns the value of the flag, or NULL if the parsing failed. +const char* ParseFlagValue(const char* str, + const char* flag, + bool def_optional) { + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; + + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const String flag_str = String::Format("--%s%s", GTEST_FLAG_PREFIX_, flag); + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + + // Skips the flag name. + const char* flag_end = str + flag_len; + + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) { + return flag_end; + } + + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; + + // Returns the string after "=". + return flag_end + 1; +} + +// Parses a string for a bool flag, in the form of either +// "--flag=value" or "--flag". +// +// In the former case, the value is taken as true as long as it does +// not start with '0', 'f', or 'F'. +// +// In the latter case, the value is taken as true. +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseBoolFlag(const char* str, const char* flag, bool* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; +} + +// Parses a string for an Int32 flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); +} + +// Parses a string for a string flag, in the form of +// "--flag=value". +// +// On success, stores the value of the flag in *value, and returns +// true. On failure, returns false without changing *value. +bool ParseStringFlag(const char* str, const char* flag, String* value) { + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); + + // Aborts if the parsing failed. + if (value_str == NULL) return false; + + // Sets *value to the value of the flag. + *value = value_str; + return true; +} + +// Determines whether a string has a prefix that Google Test uses for its +// flags, i.e., starts with GTEST_FLAG_PREFIX_ or GTEST_FLAG_PREFIX_DASH_. +// If Google Test detects that a command line flag has its prefix but is not +// recognized, it will print its help message. Flags starting with +// GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test +// internal flags and do not trigger the help message. +static bool HasGoogleTestFlagPrefix(const char* str) { + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +} + +// Prints a string containing code-encoded text. The following escape +// sequences can be used in the string to control the text color: +// +// @@ prints a single '@' character. +// @R changes the color to red. +// @G changes the color to green. +// @Y changes the color to yellow. +// @D changes to the default terminal text color. +// +// TODO(wan@google.com): Write tests for this once we add stdout +// capturing to Google Test. +static void PrintColorEncoded(const char* str) { + GTestColor color = COLOR_DEFAULT; // The current color. + + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) { + const char* p = strchr(str, '@'); + if (p == NULL) { + ColoredPrintf(color, "%s", str); + return; + } + + ColoredPrintf(color, "%s", String(str, p - str).c_str()); + + const char ch = p[1]; + str = p + 2; + if (ch == '@') { + ColoredPrintf(color, "@"); + } else if (ch == 'D') { + color = COLOR_DEFAULT; + } else if (ch == 'R') { + color = COLOR_RED; + } else if (ch == 'G') { + color = COLOR_GREEN; + } else if (ch == 'Y') { + color = COLOR_YELLOW; + } else { + --str; + } + } +} + +static const char kColorEncodedHelpMessage[] = +"This program contains tests written using " GTEST_NAME_ ". You can use the\n" +"following command line flags to control its behavior:\n" +"\n" +"Test Selection:\n" +" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" +" List the names of all tests instead of running them. The name of\n" +" TEST(Foo, Bar) is \"Foo.Bar\".\n" +" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" +" Run only the tests whose name matches one of the positive patterns but\n" +" none of the negative patterns. '?' matches any single character; '*'\n" +" matches any substring; ':' separates two patterns.\n" +" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" +" Run all disabled tests too.\n" +"\n" +"Test Execution:\n" +" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" +" Run the tests repeatedly; use a negative count to repeat forever.\n" +" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" +" Randomize tests' orders on every iteration.\n" +" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" +" Random number seed to use for shuffling test orders (between 1 and\n" +" 99999, or 0 to use a seed based on the current time).\n" +"\n" +"Test Output:\n" +" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" +" Enable/disable colored output. The default is @Gauto@D.\n" +" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" +" Don't print the elapsed time of each test.\n" +" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" + GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" +" Generate an XML report in the given directory or with the given file\n" +" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" +#if GTEST_CAN_STREAM_RESULTS_ +" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" +" Stream test results to the given server.\n" +#endif // GTEST_CAN_STREAM_RESULTS_ +"\n" +"Assertion Behavior:\n" +#if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" +" Set the default death test style.\n" +#endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS +" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" +" Turn assertion failures into debugger break-points.\n" +" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" +" Turn assertion failures into C++ exceptions.\n" +" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" +" Do not report exceptions as test failures. Instead, allow them\n" +" to crash the program or throw a pop-up (on Windows).\n" +"\n" +"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " + "the corresponding\n" +"environment variable of a flag (all letters in upper-case). For example, to\n" +"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" +"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" +"\n" +"For more information, please read the " GTEST_NAME_ " documentation at\n" +"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" +"(not one in your own code or tests), please report it to\n" +"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. The type parameter CharType can be +// instantiated to either char or wchar_t. +template <typename CharType> +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { + for (int i = 1; i < *argc; i++) { + const String arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); + + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; + + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure)) + ) { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) { + argv[j] = argv[j + 1]; + } + + // Decrements the argument count. + (*argc)--; + + // We also need to decrement the iterator as we just removed + // an element. + i--; + } else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } + + if (g_help_flag) { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } +} + +// Parses the command line for Google Test flags, without initializing +// other parts of Google Test. +void ParseGoogleTestFlagsOnly(int* argc, char** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { + ParseGoogleTestFlagsOnlyImpl(argc, argv); +} + +// The internal implementation of InitGoogleTest(). +// +// The type parameter CharType can be instantiated to either char or +// wchar_t. +template <typename CharType> +void InitGoogleTestImpl(int* argc, CharType** argv) { + g_init_gtest_count++; + + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; + + if (*argc <= 0) return; + + internal::g_executable_path = internal::StreamableToString(argv[0]); + +#if GTEST_HAS_DEATH_TEST + + g_argvs.clear(); + for (int i = 0; i != *argc; i++) { + g_argvs.push_back(StreamableToString(argv[i])); + } + +#endif // GTEST_HAS_DEATH_TEST + + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); +} + +} // namespace internal + +// Initializes Google Test. This must be called before calling +// RUN_ALL_TESTS(). In particular, it parses a command line for the +// flags that Google Test recognizes. Whenever a Google Test flag is +// seen, it is removed from argv, and *argc is decremented. +// +// No value is returned. Instead, the Google Test flag variables are +// updated. +// +// Calling the function for the second time has no user-visible effect. +void InitGoogleTest(int* argc, char** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +// This overloaded version can be used in Windows programs compiled in +// UNICODE mode. +void InitGoogleTest(int* argc, wchar_t** argv) { + internal::InitGoogleTestImpl(argc, argv); +} + +} // namespace testing diff --git a/lib/gtest/src/gtest_main.cc b/lib/gtest/src/gtest_main.cc new file mode 100644 index 0000000..a09bbe0 --- /dev/null +++ b/lib/gtest/src/gtest_main.cc @@ -0,0 +1,39 @@ +// Copyright 2006, Google 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: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * 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. +// * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT +// OWNER OR 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. + +#include <iostream> + +#include "gtest/gtest.h" + +GTEST_API_ int main(int argc, char **argv) { + std::cout << "Running main() from gtest_main.cc\n"; + + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index efbd681..07e487d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,5 +1,14 @@ # CBot shared library is built separately add_subdirectory(CBot) +<<<<<<< HEAD + +# Tools directory is built separately +add_subdirectory(tools) + +# Tests +add_subdirectory(graphics/engine/test) +======= +>>>>>>> dev-ui # Configure options diff --git a/src/app/app.cpp b/src/app/app.cpp index 182e0fd..00cd13d 100644 --- a/src/app/app.cpp +++ b/src/app/app.cpp @@ -113,6 +113,7 @@ CApplication::~CApplication() bool CApplication::ParseArguments(int argc, char *argv[]) { bool waitDataDir = false; + bool waitLogLevel = false; for (int i = 1; i < argc; ++i) { @@ -125,10 +126,34 @@ bool CApplication::ParseArguments(int argc, char *argv[]) continue; } + if (waitLogLevel) + { + waitLogLevel = false; + if (arg == "trace") + GetLogger()->SetLogLevel(LOG_TRACE); + else if (arg == "debug") + GetLogger()->SetLogLevel(LOG_DEBUG); + else if (arg == "info") + GetLogger()->SetLogLevel(LOG_INFO); + else if (arg == "warn") + GetLogger()->SetLogLevel(LOG_WARN); + else if (arg == "error") + GetLogger()->SetLogLevel(LOG_ERROR); + else if (arg == "none") + GetLogger()->SetLogLevel(LOG_NONE); + else + return false; + continue; + } + if (arg == "-debug") { SetDebugMode(true); } + else if (arg == "-loglevel") + { + waitLogLevel = true; + } else if (arg == "-datadir") { waitDataDir = true; @@ -140,8 +165,8 @@ bool CApplication::ParseArguments(int argc, char *argv[]) } } - // Data dir not given? - if (waitDataDir) + // Args not given? + if (waitDataDir || waitLogLevel) return false; return true; diff --git a/src/common/ioutils.h b/src/common/ioutils.h index a7bd044..2a542c6 100644 --- a/src/common/ioutils.h +++ b/src/common/ioutils.h @@ -27,9 +27,10 @@ namespace IOUtils { //! Writes a binary number to output stream /** - \c T is a numeric type (int, unsigned int, etc.) - \c N is number of bytes - Write order is little-endian */ + * \c T is a numeric type (int, unsigned int, etc.) + * \c N is number of bytes + * Write order is little-endian + */ template<int N, typename T> void WriteBinary(T value, std::ostream &ostr) { @@ -42,9 +43,10 @@ void WriteBinary(T value, std::ostream &ostr) //! Reads a binary number from input stream /** - \c T is a numeric type (int, unsigned int, etc.) - \c N is number of bytes - Read order is little-endian */ + * \c T is a numeric type (int, unsigned int, etc.) + * \c N is number of bytes + * Read order is little-endian + */ template<int N, typename T> T ReadBinary(std::istream &istr) { @@ -58,10 +60,31 @@ T ReadBinary(std::istream &istr) return value; } +//! Writes a binary 1-byte boolean +/** + * false is 0; true is 1. + */ +void WriteBinaryBool(float value, std::ostream &ostr) +{ + unsigned char v = value ? 1 : 0; + IOUtils::WriteBinary<1, unsigned char>(v, ostr); +} + +//! Reads a binary 1-byte boolean +/** + * 0 is false; other values are true. + */ +bool ReadBinaryBool(std::istream &istr) +{ + int v = IOUtils::ReadBinary<1, unsigned char>(istr); + return v != 0; +} + //! Writes a binary 32-bit float to output stream /** - Write order is little-endian - NOTE: code is probably not portable as there are platforms with other float representations. */ + * Write order is little-endian + * NOTE: code is probably not portable as there are platforms with other float representations. + */ void WriteBinaryFloat(float value, std::ostream &ostr) { union { float fValue; unsigned int iValue; } u; @@ -72,8 +95,9 @@ void WriteBinaryFloat(float value, std::ostream &ostr) //! Reads a binary 32-bit float from input stream /** - Read order is little-endian - NOTE: code is probably not portable as there are platforms with other float representations. */ + * Read order is little-endian + * NOTE: code is probably not portable as there are platforms with other float representations. + */ float ReadBinaryFloat(std::istream &istr) { union { float fValue; unsigned int iValue; } u; @@ -82,4 +106,40 @@ float ReadBinaryFloat(std::istream &istr) return u.fValue; } +//! Writes a variable binary string to output stream +/** + * The string is written by first writing string length + * in \c N byte binary number and then the string bytes. + */ +template<int N> +void WriteBinaryString(const std::string &value, std::ostream &ostr) +{ + int length = value.size(); + WriteBinary<N, int>(length, ostr); + + for (int i = 0; i < length; ++i) + ostr.put(value[i]); +} + +//! Reads a variable binary string from output stream +/** + * The string is read by first reading string length + * in \c N byte binary number and then the string bytes. + */ +template<int N> +std::string ReadBinaryString(std::istream &istr) +{ + int length = ReadBinary<N, int>(istr); + + std::string str; + char c = 0; + for (int i = 0; i < length; ++i) + { + istr.read(&c, 1); + str += c; + } + + return str; +} + }; // namespace IOUtils diff --git a/src/common/restext.cpp b/src/common/restext.cpp index 487d1a6..ee5d961 100644 --- a/src/common/restext.cpp +++ b/src/common/restext.cpp @@ -14,9 +14,10 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/.// restext.cpp -#include <libintl.h> -#include <SDL/SDL_keyboard.h> -#include "common/struct.h" +#include <stdio.h> +//#include "common/struct.h" +//#include "old/d3dengine.h" +#include "graphics/engine/engine.h" #include "common/language.h" #include "common/misc.h" #include "common/event.h" @@ -25,12 +26,14 @@ #include "common/restext.h" -// Gives the pointer to the engine. -static CD3DEngine* g_engine; -static char g_gamerName[100]; +//** -> text to translate! + + -void SetEngine(CD3DEngine *engine) +// Gives the pointer to the engine. + +void SetEngine(Gfx::CEngine *engine) { g_engine = engine; } @@ -78,7 +81,7 @@ static KeyDesc keyTable[22] = // Seeks a key. -bool SearchKey(const char *cmd, KeyRank &key) +bool SearchKey(char *cmd, KeyRank &key) { int i; @@ -95,7 +98,7 @@ bool SearchKey(const char *cmd, KeyRank &key) // Replaces the commands "\key name;" in a text. -static void PutKeyName(char* dst, const char* src) +void PutKeyName(char* dst, char* src) { KeyRank key; char name[50]; @@ -112,8 +115,7 @@ static void PutKeyName(char* dst, const char* src) { if ( SearchKey(src+s+5, key) ) { - // FIXME: res = g_engine->RetKey(key, 0); - res = 0; + // res = g_engine->GetKey(key, 0); TODO if ( res != 0 ) { if ( GetResource(RES_KEY, res, name) ) @@ -135,60 +137,3524 @@ static void PutKeyName(char* dst, const char* src) dst[d++] = 0; } -// Returns the translated text of a resource that needs key substitution - -static const char* GetResourceBase(ResType type, int num) -{ - const char *str = NULL; - - assert(num >= 0); - - switch (type) - { - case RES_TEXT: - assert(num < strings_text_len); - str = strings_text[num]; - break; - case RES_EVENT: - assert(num < strings_event_len); - str = strings_event[num]; - break; - case RES_OBJECT: - assert(num < strings_object_len); - if (num == OBJECT_HUMAN) - return g_gamerName; - str = strings_object[num]; - break; - case RES_ERR: - assert(num < strings_err_len); - str = strings_err[num]; - break; - case RES_CBOT: - assert(num < strings_cbot_len); - str = strings_cbot[num]; - break; - case RES_KEY: - assert(num < SDLK_LAST); - str = SDL_GetKeyName(static_cast<SDLKey>(num)); - break; - default: - assert(false); - } - return gettext(str); -} // Returns the text of a resource. bool GetResource(ResType type, int num, char* text) { - const char *tmpl = GetResourceBase(type, num); + char buffer[100]; - if (!tmpl) + if ( !GetResourceBase(type, num, buffer) ) { text[0] = 0; return false; } - PutKeyName(text, tmpl); + PutKeyName(text, buffer); return true; } + + +// Returns the text of a resource. + +bool GetResourceBase(ResType type, int num, char* text) +{ + text[0] = 0; + +#if _ENGLISH + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /e"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /e"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Maximize"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Minimize"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normal size"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Close"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Program editor"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "New"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Player"); + if ( num == RT_IO_NEW ) strcpy(text, "New ..."); + if ( num == RT_KEY_OR ) strcpy(text, " or "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programming exercises"); + if ( num == RT_TITLE_DEFI ) strcpy(text, "Challenges"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Missions"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Free game"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Free game"); + if ( num == RT_TITLE_USER ) strcpy(text, "User levels"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypes"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Options"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Player's name"); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Customize your appearance"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Save the current mission"); + if ( num == RT_TITLE_READ ) strcpy(text, "Load a saved mission"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Chapters:"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Chapters:"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Planets:"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Planets:"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " User levels:"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Planets:"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Chapters:"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " Exercises in the chapter:"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Challenges in the chapter:"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Missions on this planet:"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Free game on this planet:"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Missions on this level:"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Prototypes on this planet:"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Free game on this chapter:"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " Summary:"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Drivers:"); + if ( num == RT_SETUP_MODE ) strcpy(text, " Resolution:"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) First click on the key you want to redefine."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Then press the key you want to use instead."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Face type:"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Eyeglasses:"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Hair color:"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Suit color:"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Strip color:"); + +#if _NEWLOOK + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Do you want to quit CeeBot ?"); + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quit\\Quit CeeBot"); +#else + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Do you want to quit COLOBOT ?"); + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quit\\Quit COLOBOT"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Quit the mission?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Abort\\Abort the current mission"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Continue\\Continue the current mission"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Continue\\Continue the game"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Do you really want to destroy the selected building?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Do you want to delete %s's saved games? "); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Delete"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Cancel"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "LOADING"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Keyword help(\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Compilation ok (0 errors)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Program finished"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;List of objects\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Robots\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Buildings\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Moveable objects\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Aliens\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (none)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Error\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "The list is only available if a \\l;radar station\\u object\\radar; is working.\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "Open"); + if ( num == RT_IO_SAVE ) strcpy(text, "Save"); + if ( num == RT_IO_LIST ) strcpy(text, "Folder: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Name:"); + if ( num == RT_IO_DIR ) strcpy(text, "Folder:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Private\\Private folder"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "Public\\Common folder"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Developed by :"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); +//? if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "English version published by:"); +//? if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.?.com"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Cancel"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Next"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Previous"); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Cancel"); + + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Exercises\\Programming exercises"); + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Challenges\\Programming challenges"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missions\\Select mission"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Free game\\Free game without a specific goal"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Free game\\Free game without a specific goal"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "User\\User levels"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\Prototypes under development"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "New player\\Choose player's name"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Options\\Preferences"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Restart\\Restart the mission from the beginning"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Save\\Save the current mission "); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Load\\Load a saved mission"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Return to CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quit\\Quit CeeBot"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Return to COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quit\\Quit COLOBOT"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Back \\Back to the previous screen"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Play\\Start mission!"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Device\\Driver and resolution settings"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Graphics\\Graphics settings"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Game\\Game settings"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Controls\\Keyboard, joystick and mouse settings"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Sound\\Music and game sound volume"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Unit"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Resolution"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Full screen\\Full screen or window mode"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Apply changes\\Activates the changed settings"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Your assistant"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Shadows\\Shadows on the ground"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Marks on the ground\\Marks on the ground"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Dust\\Dust and dirt on bots and buildings"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Fog\\Fog"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Sunbeams\\Sunbeams in the sky"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Sky\\Clouds and nebulae"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planets and stars\\Astronomical objects in the sky"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamic lighting\\Mobile light sources"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Number of particles\\Explosions, dust, reflections, etc."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Depth of field\\Maximum visibility"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Details\\Visual quality of 3D objects"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Textures\\Quality of textures "); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Num of decorative objects\\Number of purely ornamental objects"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Particles in the interface\\Steam clouds and sparks in the interface"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Reflections on the buttons \\Shiny buttons"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Help balloons\\Explain the function of the buttons"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Film sequences\\Films before and after the missions"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Exit film\\Film at the exit of exercises"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Friendly fire\\Your shooting can damage your own objects "); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Scrolling\\Scrolling when the mouse touches right or left border"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Mouse inversion X\\Inversion of the scrolling direction on the X axis"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Mouse inversion Y\\Inversion of the scrolling direction on the Y axis"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Quake at explosions\\The screen shakes at explosions"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Mouse shadow\\Gives the mouse a shadow"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatic indent\\When program editing"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Big indent\\Indent 2 or 4 spaces per level defined by braces"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Access to solutions\\Show program \"4: Solution\" in the exercises"); //** + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Standard controls\\Standard key functions"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Turn left\\turns the bot to the left"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Turn right\\turns the bot to the right"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Forward\\Moves forward"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Backward\\Moves backward"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Climb\\Increases the power of the jet"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Descend\\Reduces the power of the jet"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Change camera\\Switches between onboard camera and following camera"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Previous object\\Selects the previous object"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standard action\\Standard action of the bot (take/grab, shoot, sniff, etc)"); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Camera closer\\Moves the camera forward"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Camera back\\Moves the camera backward"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Next object\\Selects the next object"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Select the astronaut\\Selects the astronaut"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Quit\\Quit the current mission or exercise"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Instructions\\Shows the instructions for the current mission"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Programming help\\Gives more detailed help with programming"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Key word help\\More detailed help about key words"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Origin of last message\\Shows where the last message was sent from"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Speed 1.0x\\Normal speed"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Speed 1.5x\\1.5 times faster"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Speed 2.0x\\Double speed"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Speed 3.0x\\Three times faster"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Sound effects:\\Volume of engines, voice, shooting, etc."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Background sound :\\Volume of audio tracks on the CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "3D sound\\3D positioning of the sound"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Lowest\\Minimum graphic quality (highest frame rate)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Normal graphic quality"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Highest\\Highest graphic quality (lowest frame rate)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Mute\\No sound"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Normal sound volume"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Use a joystick\\Joystick or keyboard"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Access to solution\\Shows the solution (detailed instructions for missions)"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\New player name"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Choose the selected player"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Cancel\\Keep current player name"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Delete player\\Deletes the player from the list"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Player name"); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Save\\Saves the current mission"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Load\\Loads the selected mission"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "List of saved missions"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Filename:"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Mission name"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Photography"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Delete\\Deletes the selected file"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Appearance\\Choose your appearance"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Cancel"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Standard appearance settings"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Head\\Face and hair"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Suit\\Astronaut suit"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Turn left"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Turn right"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Red"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Green"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Blue"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Red"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Green"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Blue"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Face 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Face 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Face 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Face 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\No eyeglasses"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Eyeglasses 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Eyeglasses 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Eyeglasses 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Eyeglasses 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Eyeglasses 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Previous selection (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Turn left (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Turn right (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Forward (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Backward (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Up (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Down (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Grab or drop (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Grab or drop (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..in front"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..behind"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..power cell"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Instructions for the mission (\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Take off to finish the mission"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Build a derrick"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Build a power station"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Build a bot factory"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Build a repair center"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Build a converter"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Build a defense tower"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Build a research center"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Build a radar station"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Build a power cell factory"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Build an autolab"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Build a nuclear power plant"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Build a lightning conductor"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Build a exchange post"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Show if the ground is flat"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Plant a flag"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Remove a flag"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Blue flags"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Red flags"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Green flags"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Yellow flags"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Violet flags"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Build a winged grabber"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Build a tracked grabber"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Build a wheeled grabber"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Build a legged grabber"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Build a winged shooter"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Build a tracked shooter"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Build a wheeled shooter"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Build a legged shooter"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Build a winged orga shooter"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Build a tracked orga shooter"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Build a wheeled orga shooter"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Build a legged orga shooter"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Build a winged sniffer"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Build a tracked sniffer"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Build a wheeled sniffer"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Build a legged sniffer"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Build a thumper"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Build a phazer shooter"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Build a recycler"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Build a shielder"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Build a subber"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Run research program for tracked bots"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Run research program for winged bots"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Run research program for thumper"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Run research program for shooter"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Run research program for defense tower"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Run research program for phazer shooter"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Run research program for shielder"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Run research program for nuclear power"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Run research program for legged bots"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Run research program for orga shooter"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Return to start"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Sniff (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Thump (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Shoot (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recycle (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Extend shield (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Withdraw shield (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Shield radius"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Execute the selected program"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edit the selected program"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\SatCom on standby"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Destroy the building"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Energy level"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Shield level"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Jet temperature"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Still working ..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Number of insects detected"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Transmitted information"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Compass"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mini-map"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom mini-map"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Camera (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Camera to left"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Camera to right"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Camera nearest"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Camera awayest"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Help about selected object"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Show the solution"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Switch bots <-> buildings"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Show the range"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Raise the pencil"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Use the black pencil"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Use the yellow pencil"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Use the orange pencil"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Use the red pencil"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Use the purple pencil"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Use the blue pencil"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Use the green pencil"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Use the brown pencil"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Start recording"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stop recording"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Show the place"); + if ( num == EVENT_DT_END ) strcpy(text, "Continue"); + if ( num == EVENT_CMD ) strcpy(text, "Command line"); + if ( num == EVENT_SPEED ) strcpy(text, "Game speed"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Back"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Forward"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Home"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Copy"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Size 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Size 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Size 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Size 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Size 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Instructions from Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Dictionnary"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Satellite report"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Programs dispatched by Houston"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "List of objects"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Programming help"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Solution"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Close program editor and return to game"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Cancel\\Cancel all changes"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "New"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Open (Ctrl+o)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Save (Ctrl+s)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Undo (Ctrl+z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Cut (Ctrl+x)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Copy (Ctrl+c)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Paste (Ctrl+v)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Font size"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Instructions (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Programming help (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Compile"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Execute/stop"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/continue"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "One step"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "Gantry crane"); + if ( num == OBJECT_BASE ) strcpy(text, "Spaceship"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Derrick"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Bot factory"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Repair center"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Destroyer"); + if ( num == OBJECT_STATION ) strcpy(text, "Power station"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Converts ore to titanium"); + if ( num == OBJECT_TOWER ) strcpy(text, "Defense tower"); + if ( num == OBJECT_NEST ) strcpy(text, "Nest"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Research center"); + if ( num == OBJECT_RADAR ) strcpy(text, "Radar station"); + if ( num == OBJECT_INFO ) strcpy(text, "Information exchange post"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "Power cell factory"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Power cell factory"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Autolab"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Nuclear power station"); + if ( num == OBJECT_PARA ) strcpy(text, "Lightning conductor"); + if ( num == OBJECT_SAFE ) strcpy(text, "Vault"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Houston Mission Control"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Target"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Target"); + if ( num == OBJECT_START ) strcpy(text, "Start"); + if ( num == OBJECT_END ) strcpy(text, "Finish"); + if ( num == OBJECT_STONE ) strcpy(text, "Titanium ore"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Uranium ore"); + if ( num == OBJECT_BULLET ) strcpy(text, "Organic matter"); + if ( num == OBJECT_METAL ) strcpy(text, "Titanium"); + if ( num == OBJECT_POWER ) strcpy(text, "Power cell"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Nuclear power cell"); + if ( num == OBJECT_BBOX ) strcpy(text, "Black box"); + if ( num == OBJECT_KEYa ) strcpy(text, "Key A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Key B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Key C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Key D"); + if ( num == OBJECT_TNT ) strcpy(text, "Explosive"); + if ( num == OBJECT_BOMB ) strcpy(text, "Fixed mine"); + if ( num == OBJECT_BAG ) strcpy(text, "Survival kit"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Checkpoint"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Blue flag"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Red flag"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Green flag"); + if ( num == OBJECT_FLAGy ) strcpy(text, "Yellow flag"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Violet flag"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "Energy deposit (site for power station)"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Uranium deposit (site for derrick)"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Found key A (site for derrick)"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Found key B (site for derrick)"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Found key C (site for derrick)"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Found key D (site for derrick)"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Titanium deposit (site for derrick)"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "Practice bot"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Winged grabber"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Tracked grabber"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Wheeled grabber"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Legged grabber"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Winged shooter"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Tracked shooter"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Wheeled shooter"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Legged shooter"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "Winged orga shooter"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "Tracked orga shooter"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "Wheeled orga shooter"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "Legged orga shooter"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Winged sniffer"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Tracked sniffer"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Wheeled sniffer"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Legged sniffer"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Thumper"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Phazer shooter"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Recycler"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Shielder"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Subber"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Target bot"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Drawer bot"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "Engineer"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Alien Queen"); + if ( num == OBJECT_ANT ) strcpy(text, "Ant"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Spider"); + if ( num == OBJECT_BEE ) strcpy(text, "Wasp"); + if ( num == OBJECT_WORM ) strcpy(text, "Worm"); + if ( num == OBJECT_EGG ) strcpy(text, "Egg"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Wreckage"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "Waste"); + if ( num == OBJECT_RUINradar ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "Ruin"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Spaceship ruin"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Spaceship ruin"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "Remains of Apollo mission"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "Error"); + if ( num == ERR_CMD ) strcpy(text, "Unknown command"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "CeeBot not installed."); + if ( num == ERR_NOCD ) strcpy(text, "Please insert the CeeBot CD\nand re-run the game."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT not installed."); + if ( num == ERR_NOCD ) strcpy(text, "Please insert the COLOBOT CD\nand re-run the game."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Already carrying something"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Nothing to grab"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Place occupied"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "No other robot"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "You can not carry a radioactive object"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "You can not carry an object under water"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nothing to drop"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Impossible under water"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titanium too far away"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titanium too close"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "No titanium around"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Ground not flat enough"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Flat ground not large enough"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Place occupied"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Too close to space ship"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Too close to a building"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Ground inappropriate"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Building too close"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Object too close"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nothing to recycle"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "No more energy"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Error in instruction move"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Object not found"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Goto: inaccessible destination"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Goto: inaccessible destination"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Goto: destination occupied"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Inappropriate bot"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "No titanium ore to convert"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "No ore in the subsoil"); + if ( num == ERR_STATION_NULL ) strcpy(text, "No energy in the subsoil"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "No power cell"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "No more energy"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "No power cell"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Not enough energy"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Inappropriate cell type"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Research program already performed"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "No energy in the subsoil"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Not enough energy yet"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "No titanium to transform"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Transforms only titanium"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Doors blocked by a robot or another object "); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "You must get on the spaceship to take off "); + if ( num == ERR_LABO_NULL ) strcpy(text, "Nothing to analyze"); + if ( num == ERR_LABO_BAD ) strcpy(text, "Analyzes only organic matter"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analysis already performed"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "No energy in the subsoil"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Not yet enough energy"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "No uranium to transform"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Transforms only uranium"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "No titanium"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Object too close"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Place occupied"); + if ( num == ERR_INFO_NULL ) strcpy(text, "No information exchange post within range"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Program infected by a virus"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Infected by a virus, temporarily out of order"); + if ( num == ERR_VEH_POWER ) strcpy(text, "No power cell"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "No more energy"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Impossible when flying"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Impossible when swimming"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Impossible when moving"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Impossible when carrying an object"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Too many flags of this color (maximum 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Too close to an existing flag"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "No flag nearby"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "The mission is not accomplished yet (press \\key help; for more details)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Bot destroyed"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "Building destroyed"); + if ( num == ERR_TOOMANY ) strcpy(text, "Can not create this, there are too many objects"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "\"%s\" missing in this exercise"); //** + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Do not use in this exercise"); //** + + if ( num == INFO_BUILD ) strcpy(text, "Building completed"); + if ( num == INFO_CONVERT ) strcpy(text, "Titanium available"); + if ( num == INFO_RESEARCH ) strcpy(text, "Research program completed"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Plans for tracked robots available "); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "You can fly with the keys (\\key gup;) and (\\key gdown;)"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Plans for thumper available"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Plans for shooter available"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Plans for defense tower available"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Plans for phazer shooter available"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Plans for shielder available"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Plans for nuclear power plant available"); + if ( num == INFO_FACTORY ) strcpy(text, "New bot available"); + if ( num == INFO_LABO ) strcpy(text, "Analysis performed"); + if ( num == INFO_ENERGY ) strcpy(text, "Power cell available"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Nuclear power cell available"); + if ( num == INFO_FINDING ) strcpy(text, "You found a usable object"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Found a site for power station"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Found a site for a derrick"); + if ( num == INFO_WIN ) strcpy(text, "<<< Well done, mission accomplished >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< Sorry, mission failed >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< Sorry, mission failed >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Current mission saved"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Checkpoint crossed"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Alien Queen killed"); + if ( num == INFO_DELETEANT ) strcpy(text, "Ant fatally wounded"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Wasp fatally wounded"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Worm fatally wounded"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Spider fatally wounded"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Press \\key help; to read instructions on your SatCom"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "Error"); + if ( num == TX_OPENPAR ) strcpy(text, "Opening bracket missing"); + if ( num == TX_CLOSEPAR ) strcpy(text, "Closing bracket missing "); + if ( num == TX_NOTBOOL ) strcpy(text, "The expression must return a boolean value"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Variable not declared"); + if ( num == TX_BADLEFT ) strcpy(text, "Assignment impossible"); + if ( num == TX_ENDOF ) strcpy(text, "Semicolon terminator missing"); + if ( num == TX_OUTCASE ) strcpy(text, "Instruction ""case"" outside a block ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Instructions after the final closing brace"); + if ( num == TX_CLOSEBLK ) strcpy(text, "End of block missing"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Instruction ""else"" without corresponding ""if"" "); + if ( num == TX_OPENBLK ) strcpy(text, "Opening brace missing ");//d�but d'un bloc attendu? + if ( num == TX_BADTYPE ) strcpy(text, "Wrong type for the assignment"); + if ( num == TX_REDEFVAR ) strcpy(text, "A variable can not be declared twice"); + if ( num == TX_BAD2TYPE ) strcpy(text, "The types of the two operands are incompatible "); + if ( num == TX_UNDEFCALL ) strcpy(text, "Unknown function"); + if ( num == TX_MISDOTS ) strcpy(text, "Sign "" : "" missing"); + if ( num == TX_WHILE ) strcpy(text, "Keyword ""while"" missing"); + if ( num == TX_BREAK ) strcpy(text, "Instruction ""break"" outside a loop"); + if ( num == TX_LABEL ) strcpy(text, "A label must be followed by ""for"", ""while"", ""do"" or ""switch"""); + if ( num == TX_NOLABEL ) strcpy(text, "This label does not exist");// Cette �tiquette n'existe pas + if ( num == TX_NOCASE ) strcpy(text, "Instruction ""case"" missing"); + if ( num == TX_BADNUM ) strcpy(text, "Number missing"); + if ( num == TX_VOID ) strcpy(text, "Void parameter"); + if ( num == TX_NOTYP ) strcpy(text, "Type declaration missing"); + if ( num == TX_NOVAR ) strcpy(text, "Variable name missing"); + if ( num == TX_NOFONC ) strcpy(text, "Function name missing"); + if ( num == TX_OVERPARAM ) strcpy(text, "Too many parameters"); + if ( num == TX_REDEF ) strcpy(text, "Function already exists"); + if ( num == TX_LOWPARAM ) strcpy(text, "Parameters missing "); + if ( num == TX_BADPARAM ) strcpy(text, "No function with this name accepts this kind of parameter"); + if ( num == TX_NUMPARAM ) strcpy(text, "No function with this name accepts this number of parameters"); + if ( num == TX_NOITEM ) strcpy(text, "This is not a member of this class"); + if ( num == TX_DOT ) strcpy(text, "This object is not a member of a class"); + if ( num == TX_NOCONST ) strcpy(text, "Appropriate constructor missing"); + if ( num == TX_REDEFCLASS ) strcpy(text, "This class already exists"); + if ( num == TX_CLBRK ) strcpy(text, """ ] "" missing"); + if ( num == TX_RESERVED ) strcpy(text, "Reserved keyword of CBOT language"); + if ( num == TX_BADNEW ) strcpy(text, "Bad argument for ""new"""); + if ( num == TX_OPBRK ) strcpy(text, """ [ "" expected"); + if ( num == TX_BADSTRING ) strcpy(text, "String missing"); + if ( num == TX_BADINDEX ) strcpy(text, "Incorrect index type"); + if ( num == TX_PRIVATE ) strcpy(text, "Private element"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Public required"); + if ( num == TX_DIVZERO ) strcpy(text, "Dividing by zero"); + if ( num == TX_NOTINIT ) strcpy(text, "Variable not initialized"); + if ( num == TX_BADTHROW ) strcpy(text, "Negative value rejected by ""throw""");//C'est quoi, �a? + if ( num == TX_NORETVAL ) strcpy(text, "The function returned no value "); + if ( num == TX_NORUN ) strcpy(text, "No function running"); + if ( num == TX_NOCALL ) strcpy(text, "Calling an unknown function"); + if ( num == TX_NOCLASS ) strcpy(text, "This class does not exist"); + if ( num == TX_NULLPT ) strcpy(text, "Unknown Object"); + if ( num == TX_OPNAN ) strcpy(text, "Operation impossible with value ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Access beyond array limit"); + if ( num == TX_STACKOVER ) strcpy(text, "Stack overflow"); + if ( num == TX_DELETEDPT ) strcpy(text, "Illegal object"); + if ( num == TX_FILEOPEN ) strcpy(text, "Can't open file"); + if ( num == TX_NOTOPEN ) strcpy(text, "File not open"); + if ( num == TX_ERRREAD ) strcpy(text, "Read error"); + if ( num == TX_ERRWRITE ) strcpy(text, "Write error"); + } +// \TODO + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< none >"); + if ( num == SDLK_LEFT ) strcpy(text, "Arrow left"); + if ( num == SDLK_RIGHT ) strcpy(text, "Arrow right"); + if ( num == SDLK_UP ) strcpy(text, "Arrow up"); + if ( num == SDLK_DOWN ) strcpy(text, "Arrow down"); +// if ( num == SDLK_CANCEL ) strcpy(text, "Control-break"); +// if ( num == SDLK_BACK ) strcpy(text, "<--"); + if ( num == SDLK_TAB ) strcpy(text, "Tab"); + if ( num == SDLK_CLEAR ) strcpy(text, "Clear"); + if ( num == SDLK_RETURN ) strcpy(text, "Enter"); +// if ( num == SDLK_SHIFT ) strcpy(text, "Shift"); +// if ( num == SDLK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == SDLK_MENU ) strcpy(text, "Alt"); + if ( num == SDLK_PAUSE ) strcpy(text, "Pause"); +// if ( num == SDLK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == SDLK_ESCAPE ) strcpy(text, "Esc"); + if ( num == SDLK_SPACE ) strcpy(text, "Space"); +// if ( num == SDLK_PRIOR ) strcpy(text, "Page Up"); +// if ( num == SDLK_NEXT ) strcpy(text, "Page Down"); + if ( num == SDLK_END ) strcpy(text, "End"); + if ( num == SDLK_HOME ) strcpy(text, "Home"); +// if ( num == SDLK_SELECT ) strcpy(text, "Select"); +// if ( num == SDLK_EXECUTE ) strcpy(text, "Execute"); +// if ( num == SDLK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == SDLK_INSERT ) strcpy(text, "Insert"); + if ( num == SDLK_DELETE ) strcpy(text, "Delete"); + if ( num == SDLK_HELP ) strcpy(text, "Help"); +// if ( num == SDLK_LWIN ) strcpy(text, "Left Windows"); +// if ( num == SDLK_RWIN ) strcpy(text, "Right Windows"); +// if ( num == SDLK_APPS ) strcpy(text, "Application key"); +// if ( num == SDLK_NUMPAD0 ) strcpy(text, "NumPad 0"); +// if ( num == SDLK_NUMPAD1 ) strcpy(text, "NumPad 1"); +// if ( num == SDLK_NUMPAD2 ) strcpy(text, "NumPad 2"); +// if ( num == SDLK_NUMPAD3 ) strcpy(text, "NumPad 3"); +// if ( num == SDLK_NUMPAD4 ) strcpy(text, "NumPad 4"); +// if ( num == SDLK_NUMPAD5 ) strcpy(text, "NumPad 5"); +// if ( num == SDLK_NUMPAD6 ) strcpy(text, "NumPad 6"); +// if ( num == SDLK_NUMPAD7 ) strcpy(text, "NumPad 7"); +// if ( num == SDLK_NUMPAD8 ) strcpy(text, "NumPad 8"); +// if ( num == SDLK_NUMPAD9 ) strcpy(text, "NumPad 9"); +// if ( num == SDLK_MULTIPLY ) strcpy(text, "NumPad *"); +// if ( num == SDLK_ADD ) strcpy(text, "NumPad +"); +// if ( num == SDLK_SEPARATOR ) strcpy(text, "NumPad sep"); +// if ( num == SDLK_SUBTRACT ) strcpy(text, "NumPad -"); +// if ( num == SDLK_DECIMAL ) strcpy(text, "NumPad ."); +// if ( num == SDLK_DIVIDE ) strcpy(text, "NumPad /"); + if ( num == SDLK_F1 ) strcpy(text, "F1"); + if ( num == SDLK_F2 ) strcpy(text, "F2"); + if ( num == SDLK_F3 ) strcpy(text, "F3"); + if ( num == SDLK_F4 ) strcpy(text, "F4"); + if ( num == SDLK_F5 ) strcpy(text, "F5"); + if ( num == SDLK_F6 ) strcpy(text, "F6"); + if ( num == SDLK_F7 ) strcpy(text, "F7"); + if ( num == SDLK_F8 ) strcpy(text, "F8"); + if ( num == SDLK_F9 ) strcpy(text, "F9"); + if ( num == SDLK_F10 ) strcpy(text, "F10"); + if ( num == SDLK_F11 ) strcpy(text, "F11"); + if ( num == SDLK_F12 ) strcpy(text, "F12"); + if ( num == SDLK_F13 ) strcpy(text, "F13"); + if ( num == SDLK_F14 ) strcpy(text, "F14"); + if ( num == SDLK_F15 ) strcpy(text, "F15"); +// if ( num == SDLK_F16 ) strcpy(text, "F16"); +// if ( num == SDLK_F17 ) strcpy(text, "F17"); +// if ( num == SDLK_F18 ) strcpy(text, "F18"); +// if ( num == SDLK_F19 ) strcpy(text, "F19"); +// if ( num == SDLK_F20 ) strcpy(text, "F20"); + if ( num == SDLK_NUMLOCK ) strcpy(text, "Num Lock"); +// if ( num == SDLK_SCROLL ) strcpy(text, "Scroll"); +// if ( num == SDLK_ATTN ) strcpy(text, "Attn"); +// if ( num == SDLK_CRSEL ) strcpy(text, "CrSel"); +// if ( num == SDLK_EXSEL ) strcpy(text, "ExSel"); +// if ( num == SDLK_EREOF ) strcpy(text, "Erase EOF"); +// if ( num == SDLK_PLAY ) strcpy(text, "Play"); +// if ( num == SDLK_ZOOM ) strcpy(text, "Zoom"); +// if ( num == SDLK_PA1 ) strcpy(text, "PA1"); +// if ( num == SDLK_OEM_CLEAR ) strcpy(text, "Clear"); +// if ( num == SDLK_BUTTON1 ) strcpy(text, "Button 1"); +// if ( num == SDLK_BUTTON2 ) strcpy(text, "Button 2"); +// if ( num == SDLK_BUTTON3 ) strcpy(text, "Button 3"); +// if ( num == SDLK_BUTTON4 ) strcpy(text, "Button 4"); +// if ( num == SDLK_BUTTON5 ) strcpy(text, "Button 5"); +// if ( num == SDLK_BUTTON6 ) strcpy(text, "Button 6"); +// if ( num == SDLK_BUTTON7 ) strcpy(text, "Button 7"); +// if ( num == SDLK_BUTTON8 ) strcpy(text, "Button 8"); +// if ( num == SDLK_BUTTON9 ) strcpy(text, "Button 9"); +// if ( num == SDLK_BUTTON10 ) strcpy(text, "Button 10"); +// if ( num == SDLK_BUTTON11 ) strcpy(text, "Button 11"); +// if ( num == SDLK_BUTTON12 ) strcpy(text, "Button 12"); +// if ( num == SDLK_BUTTON13 ) strcpy(text, "Button 13"); +// if ( num == SDLK_BUTTON14 ) strcpy(text, "Button 14"); +// if ( num == SDLK_BUTTON15 ) strcpy(text, "Button 15"); +// if ( num == SDLK_BUTTON16 ) strcpy(text, "Button 16"); +// if ( num == SDLK_BUTTON17 ) strcpy(text, "Button 17"); +// if ( num == SDLK_BUTTON18 ) strcpy(text, "Button 18"); +// if ( num == SDLK_BUTTON19 ) strcpy(text, "Button 19"); +// if ( num == SDLK_BUTTON20 ) strcpy(text, "Button 20"); +// if ( num == SDLK_BUTTON21 ) strcpy(text, "Button 21"); +// if ( num == SDLK_BUTTON22 ) strcpy(text, "Button 22"); +// if ( num == SDLK_BUTTON23 ) strcpy(text, "Button 23"); +// if ( num == SDLK_BUTTON24 ) strcpy(text, "Button 24"); +// if ( num == SDLK_BUTTON25 ) strcpy(text, "Button 25"); +// if ( num == SDLK_BUTTON26 ) strcpy(text, "Button 26"); +// if ( num == SDLK_BUTTON27 ) strcpy(text, "Button 27"); +// if ( num == SDLK_BUTTON28 ) strcpy(text, "Button 28"); +// if ( num == SDLK_BUTTON29 ) strcpy(text, "Button 29"); +// if ( num == SDLK_BUTTON30 ) strcpy(text, "Button 30"); +// if ( num == SDLK_BUTTON31 ) strcpy(text, "Button 31"); +// if ( num == SDLK_BUTTON32 ) strcpy(text, "Button 32"); +// if ( num == SDLK_WHEELUP ) strcpy(text, "Wheel up"); +// if ( num == SDLK_WHEELDOWN ) strcpy(text, "Wheel down"); + } +#endif + +#if _FRENCH + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /f"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /f"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Taille maximale"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Taille r�duite"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Taille normale"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Fermer"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Edition du programme"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "Nouveau"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Joueur"); + if ( num == RT_IO_NEW ) strcpy(text, "Nouveau ..."); + if ( num == RT_KEY_OR ) strcpy(text, " ou "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programmation"); + if ( num == RT_TITLE_DEFI ) strcpy(text, "D�fis"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Missions"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Jeu libre"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Jeu libre"); + if ( num == RT_TITLE_USER ) strcpy(text, "Niveaux suppl�mentaires"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypes"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Options"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Nom du joueur"); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Personnalisation de votre apparence"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Enregistrement de la mission en cours"); + if ( num == RT_TITLE_READ ) strcpy(text, "Chargement d'une mission enregistr�e"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Liste des chapitres :"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Liste des chapitres :"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Liste des plan�tes :"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Liste des plan�tes :"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " Niveaux suppl�mentaires :"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Liste des plan�tes :"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Liste des chapitres :"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " Liste des exercices du chapitre :"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Liste des d�fis du chapitre :"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Liste des missions du chapitre :"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Liste des jeux libres du chapitre :"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Missions du niveau :"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Liste des prototypes du chapitre :"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Liste des jeux libres du chapitre :"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " R�sum� :"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Pilotes :"); + if ( num == RT_SETUP_MODE ) strcpy(text, " R�solutions :"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Cliquez d'abord sur la touche � red�finir."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Appuyez ensuite sur la nouvelle touche souhait�e."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Type de visage :"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Lunettes :"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Couleur des cheveux :"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Couleur de la combinaison :"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Couleur des bandes :"); + +#if _NEWLOOK + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Voulez-vous quitter CeeBot ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quitter\\Quitter CeeBot"); +#else + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Voulez-vous quitter COLOBOT ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Quitter\\Quitter COLOBOT"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Quitter la mission ?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Abandonner\\Abandonner la mission en cours"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Continuer\\Continuer la mission en cours"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Continuer\\Continuer de jouer"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Voulez-vous vraiment d�truire le b�timent s�lectionn� ?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Voulez-vous d�truire les sauvegardes de %s ?"); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "D�truire"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Annuler"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "CHARGEMENT"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Aide sur le mot-cl� (\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Compilation ok (0 erreur)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Programme termin�"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Listes des objets\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Listes des robots\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Listes des b�timents\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Listes des objets transportables\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Listes des ennemis\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (aucun)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Erreur\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Liste non disponible sans \\l;radar\\u object\\radar; !\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "Ouvrir"); + if ( num == RT_IO_SAVE ) strcpy(text, "Enregistrer"); + if ( num == RT_IO_LIST ) strcpy(text, "Dossier: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Nom:"); + if ( num == RT_IO_DIR ) strcpy(text, "Dans:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Priv�\\Dossier priv�"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "Public\\Dossier commun � tous les joueurs"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "D�velopp� par :"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); +#if _SCHOOL + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); +#else + //?if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Version fran�aise �dit�e par :"); + //?if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.alsyd.com"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); +#endif + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Enregistreur"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "D'accord"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Annuler"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Suivant"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Pr�c�dent"); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "D'accord"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Annuler"); + + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Programmation\\Exercices de programmation"); + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "D�fis\\D�fis de programmation"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missions\\La grande aventure"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Jeu libre\\Jeu libre sans but pr�cis"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Jeu libre\\Jeu libre sans but pr�cis"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "Suppl.\\Niveaux suppl�mentaires"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\Prototypes en cours d'�laboration"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Autre joueur\\Choix du nom du joueur"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Options\\R�glages"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Recommencer\\Recommencer la mission au d�but"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Enregistrer\\Enregistrer la mission en cours"); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Charger\\Charger une mission enregistr�e"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Retourner dans CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quitter\\Quitter CeeBot"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Retourner dans COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Quitter\\Quitter COLOBOT"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Retour \\Retour au niveau pr�c�dent"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Jouer ...\\D�marrer l'action"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Affichage\\Pilote et r�solution d'affichage"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Graphique\\Options graphiques"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Jeu\\Options de jouabilit�"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Commandes\\Touches du clavier"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Son\\Volumes bruitages & musiques"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Unit�"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "R�solution"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Plein �cran\\Plein �cran ou fen�tr�"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Appliquer les changements\\Active les changements effectu�s"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Votre assistant"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Ombres\\Ombres projet�es au sol"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Marques sur le sol\\Marques dessin�es sur le sol"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Salissures\\Salissures des robots et b�timents"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Brouillard\\Nappes de brouillard"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Rayons du soleil\\Rayons selon l'orientation"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Ciel\\Ciel et nuages"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Plan�tes et �toiles\\Motifs mobiles dans le ciel"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Lumi�res dynamiques\\Eclairages mobiles"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Quantit� de particules\\Explosions, poussi�res, reflets, etc."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Profondeur de champ\\Distance de vue maximale"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "D�tails des objets\\Qualit� des objets en 3D"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Qualit� des textures\\Qualit� des images"); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Nb d'objets d�coratifs\\Qualit� d'objets non indispensables"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Particules dans l'interface\\Pluie de particules"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Reflets sur les boutons\\Boutons brillants"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Bulles d'aide\\Bulles explicatives"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "S�quences cin�matiques\\Films avant ou apr�s une mission"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Retour anim�\\Retour anim� dans les exercices"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "D�g�ts � soi-m�me\\Vos tirs infligent des dommages � vos unit�s"); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "D�filement dans les bords\\D�filement lorsque la souris touches les bords gauche ou droite"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Inversion souris X\\Inversion de la rotation lorsque la souris touche un bord"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Inversion souris Y\\Inversion de la rotation lorsque la souris touche un bord"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Secousses lors d'explosions\\L'�cran vibre lors d'une explosion"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Souris ombr�e\\Jolie souris avec une ombre"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Indentation automatique\\Pendant l'�dition d'un programme"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Grande indentation\\Indente avec 2 ou 4 espaces"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Acc�s aux solutions\\Programme \"4: Solution\" dans les exercices"); + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Tout r�initialiser\\Remet toutes les touches standards"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Tourner � gauche\\Moteur � gauche"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Tourner � droite\\Moteur � droite"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Avancer\\Moteur en avant"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Reculer\\Moteur en arri�re"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Monter\\Augmenter la puissance du r�acteur"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Descendre\\Diminuer la puissance du r�acteur"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Changement de cam�ra\\Autre de point de vue"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "S�lection pr�c�dente\\S�lectionne l'objet pr�c�dent"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Action standard\\Action du bouton avec le cadre rouge"); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Cam�ra plus proche\\Avance la cam�ra"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Cam�ra plus loin\\Recule la cam�ra"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "S�lectionner l'objet suivant\\S�lectionner l'objet suivant"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "S�lectionner le cosmonaute\\S�lectionner le cosmonaute"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Quitter la mission en cours\\Terminer un exercice ou une mssion"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Instructions mission\\Marche � suivre"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Instructions programmation\\Explication sur la programmation"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Instructions mot-cl�\\Explication sur le mot-cl�"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Montrer le lieu d'un message\\Montrer le lieu du dernier message"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Vitesse 1.0x\\Vitesse normale"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Vitesse 1.5x\\Une fois et demi plus rapide"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Vitesse 2.0x\\Deux fois plus rapide"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Vitesse 3.0x\\Trois fois plus rapide"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Bruitages :\\Volume des moteurs, voix, etc."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Fond sonore :\\Volume des pistes audio du CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "Bruitages 3D\\Positionnement sonore dans l'espace"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Mini\\Qualit� minimale (+ rapide)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Qualit� standard"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Maxi\\Haute qualit� (+ lent)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Silencieux\\Totalement silencieux"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Niveaux normaux"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Utilise un joystick\\Joystick ou clavier"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Acc�s � la solution\\Donne la solution"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Nom du joueur � cr�er"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "D'accord\\Choisir le joueur"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Annuler\\Conserver le joueur actuel"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Supprimer le joueur\\Supprimer le joueur de la liste"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Nom du joueur"); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Enregistrer\\Enregistrer la mission en cours"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Charger\\Charger la mission s�lectionn�e"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Liste des missions enregistr�es"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Nom du fichier :"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Nom de la mission"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Vue de la mission"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Supprimer\\Supprime l'enregistrement s�lectionn�"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Aspect\\Choisir votre aspect"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "D'accord"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Annuler"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Remet les couleurs standards"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "T�te\\Visage et cheveux"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Corps\\Combinaison"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Rotation � gauche"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Rotation � droite"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Rouge"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Vert"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Bleu"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Rouge"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Vert"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Bleu"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Visage 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Visage 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Visage 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Visage 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Pas de lunettes"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Lunettes 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Lunettes 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Lunettes 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Lunettes 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Lunettes 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "S�lection pr�c�dente (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Tourne � gauche (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Tourne � droite (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Avance (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Recule (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Monte (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Descend (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Prend ou d�pose (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Prend ou d�pose (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..devant"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..derri�re"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..pile"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Instructions sur la mission (\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "D�colle pour terminer la mission"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Construit un derrick"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Construit une station"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Construit une fabrique de robots"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Construit un centre de r�paration"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Construit un convertisseur"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Construit une tour"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Construit un centre de recherches"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Construit un radar"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Construit une fabrique de piles"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Construit un laboratoire"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Construit une centrale nucl�aire"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Construit un paratonnerre"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Construit une borne d'information"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Montre si le sol est plat"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Pose un drapeau de couleur"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Enl�ve un drapeau"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Drapeaux bleus"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Drapeaux rouges"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Drapeaux verts"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Drapeaux jaunes"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Drapeaux violets"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Fabrique un d�m�nageur volant"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Fabrique un d�m�nageur � chenilles"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Fabrique un d�m�nageur � roues"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Fabrique un d�m�nageur � pattes"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Fabrique un shooter volant"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Fabrique un shooter � chenilles"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Fabrique un shooter � roues"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Fabrique un shooter � pattes"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Fabrique un orgaShooter volant"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Fabrique un orgaShooter � chenilles"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Fabrique un orgaShooter � roues"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Fabrique un orgaShooter � pattes"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Fabrique un renifleur volant"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Fabrique un renifleur � chenilles"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Fabrique un renifleur � roues"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Fabrique un renifleur � pattes"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Fabrique un robot secoueur"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Fabrique un robot phazer"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Fabrique un robot recycleur"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Fabrique un robot bouclier"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Fabrique un robot sous-marin"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Recherche les chenilles"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Recherche les robots volants"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Recherche le secoueur"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Recherche le canon shooter"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Recherche la tour de d�fense"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Recherche le canon phazer"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Recherche le bouclier"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Recherche le nucl�aire"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Recherche les pattes"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Recherche le canon orgaShooter"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Remet au d�part"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Cherche (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Secoue (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Tir (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recycle (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "D�ploie le bouclier (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Stoppe le bouclier (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Rayon du bouclier"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Ex�cute le programme s�lectionn�"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edite le programme s�lectionn�"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\Mettre le SatCom en veille"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "D�molit le b�timent"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Niveau d'�nergie"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Niveau du bouclier"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Temp�rature du r�acteur"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Travail en cours ..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Nombre d'insectes d�tect�s"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Informations diffus�es"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Boussole"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mini-carte"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom mini-carte"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Cam�ra (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Cam�ra � gauche"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Cam�ra � droite"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Cam�ra plus proche"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Cam�ra plus loin"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Instructions sur la s�lection"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Donne la solution"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Permute robots <-> b�timents"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Montre le rayon d'action"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Rel�ve le crayon"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Abaisse le crayon noir"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Abaisse le crayon jaune"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Abaisse le crayon orange"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Abaisse le crayon rouge"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Abaisse le crayon violet"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Abaisse le crayon bleu"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Abaisse le crayon vert"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Abaisse le crayon brun"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\D�marre l'enregistrement"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stoppe l'enregistrement"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Montre l'endroit"); + if ( num == EVENT_DT_END ) strcpy(text, "Continuer"); + if ( num == EVENT_CMD ) strcpy(text, "Console de commande"); + if ( num == EVENT_SPEED ) strcpy(text, "Vitesse du jeu"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Page pr�c�dente"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Page suivante"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Page initiale"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Copier"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Taille 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Taille 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Taille 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Taille 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Taille 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Instructions de Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Dictionnaire anglais-fran�ais"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Rapport du satellite"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Programmes envoy�s par Houston"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Liste des objets"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Aide � la programmation"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Solution"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "D'accord\\Compiler le programme"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Annuler\\Annuler toutes les modifications"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Nouveau"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Ouvrir (Ctrl+o)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Enregistrer (Ctrl+s)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Annuler (Ctrl+z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Couper (Ctrl+x)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Copier (Ctrl+c)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Coller (Ctrl+v)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Taille des caract�res"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Instructions (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Aide � la programmation (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Compiler"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "D�marrer/stopper"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/continuer"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Un pas"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "Portique"); + if ( num == OBJECT_BASE ) strcpy(text, "Vaisseau spatial"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Derrick"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Fabrique de robots"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Centre de r�paration"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Destructeur"); + if ( num == OBJECT_STATION ) strcpy(text, "Station de recharge"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Conversion minerai en titanium"); + if ( num == OBJECT_TOWER ) strcpy(text, "Tour de d�fense"); + if ( num == OBJECT_NEST ) strcpy(text, "Nid"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Centre de recherches"); + if ( num == OBJECT_RADAR ) strcpy(text, "Radar"); + if ( num == OBJECT_INFO ) strcpy(text, "Borne d'information"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "D�sint�grateur"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Fabrique de piles"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Laboratoire de mati�res organiques"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Centrale nucl�aire"); + if ( num == OBJECT_PARA ) strcpy(text, "Paratonnerre"); + if ( num == OBJECT_SAFE ) strcpy(text, "Coffre-fort"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Centre de contr�le"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Cible"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Cible"); + if ( num == OBJECT_START ) strcpy(text, "D�part"); + if ( num == OBJECT_END ) strcpy(text, "But"); + if ( num == OBJECT_STONE ) strcpy(text, "Minerai de titanium"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Minerai d'uranium"); + if ( num == OBJECT_BULLET ) strcpy(text, "Mati�re organique"); + if ( num == OBJECT_METAL ) strcpy(text, "Titanium"); + if ( num == OBJECT_POWER ) strcpy(text, "Pile normale"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Pile nucl�aire"); + if ( num == OBJECT_BBOX ) strcpy(text, "Bo�te noire"); + if ( num == OBJECT_KEYa ) strcpy(text, "Cl� A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Cl� B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Cl� C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Cl� D"); + if ( num == OBJECT_TNT ) strcpy(text, "Explosif"); + if ( num == OBJECT_BOMB ) strcpy(text, "Mine fixe"); + if ( num == OBJECT_BAG ) strcpy(text, "Sac de survie"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Indicateur"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Drapeau bleu"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Drapeau rouge"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Drapeau vert"); + if ( num == OBJECT_FLAGy ) strcpy(text, "Drapeau jaune"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Drapeau violet"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "Emplacement pour station"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Emplacement pour derrick (uranium)"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Emplacement pour derrick (cl� A)"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Emplacement pour derrick (cl� B)"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Emplacement pour derrick (cl� C)"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Emplacement pour derrick (cl� D)"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Emplacement pour derrick (titanium)"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "Robot d'entra�nement"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "Robot d'entra�nement"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "Robot d'entra�nement"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "Robot d'entra�nement"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Robot d�m�nageur"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Robot d�m�nageur"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Robot d�m�nageur"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Robot d�m�nageur"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Robot shooter"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "Robot orgaShooter"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Robot renifleur"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Robot secoueur"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Robot phazer"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Robot recycleur"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Robot bouclier"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Robot sous-marin"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Cible d'entra�nement"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Robot dessinateur"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "Technicien"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Pondeuse"); + if ( num == OBJECT_ANT ) strcpy(text, "Fourmi"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Araign�e"); + if ( num == OBJECT_BEE ) strcpy(text, "Gu�pe"); + if ( num == OBJECT_WORM ) strcpy(text, "Ver"); + if ( num == OBJECT_EGG ) strcpy(text, "Oeuf"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Epave de robot"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "B�timent en ruine"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "B�timent en ruine"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "D�chet"); + if ( num == OBJECT_RUINradar ) strcpy(text, "B�timent en ruine"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "B�timent en ruine"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Epave de vaisseau spatial"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Epave de vaisseau spatial"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "Vestige d'une mission Apollo"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "Erreur"); + if ( num == ERR_CMD ) strcpy(text, "Commande inconnue"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "CeeBot n'est pas install�."); + if ( num == ERR_NOCD ) strcpy(text, "Veuillez mettre le CD de CeeBot\net relancer le jeu."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT n'est pas install�."); + if ( num == ERR_NOCD ) strcpy(text, "Veuillez mettre le CD de COLOBOT\net relancer le jeu."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Robot inadapt�"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Porte d�j� quelque chose"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Rien � prendre"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Emplacement occup�"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Pas d'autre robot"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "Vous ne pouvez pas transporter un objet radioactif"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "Vous ne pouvez pas transporter un objet sous l'eau"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Rien � d�poser"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Impossible sous l'eau"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Pas assez d'�nergie"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titanium trop loin"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titanium trop proche"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Titanium inexistant"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Sol pas assez plat"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Sol plat pas assez grand"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Emplacement occup�"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Trop proche du vaisseau spatial"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Trop proche d'un b�timent"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Robot inadapt�"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Robot inadapt�"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Pas assez d'�nergie"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Terrain inadapt�"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "B�timent trop proche"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Objet trop proche"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Robot inadapt�"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Pas assez d'�nergie"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Rien � recycler"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Robot inadapt�"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Plus d'�nergie"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "D�placement impossible"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Objet n'existe pas"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Chemin introuvable"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Position inaccessible"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Destination occup�e"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Robot inadapt�"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Pas assez d'�nergie"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Pas de minerai de titanium � convertir"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "Pas de minerai en sous-sol"); + if ( num == ERR_STATION_NULL ) strcpy(text, "Pas d'�nergie en sous-sol"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "Pas de pile"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Plus d'�nergie"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Pas de pile"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Plus assez d'�nergie"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Pas le bon type de pile"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Recherche d�j� effectu�e"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "Pas d'�nergie en sous-sol"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Pas encore assez d'�nergie"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Pas de titanium � transformer"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Ne transforme que le titanium"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Portes bloqu�es par un robot ou un objet"); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Vous devez embarquer pour pouvoir d�coller"); + if ( num == ERR_LABO_NULL ) strcpy(text, "Rien � analyser"); + if ( num == ERR_LABO_BAD ) strcpy(text, "N'analyse que la mati�re organique"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analyse d�j� effectu�e"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Pas d'�nergie en sous-sol"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Pas encore assez d'�nergie"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Pas d'uranium � transformer"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Ne transforme que l'uranium"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "Pas de titanium"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Quelque chose est trop proche"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Emplacement occup�"); + if ( num == ERR_INFO_NULL ) strcpy(text, "Pas trouv� de borne d'information"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Un programme est infect� par un virus"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Infect� par un virus, ne fonctionne plus temporairement"); + if ( num == ERR_VEH_POWER ) strcpy(text, "Pas de pile"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "Plus d'�nergie"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Impossible en vol"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Impossible en nageant"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Impossible en mouvement"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Impossible en portant un objet"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Trop de drapeaux de cette couleur (maximum 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Trop proche d'un drapeau existant"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "Aucun drapeau � proximit�"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "La misssion n'est pas termin�e (appuyez sur \\key help; pour plus de d�tails)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Robot d�truit"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "B�timent d�truit"); + if ( num == ERR_TOOMANY ) strcpy(text, "Cr�ation impossible, il y a trop d'objets"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "Il manque \"%s\" dans le programme"); + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Interdit dans cet exercice"); + + if ( num == INFO_BUILD ) strcpy(text, "B�timent termin�"); + if ( num == INFO_CONVERT ) strcpy(text, "Titanium disponible"); + if ( num == INFO_RESEARCH ) strcpy(text, "Recherche termin�e"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Fabrication d'un robot � chenilles possible"); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "Il est possible de voler avec les touches (\\key gup;) et (\\key gdown;)"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Fabrication d'un robot secoueur possible"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Fabrication de robots shooter possible"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Construction d'une tour de d�fense possible"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Fabrication d'un robot phazer possible"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Fabrication d'un robot bouclier possible"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Construction d'une centrale nucl�aire possible"); + if ( num == INFO_FACTORY ) strcpy(text, "Nouveau robot disponible"); + if ( num == INFO_LABO ) strcpy(text, "Analyse termin�e"); + if ( num == INFO_ENERGY ) strcpy(text, "Pile disponible"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Pile nucl�aire disponible"); + if ( num == INFO_FINDING ) strcpy(text, "Vous avez trouv� un objet utilisable"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Emplacement pour station trouv�"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Emplacement pour derrick trouv�"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Emplacement pour derrick trouv�"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Emplacement pour derrick trouv�"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Emplacement pour derrick trouv�"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Emplacement pour derrick trouv�"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Emplacement pour derrick trouv�"); + if ( num == INFO_WIN ) strcpy(text, "<<< Bravo, mission termin�e >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< D�sol�, mission �chou�e >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< D�sol�, mission �chou�e >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Enregistrement effectu�"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Indicateur atteint"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Pondeuse mortellement touch�e"); + if ( num == INFO_DELETEANT ) strcpy(text, "Fourmi mortellement touch�e"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Gu�pe mortellement touch�e"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Ver mortellement touch�"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Araign�e mortellement touch�e"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Consultez votre SatCom en appuyant sur \\key help;"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "Erreur"); + if ( num == TX_OPENPAR ) strcpy(text, "Il manque une parenth�se ouvrante"); + if ( num == TX_CLOSEPAR ) strcpy(text, "Il manque une parenth�se fermante"); + if ( num == TX_NOTBOOL ) strcpy(text, "L'expression doit �tre un boolean"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Variable non d�clar�e"); + if ( num == TX_BADLEFT ) strcpy(text, "Assignation impossible"); + if ( num == TX_ENDOF ) strcpy(text, "Terminateur point-virgule non trouv�"); + if ( num == TX_OUTCASE ) strcpy(text, "Instruction ""case"" hors d'un bloc ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Instructions apr�s la fin"); + if ( num == TX_CLOSEBLK ) strcpy(text, "Il manque la fin du bloc"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Instruction ""else"" sans ""if"" correspondant"); + if ( num == TX_OPENBLK ) strcpy(text, "D�but d'un bloc attendu"); + if ( num == TX_BADTYPE ) strcpy(text, "Mauvais type de r�sultat pour l'assignation"); + if ( num == TX_REDEFVAR ) strcpy(text, "Red�finition d'une variable"); + if ( num == TX_BAD2TYPE ) strcpy(text, "Les deux op�randes ne sont pas de types compatibles"); + if ( num == TX_UNDEFCALL ) strcpy(text, "Routine inconnue"); + if ( num == TX_MISDOTS ) strcpy(text, "S�parateur "" : "" attendu"); + if ( num == TX_WHILE ) strcpy(text, "Manque le mot ""while"""); + if ( num == TX_BREAK ) strcpy(text, "Instruction ""break"" en dehors d'une boucle"); + if ( num == TX_LABEL ) strcpy(text, "Un label ne peut se placer que devant un ""for"", un ""while"", un ""do"" ou un ""switch"""); + if ( num == TX_NOLABEL ) strcpy(text, "Cette �tiquette n'existe pas"); + if ( num == TX_NOCASE ) strcpy(text, "Manque une instruction ""case"""); + if ( num == TX_BADNUM ) strcpy(text, "Un nombre est attendu"); + if ( num == TX_VOID ) strcpy(text, "Param�tre void"); + if ( num == TX_NOTYP ) strcpy(text, "D�claration de type attendu"); + if ( num == TX_NOVAR ) strcpy(text, "Nom d'une variable attendu"); + if ( num == TX_NOFONC ) strcpy(text, "Nom de la fonction attendu"); + if ( num == TX_OVERPARAM ) strcpy(text, "Trop de param�tres"); + if ( num == TX_REDEF ) strcpy(text, "Cette fonction existe d�j�"); + if ( num == TX_LOWPARAM ) strcpy(text, "Pas assez de param�tres"); + if ( num == TX_BADPARAM ) strcpy(text, "Aucune fonction de ce nom n'accepte ce(s) type(s) de param�tre(s)"); + if ( num == TX_NUMPARAM ) strcpy(text, "Aucune fonction de ce nom n'accepte ce nombre de param�tres"); + if ( num == TX_NOITEM ) strcpy(text, "Cet �l�ment n'existe pas dans cette classe"); + if ( num == TX_DOT ) strcpy(text, "L'objet n'est pas une instance d'une classe"); + if ( num == TX_NOCONST ) strcpy(text, "Il n'y a pas de constructeur appropri�"); + if ( num == TX_REDEFCLASS ) strcpy(text, "Cette classe existe d�j�"); + if ( num == TX_CLBRK ) strcpy(text, """ ] "" attendu"); + if ( num == TX_RESERVED ) strcpy(text, "Ce mot est r�serv�"); + if ( num == TX_BADNEW ) strcpy(text, "Mauvais argument pour ""new"""); + if ( num == TX_OPBRK ) strcpy(text, """ [ "" attendu"); + if ( num == TX_BADSTRING ) strcpy(text, "Une cha�ne de caract�re est attendue"); + if ( num == TX_BADINDEX ) strcpy(text, "Mauvais type d'index"); + if ( num == TX_PRIVATE ) strcpy(text, "El�ment prot�g�"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Public requis"); + if ( num == TX_DIVZERO ) strcpy(text, "Division par z�ro"); + if ( num == TX_NOTINIT ) strcpy(text, "Variable non initialis�e"); + if ( num == TX_BADTHROW ) strcpy(text, "Valeur n�gative refus�e pour ""throw"""); + if ( num == TX_NORETVAL ) strcpy(text, "La fonction n'a pas retourn� de r�sultat"); + if ( num == TX_NORUN ) strcpy(text, "Pas de fonction en ex�cution"); + if ( num == TX_NOCALL ) strcpy(text, "Appel d'une fonction inexistante"); + if ( num == TX_NOCLASS ) strcpy(text, "Cette classe n'existe pas"); + if ( num == TX_NULLPT ) strcpy(text, "Objet n'existe pas"); + if ( num == TX_OPNAN ) strcpy(text, "Op�ration sur un ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Acc�s hors du tableau"); + if ( num == TX_STACKOVER ) strcpy(text, "D�bordement de la pile"); + if ( num == TX_DELETEDPT ) strcpy(text, "Objet inaccessible"); + if ( num == TX_FILEOPEN ) strcpy(text, "Ouverture du fichier impossible"); + if ( num == TX_NOTOPEN ) strcpy(text, "Le fichier n'est pas ouvert"); + if ( num == TX_ERRREAD ) strcpy(text, "Erreur � la lecture"); + if ( num == TX_ERRWRITE ) strcpy(text, "Erreur � l'�criture"); + } + + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< aucune >"); + if ( num == SDLK_LEFT ) strcpy(text, "Fl�che Gauche"); + if ( num == SDLK_RIGHT ) strcpy(text, "Fl�che Droite"); + if ( num == SDLK_UP ) strcpy(text, "Fl�che Haut"); + if ( num == SDLK_DOWN ) strcpy(text, "Fl�che Bas"); + if ( num == SDLK_CANCEL ) strcpy(text, "Control-break"); + if ( num == SDLK_BACK ) strcpy(text, "<--"); + if ( num == SDLK_TAB ) strcpy(text, "Tab"); + if ( num == SDLK_CLEAR ) strcpy(text, "Clear"); + if ( num == SDLK_RETURN ) strcpy(text, "Entr�e"); + if ( num == SDLK_SHIFT ) strcpy(text, "Shift"); + if ( num == SDLK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == SDLK_MENU ) strcpy(text, "Alt"); + if ( num == SDLK_PAUSE ) strcpy(text, "Pause"); + if ( num == SDLK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == SDLK_ESCAPE ) strcpy(text, "Esc"); + if ( num == SDLK_SPACE ) strcpy(text, "Espace"); + if ( num == SDLK_PRIOR ) strcpy(text, "Page Up"); + if ( num == SDLK_NEXT ) strcpy(text, "Page Down"); + if ( num == SDLK_END ) strcpy(text, "End"); + if ( num == SDLK_HOME ) strcpy(text, "Home"); + if ( num == SDLK_SELECT ) strcpy(text, "Select"); + if ( num == SDLK_EXECUTE ) strcpy(text, "Execute"); + if ( num == SDLK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == SDLK_INSERT ) strcpy(text, "Insert"); + if ( num == SDLK_DELETE ) strcpy(text, "Delete"); + if ( num == SDLK_HELP ) strcpy(text, "Help"); + if ( num == SDLK_LWIN ) strcpy(text, "Left Windows"); + if ( num == SDLK_RWIN ) strcpy(text, "Right Windows"); + if ( num == SDLK_APPS ) strcpy(text, "Application key"); + if ( num == SDLK_NUMPAD0 ) strcpy(text, "NumPad 0"); + if ( num == SDLK_NUMPAD1 ) strcpy(text, "NumPad 1"); + if ( num == SDLK_NUMPAD2 ) strcpy(text, "NumPad 2"); + if ( num == SDLK_NUMPAD3 ) strcpy(text, "NumPad 3"); + if ( num == SDLK_NUMPAD4 ) strcpy(text, "NumPad 4"); + if ( num == SDLK_NUMPAD5 ) strcpy(text, "NumPad 5"); + if ( num == SDLK_NUMPAD6 ) strcpy(text, "NumPad 6"); + if ( num == SDLK_NUMPAD7 ) strcpy(text, "NumPad 7"); + if ( num == SDLK_NUMPAD8 ) strcpy(text, "NumPad 8"); + if ( num == SDLK_NUMPAD9 ) strcpy(text, "NumPad 9"); + if ( num == SDLK_MULTIPLY ) strcpy(text, "NumPad *"); + if ( num == SDLK_ADD ) strcpy(text, "NumPad +"); + if ( num == SDLK_SEPARATOR ) strcpy(text, "NumPad sep"); + if ( num == SDLK_SUBTRACT ) strcpy(text, "NumPad -"); + if ( num == SDLK_DECIMAL ) strcpy(text, "NumPad ."); + if ( num == SDLK_DIVIDE ) strcpy(text, "NumPad /"); + if ( num == SDLK_F1 ) strcpy(text, "F1"); + if ( num == SDLK_F2 ) strcpy(text, "F2"); + if ( num == SDLK_F3 ) strcpy(text, "F3"); + if ( num == SDLK_F4 ) strcpy(text, "F4"); + if ( num == SDLK_F5 ) strcpy(text, "F5"); + if ( num == SDLK_F6 ) strcpy(text, "F6"); + if ( num == SDLK_F7 ) strcpy(text, "F7"); + if ( num == SDLK_F8 ) strcpy(text, "F8"); + if ( num == SDLK_F9 ) strcpy(text, "F9"); + if ( num == SDLK_F10 ) strcpy(text, "F10"); + if ( num == SDLK_F11 ) strcpy(text, "F11"); + if ( num == SDLK_F12 ) strcpy(text, "F12"); + if ( num == SDLK_F13 ) strcpy(text, "F13"); + if ( num == SDLK_F14 ) strcpy(text, "F14"); + if ( num == SDLK_F15 ) strcpy(text, "F15"); + if ( num == SDLK_F16 ) strcpy(text, "F16"); + if ( num == SDLK_F17 ) strcpy(text, "F17"); + if ( num == SDLK_F18 ) strcpy(text, "F18"); + if ( num == SDLK_F19 ) strcpy(text, "F19"); + if ( num == SDLK_F20 ) strcpy(text, "F20"); + if ( num == SDLK_NUMLOCK ) strcpy(text, "Num Lock"); + if ( num == SDLK_SCROLL ) strcpy(text, "Scroll"); + if ( num == SDLK_ATTN ) strcpy(text, "Attn"); + if ( num == SDLK_CRSEL ) strcpy(text, "CrSel"); + if ( num == SDLK_EXSEL ) strcpy(text, "ExSel"); + if ( num == SDLK_EREOF ) strcpy(text, "Erase EOF"); + if ( num == SDLK_PLAY ) strcpy(text, "Play"); + if ( num == SDLK_ZOOM ) strcpy(text, "Zoom"); + if ( num == SDLK_PA1 ) strcpy(text, "PA1"); + if ( num == SDLK_OEM_CLEAR ) strcpy(text, "Clear"); + if ( num == SDLK_BUTTON1 ) strcpy(text, "Bouton 1"); + if ( num == SDLK_BUTTON2 ) strcpy(text, "Bouton 2"); + if ( num == SDLK_BUTTON3 ) strcpy(text, "Bouton 3"); + if ( num == SDLK_BUTTON4 ) strcpy(text, "Bouton 4"); + if ( num == SDLK_BUTTON5 ) strcpy(text, "Bouton 5"); + if ( num == SDLK_BUTTON6 ) strcpy(text, "Bouton 6"); + if ( num == SDLK_BUTTON7 ) strcpy(text, "Bouton 7"); + if ( num == SDLK_BUTTON8 ) strcpy(text, "Bouton 8"); + if ( num == SDLK_BUTTON9 ) strcpy(text, "Bouton 9"); + if ( num == SDLK_BUTTON10 ) strcpy(text, "Bouton 10"); + if ( num == SDLK_BUTTON11 ) strcpy(text, "Bouton 11"); + if ( num == SDLK_BUTTON12 ) strcpy(text, "Bouton 12"); + if ( num == SDLK_BUTTON13 ) strcpy(text, "Bouton 13"); + if ( num == SDLK_BUTTON14 ) strcpy(text, "Bouton 14"); + if ( num == SDLK_BUTTON15 ) strcpy(text, "Bouton 15"); + if ( num == SDLK_BUTTON16 ) strcpy(text, "Bouton 16"); + if ( num == SDLK_BUTTON17 ) strcpy(text, "Bouton 17"); + if ( num == SDLK_BUTTON18 ) strcpy(text, "Bouton 18"); + if ( num == SDLK_BUTTON19 ) strcpy(text, "Bouton 19"); + if ( num == SDLK_BUTTON20 ) strcpy(text, "Bouton 20"); + if ( num == SDLK_BUTTON21 ) strcpy(text, "Bouton 21"); + if ( num == SDLK_BUTTON22 ) strcpy(text, "Bouton 22"); + if ( num == SDLK_BUTTON23 ) strcpy(text, "Bouton 23"); + if ( num == SDLK_BUTTON24 ) strcpy(text, "Bouton 24"); + if ( num == SDLK_BUTTON25 ) strcpy(text, "Bouton 25"); + if ( num == SDLK_BUTTON26 ) strcpy(text, "Bouton 26"); + if ( num == SDLK_BUTTON27 ) strcpy(text, "Bouton 27"); + if ( num == SDLK_BUTTON28 ) strcpy(text, "Bouton 28"); + if ( num == SDLK_BUTTON29 ) strcpy(text, "Bouton 29"); + if ( num == SDLK_BUTTON30 ) strcpy(text, "Bouton 30"); + if ( num == SDLK_BUTTON31 ) strcpy(text, "Bouton 31"); + if ( num == SDLK_BUTTON32 ) strcpy(text, "Bouton 32"); + if ( num == SDLK_WHEELUP ) strcpy(text, "Molette haut"); + if ( num == SDLK_WHEELDOWN ) strcpy(text, "Molette bas"); + } +#endif + +#if _GERMAN | _WG + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "1.18 /d"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /d"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Gro�es Fenster"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Reduzieren"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normale Gr��e"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Schlie�en"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Programmeditor"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "Neu"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Spieler"); + if ( num == RT_IO_NEW ) strcpy(text, "Neu ..."); + if ( num == RT_KEY_OR ) strcpy(text, " oder "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif +#if _SCHOOL + if ( num == RT_TITLE_TRAINER ) strcpy(text, "�bungen"); +#else + if ( num == RT_TITLE_TRAINER ) strcpy(text, "Programmieren"); +#endif + if ( num == RT_TITLE_DEFI ) strcpy(text, "Challenges"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Missionen"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Freestyle"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Freestyle"); + if ( num == RT_TITLE_USER ) strcpy(text, "Userlevels"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypen"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Einstellungen"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Name "); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Aussehen einstellen"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Aktuelle Mission speichern"); + if ( num == RT_TITLE_READ ) strcpy(text, "Gespeicherte Mission laden"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Liste der Kapitel:"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Liste der Kapitel:"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Liste der Planeten:"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Liste der Planeten:"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " Userlevels:"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Liste der Planeten:"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Liste der Kapitel:"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " Liste der �bungen des Kapitels:"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Liste der Challenges des Kapitels:"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Liste der Missionen des Planeten:"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Liste der freien Levels des Planeten:"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Missionen des Userlevels:"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Liste der Prototypen des Planeten:"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Liste der freien Levels des Kapitel:"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " Zusammenfassung:"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Driver:"); + if ( num == RT_SETUP_MODE ) strcpy(text, " Aufl�sung:"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Klicken Sie auf die neu zu definierende Taste."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Dr�cken Sie auf die neue Taste."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Kopf:"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Brille:"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Haarfarbe:"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Farbe des Anzugs:"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Farbe der Streifen:"); + +#if _NEWLOOK + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Wollen Sie CeeBot schlie�en ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Schlie�en\\CeeBot schlie�en"); +#else + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Wollen Sie COLOBOT schlie�en ?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Schlie�en\\COLOBOT schlie�en"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Mission abbrechen ?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Abbrechen\\Mission abbrechen"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Weitermachen\\Mission weitermachen"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Weitermachen\\Weitermachen"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Wollen Sie das angew�hlte Geb�ude wirklich zerst�ren ?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Wollen Sie die gespeicherten Missionen von %s l�schen ?"); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Zerst�ren"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Abbrechen"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "Laden"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Hilfe �ber den Begriff (\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Kompilieren OK (0 Fehler)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Programm beendet"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Liste der Objekte\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Liste der Roboter\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Listes der Geb�ude\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Listes der tragbaren Gegenst�nde\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Listes der Feinde\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (keine)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;Fehler\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Die Liste ist ohne \\l;Radar\\u object\\radar; nicht verf�gbar !\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "�ffnen"); + if ( num == RT_IO_SAVE ) strcpy(text, "Speichern"); + if ( num == RT_IO_LIST ) strcpy(text, "Ordner: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Name:"); + if ( num == RT_IO_DIR ) strcpy(text, "In:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Privat\\Privater Ordner"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "�ffentlich\\Gemeinsamer Ordner f�r alle Spieler"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Entwickelt von:"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); +#if _WG + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Herausgegeben von:"); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.wg-verlag.ch"); +#else + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); +#endif + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Abbrechen"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "N�chster"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Vorherg."); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Men� (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Abbrechen"); + +#if _SCHOOL + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "�bungen\\Programmier�bungen"); +#else + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "Programmieren\\Programmier�bungen"); +#endif + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Challenges\\Herausforderungen"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Missionen\\Aufbruch ins Weltall"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Freestyle\\Freies Spielen ohne vorgegebenes Ziel"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Freestyle\\Freies Spielen ohne vorgegebenes Ziel"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "User\\Userlevels"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Proto\\In Entwicklung befindliche Prototypen"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Anderer Spieler\\Spielername �ndern"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Einstellungen\\Einstellungen"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Neu anfangen\\Die Mission von vorne anfangen"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Speichern\\Aktuelle Mission speichern"); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Laden\\Eine gespeicherte Mission �ffnen"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Zur�ck zu CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Schlie�en\\CeeBot schlie�en"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Zur�ck zu COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Schlie�en\\COLOBOT schlie�en"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Zur�ck \\Zur�ck zum Hauptmen�"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Spielen ...\\Los geht's"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Bildschirm\\Driver und Bildschirmaufl�sung"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Grafik\\Grafische Einstellungen"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Spiel\\Gameplay Einstellungen"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Steuerung\\Auswahl der Tasten"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "Ger�usche\\Lautst�rke Ger�usche und Musik"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Einheit"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Aufl�sung"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Vollbildschirm\\Vollbildschirm oder Fenster"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "�nderungen ausf�hren\\Get�tigte Einstellungen ausf�hren"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robby\\Ihr Assistent"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Schatten\\Schlagschatten auf dem Boden"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Markierungen\\Markierungen auf dem Boden"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Schmutz\\Schmutz auf Robotern und Bauten"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Nebel\\Nebelschwaden"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Sonnenstrahlen\\Sonnenstrahlen"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Himmel\\Himmel und Wolken"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planeten und Sterne\\Kreisende Planeten und Sterne"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamische Beleuchtung\\Dynamische Beleuchtung"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Anzahl Partikel\\Explosionen, Staub, usw."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "Sichtweite\\Maximale Sichtweite"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Details\\Detailliertheit der Objekte in 3D"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Qualit�t der Texturen\\Qualit�t der Anzeige"); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Anzahl Ziergegenst�nde\\Anzahl Gegenst�nde ohne Funktion"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Partikel in den Men�s\\Funken und Sterne in den Men�s"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Gl�nzende Tasten\\Gl�nzende Tasten in den Men�s"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Hilfsblasen\\Hilfsblasen"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Filme\\Filme vor und nach den Missionen"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Zur�cksetzen \\Kleine Show beim Zur�cksetzen in den �bungen"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Eigenbeschuss\\Ihre Einheiten werden von Ihren Waffen besch�digt."); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Kameradrehung mit der Maus\\Die Kamera dreht wenn die Maus den Rand erreicht"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Umkehr X\\Umkehr der Kameradrehung X-Achse"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Umkehr Y\\Umkehr der Kameradrehung Y-Achse"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Beben bei Explosionen\\Die Kamera bebt bei Explosionen"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Schatten unter der Maus\\Ein Schatten erscheint unter der Maus"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatisches Einr�cken\\Beim Bearbeiten der Programme"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Einr�cken mit 4 Leerstellen\\Einr�cken mit 2 oder 4 Leerstellen"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "L�sung zug�nglich\\Die L�sung ist im Programmslot \"4: L�sung\" zug�nglich"); + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Alles zur�cksetzen\\Standarddefinition aller Tasten"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Drehung nach links\\Steuer links"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Drehung nach rechts\\Steuer rechts"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Vorw�rts\\Bewegung nach vorne"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "R�ckw�rts\\Bewegung nach hinten"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "Steigen\\Leistung des Triebwerks steigern"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "Sinken\\Leistung des Triebwerks drosseln"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Andere Kamera\\Sichtpunkt einstellen"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Vorherg. Auswahl\\Das vorhergehende Objekt ausw�hlen"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standardhandlung\\F�hrt die Standardhandlung des Roboters aus."); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Kamera n�her\\Bewegung der Kamera vorw�rts"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Kamera weiter\\Bewegung der Kamera r�ckw�rts"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "N�chstes ausw�hlen\\N�chstes Objekt ausw�hlen"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Astronauten ausw�hlen\\Astronauten ausw�hlen"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Mission verlassen\\Eine Mission oder �bung verlassen"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Anweisungen\\Anweisungen f�r die Mission oder �bung"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Hilfe CBOT-Sprache\\Hilfe �ber die Programmiersprache CBOT"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Hilfe �ber Begriff\\Hilfe �ber einen Begriff"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Ort der Meldung\\Zeigt den Ort, von dem die letzte Meldung stammt"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Geschwindigkeit 1.0x\\Normale Spielgeschwindigkeit"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Geschwindigkeit 1.5x\\Spielgeschwindigkeit anderthalb Mal schneller"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Geschwindigkeit 2.0x\\Spielgeschwindigkeit doppelt so schnell"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Geschwindigkeit 3.0x\\Spielgeschwindigkeit drei Mal schneller"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Ger�usche:\\Lautst�rke Motoren, Stimmen, usw."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Ger�uschkulisse:\\Lautst�rke der Soundtracks der CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "3D-Ger�usche\\Orten der Ger�usche im Raum"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Min.\\Minimale Qualit�t (gro�es Framerate)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normal\\Standardqualit�t"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Max.\\Beste Qualit�t (niedriges Framerate)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Kein Ton\\Keine Ger�usche und Ger�uschkulisse"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normal\\Normale Lautst�rke"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "Joystick\\Joystick oder Tastatur"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Zeigt die L�sung\\Zeigt nach 3mal Scheitern die L�sung"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Name des Spielers"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Spieler ausw�hlen"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Abbrechen\\Beh�lt den bisherigen Spieler bei"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Spieler l�schen\\L�scht den Spieler aus der Liste"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Name "); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Speichern\\Speichert die Mission"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Laden\\�ffnet eine gespeicherte Mission"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Liste der gespeicherten Missionen"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Dateiname:"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Name der Mission"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Ansicht der Mission"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "L�schen\\L�scht die gespeicherte Mission"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Aussehen\\Erscheinungsbild des Astronauten einstellen"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Abbrechen"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standard\\Standardfarben einsetzen"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "Kopf\\Gesicht und Haare"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Anzug\\Raumfahrtanzug"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Drehung links"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Drehung rechts"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Rot"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Gr�n"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Blau"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Rot"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Gr�n"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Blau"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Kopf 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Kopf 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Kopf 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Kopf 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Keine Brille"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Brille 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Brille 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Brille 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Brille 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Brille 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Vorherg. Auwahl (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Drehung links (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Drehung rechts (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Vorw�rts (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "R�ckw�rts (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "Steigt (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "Sinkt (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Nehmen oder hinlegen (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Nehmen oder hinlegen (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..vorne"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..hinten"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..Batterie"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Anweisungen �ber die Mission(\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Abheben nach vollbrachter Mission"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Baut einen Bohrturm"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Baut ein Kraftwerk"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Baut eine Roboterfabrik"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Baut ein Reparaturzentrum"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Baut einen Konverter"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Baut einen Gesch�tzturm"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Baut ein Forschungszentrum"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Baut ein Radar"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Baut eine Batteriefabrik"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Baut ein automatisches Labor"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Baut eine Brennstoffzellenfabrik"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Baut einen Blitzableiter"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Baut einen Infoserver"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Zeigt ob der Boden eben ist"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Setzt eine Fahne"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Sammelt die Fahne ein"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Blaue Fahne"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Rote Fahne"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Gr�ne Fahne"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\Gelbe Fahne"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Violette Fahne"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Baut einen Jettransporter"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Baut einen Kettentransporter"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Baut einen Radtransporter"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Baut einen Krabbeltransporter"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Baut einen Jetshooter"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Baut einen Kettenshooter"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Baut einen Radshooter"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Baut einen Krabbelshooter"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Baut einen Jetorgashooter"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Baut einen Kettenorgashooter"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Baut einen Radorgashooter"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Baut einen Krabbelorgashooter"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Baut einen Jetschn�ffler"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Baut einen Kettenschn�ffler"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Baut einen Radschn�ffler"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Baut einen Krabbelschn�ffler"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Baut einen Stampfer"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Baut einen Phazershooter"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Baut einen Recycler"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Baut einen Schutzschild"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Baut einen Kettentaucher"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Forschungsprogramm Kettenantrieb"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Forschungsprogramm Jetantrieb"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Forschungsprogramm Stampfer"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Forschungsprogramm Shooterkanone"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Forschungsprogramm Gesch�tzturm"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Forschungsprogramm Phazerkanone"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Forschungsprogramm Schutzschild"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Forschungsprogramm Brennstoffzelle"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Forschungsprogramm Krabbelantrieb"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Forschungsprogramm Orgashooterkanone"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Alles zur�cksetzen"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Schn�ffeln (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Stampfen (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Feuer (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Recyceln (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Schutzschild ausfahren (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Schutzschild einholen (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Reichweite Schutzschild"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Gew�hltes Programm ausf�hren"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Gew�hltes Programm bearbeiten"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\SatCom in Standby"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Geb�ude sprengen"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Energievorrat"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Sch�den"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Triebwerktemperatur"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Prozess im Gang ..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Anzahl erfasster Insekten"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Gesendete Informationen"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Kompass"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Minikarte"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Zoom Minikarte"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Kamera (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Kamera links"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Kamera rechts"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Kamera n�her"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Kamera weiter weg"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Anweisungen �ber das ausgew�hlte Objekt"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Zeigt die L�sung"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Anzeige Roboter <-> Bauten"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Zeigt die Reichweite"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Bleistift abheben"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Schwarzen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Gelben Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Orangefarbenen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Roten Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Violetten Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Blauen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Gr�nen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Braunen Bleistift hinunterlassen"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\Aufnahme starten"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Aufnahme stoppen"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Zeigt den Ort"); + if ( num == EVENT_DT_END ) strcpy(text, "Weitermachen"); + if ( num == EVENT_CMD ) strcpy(text, "Befehleingabe"); + if ( num == EVENT_SPEED ) strcpy(text, "Spielgeschwindigkeit"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Vorherg. Seite"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "N�chste Seite"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Home"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Kopieren"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Gr��e 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Gr��e 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Gr��e 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Gr��e 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Gr��e 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Anweisungen von Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "W�rterbuch Englisch-Deutsch"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Satellitenbericht"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Von Houston �bermittelte Programme"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Liste der Objekte"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Hilfe �ber Programmieren"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "L�sung"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Programm kompilieren"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Abbrechen\\Editor schlie�en"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Neu"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "�ffnen (Ctrl+o)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Speichern (Ctrl+s)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Widerrufen (Ctrl+z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Ausschneiden (Ctrl+x)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Kopieren (Ctrl+c)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Einf�gen (Ctrl+v)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Zeichengr��e"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Anweisungen (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Hilfe �ber Programmieren (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Kompilieren"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Start/Stop"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pause/Weitermachen"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Ein Schritt"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "Tr�ger"); + if ( num == OBJECT_BASE ) strcpy(text, "Raumschiff"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Bohrturm"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Roboterfabrik"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Reparaturzentrum"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Einstampfer"); + if ( num == OBJECT_STATION ) strcpy(text, "Kraftwerk"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Konverter Erz-Titan"); + if ( num == OBJECT_TOWER ) strcpy(text, "Gesch�tzturm"); + if ( num == OBJECT_NEST ) strcpy(text, "Orgastoffquelle"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Forschungszentrum"); + if ( num == OBJECT_RADAR ) strcpy(text, "Radar"); + if ( num == OBJECT_INFO ) strcpy(text, "Infoserver"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "Aufl�ser"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Batteriefabrik"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Automatisches Labor"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Brennstoffzellenfabrik"); + if ( num == OBJECT_PARA ) strcpy(text, "Blitzableiter"); + if ( num == OBJECT_SAFE ) strcpy(text, "Bunker"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Kontrollzentrum"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Zielscheibe"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Zielscheibe"); + if ( num == OBJECT_START ) strcpy(text, "Startfl�che"); + if ( num == OBJECT_END ) strcpy(text, "Zielfl�che"); + if ( num == OBJECT_STONE ) strcpy(text, "Titanerz"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Platinerz"); + if ( num == OBJECT_BULLET ) strcpy(text, "Orgastoff"); + if ( num == OBJECT_METAL ) strcpy(text, "Titan"); + if ( num == OBJECT_POWER ) strcpy(text, "Elektrolytische Batterie"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Brennstoffzelle"); + if ( num == OBJECT_BBOX ) strcpy(text, "Flugschreiber"); + if ( num == OBJECT_KEYa ) strcpy(text, "Schl�ssel A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Schl�ssel B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Schl�ssel C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Schl�ssel D"); + if ( num == OBJECT_TNT ) strcpy(text, "Sprengstoff"); + if ( num == OBJECT_BOMB ) strcpy(text, "Landmine"); + if ( num == OBJECT_BAG ) strcpy(text, "�berlebenskit"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Checkpoint"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Blaue Fahne"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Rote Fahne"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Gr�ne Fahne"); + if ( num == OBJECT_FLAGy ) strcpy(text, "Gelbe Fahne"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Violette Fahne"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "Markierung f�r unterirdische Energiequelle"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Markierung f�r unterirdisches Platinvorkommen"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Markierung f�r vergrabenen Schl�ssel A"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Markierung f�r vergrabenen Schl�ssel B"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Markierung f�r vergrabenen Schl�ssel C"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Markierung f�r vergrabenen Schl�ssel D"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Markierung f�r unterirdisches Titanvorkommen"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "�bungsroboter"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "�bungsroboter"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "�bungsroboter"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "�bungsroboter"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Transporter"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Shooter"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "OrgaShooter"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Schn�ffler"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Schn�ffler"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Schn�ffler"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Schn�ffler"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Stampfer"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Phazershooter"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Recycler"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Schutzschild"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Kettentaucher"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Mobile Zielscheibe"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Zeichner"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "Techniker"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robby"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Insektenk�nigin"); + if ( num == OBJECT_ANT ) strcpy(text, "Ameise"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Spinne"); + if ( num == OBJECT_BEE ) strcpy(text, "Wespe"); + if ( num == OBJECT_WORM ) strcpy(text, "Wurm"); + if ( num == OBJECT_EGG ) strcpy(text, "Ei"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Roboterwrack"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "Geb�uderuine"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "Geb�uderuine"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "Abfall"); + if ( num == OBJECT_RUINradar ) strcpy(text, "Geb�uderuine"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "Geb�uderuine"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Raumschiffruine"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Raumschiffruine"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "�berreste einer Apollo-Mission"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Lunar Roving Vehicle"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "Fehler"); + if ( num == ERR_CMD ) strcpy(text, "Befehl unbekannt"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "CeeBot wurde nicht installiert."); + if ( num == ERR_NOCD ) strcpy(text, "Legen Sie die CeeBot-CD ein\nund starten Sie das Spiel neu."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "COLOBOT wurde nicht installiert."); + if ( num == ERR_NOCD ) strcpy(text, "Legen Sie die COLOBOT-CD ein\nund starten Sie das Spiel neu."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Im Flug unm�glich"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Tr�gt schon etwas"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Nichts zu ergreifen"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "In Fahrt unm�glich"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Stelle schon besetzt"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Kein anderer Roboter"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "Sie k�nnen keinen radioaktiven Gegenstand tragen"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "Sie k�nnen unter Wasser nichts tragen"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nichts abzulegen"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Im Flug unm�glich"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Unter Wasser unm�glich"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Titan zu weit weg"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Titan zu nahe"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Kein Titan vorhanden"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Boden nicht eben genug"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Ebener Boden nicht gro� genug"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Stelle schon besetzt"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Zu nahe am Raumschiff"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Zu nahe an einem Geb�ude"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "In Fahrt unm�glich"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Im Flug unm�glich"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "In Fahrt unm�glich"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Boden ungeeignet"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Geb�ude zu nahe"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Gegenstand zu nahe"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nichts zu recyceln"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Keine Energie mehr"); +//? if ( num == ERR_COM ) strcpy(text, "Kommunikationsproblem mit dem Roboter"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "Ziel kann nicht erreicht werden"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Das Objekt existiert nicht"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Ziel kann nicht erreicht werden"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Ziel kann nicht erreicht werden"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Ziel ist schon besetzt"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Roboter ungeeignet"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Nicht genug Energie"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Im Flug unm�glich"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Kein konvertierbares Titanerz vorhanden"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "Keine unterirdische Erzlagerst�tte"); + if ( num == ERR_STATION_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "Keine Batterie"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Keine Energie mehr"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Keine Batterie"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Nicht mehr genug Energie"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Falscher Batterietyp"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Forschungsprogramm schon ausgef�hrt"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Noch nicht genug Energie"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Kein konvertierbares Titanerz vorhanden"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Wandelt nur Titanerz um"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Die T�ren werden von einem Gegenstand blockiert"); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Gehen Sie an Bord, bevor Sie abheben"); + if ( num == ERR_LABO_NULL ) strcpy(text, "Nichts zu analysieren"); + if ( num == ERR_LABO_BAD ) strcpy(text, "Analysiert nur Orgastoff"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analyse schon durchgef�hrt"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Kein unterirdisches Energievorkommen"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Noch nicht genug Energie"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Kein konvertierbares Platin"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Wandelt nur Platin um"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "Kein Titan vorhanden"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Ein Gegenstand ist zu nahe"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Stelle schon besetzt"); + if ( num == ERR_INFO_NULL ) strcpy(text, "Kein Infoserver in Reichweite"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Ein Programm wurde von einem Virus infiziert"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Von Virus infiziert, zeitweise au�er Betrieb"); + if ( num == ERR_VEH_POWER ) strcpy(text, "Keine Batterie"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "Keine Energie mehr"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Im Flug unm�glich"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Im Wasser unm�glich"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Beim Gehen unm�glich"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Unm�glich wenn Sie etwas tragen"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Zu viele Fahnen dieser Farbe (Maximum 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Zu nahe an einer anderen Fahne"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "Keine Fahne in Reichweite"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "Mission noch nicht beendet (Dr�cken Sie auf \\key help; f�r weitere Informationen)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Roboter zerst�rt"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "Geb�ude zerst�rt"); + if ( num == ERR_TOOMANY ) strcpy(text, "Kein neues Objekt kann erstellt werden (zu viele vorhanden)"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "Es fehlt \"%s\" in Ihrem Programm"); + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "In dieser �bung verboten"); + + if ( num == INFO_BUILD ) strcpy(text, "Geb�ude fertiggestellt"); + if ( num == INFO_CONVERT ) strcpy(text, "Titan verf�gbar"); + if ( num == INFO_RESEARCH ) strcpy(text, "Forschungsprogramm abgeschlossen"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Herstellung eines Roboters mit Kettenantrieb m�glich"); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "Sie k�nnen jetzt mit den Tasten \\key gup; und \\key gdown; fliegen"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Herstellung eines Stampfers m�glich"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Herstellung eines Shooters m�glich"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Errichtung eines Gesch�tzturms m�glich"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Herstellung eines Phazershooters m�glich"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Herstellung eines Schutzschildes m�glich"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Errichtung einer Brennstoffzellenfabrik m�glich"); + if ( num == INFO_FACTORY ) strcpy(text, "Neuer Roboter verf�gbar"); + if ( num == INFO_LABO ) strcpy(text, "Analyse vollendet"); + if ( num == INFO_ENERGY ) strcpy(text, "Batterie verf�gbar"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Brennstoffzelle verf�gbar"); + if ( num == INFO_FINDING ) strcpy(text, "Sie haben ein brauchbares Objekt gefunden"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Geeignete Stelle f�r Kraftwerk gefunden"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Geeignete Stelle f�r Bohrturm gefunden"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Geeignete Stelle f�r Bohrturm gefunden"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Geeignete Stelle f�r Bohrturm gefunden"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Geeignete Stelle f�r Bohrturm gefunden"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Geeignete Stelle f�r Bohrturm gefunden"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Geeignete Stelle f�r Bohrturm gefunden"); + if ( num == INFO_WIN ) strcpy(text, "<<< Bravo, Mission vollendet >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< Mission gescheitert >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< Mission gescheitert >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Mission gespeichert"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Checkpoint erreicht"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Insektenk�nigin t�dlich verwundet"); + if ( num == INFO_DELETEANT ) strcpy(text, "Ameise t�dlich verwundet"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Wespe t�dlich verwundet"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Wurm t�dlich verwundet"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Spinne t�dlich verwundet"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Beziehen Sie sich auf Ihren SatCom, indem Sie auf \\key help; dr�cken"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "Fehler"); + if ( num == TX_OPENPAR ) strcpy(text, "Es fehlt eine offene Klammer ""("""); + if ( num == TX_CLOSEPAR ) strcpy(text, "Es fehlt eine geschlossene Klammer "")"""); + if ( num == TX_NOTBOOL ) strcpy(text, "Der Ausdruck muss einen boolschen Wert ergeben"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Variable nicht deklariert"); + if ( num == TX_BADLEFT ) strcpy(text, "Zuweisung unm�glich"); + if ( num == TX_ENDOF ) strcpy(text, "Es fehlt ein Strichpunkt "";"" am Ende der Anweisung"); + if ( num == TX_OUTCASE ) strcpy(text, "Anweisung ""case"" ohne vorhergehende Anweisung ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Hier ist eine Anweisung nach dem Ende des Programms"); + if ( num == TX_CLOSEBLK ) strcpy(text, "Es fehlt eine geschlossene geschweifte Klammer ""}"" (Ende des Blocks)"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Anweisung ""else"" ohne vorhergehende Anweisung ""if"""); + if ( num == TX_OPENBLK ) strcpy(text, "Es fehlt eine offene geschweifte Klammer""{"""); + if ( num == TX_BADTYPE ) strcpy(text, "Der Ausdruck ergibt einen falschen Typ f�r die Zuweisung"); + if ( num == TX_REDEFVAR ) strcpy(text, "Eine Variable wird zum zweiten Mal deklariert"); + if ( num == TX_BAD2TYPE ) strcpy(text, "Die zwei Operanden sind nicht kompatibel"); + if ( num == TX_UNDEFCALL ) strcpy(text, "Unbekannte Funktion"); + if ( num == TX_MISDOTS ) strcpy(text, "Es fehlt ein Doppelpunkt "" : """); + if ( num == TX_WHILE ) strcpy(text, "Es fehlt das Wort ""while"""); + if ( num == TX_BREAK ) strcpy(text, "Anweisung ""break"" au�erhalb einer Schleife"); + if ( num == TX_LABEL ) strcpy(text, "Ein Label kann nur vor den Anweisungen ""for"", ""while"", ""do"" oder ""switch"" vorkommen"); + if ( num == TX_NOLABEL ) strcpy(text, "Dieses Label existiert nicht"); + if ( num == TX_NOCASE ) strcpy(text, "Es fehlt eine Anweisung ""case"""); + if ( num == TX_BADNUM ) strcpy(text, "Es fehlt eine Zahl"); + if ( num == TX_VOID ) strcpy(text, "Parameter void"); + if ( num == TX_NOTYP ) strcpy(text, "Hier muss ein Variablentyp stehen"); + if ( num == TX_NOVAR ) strcpy(text, "Es fehlt der Name einer Variable"); + if ( num == TX_NOFONC ) strcpy(text, "Hier muss der Name der Funktion stehen"); + if ( num == TX_OVERPARAM ) strcpy(text, "Zu viele Parameter"); + if ( num == TX_REDEF ) strcpy(text, "Diese Funktion gibt es schon"); + if ( num == TX_LOWPARAM ) strcpy(text, "Nicht genug Parameter"); + if ( num == TX_BADPARAM ) strcpy(text, "Keine Funktion mit diesem Namen vertr�gt Parameter diesen Typs"); + if ( num == TX_NUMPARAM ) strcpy(text, "Keine Funktion mit diesem Namen vertr�gt diese Anzahl Parameter"); + if ( num == TX_NOITEM ) strcpy(text, "Dieses Element gibt es nicht in dieser Klasse"); + if ( num == TX_DOT ) strcpy(text, "Das Objekt ist nicht eine Instanz einer Klasse"); + if ( num == TX_NOCONST ) strcpy(text, "Es gibt keinen geeigneten Konstruktor"); + if ( num == TX_REDEFCLASS ) strcpy(text, "Diese Klasse gibt es schon"); + if ( num == TX_CLBRK ) strcpy(text, "Es fehlt eine geschlossene eckige Klammer "" ] """); + if ( num == TX_RESERVED ) strcpy(text, "Dieses Wort ist reserviert"); + if ( num == TX_BADNEW ) strcpy(text, "Falsche Argumente f�r ""new"""); + if ( num == TX_OPBRK ) strcpy(text, "Es fehlt eine offene eckige Klammer "" [ """); + if ( num == TX_BADSTRING ) strcpy(text, "Hier wird eine Zeichenkette erwartet"); + if ( num == TX_BADINDEX ) strcpy(text, "Falscher Typ f�r einen Index"); + if ( num == TX_PRIVATE ) strcpy(text, "Gesch�tztes Element (private)"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Hier muss das Wort ""public"" stehen"); + if ( num == TX_DIVZERO ) strcpy(text, "Teilung durch Null"); + if ( num == TX_NOTINIT ) strcpy(text, "Der Wert dieser Variable wurde nicht definiert"); + if ( num == TX_BADTHROW ) strcpy(text, "Negativer Wert ungeeignet f�r Anweisung ""throw"""); + if ( num == TX_NORETVAL ) strcpy(text, "Die Funktion hat kein Ergebnis zur�ckgegeben"); + if ( num == TX_NORUN ) strcpy(text, "Keine Funktion wird ausgef�hrt"); + if ( num == TX_NOCALL ) strcpy(text, "Die aufgerufene Funktion existiert nicht"); + if ( num == TX_NOCLASS ) strcpy(text, "Diese Klasse existiert nicht"); + if ( num == TX_NULLPT ) strcpy(text, "Das Objekt existiert nicht"); + if ( num == TX_OPNAN ) strcpy(text, "Operation mit dem Wert ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Zugriff im Array au�erhalb der Grenzen"); + if ( num == TX_STACKOVER ) strcpy(text, "Stack overflow"); + if ( num == TX_DELETEDPT ) strcpy(text, "Objekt nicht verf�gbar"); + if ( num == TX_FILEOPEN ) strcpy(text, "Die Datei kann nicht ge�ffnet werden"); + if ( num == TX_NOTOPEN ) strcpy(text, "Die Datei wurde nicht ge�ffnet"); + if ( num == TX_ERRREAD ) strcpy(text, "Fehler beim Lesezugriff"); + if ( num == TX_ERRWRITE ) strcpy(text, "Fehler beim Schreibzugriff"); + } + + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< keine >"); + if ( num == SDLK_LEFT ) strcpy(text, "Pfeiltaste links"); + if ( num == SDLK_RIGHT ) strcpy(text, "Pfeiltaste rechts"); + if ( num == SDLK_UP ) strcpy(text, "Pfeil nach oben"); + if ( num == SDLK_DOWN ) strcpy(text, "Pfeil nach unten"); + if ( num == SDLK_CANCEL ) strcpy(text, "Ctrl-Break"); + if ( num == SDLK_BACK ) strcpy(text, "<--"); + if ( num == SDLK_TAB ) strcpy(text, "Tab"); + if ( num == SDLK_CLEAR ) strcpy(text, "Clear"); + if ( num == SDLK_RETURN ) strcpy(text, "Eingabe"); + if ( num == SDLK_SHIFT ) strcpy(text, "Shift"); + if ( num == SDLK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == SDLK_MENU ) strcpy(text, "Alt"); + if ( num == SDLK_PAUSE ) strcpy(text, "Pause"); + if ( num == SDLK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == SDLK_ESCAPE ) strcpy(text, "Esc"); + if ( num == SDLK_SPACE ) strcpy(text, "Leertaste"); + if ( num == SDLK_PRIOR ) strcpy(text, "Page Up"); + if ( num == SDLK_NEXT ) strcpy(text, "Page Down"); + if ( num == SDLK_END ) strcpy(text, "End"); + if ( num == SDLK_HOME ) strcpy(text, "Home"); + if ( num == SDLK_SELECT ) strcpy(text, "Select"); + if ( num == SDLK_EXECUTE ) strcpy(text, "Execute"); + if ( num == SDLK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == SDLK_INSERT ) strcpy(text, "Insert"); + if ( num == SDLK_DELETE ) strcpy(text, "Delete"); + if ( num == SDLK_HELP ) strcpy(text, "Help"); + if ( num == SDLK_LWIN ) strcpy(text, "Left Windows"); + if ( num == SDLK_RWIN ) strcpy(text, "Right Windows"); + if ( num == SDLK_APPS ) strcpy(text, "Application key"); + if ( num == SDLK_NUMPAD0 ) strcpy(text, "NumPad 0"); + if ( num == SDLK_NUMPAD1 ) strcpy(text, "NumPad 1"); + if ( num == SDLK_NUMPAD2 ) strcpy(text, "NumPad 2"); + if ( num == SDLK_NUMPAD3 ) strcpy(text, "NumPad 3"); + if ( num == SDLK_NUMPAD4 ) strcpy(text, "NumPad 4"); + if ( num == SDLK_NUMPAD5 ) strcpy(text, "NumPad 5"); + if ( num == SDLK_NUMPAD6 ) strcpy(text, "NumPad 6"); + if ( num == SDLK_NUMPAD7 ) strcpy(text, "NumPad 7"); + if ( num == SDLK_NUMPAD8 ) strcpy(text, "NumPad 8"); + if ( num == SDLK_NUMPAD9 ) strcpy(text, "NumPad 9"); + if ( num == SDLK_MULTIPLY ) strcpy(text, "NumPad *"); + if ( num == SDLK_ADD ) strcpy(text, "NumPad +"); + if ( num == SDLK_SEPARATOR ) strcpy(text, "NumPad sep"); + if ( num == SDLK_SUBTRACT ) strcpy(text, "NumPad -"); + if ( num == SDLK_DECIMAL ) strcpy(text, "NumPad ."); + if ( num == SDLK_DIVIDE ) strcpy(text, "NumPad /"); + if ( num == SDLK_F1 ) strcpy(text, "F1"); + if ( num == SDLK_F2 ) strcpy(text, "F2"); + if ( num == SDLK_F3 ) strcpy(text, "F3"); + if ( num == SDLK_F4 ) strcpy(text, "F4"); + if ( num == SDLK_F5 ) strcpy(text, "F5"); + if ( num == SDLK_F6 ) strcpy(text, "F6"); + if ( num == SDLK_F7 ) strcpy(text, "F7"); + if ( num == SDLK_F8 ) strcpy(text, "F8"); + if ( num == SDLK_F9 ) strcpy(text, "F9"); + if ( num == SDLK_F10 ) strcpy(text, "F10"); + if ( num == SDLK_F11 ) strcpy(text, "F11"); + if ( num == SDLK_F12 ) strcpy(text, "F12"); + if ( num == SDLK_F13 ) strcpy(text, "F13"); + if ( num == SDLK_F14 ) strcpy(text, "F14"); + if ( num == SDLK_F15 ) strcpy(text, "F15"); + if ( num == SDLK_F16 ) strcpy(text, "F16"); + if ( num == SDLK_F17 ) strcpy(text, "F17"); + if ( num == SDLK_F18 ) strcpy(text, "F18"); + if ( num == SDLK_F19 ) strcpy(text, "F19"); + if ( num == SDLK_F20 ) strcpy(text, "F20"); + if ( num == SDLK_NUMLOCK ) strcpy(text, "Num Lock"); + if ( num == SDLK_SCROLL ) strcpy(text, "Scroll"); + if ( num == SDLK_ATTN ) strcpy(text, "Attn"); + if ( num == SDLK_CRSEL ) strcpy(text, "CrSel"); + if ( num == SDLK_EXSEL ) strcpy(text, "ExSel"); + if ( num == SDLK_EREOF ) strcpy(text, "Erase EOF"); + if ( num == SDLK_PLAY ) strcpy(text, "Play"); + if ( num == SDLK_ZOOM ) strcpy(text, "Zoom"); + if ( num == SDLK_PA1 ) strcpy(text, "PA1"); + if ( num == SDLK_OEM_CLEAR ) strcpy(text, "Clear"); + if ( num == SDLK_BUTTON1 ) strcpy(text, "Knopf 1"); + if ( num == SDLK_BUTTON2 ) strcpy(text, "Knopf 2"); + if ( num == SDLK_BUTTON3 ) strcpy(text, "Knopf 3"); + if ( num == SDLK_BUTTON4 ) strcpy(text, "Knopf 4"); + if ( num == SDLK_BUTTON5 ) strcpy(text, "Knopf 5"); + if ( num == SDLK_BUTTON6 ) strcpy(text, "Knopf 6"); + if ( num == SDLK_BUTTON7 ) strcpy(text, "Knopf 7"); + if ( num == SDLK_BUTTON8 ) strcpy(text, "Knopf 8"); + if ( num == SDLK_BUTTON9 ) strcpy(text, "Knopf 9"); + if ( num == SDLK_BUTTON10 ) strcpy(text, "Knopf 10"); + if ( num == SDLK_BUTTON11 ) strcpy(text, "Knopf 11"); + if ( num == SDLK_BUTTON12 ) strcpy(text, "Knopf 12"); + if ( num == SDLK_BUTTON13 ) strcpy(text, "Knopf 13"); + if ( num == SDLK_BUTTON14 ) strcpy(text, "Knopf 14"); + if ( num == SDLK_BUTTON15 ) strcpy(text, "Knopf 15"); + if ( num == SDLK_BUTTON16 ) strcpy(text, "Knopf 16"); + if ( num == SDLK_BUTTON17 ) strcpy(text, "Knopf 17"); + if ( num == SDLK_BUTTON18 ) strcpy(text, "Knopf 18"); + if ( num == SDLK_BUTTON19 ) strcpy(text, "Knopf 19"); + if ( num == SDLK_BUTTON20 ) strcpy(text, "Knopf 20"); + if ( num == SDLK_BUTTON21 ) strcpy(text, "Knopf 21"); + if ( num == SDLK_BUTTON22 ) strcpy(text, "Knopf 22"); + if ( num == SDLK_BUTTON23 ) strcpy(text, "Knopf 23"); + if ( num == SDLK_BUTTON24 ) strcpy(text, "Knopf 24"); + if ( num == SDLK_BUTTON25 ) strcpy(text, "Knopf 25"); + if ( num == SDLK_BUTTON26 ) strcpy(text, "Knopf 26"); + if ( num == SDLK_BUTTON27 ) strcpy(text, "Knopf 27"); + if ( num == SDLK_BUTTON28 ) strcpy(text, "Knopf 28"); + if ( num == SDLK_BUTTON29 ) strcpy(text, "Knopf 29"); + if ( num == SDLK_BUTTON30 ) strcpy(text, "Knopf 30"); + if ( num == SDLK_BUTTON31 ) strcpy(text, "Knopf 31"); + if ( num == SDLK_BUTTON32 ) strcpy(text, "Knopf 32"); + if ( num == SDLK_WHEELUP ) strcpy(text, "Mausrad nach vorne"); + if ( num == SDLK_WHEELDOWN ) strcpy(text, "Mausrad zur�ck"); + } +#endif + +#if _POLISH + if ( type == RES_TEXT ) + { + #if _FULL + if ( num == RT_VERSION_ID ) strcpy(text, "Wersja 1.18 /pl"); + #endif + #if _NET + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A 1.18"); + #endif + #if _SCHOOL & _EDU + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen EDU 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A EDU 1.18"); + #endif + #endif + #if _SCHOOL & _PERSO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen PERSO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A PERSO 1.18"); + #endif + #endif + #if _SCHOOL & _CEEBOTDEMO + #if _TEEN + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-Teen DEMO 1.18"); + #else + if ( num == RT_VERSION_ID ) strcpy(text, "CeeBot-A DEMO 1.18"); + #endif + #endif + #if _DEMO + if ( num == RT_VERSION_ID ) strcpy(text, "Demo 1.18 /pl"); + #endif + if ( num == RT_DISINFO_TITLE ) strcpy(text, "SatCom"); + if ( num == RT_WINDOW_MAXIMIZED ) strcpy(text, "Powi�ksz"); + if ( num == RT_WINDOW_MINIMIZED ) strcpy(text, "Pomniejsz"); + if ( num == RT_WINDOW_STANDARD ) strcpy(text, "Normalna wielko��"); + if ( num == RT_WINDOW_CLOSE ) strcpy(text, "Zamknij"); + + if ( num == RT_STUDIO_TITLE ) strcpy(text, "Edytor programu"); + if ( num == RT_SCRIPT_NEW ) strcpy(text, "Nowy"); + if ( num == RT_NAME_DEFAULT ) strcpy(text, "Gracz"); + if ( num == RT_IO_NEW ) strcpy(text, "Nowy ..."); + if ( num == RT_KEY_OR ) strcpy(text, " lub "); + +#if _NEWLOOK + if ( num == RT_TITLE_BASE ) strcpy(text, "CeeBot"); + if ( num == RT_TITLE_INIT ) strcpy(text, "CeeBot"); +#else + if ( num == RT_TITLE_BASE ) strcpy(text, "COLOBOT"); + if ( num == RT_TITLE_INIT ) strcpy(text, "COLOBOT"); +#endif + if ( num == RT_TITLE_TRAINER ) strcpy(text, "�wiczenia programistyczne"); + if ( num == RT_TITLE_DEFI ) strcpy(text, "Wyzwania"); + if ( num == RT_TITLE_MISSION ) strcpy(text, "Misje"); + if ( num == RT_TITLE_FREE ) strcpy(text, "Swobodna gra"); + if ( num == RT_TITLE_TEEN ) strcpy(text, "Swobodna gra"); + if ( num == RT_TITLE_USER ) strcpy(text, "Poziomy u�ytkownika"); + if ( num == RT_TITLE_PROTO ) strcpy(text, "Prototypy"); + if ( num == RT_TITLE_SETUP ) strcpy(text, "Opcje"); + if ( num == RT_TITLE_NAME ) strcpy(text, "Imi� gracza"); + if ( num == RT_TITLE_PERSO ) strcpy(text, "Dostosuj wygl�d"); + if ( num == RT_TITLE_WRITE ) strcpy(text, "Zapisz bie��c� misj�"); + if ( num == RT_TITLE_READ ) strcpy(text, "Wczytaj zapisan� misj�"); + + if ( num == RT_PLAY_CHAPt ) strcpy(text, " Rozdzia�y:"); + if ( num == RT_PLAY_CHAPd ) strcpy(text, " Rozdzia�y:"); + if ( num == RT_PLAY_CHAPm ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_CHAPf ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_CHAPu ) strcpy(text, " Poziomy u�ytkownika:"); + if ( num == RT_PLAY_CHAPp ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_CHAPte ) strcpy(text, " Planety:"); + if ( num == RT_PLAY_LISTt ) strcpy(text, " �wiczenia w tym rozdziale:"); + if ( num == RT_PLAY_LISTd ) strcpy(text, " Wyzwania w tym rozdziale:"); + if ( num == RT_PLAY_LISTm ) strcpy(text, " Misje na tej planecie:"); + if ( num == RT_PLAY_LISTf ) strcpy(text, " Swobodna gra na tej planecie:"); + if ( num == RT_PLAY_LISTu ) strcpy(text, " Misje na tym poziomie:"); + if ( num == RT_PLAY_LISTp ) strcpy(text, " Prototypy na tej planecie:"); + if ( num == RT_PLAY_LISTk ) strcpy(text, " Prototypy na tej planecie:"); + if ( num == RT_PLAY_RESUME ) strcpy(text, " Streszczenie:"); + + if ( num == RT_SETUP_DEVICE ) strcpy(text, " Sterowniki:"); + if ( num == RT_SETUP_MODE ) strcpy(text, " Rozdzielczo��:"); + if ( num == RT_SETUP_KEY1 ) strcpy(text, "1) Najpierw kliknij klawisz, kt�ry chcesz przedefiniowa�."); + if ( num == RT_SETUP_KEY2 ) strcpy(text, "2) Nast�pnie naci�nij klawisz, kt�rego chcesz u�ywa�."); + + if ( num == RT_PERSO_FACE ) strcpy(text, "Rodzaj twarzy:"); + if ( num == RT_PERSO_GLASSES ) strcpy(text, "Okulary:"); + if ( num == RT_PERSO_HAIR ) strcpy(text, "Kolor w�os�w:"); + if ( num == RT_PERSO_COMBI ) strcpy(text, "Kolor skafandra:"); + if ( num == RT_PERSO_BAND ) strcpy(text, "Kolor pask�w:"); + +#if _NEWLOOK + if ( num == RT_DIALOG_TITLE ) strcpy(text, "CeeBot"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Czy na pewno chcesz opu�ci� gr� CeeBot?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Zako�cz\\Ko�czy gr� CeeBot"); +#else + if ( num == RT_DIALOG_TITLE ) strcpy(text, "COLOBOT"); + if ( num == RT_DIALOG_QUIT ) strcpy(text, "Czy na pewno chcesz opu�ci� gr� COLOBOT?"); + if ( num == RT_DIALOG_YESQUIT ) strcpy(text, "Zako�cz\\Ko�czy gr� COLOBOT"); +#endif + if ( num == RT_DIALOG_ABORT ) strcpy(text, "Opu�ci� misj�?"); + if ( num == RT_DIALOG_YES ) strcpy(text, "Przerwij\\Przerywa bie��c� misj�"); + if ( num == RT_DIALOG_NO ) strcpy(text, "Kontynuuj\\Kontynuuje bie��c� misj�"); + if ( num == RT_DIALOG_NOQUIT ) strcpy(text, "Kontynuuj\\Kontynuuje gr�"); + if ( num == RT_DIALOG_DELOBJ ) strcpy(text, "Czy na pewno chcesz zniszczy� zaznaczony budynek?"); + if ( num == RT_DIALOG_DELGAME ) strcpy(text, "Czy na pewno chcesz skasowa� zapisane gry gracza %s? "); + if ( num == RT_DIALOG_YESDEL ) strcpy(text, "Usu�"); + if ( num == RT_DIALOG_NODEL ) strcpy(text, "Anuluj"); + if ( num == RT_DIALOG_LOADING ) strcpy(text, "WCZYTYWANIE"); + + if ( num == RT_STUDIO_LISTTT ) strcpy(text, "Skr�ty klawiszowe (\\key cbot;)"); + if ( num == RT_STUDIO_COMPOK ) strcpy(text, "Program skompilowany (0 b��d�w)"); + if ( num == RT_STUDIO_PROGSTOP ) strcpy(text, "Program zako�czony"); + + if ( num == RT_SATCOM_LIST ) strcpy(text, "\\b;Lista obiekt�w\n"); + if ( num == RT_SATCOM_BOT ) strcpy(text, "\\b;Roboty\n"); + if ( num == RT_SATCOM_BUILDING ) strcpy(text, "\\b;Budynki\n"); + if ( num == RT_SATCOM_FRET ) strcpy(text, "\\b;Obiekty ruchome\n"); + if ( num == RT_SATCOM_ALIEN ) strcpy(text, "\\b;Obcy\n"); + if ( num == RT_SATCOM_NULL ) strcpy(text, "\\c; (brak)\\n;\n"); + if ( num == RT_SATCOM_ERROR1 ) strcpy(text, "\\b;B��d\n"); + if ( num == RT_SATCOM_ERROR2 ) strcpy(text, "Lista jest dost�pna jedynie gdy dzia�a \\l;stacja radarowa\\u object\\radar;.\n"); + + if ( num == RT_IO_OPEN ) strcpy(text, "Otw�rz"); + if ( num == RT_IO_SAVE ) strcpy(text, "Zapisz"); + if ( num == RT_IO_LIST ) strcpy(text, "Folder: %s"); + if ( num == RT_IO_NAME ) strcpy(text, "Nazwa:"); + if ( num == RT_IO_DIR ) strcpy(text, "Folder:"); + if ( num == RT_IO_PRIVATE ) strcpy(text, "Prywatny\\Folder prywatny"); + if ( num == RT_IO_PUBLIC ) strcpy(text, "Publiczny\\Folder og�lnodost�pny"); + + if ( num == RT_GENERIC_DEV1 ) strcpy(text, "Tw�rcy:"); + if ( num == RT_GENERIC_DEV2 ) strcpy(text, "www.epsitec.com"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, "Wersja polska wydana przez:"); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, "www.manta.com.pl"); + if ( num == RT_GENERIC_EDIT1 ) strcpy(text, " "); + if ( num == RT_GENERIC_EDIT2 ) strcpy(text, " "); + + if ( num == RT_INTERFACE_REC ) strcpy(text, "Recorder"); + } + + if ( type == RES_EVENT ) + { + if ( num == EVENT_BUTTON_OK ) strcpy(text, "OK"); + if ( num == EVENT_BUTTON_CANCEL ) strcpy(text, "Anuluj"); + if ( num == EVENT_BUTTON_NEXT ) strcpy(text, "Nast�pny"); + if ( num == EVENT_BUTTON_PREV ) strcpy(text, "Poprzedni"); + if ( num == EVENT_BUTTON_QUIT ) strcpy(text, "Menu (\\key quit;)"); + + if ( num == EVENT_DIALOG_OK ) strcpy(text, "OK"); + if ( num == EVENT_DIALOG_CANCEL ) strcpy(text, "Anuluj"); + + if ( num == EVENT_INTERFACE_TRAINER) strcpy(text, "�wiczenia\\�wiczenia programistyczne"); + if ( num == EVENT_INTERFACE_DEFI ) strcpy(text, "Wyzwania\\Wyzwania programistyczne"); + if ( num == EVENT_INTERFACE_MISSION) strcpy(text, "Misje\\Wybierz misj�"); + if ( num == EVENT_INTERFACE_FREE ) strcpy(text, "Swobodna gra\\Swobodna gra bez konkretnych cel�w"); + if ( num == EVENT_INTERFACE_TEEN ) strcpy(text, "Swobodna gra\\Swobodna gra bez konkretnych cel�w"); + if ( num == EVENT_INTERFACE_USER ) strcpy(text, "Poziomy\\Poziomy u�ytkownika"); + if ( num == EVENT_INTERFACE_PROTO ) strcpy(text, "Prototypy\\Prototypy w trakcie rozwijania"); + if ( num == EVENT_INTERFACE_NAME ) strcpy(text, "Nowy gracz\\Wybierz imi� gracza"); + if ( num == EVENT_INTERFACE_SETUP ) strcpy(text, "Opcje\\Preferencje"); + if ( num == EVENT_INTERFACE_AGAIN ) strcpy(text, "Uruchom ponownie\\Uruchamia ponownie misj� od pocz�tku"); + if ( num == EVENT_INTERFACE_WRITE ) strcpy(text, "Zapisz\\Zapisuje bie��c� misj�"); + if ( num == EVENT_INTERFACE_READ ) strcpy(text, "Wczytaj\\Wczytuje zapisan� misj�"); +#if _NEWLOOK + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Powr�� do gry CeeBot"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Zako�cz\\Ko�czy gr� CeeBot"); +#else + if ( num == EVENT_INTERFACE_ABORT ) strcpy(text, "\\Powr�� do gry COLOBOT"); + if ( num == EVENT_INTERFACE_QUIT ) strcpy(text, "Zako�cz\\Ko�czy gr� COLOBOT"); +#endif + if ( num == EVENT_INTERFACE_BACK ) strcpy(text, "<< Wstecz \\Wraca do poprzedniego ekranu"); + if ( num == EVENT_INTERFACE_PLAY ) strcpy(text, "Graj\\Rozpoczyna misj�!"); + if ( num == EVENT_INTERFACE_SETUPd ) strcpy(text, "Urz�dzenie\\Ustawienia sterownika i rozdzielczo�ci"); + if ( num == EVENT_INTERFACE_SETUPg ) strcpy(text, "Grafika\\Ustawienia grafiki"); + if ( num == EVENT_INTERFACE_SETUPp ) strcpy(text, "Gra\\Ustawienia gry"); + if ( num == EVENT_INTERFACE_SETUPc ) strcpy(text, "Sterowanie\\Ustawienia klawiatury, joysticka i myszy"); + if ( num == EVENT_INTERFACE_SETUPs ) strcpy(text, "D�wi�k\\G�o�no�� muzyki i d�wi�k�w gry"); + if ( num == EVENT_INTERFACE_DEVICE ) strcpy(text, "Jednostka"); + if ( num == EVENT_INTERFACE_RESOL ) strcpy(text, "Rozdzielczo��"); + if ( num == EVENT_INTERFACE_FULL ) strcpy(text, "Pe�ny ekran\\Pe�ny ekran lub tryb okna"); + if ( num == EVENT_INTERFACE_APPLY ) strcpy(text, "Zastosuj zmiany\\Aktywuje zmienione ustawienia"); + + if ( num == EVENT_INTERFACE_TOTO ) strcpy(text, "Robbie\\Tw�j asystent"); + if ( num == EVENT_INTERFACE_SHADOW ) strcpy(text, "Cienie\\Cienie na ziemi"); + if ( num == EVENT_INTERFACE_GROUND ) strcpy(text, "Znaki na ziemi\\Znaki na ziemi"); + if ( num == EVENT_INTERFACE_DIRTY ) strcpy(text, "Kurz\\Kurz i br�d na robotach i budynkach"); + if ( num == EVENT_INTERFACE_FOG ) strcpy(text, "Mg�a\\Mg�a"); + if ( num == EVENT_INTERFACE_LENS ) strcpy(text, "Promienie s�oneczne\\Promienie s�oneczne na niebie"); + if ( num == EVENT_INTERFACE_SKY ) strcpy(text, "Niebo\\Chmury i mg�awice"); + if ( num == EVENT_INTERFACE_PLANET ) strcpy(text, "Planety i gwiazdy\\Obiekty astronomiczne na niebie"); + if ( num == EVENT_INTERFACE_LIGHT ) strcpy(text, "Dynamiczne o�wietlenie\\Ruchome �r�d�a �wiat�a"); + if ( num == EVENT_INTERFACE_PARTI ) strcpy(text, "Liczba cz�stek\\Wybuchy, kurz, odbicia, itp."); + if ( num == EVENT_INTERFACE_CLIP ) strcpy(text, "G��boko�� pola\\Maksymalna widoczno��"); + if ( num == EVENT_INTERFACE_DETAIL ) strcpy(text, "Szczeg�y\\Jako�� wizualna obiekt�w 3D"); + if ( num == EVENT_INTERFACE_TEXTURE) strcpy(text, "Tekstury\\Jako�� tekstur "); + if ( num == EVENT_INTERFACE_GADGET ) strcpy(text, "Ilo�� element�w dekoracyjnych \\Ilo�� element�w czysto dekoracyjnych"); + if ( num == EVENT_INTERFACE_RAIN ) strcpy(text, "Cz�stki w interfejsie\\Para i iskry z silnik�w w interfejsie"); + if ( num == EVENT_INTERFACE_GLINT ) strcpy(text, "Odbicia na przyciskach \\�wiec�ce przyciski"); + if ( num == EVENT_INTERFACE_TOOLTIP) strcpy(text, "Dymki pomocy\\Wyja�nia funkcje przycisk�w"); + if ( num == EVENT_INTERFACE_MOVIES ) strcpy(text, "Sekwencje filmowe\\Filmy przed rozpocz�ciem i na zako�czenie misji"); + if ( num == EVENT_INTERFACE_NICERST) strcpy(text, "Ko�cowy film\\Film na zako�czenie �wicze�"); + if ( num == EVENT_INTERFACE_HIMSELF) strcpy(text, "Przyjacielski ogie�\\W�asne strza�y uszkadzaj� Twoje obiekty"); + if ( num == EVENT_INTERFACE_SCROLL ) strcpy(text, "Przewijanie\\Ekran jest przewijany gdy mysz dotknie prawej lub lewej jego kraw�dzi"); + if ( num == EVENT_INTERFACE_INVERTX) strcpy(text, "Odwr�cenie myszy X\\Odwr�cenie kierunk�w przewijania w poziomie"); + if ( num == EVENT_INTERFACE_INVERTY) strcpy(text, "Odwr�cenie myszy Y\\Odwr�cenie kierunk�w przewijania w pionie"); + if ( num == EVENT_INTERFACE_EFFECT ) strcpy(text, "Wstrz�sy przy wybuchach\\Ekran trz�sie si� podczas wybuch�w"); + if ( num == EVENT_INTERFACE_MOUSE ) strcpy(text, "Cie� kursora myszy\\Dodaje cie� kursorowi myszy"); + if ( num == EVENT_INTERFACE_EDITMODE) strcpy(text, "Automatyczne wci�cia\\Automatyczne wci�cia podczas edycji programu"); + if ( num == EVENT_INTERFACE_EDITVALUE)strcpy(text, "Du�e wci�cie\\2 lub 4 spacje wci�cia na ka�dy poziom zdefiniowany przez klamry"); + if ( num == EVENT_INTERFACE_SOLUCE4) strcpy(text, "Acc�s aux solutions\\Programme \"4: Solution\" dans les exercices"); + + if ( num == EVENT_INTERFACE_KDEF ) strcpy(text, "Standardowa kontrola\\Standardowe klawisze funkcyjne"); + if ( num == EVENT_INTERFACE_KLEFT ) strcpy(text, "Skr�� w lewo\\Obraca robota w lewo"); + if ( num == EVENT_INTERFACE_KRIGHT ) strcpy(text, "Obr�� w prawo\\Obraca robota w prawo"); + if ( num == EVENT_INTERFACE_KUP ) strcpy(text, "Naprz�d\\Porusza do przodu"); + if ( num == EVENT_INTERFACE_KDOWN ) strcpy(text, "Wstecz\\Porusza do ty�u"); + if ( num == EVENT_INTERFACE_KGUP ) strcpy(text, "W g�r�\\Zwi�ksza moc silnika"); + if ( num == EVENT_INTERFACE_KGDOWN ) strcpy(text, "W d�\\Zmniejsza moc silnika"); + if ( num == EVENT_INTERFACE_KCAMERA) strcpy(text, "Zmie� kamer�\\Prze��cza pomi�dzy kamer� pok�adow� i �ledz�c�"); + if ( num == EVENT_INTERFACE_KDESEL ) strcpy(text, "Poprzedni obiekt\\Zaznacz poprzedni obiekt"); + if ( num == EVENT_INTERFACE_KACTION) strcpy(text, "Standardowa akcja\\Standardowa akcja robota (podnie�/upu��, strzelaj, szukaj, itp.)"); + if ( num == EVENT_INTERFACE_KNEAR ) strcpy(text, "Kamera bli�ej\\Przybli�a kamer�"); + if ( num == EVENT_INTERFACE_KAWAY ) strcpy(text, "Kamera dalej\\Oddala kamer�"); + if ( num == EVENT_INTERFACE_KNEXT ) strcpy(text, "Nast�pny obiekt\\Zaznacza nast�pny obiekt"); + if ( num == EVENT_INTERFACE_KHUMAN ) strcpy(text, "Zaznacz astronaut�\\Zaznacza astronaut�"); + if ( num == EVENT_INTERFACE_KQUIT ) strcpy(text, "Zako�cz\\Ko�czy bie��c� misj� lub �wiczenie"); + if ( num == EVENT_INTERFACE_KHELP ) strcpy(text, "Rozkazy\\Pokazuje rozkazy dotycz�ce bie��cej misji"); + if ( num == EVENT_INTERFACE_KPROG ) strcpy(text, "Podr�cznik programowania\\Dostarcza szczeg�ow� pomoc w programowaniu"); + if ( num == EVENT_INTERFACE_KCBOT ) strcpy(text, "Pomoc dot. s��w kluczowych\\Dok�adniejsza pomoc na temat s��w kluczowych"); + if ( num == EVENT_INTERFACE_KVISIT ) strcpy(text, "Miejsce nadania wiadomo�ci\\Pokazuje sk�d zosta�a wys�ana ostatnia wiadomo��"); + if ( num == EVENT_INTERFACE_KSPEED10) strcpy(text, "Pr�dko�� 1,0x\\Pr�dko�� normalna"); + if ( num == EVENT_INTERFACE_KSPEED15) strcpy(text, "Pr�dko�� 1,5x\\1,5 raza szybciej"); + if ( num == EVENT_INTERFACE_KSPEED20) strcpy(text, "Pr�dko�� 2,0x\\Dwa razy szybciej"); + if ( num == EVENT_INTERFACE_KSPEED30) strcpy(text, "Pr�dko�� 3,0x\\Trzy razy szybciej"); + + if ( num == EVENT_INTERFACE_VOLSOUND) strcpy(text, "Efekty d�wi�kowe:\\G�o�no�� silnik�w, g�os�w, strza��w, itp."); + if ( num == EVENT_INTERFACE_VOLMUSIC) strcpy(text, "Muzyka w tle :\\G�o�no�� �cie�ek d�wi�kowych z p�yty CD"); + if ( num == EVENT_INTERFACE_SOUND3D) strcpy(text, "D�wi�k 3D\\Przestrzenne pozycjonowanie d�wi�k�w"); + + if ( num == EVENT_INTERFACE_MIN ) strcpy(text, "Najni�sza\\Minimalna jako�� grafiki (najwy�sza cz�stotliwo�� od�wie�ania)"); + if ( num == EVENT_INTERFACE_NORM ) strcpy(text, "Normalna\\Normalna jako�� grafiki"); + if ( num == EVENT_INTERFACE_MAX ) strcpy(text, "Najwy�sza\\Maksymalna jako�� grafiki (najni�sza cz�stotliwo�� od�wie�ania)"); + + if ( num == EVENT_INTERFACE_SILENT ) strcpy(text, "Cisza\\Brak d�wi�k�w"); + if ( num == EVENT_INTERFACE_NOISY ) strcpy(text, "Normalne\\Normalna g�o�no�� d�wi�k�w"); + + if ( num == EVENT_INTERFACE_JOYSTICK) strcpy(text, "U�ywaj joysticka\\Joystick lub klawiatura"); + if ( num == EVENT_INTERFACE_SOLUCE ) strcpy(text, "Dost�p do rozwi�zania\\Pokazuje rozwi�zanie (szczeg�owe instrukcje dotycz�ce misji)"); + + if ( num == EVENT_INTERFACE_NEDIT ) strcpy(text, "\\Nowe imi� gracza"); + if ( num == EVENT_INTERFACE_NOK ) strcpy(text, "OK\\Wybiera zaznaczonego gracza"); + if ( num == EVENT_INTERFACE_NCANCEL) strcpy(text, "Anuluj\\Zachowuje bie��ce imi� gracza"); + if ( num == EVENT_INTERFACE_NDELETE) strcpy(text, "Usu� gracza\\Usuwa gracza z listy"); + if ( num == EVENT_INTERFACE_NLABEL ) strcpy(text, "Imi� gracza"); + + if ( num == EVENT_INTERFACE_IOWRITE) strcpy(text, "Zapisz\\Zapisuje bie��c� misj�"); + if ( num == EVENT_INTERFACE_IOREAD ) strcpy(text, "Wczytaj\\Wczytuje zaznaczon� misj�"); + if ( num == EVENT_INTERFACE_IOLIST ) strcpy(text, "Lista zapisanych misji"); + if ( num == EVENT_INTERFACE_IOLABEL) strcpy(text, "Nazwa pliku:"); + if ( num == EVENT_INTERFACE_IONAME ) strcpy(text, "Nazwa misji"); + if ( num == EVENT_INTERFACE_IOIMAGE) strcpy(text, "Fotografia"); + if ( num == EVENT_INTERFACE_IODELETE) strcpy(text, "Usu�\\Usuwa zaznaczony plik"); + + if ( num == EVENT_INTERFACE_PERSO ) strcpy(text, "Wygl�d\\Wybierz swoj� posta�"); + if ( num == EVENT_INTERFACE_POK ) strcpy(text, "OK"); + if ( num == EVENT_INTERFACE_PCANCEL) strcpy(text, "Anuluj"); + if ( num == EVENT_INTERFACE_PDEF ) strcpy(text, "Standardowe\\Standardowe ustawienia wygl�du"); + if ( num == EVENT_INTERFACE_PHEAD ) strcpy(text, "G�owa\\Twarz i w�osy"); + if ( num == EVENT_INTERFACE_PBODY ) strcpy(text, "Skafander\\Skafander astronauty"); + if ( num == EVENT_INTERFACE_PLROT ) strcpy(text, "\\Obr�� w lewo"); + if ( num == EVENT_INTERFACE_PRROT ) strcpy(text, "\\Obr�� w prawo"); + if ( num == EVENT_INTERFACE_PCRa ) strcpy(text, "Czerwony"); + if ( num == EVENT_INTERFACE_PCGa ) strcpy(text, "Zielony"); + if ( num == EVENT_INTERFACE_PCBa ) strcpy(text, "Niebieski"); + if ( num == EVENT_INTERFACE_PCRb ) strcpy(text, "Czerwony"); + if ( num == EVENT_INTERFACE_PCGb ) strcpy(text, "Zielony"); + if ( num == EVENT_INTERFACE_PCBb ) strcpy(text, "Niebieski"); + if ( num == EVENT_INTERFACE_PFACE1 ) strcpy(text, "\\Twarz 1"); + if ( num == EVENT_INTERFACE_PFACE2 ) strcpy(text, "\\Twarz 4"); + if ( num == EVENT_INTERFACE_PFACE3 ) strcpy(text, "\\Twarz 3"); + if ( num == EVENT_INTERFACE_PFACE4 ) strcpy(text, "\\Twarz 2"); + if ( num == EVENT_INTERFACE_PGLASS0) strcpy(text, "\\Bez okular�w"); + if ( num == EVENT_INTERFACE_PGLASS1) strcpy(text, "\\Okulary 1"); + if ( num == EVENT_INTERFACE_PGLASS2) strcpy(text, "\\Okulary 2"); + if ( num == EVENT_INTERFACE_PGLASS3) strcpy(text, "\\Okulary 3"); + if ( num == EVENT_INTERFACE_PGLASS4) strcpy(text, "\\Okulary 4"); + if ( num == EVENT_INTERFACE_PGLASS5) strcpy(text, "\\Okulary 5"); + + if ( num == EVENT_OBJECT_DESELECT ) strcpy(text, "Poprzednie zaznaczenie (\\key desel;)"); + if ( num == EVENT_OBJECT_LEFT ) strcpy(text, "Skr�� w lewo (\\key left;)"); + if ( num == EVENT_OBJECT_RIGHT ) strcpy(text, "Skr�� w prawo (\\key right;)"); + if ( num == EVENT_OBJECT_UP ) strcpy(text, "Naprz�d (\\key up;)"); + if ( num == EVENT_OBJECT_DOWN ) strcpy(text, "Cofnij (\\key down;)"); + if ( num == EVENT_OBJECT_GASUP ) strcpy(text, "G�ra (\\key gup;)"); + if ( num == EVENT_OBJECT_GASDOWN ) strcpy(text, "D� (\\key gdown;)"); + if ( num == EVENT_OBJECT_HTAKE ) strcpy(text, "Podnie� lub upu�� (\\key action;)"); + if ( num == EVENT_OBJECT_MTAKE ) strcpy(text, "Podnie� lub upu�� (\\key action;)"); + if ( num == EVENT_OBJECT_MFRONT ) strcpy(text, "..przed"); + if ( num == EVENT_OBJECT_MBACK ) strcpy(text, "..za"); + if ( num == EVENT_OBJECT_MPOWER ) strcpy(text, "..ogniwo elektryczne"); + if ( num == EVENT_OBJECT_BHELP ) strcpy(text, "Rozkazy dotycz�ce misji (\\key help;)"); + if ( num == EVENT_OBJECT_BTAKEOFF ) strcpy(text, "Odle�, aby zako�czy� misj�"); + if ( num == EVENT_OBJECT_BDERRICK ) strcpy(text, "Zbuduj kopalni�"); + if ( num == EVENT_OBJECT_BSTATION ) strcpy(text, "Zbuduj elektrowni�"); + if ( num == EVENT_OBJECT_BFACTORY ) strcpy(text, "Zbuduj fabryk� robot�w"); + if ( num == EVENT_OBJECT_BREPAIR ) strcpy(text, "Zbuduj warsztat"); + if ( num == EVENT_OBJECT_BCONVERT ) strcpy(text, "Zbuduj hut�"); + if ( num == EVENT_OBJECT_BTOWER ) strcpy(text, "Zbuduj wie�� obronn�"); + if ( num == EVENT_OBJECT_BRESEARCH ) strcpy(text, "Zbuduj centrum badawcze"); + if ( num == EVENT_OBJECT_BRADAR ) strcpy(text, "Zbuduj stacj� radarow�"); + if ( num == EVENT_OBJECT_BENERGY ) strcpy(text, "Zbuduj fabryk� ogniw elektrycznych"); + if ( num == EVENT_OBJECT_BLABO ) strcpy(text, "Zbuduj laboratorium"); + if ( num == EVENT_OBJECT_BNUCLEAR ) strcpy(text, "Zbuduj elektrowni� atomow�"); + if ( num == EVENT_OBJECT_BPARA ) strcpy(text, "Zbuduj odgromnik"); + if ( num == EVENT_OBJECT_BINFO ) strcpy(text, "Zbuduj stacj� przeka�nikow�"); + if ( num == EVENT_OBJECT_GFLAT ) strcpy(text, "Poka� czy teren jest p�aski"); + if ( num == EVENT_OBJECT_FCREATE ) strcpy(text, "Postaw flag�"); + if ( num == EVENT_OBJECT_FDELETE ) strcpy(text, "Usu� flag�"); + if ( num == EVENT_OBJECT_FCOLORb ) strcpy(text, "\\Niebieskie flagi"); + if ( num == EVENT_OBJECT_FCOLORr ) strcpy(text, "\\Czerwone flagi"); + if ( num == EVENT_OBJECT_FCOLORg ) strcpy(text, "\\Zielone flagi"); + if ( num == EVENT_OBJECT_FCOLORy ) strcpy(text, "\\��te flagi"); + if ( num == EVENT_OBJECT_FCOLORv ) strcpy(text, "\\Fioletowe flagi"); + if ( num == EVENT_OBJECT_FACTORYfa ) strcpy(text, "Zbuduj transporter lataj�cy"); + if ( num == EVENT_OBJECT_FACTORYta ) strcpy(text, "Zbuduj transporter na g�sienicach"); + if ( num == EVENT_OBJECT_FACTORYwa ) strcpy(text, "Zbuduj transporter na ko�ach"); + if ( num == EVENT_OBJECT_FACTORYia ) strcpy(text, "Zbuduj transporter na nogach"); + if ( num == EVENT_OBJECT_FACTORYfc ) strcpy(text, "Zbuduj dzia�o lataj�ce"); + if ( num == EVENT_OBJECT_FACTORYtc ) strcpy(text, "Zbuduj dzia�o na g�sienicach"); + if ( num == EVENT_OBJECT_FACTORYwc ) strcpy(text, "Zbuduj dzia�o na ko�ach"); + if ( num == EVENT_OBJECT_FACTORYic ) strcpy(text, "Zbuduj dzia�o na nogach"); + if ( num == EVENT_OBJECT_FACTORYfi ) strcpy(text, "Zbuduj lataj�ce dzia�o organiczne"); + if ( num == EVENT_OBJECT_FACTORYti ) strcpy(text, "Zbuduj dzia�o organiczne na g�sienicach"); + if ( num == EVENT_OBJECT_FACTORYwi ) strcpy(text, "Zbuduj dzia�o organiczne na ko�ach"); + if ( num == EVENT_OBJECT_FACTORYii ) strcpy(text, "Zbuduj dzia�o organiczne na nogach"); + if ( num == EVENT_OBJECT_FACTORYfs ) strcpy(text, "Zbuduj szperacz lataj�cy"); + if ( num == EVENT_OBJECT_FACTORYts ) strcpy(text, "Zbuduj szperacz na g�sienicach"); + if ( num == EVENT_OBJECT_FACTORYws ) strcpy(text, "Zbuduj szperacz na ko�ach"); + if ( num == EVENT_OBJECT_FACTORYis ) strcpy(text, "Zbuduj szperacz na nogach"); + if ( num == EVENT_OBJECT_FACTORYrt ) strcpy(text, "Zbuduj robota uderzacza"); + if ( num == EVENT_OBJECT_FACTORYrc ) strcpy(text, "Zbuduj dzia�o fazowe"); + if ( num == EVENT_OBJECT_FACTORYrr ) strcpy(text, "Zbuduj robota recyklera"); + if ( num == EVENT_OBJECT_FACTORYrs ) strcpy(text, "Zbuduj robota os�aniajacza"); + if ( num == EVENT_OBJECT_FACTORYsa ) strcpy(text, "Zbuduj robota nurka"); + if ( num == EVENT_OBJECT_RTANK ) strcpy(text, "Rozpocznij prace badawcze nad transporterem na g�sienicach"); + if ( num == EVENT_OBJECT_RFLY ) strcpy(text, "Rozpocznij prace badawcze nad transporterem lataj�cym"); + if ( num == EVENT_OBJECT_RTHUMP ) strcpy(text, "Rozpocznij prace badawcze nad robotem uderzaczem"); + if ( num == EVENT_OBJECT_RCANON ) strcpy(text, "Rozpocznij prace badawcze nad dzia�em"); + if ( num == EVENT_OBJECT_RTOWER ) strcpy(text, "Rozpocznij prace badawcze nad wie�� obronn�"); + if ( num == EVENT_OBJECT_RPHAZER ) strcpy(text, "Rozpocznij prace badawcze nad dzia�em fazowym"); + if ( num == EVENT_OBJECT_RSHIELD ) strcpy(text, "Rozpocznij prace badawcze nad robotem os�aniaczem"); + if ( num == EVENT_OBJECT_RATOMIC ) strcpy(text, "Rozpocznij prace badawcze nad energi� atomow�"); + if ( num == EVENT_OBJECT_RiPAW ) strcpy(text, "Rozpocznij prace badawcze nad transporterem na nogach"); + if ( num == EVENT_OBJECT_RiGUN ) strcpy(text, "Rozpocznij prace badawcze nad dzia�em organicznym"); + if ( num == EVENT_OBJECT_RESET ) strcpy(text, "Powr�t do pocz�tku"); + if ( num == EVENT_OBJECT_SEARCH ) strcpy(text, "Szukaj (\\key action;)"); + if ( num == EVENT_OBJECT_TERRAFORM ) strcpy(text, "Uderz (\\key action;)"); + if ( num == EVENT_OBJECT_FIRE ) strcpy(text, "Strzelaj (\\key action;)"); + if ( num == EVENT_OBJECT_RECOVER ) strcpy(text, "Odzyskaj (\\key action;)"); + if ( num == EVENT_OBJECT_BEGSHIELD ) strcpy(text, "Rozszerz os�on� (\\key action;)"); + if ( num == EVENT_OBJECT_ENDSHIELD ) strcpy(text, "Wy��cz os�on� (\\key action;)"); + if ( num == EVENT_OBJECT_DIMSHIELD ) strcpy(text, "Zasi�g os�ony"); + if ( num == EVENT_OBJECT_PROGRUN ) strcpy(text, "Wykonaj zaznaczony program"); + if ( num == EVENT_OBJECT_PROGEDIT ) strcpy(text, "Edytuj zaznaczony program"); + if ( num == EVENT_OBJECT_INFOOK ) strcpy(text, "\\Prze��cz przeka�nik SatCom w stan gotowo�ci"); + if ( num == EVENT_OBJECT_DELETE ) strcpy(text, "Zniszcz budynek"); + if ( num == EVENT_OBJECT_GENERGY ) strcpy(text, "Poziom energii"); + if ( num == EVENT_OBJECT_GSHIELD ) strcpy(text, "Poziom os�ony"); + if ( num == EVENT_OBJECT_GRANGE ) strcpy(text, "Temperatura silnika"); + if ( num == EVENT_OBJECT_GPROGRESS ) strcpy(text, "Wci�� pracuje..."); + if ( num == EVENT_OBJECT_GRADAR ) strcpy(text, "Liczba wykrytych insekt�w"); + if ( num == EVENT_OBJECT_GINFO ) strcpy(text, "Przes�ane informacje"); + if ( num == EVENT_OBJECT_COMPASS ) strcpy(text, "Kompas"); +//? if ( num == EVENT_OBJECT_MAP ) strcpy(text, "Mapka"); + if ( num == EVENT_OBJECT_MAPZOOM ) strcpy(text, "Powi�kszenie mapki"); + if ( num == EVENT_OBJECT_CAMERA ) strcpy(text, "Kamera (\\key camera;)"); + if ( num == EVENT_OBJECT_CAMERAleft) strcpy(text, "Camera to left"); + if ( num == EVENT_OBJECT_CAMERAright) strcpy(text, "Camera to right"); + if ( num == EVENT_OBJECT_CAMERAnear) strcpy(text, "Camera nearest"); + if ( num == EVENT_OBJECT_CAMERAaway) strcpy(text, "Camera awayest"); + if ( num == EVENT_OBJECT_HELP ) strcpy(text, "Pomoc na temat zaznaczonego obiektu"); + if ( num == EVENT_OBJECT_SOLUCE ) strcpy(text, "Poka� rozwi�zanie"); + if ( num == EVENT_OBJECT_SHORTCUT00) strcpy(text, "Prze��cz roboty <-> budynki"); + if ( num == EVENT_OBJECT_LIMIT ) strcpy(text, "Poka� zasi�g"); + if ( num == EVENT_OBJECT_PEN0 ) strcpy(text, "\\Rel�ve le crayon"); + if ( num == EVENT_OBJECT_PEN1 ) strcpy(text, "\\Abaisse le crayon noir"); + if ( num == EVENT_OBJECT_PEN2 ) strcpy(text, "\\Abaisse le crayon jaune"); + if ( num == EVENT_OBJECT_PEN3 ) strcpy(text, "\\Abaisse le crayon orange"); + if ( num == EVENT_OBJECT_PEN4 ) strcpy(text, "\\Abaisse le crayon rouge"); + if ( num == EVENT_OBJECT_PEN5 ) strcpy(text, "\\Abaisse le crayon violet"); + if ( num == EVENT_OBJECT_PEN6 ) strcpy(text, "\\Abaisse le crayon bleu"); + if ( num == EVENT_OBJECT_PEN7 ) strcpy(text, "\\Abaisse le crayon vert"); + if ( num == EVENT_OBJECT_PEN8 ) strcpy(text, "\\Abaisse le crayon brun"); + if ( num == EVENT_OBJECT_REC ) strcpy(text, "\\D�marre l'enregistrement"); + if ( num == EVENT_OBJECT_STOP ) strcpy(text, "\\Stoppe l'enregistrement"); + if ( num == EVENT_DT_VISIT0 || + num == EVENT_DT_VISIT1 || + num == EVENT_DT_VISIT2 || + num == EVENT_DT_VISIT3 || + num == EVENT_DT_VISIT4 ) strcpy(text, "Poka� miejsce"); + if ( num == EVENT_DT_END ) strcpy(text, "Kontynuuj"); + if ( num == EVENT_CMD ) strcpy(text, "Linia polecenia"); + if ( num == EVENT_SPEED ) strcpy(text, "Pr�dko�� gry"); + + if ( num == EVENT_HYPER_PREV ) strcpy(text, "Wstecz"); + if ( num == EVENT_HYPER_NEXT ) strcpy(text, "Naprz�d"); + if ( num == EVENT_HYPER_HOME ) strcpy(text, "Pocz�tek"); + if ( num == EVENT_HYPER_COPY ) strcpy(text, "Kopiuj"); + if ( num == EVENT_HYPER_SIZE1 ) strcpy(text, "Wielko�� 1"); + if ( num == EVENT_HYPER_SIZE2 ) strcpy(text, "Wielko�� 2"); + if ( num == EVENT_HYPER_SIZE3 ) strcpy(text, "Wielko�� 3"); + if ( num == EVENT_HYPER_SIZE4 ) strcpy(text, "Wielko�� 4"); + if ( num == EVENT_HYPER_SIZE5 ) strcpy(text, "Wielko�� 5"); + if ( num == EVENT_SATCOM_HUSTON ) strcpy(text, "Rozkazy z Houston"); +#if _TEEN + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Raport z satelity"); +#else + if ( num == EVENT_SATCOM_SAT ) strcpy(text, "Raport z satelity"); +#endif + if ( num == EVENT_SATCOM_LOADING ) strcpy(text, "Program dostarczony z Houston"); + if ( num == EVENT_SATCOM_OBJECT ) strcpy(text, "Lista obiekt�w"); + if ( num == EVENT_SATCOM_PROG ) strcpy(text, "Podr�cznik programowania"); + if ( num == EVENT_SATCOM_SOLUCE ) strcpy(text, "Rozwi�zanie"); + + if ( num == EVENT_STUDIO_OK ) strcpy(text, "OK\\Zamyka edytor programu i powraca do gry"); + if ( num == EVENT_STUDIO_CANCEL ) strcpy(text, "Anuluj\\Pomija wszystkie zmiany"); + if ( num == EVENT_STUDIO_NEW ) strcpy(text, "Nowy"); + if ( num == EVENT_STUDIO_OPEN ) strcpy(text, "Otw�rz (Ctrl+O)"); + if ( num == EVENT_STUDIO_SAVE ) strcpy(text, "Zapisz (Ctrl+S)"); + if ( num == EVENT_STUDIO_UNDO ) strcpy(text, "Cofnij (Ctrl+Z)"); + if ( num == EVENT_STUDIO_CUT ) strcpy(text, "Wytnij (Ctrl+X)"); + if ( num == EVENT_STUDIO_COPY ) strcpy(text, "Kopiuj (Ctrl+C)"); + if ( num == EVENT_STUDIO_PASTE ) strcpy(text, "Wklej (Ctrl+V)"); + if ( num == EVENT_STUDIO_SIZE ) strcpy(text, "Wielko�� czcionki"); + if ( num == EVENT_STUDIO_TOOL ) strcpy(text, "Rozkazy (\\key help;)"); + if ( num == EVENT_STUDIO_HELP ) strcpy(text, "Podr�cznik programowania (\\key prog;)"); + if ( num == EVENT_STUDIO_COMPILE ) strcpy(text, "Kompiluj"); + if ( num == EVENT_STUDIO_RUN ) strcpy(text, "Wykonaj/Zatrzymaj"); + if ( num == EVENT_STUDIO_REALTIME ) strcpy(text, "Pauza/Kontynuuj"); + if ( num == EVENT_STUDIO_STEP ) strcpy(text, "Jeden krok"); + } + + if ( type == RES_OBJECT ) + { + if ( num == OBJECT_PORTICO ) strcpy(text, "�uraw przesuwalny"); + if ( num == OBJECT_BASE ) strcpy(text, "Statek kosmiczny"); + if ( num == OBJECT_DERRICK ) strcpy(text, "Kopalnia"); + if ( num == OBJECT_FACTORY ) strcpy(text, "Fabryka robot�w"); + if ( num == OBJECT_REPAIR ) strcpy(text, "Warsztat"); + if ( num == OBJECT_DESTROYER ) strcpy(text, "Destroyer"); + if ( num == OBJECT_STATION ) strcpy(text, "Stacja energetyczna"); + if ( num == OBJECT_CONVERT ) strcpy(text, "Przetop rud� na tytan"); + if ( num == OBJECT_TOWER ) strcpy(text, "Wie�a obronna"); + if ( num == OBJECT_NEST ) strcpy(text, "Gniazdo"); + if ( num == OBJECT_RESEARCH ) strcpy(text, "Centrum badawcze"); + if ( num == OBJECT_RADAR ) strcpy(text, "Stacja radarowa"); + if ( num == OBJECT_INFO ) strcpy(text, "Stacja przeka�nikowa informacji"); +#if _TEEN + if ( num == OBJECT_ENERGY ) strcpy(text, "Fabryka ogniw elektrycznych"); +#else + if ( num == OBJECT_ENERGY ) strcpy(text, "Fabryka ogniw elektrycznych"); +#endif + if ( num == OBJECT_LABO ) strcpy(text, "Laboratorium"); + if ( num == OBJECT_NUCLEAR ) strcpy(text, "Elektrownia atomowa"); + if ( num == OBJECT_PARA ) strcpy(text, "Odgromnik"); + if ( num == OBJECT_SAFE ) strcpy(text, "Skrytka"); + if ( num == OBJECT_HUSTON ) strcpy(text, "Centrum Kontroli Misji w Houston"); + if ( num == OBJECT_TARGET1 ) strcpy(text, "Cel"); + if ( num == OBJECT_TARGET2 ) strcpy(text, "Cel"); + if ( num == OBJECT_START ) strcpy(text, "Pocz�tek"); + if ( num == OBJECT_END ) strcpy(text, "Koniec"); + if ( num == OBJECT_STONE ) strcpy(text, "Ruda tytanu"); + if ( num == OBJECT_URANIUM ) strcpy(text, "Ruda uranu"); + if ( num == OBJECT_BULLET ) strcpy(text, "Materia organiczna"); + if ( num == OBJECT_METAL ) strcpy(text, "Tytan"); + if ( num == OBJECT_POWER ) strcpy(text, "Ogniwo elektryczne"); + if ( num == OBJECT_ATOMIC ) strcpy(text, "Atomowe ogniwa elektryczne"); + if ( num == OBJECT_BBOX ) strcpy(text, "Czarna skrzynka"); + if ( num == OBJECT_KEYa ) strcpy(text, "Klucz A"); + if ( num == OBJECT_KEYb ) strcpy(text, "Klucz B"); + if ( num == OBJECT_KEYc ) strcpy(text, "Klucz C"); + if ( num == OBJECT_KEYd ) strcpy(text, "Klucz D"); + if ( num == OBJECT_TNT ) strcpy(text, "Materia�y wybuchowe"); + if ( num == OBJECT_BOMB ) strcpy(text, "Mina"); + if ( num == OBJECT_BAG ) strcpy(text, "Zestaw przetrwania"); + if ( num == OBJECT_WAYPOINT ) strcpy(text, "Punkt kontrolny"); + if ( num == OBJECT_FLAGb ) strcpy(text, "Niebieska flaga"); + if ( num == OBJECT_FLAGr ) strcpy(text, "Czerwona flaga"); + if ( num == OBJECT_FLAGg ) strcpy(text, "Zielona flaga"); + if ( num == OBJECT_FLAGy ) strcpy(text, "��ta flaga"); + if ( num == OBJECT_FLAGv ) strcpy(text, "Fioletowa flaga"); + if ( num == OBJECT_MARKPOWER ) strcpy(text, "�r�d�o energii (miejsce na elektrowni�)"); + if ( num == OBJECT_MARKURANIUM ) strcpy(text, "Z�o�e uranu (miejsce na kopalni�)"); + if ( num == OBJECT_MARKKEYa ) strcpy(text, "Znaleziono klucz A (miejsce na kopalni�)"); + if ( num == OBJECT_MARKKEYb ) strcpy(text, "Znaleziono klucz B (miejsce na kopalni�)"); + if ( num == OBJECT_MARKKEYc ) strcpy(text, "Znaleziono klucz C (miejsce na kopalni�)"); + if ( num == OBJECT_MARKKEYd ) strcpy(text, "Znaleziono klucz D (miejsce na kopalni�)"); + if ( num == OBJECT_MARKSTONE ) strcpy(text, "Z�o�e tytanu (miejsce na kopalni�)"); + if ( num == OBJECT_MOBILEft ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEtt ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEwt ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEit ) strcpy(text, "Robot treningowy"); + if ( num == OBJECT_MOBILEfa ) strcpy(text, "Transporter lataj�cy"); + if ( num == OBJECT_MOBILEta ) strcpy(text, "Transporter na g�sienicach"); + if ( num == OBJECT_MOBILEwa ) strcpy(text, "Transporter na ko�ach"); + if ( num == OBJECT_MOBILEia ) strcpy(text, "Transporter na nogach"); + if ( num == OBJECT_MOBILEfc ) strcpy(text, "Dzia�o lataj�ce"); + if ( num == OBJECT_MOBILEtc ) strcpy(text, "Dzia�o na g�sienicach"); + if ( num == OBJECT_MOBILEwc ) strcpy(text, "Dzia�o na ko�ach"); + if ( num == OBJECT_MOBILEic ) strcpy(text, "Dzia�o na nogach"); + if ( num == OBJECT_MOBILEfi ) strcpy(text, "Lataj�ce dzia�o organiczne"); + if ( num == OBJECT_MOBILEti ) strcpy(text, "Dzia�o organiczne na g�sienicach"); + if ( num == OBJECT_MOBILEwi ) strcpy(text, "Dzia�o organiczne na ko�ach"); + if ( num == OBJECT_MOBILEii ) strcpy(text, "Dzia�o organiczne na nogach"); + if ( num == OBJECT_MOBILEfs ) strcpy(text, "Szperacz lataj�cy"); + if ( num == OBJECT_MOBILEts ) strcpy(text, "Szperacz na g�sienicach"); + if ( num == OBJECT_MOBILEws ) strcpy(text, "Szperacz na ko�ach"); + if ( num == OBJECT_MOBILEis ) strcpy(text, "Szperacz na nogach"); + if ( num == OBJECT_MOBILErt ) strcpy(text, "Uderzacz"); + if ( num == OBJECT_MOBILErc ) strcpy(text, "Dzia�o fazowe"); + if ( num == OBJECT_MOBILErr ) strcpy(text, "Recykler"); + if ( num == OBJECT_MOBILErs ) strcpy(text, "Os�aniacz"); + if ( num == OBJECT_MOBILEsa ) strcpy(text, "Robot nurek"); + if ( num == OBJECT_MOBILEtg ) strcpy(text, "Robot cel"); + if ( num == OBJECT_MOBILEdr ) strcpy(text, "Drawer bot"); + if ( num == OBJECT_HUMAN ) strcpy(text, g_gamerName); + if ( num == OBJECT_TECH ) strcpy(text, "In�ynier"); + if ( num == OBJECT_TOTO ) strcpy(text, "Robbie"); + if ( num == OBJECT_MOTHER ) strcpy(text, "Kr�lowa Obcych"); + if ( num == OBJECT_ANT ) strcpy(text, "Mr�wka"); + if ( num == OBJECT_SPIDER ) strcpy(text, "Paj�k"); + if ( num == OBJECT_BEE ) strcpy(text, "Osa"); + if ( num == OBJECT_WORM ) strcpy(text, "Robal"); + if ( num == OBJECT_EGG ) strcpy(text, "Jajo"); + if ( num == OBJECT_RUINmobilew1 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobilew2 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobilet1 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobilet2 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobiler1 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINmobiler2 ) strcpy(text, "Wrak"); + if ( num == OBJECT_RUINfactory ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINdoor ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINsupport ) strcpy(text, "Odpady"); + if ( num == OBJECT_RUINradar ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINconvert ) strcpy(text, "Ruiny"); + if ( num == OBJECT_RUINbase ) strcpy(text, "Ruiny statku kosmicznego"); + if ( num == OBJECT_RUINhead ) strcpy(text, "Ruiny statku kosmicznego"); + if ( num == OBJECT_APOLLO1 || + num == OBJECT_APOLLO3 || + num == OBJECT_APOLLO4 || + num == OBJECT_APOLLO5 ) strcpy(text, "Pozosta�o�ci z misji Apollo"); + if ( num == OBJECT_APOLLO2 ) strcpy(text, "Pojazd Ksi�ycowy"); + } + + if ( type == RES_ERR ) + { + strcpy(text, "B��d"); + if ( num == ERR_CMD ) strcpy(text, "Nieznane polecenie"); +#if _NEWLOOK + if ( num == ERR_INSTALL ) strcpy(text, "Gra CeeBot nie jest zainstalowana."); + if ( num == ERR_NOCD ) strcpy(text, "W�� dysk CD z gr� CeeBot\ni uruchom gr� jeszcze raz."); +#else + if ( num == ERR_INSTALL ) strcpy(text, "Gra COLOBOT nie jest zainstalowana."); + if ( num == ERR_NOCD ) strcpy(text, "W�� dysk CD z gr� COLOBOT\ni uruchom gr� jeszcze raz."); +#endif + if ( num == ERR_MANIP_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_MANIP_FLY ) strcpy(text, "Niemo�liwe podczas lotu"); + if ( num == ERR_MANIP_BUSY ) strcpy(text, "Nie mo�na nie�� wi�cej przedmiot�w"); + if ( num == ERR_MANIP_NIL ) strcpy(text, "Nie ma nic do podniesienia"); + if ( num == ERR_MANIP_MOTOR ) strcpy(text, "Niemo�liwe podczas ruchu"); + if ( num == ERR_MANIP_OCC ) strcpy(text, "Miejsce zaj�te"); + if ( num == ERR_MANIP_FRIEND ) strcpy(text, "Brak innego robota"); + if ( num == ERR_MANIP_RADIO ) strcpy(text, "Nie mo�esz przenosi� przedmiot�w radioaktywnych"); + if ( num == ERR_MANIP_WATER ) strcpy(text, "Nie mo�esz przenosi� przedmiot�w pod wod�"); + if ( num == ERR_MANIP_EMPTY ) strcpy(text, "Nie ma nic do upuszczenia"); + if ( num == ERR_BUILD_FLY ) strcpy(text, "Niemo�liwe podczas lotu"); + if ( num == ERR_BUILD_WATER ) strcpy(text, "Niemo�liwe pod wod�"); + if ( num == ERR_BUILD_ENERGY ) strcpy(text, "Za ma�o energii"); + if ( num == ERR_BUILD_METALAWAY ) strcpy(text, "Tytan za daleko"); + if ( num == ERR_BUILD_METALNEAR ) strcpy(text, "Tytan za blisko"); + if ( num == ERR_BUILD_METALINEX ) strcpy(text, "Brak tytanu w pobli�u"); + if ( num == ERR_BUILD_FLAT ) strcpy(text, "Powierzchnia nie jest wystarczaj�co p�aska"); + if ( num == ERR_BUILD_FLATLIT ) strcpy(text, "Za ma�o p�askiego terenu"); + if ( num == ERR_BUILD_BUSY ) strcpy(text, "Miejsce zaj�te"); + if ( num == ERR_BUILD_BASE ) strcpy(text, "Za blisko statku kosmicznego"); + if ( num == ERR_BUILD_NARROW ) strcpy(text, "Za blisko budynku"); + if ( num == ERR_BUILD_MOTOR ) strcpy(text, "Niemo�liwe podczas ruchu"); + if ( num == ERR_SEARCH_FLY ) strcpy(text, "Niemo�liwe podczas lotu"); + if ( num == ERR_SEARCH_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_SEARCH_MOTOR ) strcpy(text, "Niemo�liwe podczas ruchu"); + if ( num == ERR_TERRA_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_TERRA_ENERGY ) strcpy(text, "Za ma�o energii"); + if ( num == ERR_TERRA_FLOOR ) strcpy(text, "Nieodpowiedni teren"); + if ( num == ERR_TERRA_BUILDING ) strcpy(text, "Budynek za blisko"); + if ( num == ERR_TERRA_OBJECT ) strcpy(text, "Obiekt za blisko"); + if ( num == ERR_RECOVER_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_RECOVER_ENERGY ) strcpy(text, "Za ma�o energii"); + if ( num == ERR_RECOVER_NULL ) strcpy(text, "Nie ma niczego do odzysku"); + if ( num == ERR_SHIELD_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_SHIELD_ENERGY ) strcpy(text, "Nie ma wi�cej energii"); + if ( num == ERR_MOVE_IMPOSSIBLE ) strcpy(text, "B��d w poleceniu ruchu"); + if ( num == ERR_FIND_IMPOSSIBLE ) strcpy(text, "Obiekt nieznany"); + if ( num == ERR_GOTO_IMPOSSIBLE ) strcpy(text, "Goto: miejsce docelowe niedost�pne"); + if ( num == ERR_GOTO_ITER ) strcpy(text, "Goto: miejsce docelowe niedost�pne"); + if ( num == ERR_GOTO_BUSY ) strcpy(text, "Goto: miejsce docelowe zaj�te"); + if ( num == ERR_FIRE_VEH ) strcpy(text, "Nieodpowiedni robot"); + if ( num == ERR_FIRE_ENERGY ) strcpy(text, "Za ma�o energii"); + if ( num == ERR_FIRE_FLY ) strcpy(text, "Niemo�liwe podczas lotu"); + if ( num == ERR_CONVERT_EMPTY ) strcpy(text, "Brak rudy tytanu do przetopienia"); + if ( num == ERR_DERRICK_NULL ) strcpy(text, "W ziemi nie ma �adnej rudy"); + if ( num == ERR_STATION_NULL ) strcpy(text, "Brak energii w ziemi"); + if ( num == ERR_TOWER_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); + if ( num == ERR_TOWER_ENERGY ) strcpy(text, "Nie ma wi�cej energii"); + if ( num == ERR_RESEARCH_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); + if ( num == ERR_RESEARCH_ENERGY ) strcpy(text, "Za ma�o energii"); + if ( num == ERR_RESEARCH_TYPE ) strcpy(text, "Nieodpowiedni rodzaj ogniw"); + if ( num == ERR_RESEARCH_ALREADY) strcpy(text, "Program badawczy zosta� ju� wykonany"); + if ( num == ERR_ENERGY_NULL ) strcpy(text, "Brak energii w ziemi"); + if ( num == ERR_ENERGY_LOW ) strcpy(text, "Wci�� za ma�o energii"); + if ( num == ERR_ENERGY_EMPTY ) strcpy(text, "Brak tytanu do przetworzenia"); + if ( num == ERR_ENERGY_BAD ) strcpy(text, "Przetwarza jedynie tytan"); + if ( num == ERR_BASE_DLOCK ) strcpy(text, "Drzwi zablokowane przez robota lub inny obiekt "); + if ( num == ERR_BASE_DHUMAN ) strcpy(text, "Musisz by� na statku kosmicznym aby nim odlecie�"); + if ( num == ERR_LABO_NULL ) strcpy(text, "Nie ma niczego do zanalizowania"); + if ( num == ERR_LABO_BAD ) strcpy(text, "Analizuje jedynie materi� organiczn�"); + if ( num == ERR_LABO_ALREADY ) strcpy(text, "Analiza zosta�a ju� wykonana"); + if ( num == ERR_NUCLEAR_NULL ) strcpy(text, "Brak energii w ziemi"); + if ( num == ERR_NUCLEAR_LOW ) strcpy(text, "Wci�� za ma�o energii"); + if ( num == ERR_NUCLEAR_EMPTY ) strcpy(text, "Brak uranu do przetworzenia"); + if ( num == ERR_NUCLEAR_BAD ) strcpy(text, "Przetwarza jedynie uran"); + if ( num == ERR_FACTORY_NULL ) strcpy(text, "Brak tytanu"); + if ( num == ERR_FACTORY_NEAR ) strcpy(text, "Obiekt za blisko"); + if ( num == ERR_RESET_NEAR ) strcpy(text, "Miejsce zaj�te"); + if ( num == ERR_INFO_NULL ) strcpy(text, "Nie ma �adnej stacji przeka�nikowej w zasi�gu"); + if ( num == ERR_VEH_VIRUS ) strcpy(text, "Program zawirusowany"); + if ( num == ERR_BAT_VIRUS ) strcpy(text, "Zainfekowane wirusem, chwilowo niesprawne"); + if ( num == ERR_VEH_POWER ) strcpy(text, "Brak ogniwa elektrycznego"); + if ( num == ERR_VEH_ENERGY ) strcpy(text, "Nie ma wi�cej energii"); + if ( num == ERR_FLAG_FLY ) strcpy(text, "Niemo�liwe podczas lotu"); + if ( num == ERR_FLAG_WATER ) strcpy(text, "Niemo�liwe podczas p�ywania"); + if ( num == ERR_FLAG_MOTOR ) strcpy(text, "Niemo�liwe podczas ruchu"); + if ( num == ERR_FLAG_BUSY ) strcpy(text, "Niemo�liwe podczas przenoszenia przedmiotu"); + if ( num == ERR_FLAG_CREATE ) strcpy(text, "Za du�o flag w tym kolorze (maksymalnie 5)"); + if ( num == ERR_FLAG_PROXY ) strcpy(text, "Za blisko istniej�cej flagi"); + if ( num == ERR_FLAG_DELETE ) strcpy(text, "Nie ma flagi w pobli�u"); + if ( num == ERR_MISSION_NOTERM ) strcpy(text, "Misja nie jest wype�niona (naci�nij \\key help; aby uzyska� szczeg�y)"); + if ( num == ERR_DELETEMOBILE ) strcpy(text, "Robot zniszczony"); + if ( num == ERR_DELETEBUILDING ) strcpy(text, "Budynek zniszczony"); + if ( num == ERR_TOOMANY ) strcpy(text, "Nie mo�na tego utworzy�, za du�o obiekt�w"); + if ( num == ERR_OBLIGATORYTOKEN ) strcpy(text, "It misses \"%s\" in this exercise"); + if ( num == ERR_PROHIBITEDTOKEN ) strcpy(text, "Do not use in this exercise"); + + if ( num == INFO_BUILD ) strcpy(text, "Budowa zako�czona"); + if ( num == INFO_CONVERT ) strcpy(text, "Tytan dost�pny"); + if ( num == INFO_RESEARCH ) strcpy(text, "Program badawczy zako�czony"); + if ( num == INFO_RESEARCHTANK ) strcpy(text, "Dost�pne plany tranporter�w na g�sienicach"); + if ( num == INFO_RESEARCHFLY ) strcpy(text, "Mo�esz lata� u�ywaj�c klawiszy (\\key gup;) oraz (\\key gdown;)"); + if ( num == INFO_RESEARCHTHUMP ) strcpy(text, "Dost�pne plany robota uderzacza"); + if ( num == INFO_RESEARCHCANON ) strcpy(text, "Dost�pne plany dzia�a"); + if ( num == INFO_RESEARCHTOWER ) strcpy(text, "Dost�pne plany wie�y obronnej"); + if ( num == INFO_RESEARCHPHAZER ) strcpy(text, "Dost�pne plany dzia�a fazowego"); + if ( num == INFO_RESEARCHSHIELD ) strcpy(text, "Dost�pne plany robota os�aniacza"); + if ( num == INFO_RESEARCHATOMIC ) strcpy(text, "Dost�pne plany elektrowni atomowej"); + if ( num == INFO_FACTORY ) strcpy(text, "Dost�pny nowy robot"); + if ( num == INFO_LABO ) strcpy(text, "Analiza wykonana"); + if ( num == INFO_ENERGY ) strcpy(text, "Wytworzono ogniwo elektryczne"); + if ( num == INFO_NUCLEAR ) strcpy(text, "Wytworzono atomowe ogniwo elektryczne"); + if ( num == INFO_FINDING ) strcpy(text, "Znaleziono u�yteczny przedmiot"); + if ( num == INFO_MARKPOWER ) strcpy(text, "Znaleziono miejsce na elektrowni�"); + if ( num == INFO_MARKURANIUM ) strcpy(text, "Znaleziono miejsce na kopalni�"); + if ( num == INFO_MARKSTONE ) strcpy(text, "Znaleziono miejsce na kopalni�"); + if ( num == INFO_MARKKEYa ) strcpy(text, "Znaleziono miejsce na kopalni�"); + if ( num == INFO_MARKKEYb ) strcpy(text, "Znaleziono miejsce na kopalni�"); + if ( num == INFO_MARKKEYc ) strcpy(text, "Znaleziono miejsce na kopalni�"); + if ( num == INFO_MARKKEYd ) strcpy(text, "Znaleziono miejsce na kopalni�"); + if ( num == INFO_WIN ) strcpy(text, "<<< Dobra robota, misja wype�niona >>>"); + if ( num == INFO_LOST ) strcpy(text, "<<< Niestety, misja nie powiod�a si� >>>"); + if ( num == INFO_LOSTq ) strcpy(text, "<<< Niestety, misja nie powiod�a si� >>>"); + if ( num == INFO_WRITEOK ) strcpy(text, "Bie��ca misja zapisana"); + if ( num == INFO_DELETEPATH ) strcpy(text, "Przekroczono punkt kontrolny"); + if ( num == INFO_DELETEMOTHER ) strcpy(text, "Kr�lowa Obcych zosta�a zabita"); + if ( num == INFO_DELETEANT ) strcpy(text, "Mr�wka �miertelnie raniona"); + if ( num == INFO_DELETEBEE ) strcpy(text, "Osa �miertelnie raniona"); + if ( num == INFO_DELETEWORM ) strcpy(text, "Robal �miertelnie raniony"); + if ( num == INFO_DELETESPIDER ) strcpy(text, "Paj�k �miertelnie raniony"); + if ( num == INFO_BEGINSATCOM ) strcpy(text, "Naci�nij klawisz \\key help; aby wy�wietli� rozkazy na przeka�niku SatCom"); + } + + if ( type == RES_CBOT ) + { + strcpy(text, "B��d"); + if ( num == TX_OPENPAR ) strcpy(text, "Brak nawiasu otwieraj�cego"); + if ( num == TX_CLOSEPAR ) strcpy(text, "Brak nawiasu zamykaj�cego"); + if ( num == TX_NOTBOOL ) strcpy(text, "Wyra�enie musi zwr�ci� warto�� logiczn�"); + if ( num == TX_UNDEFVAR ) strcpy(text, "Zmienna nie zosta�a zadeklarowana"); + if ( num == TX_BADLEFT ) strcpy(text, "Przypisanie niemo�liwe"); + if ( num == TX_ENDOF ) strcpy(text, "Brak �rednika na ko�cu wiersza"); + if ( num == TX_OUTCASE ) strcpy(text, "Polecenie ""case"" na zewn�trz bloku ""switch"""); + if ( num == TX_NOTERM ) strcpy(text, "Polecenie po ko�cowej klamrze zamykaj�cej"); + if ( num == TX_CLOSEBLK ) strcpy(text, "Brak ko�ca bloku"); + if ( num == TX_ELSEWITHOUTIF ) strcpy(text, "Polecenie ""else"" bez wyst�pienia ""if"" "); + if ( num == TX_OPENBLK ) strcpy(text, "Brak klamry otwieraj�cej");//d�but d'un bloc attendu? + if ( num == TX_BADTYPE ) strcpy(text, "Z�y typ dla przypisania"); + if ( num == TX_REDEFVAR ) strcpy(text, "Zmienna nie mo�e by� zadeklarowana dwukrotnie"); + if ( num == TX_BAD2TYPE ) strcpy(text, "Niezgodne typy operator�w"); + if ( num == TX_UNDEFCALL ) strcpy(text, "Funkcja nieznana"); + if ( num == TX_MISDOTS ) strcpy(text, "Brak znaku "" : "); + if ( num == TX_WHILE ) strcpy(text, "Brak kluczowego s�owa ""while"); + if ( num == TX_BREAK ) strcpy(text, "Polecenie ""break"" na zewn�trz p�tli"); + if ( num == TX_LABEL ) strcpy(text, "Po etykiecie musi wyst�pi� ""for"", ""while"", ""do"" lub ""switch"""); + if ( num == TX_NOLABEL ) strcpy(text, "Taka etykieta nie istnieje");// Cette �tiquette n'existe pas + if ( num == TX_NOCASE ) strcpy(text, "Brak polecenia ""case"); + if ( num == TX_BADNUM ) strcpy(text, "Brak liczby"); + if ( num == TX_VOID ) strcpy(text, "Pusty parametr"); + if ( num == TX_NOTYP ) strcpy(text, "Brak deklaracji typu"); + if ( num == TX_NOVAR ) strcpy(text, "Brak nazwy zmiennej"); + if ( num == TX_NOFONC ) strcpy(text, "Brakuj�ca nazwa funkcji"); + if ( num == TX_OVERPARAM ) strcpy(text, "Za du�o parametr�w"); + if ( num == TX_REDEF ) strcpy(text, "Funkcja ju� istnieje"); + if ( num == TX_LOWPARAM ) strcpy(text, "Brak wymaganego parametru"); + if ( num == TX_BADPARAM ) strcpy(text, "Funkcja o tej nazwie nie akceptuje parametr�w tego typu"); + if ( num == TX_NUMPARAM ) strcpy(text, "Funkcja o tej nazwie nie akceptuje takiej liczby parametr�w"); + if ( num == TX_NOITEM ) strcpy(text, "To nie jest obiekt tej klasy"); + if ( num == TX_DOT ) strcpy(text, "Ten obiekt nie jest cz�onkiem klasy"); + if ( num == TX_NOCONST ) strcpy(text, "Brak odpowiedniego konstruktora"); + if ( num == TX_REDEFCLASS ) strcpy(text, "Taka klasa ju� istnieje"); + if ( num == TX_CLBRK ) strcpy(text, "Brak "" ] """); + if ( num == TX_RESERVED ) strcpy(text, "S�owo zarezerwowane j�zyka CBOT"); + if ( num == TX_BADNEW ) strcpy(text, "Z�y argument dla funkcji ""new"""); + if ( num == TX_OPBRK ) strcpy(text, "Oczekiwane "" [ """); + if ( num == TX_BADSTRING ) strcpy(text, "Brak �a�cucha"); + if ( num == TX_BADINDEX ) strcpy(text, "Nieprawid�owy typ indeksu"); + if ( num == TX_PRIVATE ) strcpy(text, "Element prywatny"); + if ( num == TX_NOPUBLIC ) strcpy(text, "Wymagany publiczny"); + if ( num == TX_DIVZERO ) strcpy(text, "Dzielenie przez zero"); + if ( num == TX_NOTINIT ) strcpy(text, "Zmienna nie zosta�a zainicjalizowana"); + if ( num == TX_BADTHROW ) strcpy(text, "Warto�� ujemna odrzucona przez ""throw""");//C'est quoi, �a? + if ( num == TX_NORETVAL ) strcpy(text, "Funkcja nie zwr�ci�a �adnej warto�ci "); + if ( num == TX_NORUN ) strcpy(text, "�adna funkcja nie dzia�a"); + if ( num == TX_NOCALL ) strcpy(text, "Odwo�anie do nieznanej funkcji"); + if ( num == TX_NOCLASS ) strcpy(text, "Taka klasa nie istnieje"); + if ( num == TX_NULLPT ) strcpy(text, "Obiekt nieznany"); + if ( num == TX_OPNAN ) strcpy(text, "Dzia�anie niemo�liwe z warto�ci� ""nan"""); + if ( num == TX_OUTARRAY ) strcpy(text, "Dost�p poza tablic�"); + if ( num == TX_STACKOVER ) strcpy(text, "Przepe�nienie stosu"); + if ( num == TX_DELETEDPT ) strcpy(text, "Nieprawid�owy obiekt"); + if ( num == TX_FILEOPEN ) strcpy(text, "Nie mo�na otworzy� pliku"); + if ( num == TX_NOTOPEN ) strcpy(text, "Plik nie jest otwarty"); + if ( num == TX_ERRREAD ) strcpy(text, "B��d odczytu"); + if ( num == TX_ERRWRITE ) strcpy(text, "B��d zapisu"); + } + + if ( type == RES_KEY ) + { + if ( num == 0 ) strcpy(text, "< brak >"); + if ( num == SDLK_LEFT ) strcpy(text, "Strza�ka w lewo"); + if ( num == SDLK_RIGHT ) strcpy(text, "Strza�ka w prawo"); + if ( num == SDLK_UP ) strcpy(text, "Strza�ka w g�r�"); + if ( num == SDLK_DOWN ) strcpy(text, "Strza�ka w d�"); + if ( num == SDLK_CANCEL ) strcpy(text, "Ctrl-break"); + if ( num == SDLK_BACK ) strcpy(text, "<--"); + if ( num == SDLK_TAB ) strcpy(text, "Tab"); + if ( num == SDLK_CLEAR ) strcpy(text, "Delete"); + if ( num == SDLK_RETURN ) strcpy(text, "Enter"); + if ( num == SDLK_SHIFT ) strcpy(text, "Shift"); + if ( num == SDLK_CONTROL ) strcpy(text, "Ctrl"); + if ( num == SDLK_MENU ) strcpy(text, "Alt"); + if ( num == SDLK_PAUSE ) strcpy(text, "Pause"); + if ( num == SDLK_CAPITAL ) strcpy(text, "Caps Lock"); + if ( num == SDLK_ESCAPE ) strcpy(text, "Esc"); + if ( num == SDLK_SPACE ) strcpy(text, "Spacja"); + if ( num == SDLK_PRIOR ) strcpy(text, "Page Up"); + if ( num == SDLK_NEXT ) strcpy(text, "Page Down"); + if ( num == SDLK_END ) strcpy(text, "End"); + if ( num == SDLK_HOME ) strcpy(text, "Home"); + if ( num == SDLK_SELECT ) strcpy(text, "Zaznacz"); + if ( num == SDLK_EXECUTE ) strcpy(text, "Wykonaj"); + if ( num == SDLK_SNAPSHOT ) strcpy(text, "Print Scrn"); + if ( num == SDLK_INSERT ) strcpy(text, "Insert"); + if ( num == SDLK_DELETE ) strcpy(text, "Delete"); + if ( num == SDLK_HELP ) strcpy(text, "Pomoc"); + if ( num == SDLK_LWIN ) strcpy(text, "Lewy klawisz Windows"); + if ( num == SDLK_RWIN ) strcpy(text, "Prawy klawisz Windows"); + if ( num == SDLK_APPS ) strcpy(text, "Klawisz menu kontekstowego"); + if ( num == SDLK_NUMPAD0 ) strcpy(text, "Klaw. Num. 0"); + if ( num == SDLK_NUMPAD1 ) strcpy(text, "Klaw. Num. 1"); + if ( num == SDLK_NUMPAD2 ) strcpy(text, "Klaw. Num. 2"); + if ( num == SDLK_NUMPAD3 ) strcpy(text, "Klaw. Num. 3"); + if ( num == SDLK_NUMPAD4 ) strcpy(text, "Klaw. Num. 4"); + if ( num == SDLK_NUMPAD5 ) strcpy(text, "Klaw. Num. 5"); + if ( num == SDLK_NUMPAD6 ) strcpy(text, "Klaw. Num. 6"); + if ( num == SDLK_NUMPAD7 ) strcpy(text, "Klaw. Num. 7"); + if ( num == SDLK_NUMPAD8 ) strcpy(text, "Klaw. Num. 8"); + if ( num == SDLK_NUMPAD9 ) strcpy(text, "Klaw. Num. 9"); + if ( num == SDLK_MULTIPLY ) strcpy(text, "Klaw. Num. *"); + if ( num == SDLK_ADD ) strcpy(text, "Klaw. Num. +"); + if ( num == SDLK_SEPARATOR ) strcpy(text, "Klaw. Num. separator"); + if ( num == SDLK_SUBTRACT ) strcpy(text, "Klaw. Num. -"); + if ( num == SDLK_DECIMAL ) strcpy(text, "Klaw. Num. ."); + if ( num == SDLK_DIVIDE ) strcpy(text, "Klaw. Num. /"); + if ( num == SDLK_F1 ) strcpy(text, "F1"); + if ( num == SDLK_F2 ) strcpy(text, "F2"); + if ( num == SDLK_F3 ) strcpy(text, "F3"); + if ( num == SDLK_F4 ) strcpy(text, "F4"); + if ( num == SDLK_F5 ) strcpy(text, "F5"); + if ( num == SDLK_F6 ) strcpy(text, "F6"); + if ( num == SDLK_F7 ) strcpy(text, "F7"); + if ( num == SDLK_F8 ) strcpy(text, "F8"); + if ( num == SDLK_F9 ) strcpy(text, "F9"); + if ( num == SDLK_F10 ) strcpy(text, "F10"); + if ( num == SDLK_F11 ) strcpy(text, "F11"); + if ( num == SDLK_F12 ) strcpy(text, "F12"); + if ( num == SDLK_F13 ) strcpy(text, "F13"); + if ( num == SDLK_F14 ) strcpy(text, "F14"); + if ( num == SDLK_F15 ) strcpy(text, "F15"); + if ( num == SDLK_F16 ) strcpy(text, "F16"); + if ( num == SDLK_F17 ) strcpy(text, "F17"); + if ( num == SDLK_F18 ) strcpy(text, "F18"); + if ( num == SDLK_F19 ) strcpy(text, "F19"); + if ( num == SDLK_F20 ) strcpy(text, "F20"); + if ( num == SDLK_NUMLOCK ) strcpy(text, "Num Lock"); + if ( num == SDLK_SCROLL ) strcpy(text, "Scroll Lock"); + if ( num == SDLK_ATTN ) strcpy(text, "Attn"); + if ( num == SDLK_CRSEL ) strcpy(text, "CrSel"); + if ( num == SDLK_EXSEL ) strcpy(text, "ExSel"); + if ( num == SDLK_EREOF ) strcpy(text, "Erase EOF"); + if ( num == SDLK_PLAY ) strcpy(text, "Graj"); + if ( num == SDLK_ZOOM ) strcpy(text, "Powi�kszenie"); + if ( num == SDLK_PA1 ) strcpy(text, "PA1"); + if ( num == SDLK_OEM_CLEAR ) strcpy(text, "Wyczy��"); + if ( num == SDLK_BUTTON1 ) strcpy(text, "Przycisk 1"); + if ( num == SDLK_BUTTON2 ) strcpy(text, "Przycisk 2"); + if ( num == SDLK_BUTTON3 ) strcpy(text, "Przycisk 3"); + if ( num == SDLK_BUTTON4 ) strcpy(text, "Przycisk 4"); + if ( num == SDLK_BUTTON5 ) strcpy(text, "Przycisk 5"); + if ( num == SDLK_BUTTON6 ) strcpy(text, "Przycisk 6"); + if ( num == SDLK_BUTTON7 ) strcpy(text, "Przycisk 7"); + if ( num == SDLK_BUTTON8 ) strcpy(text, "Przycisk 8"); + if ( num == SDLK_BUTTON9 ) strcpy(text, "Przycisk 9"); + if ( num == SDLK_BUTTON10 ) strcpy(text, "Przycisk 10"); + if ( num == SDLK_BUTTON11 ) strcpy(text, "Przycisk 11"); + if ( num == SDLK_BUTTON12 ) strcpy(text, "Przycisk 12"); + if ( num == SDLK_BUTTON13 ) strcpy(text, "Przycisk 13"); + if ( num == SDLK_BUTTON14 ) strcpy(text, "Przycisk 14"); + if ( num == SDLK_BUTTON15 ) strcpy(text, "Przycisk 15"); + if ( num == SDLK_BUTTON16 ) strcpy(text, "Przycisk 16"); + if ( num == SDLK_BUTTON17 ) strcpy(text, "Przycisk 17"); + if ( num == SDLK_BUTTON18 ) strcpy(text, "Przycisk 18"); + if ( num == SDLK_BUTTON19 ) strcpy(text, "Przycisk 19"); + if ( num == SDLK_BUTTON20 ) strcpy(text, "Przycisk 20"); + if ( num == SDLK_BUTTON21 ) strcpy(text, "Przycisk 21"); + if ( num == SDLK_BUTTON22 ) strcpy(text, "Przycisk 22"); + if ( num == SDLK_BUTTON23 ) strcpy(text, "Przycisk 23"); + if ( num == SDLK_BUTTON24 ) strcpy(text, "Przycisk 24"); + if ( num == SDLK_BUTTON25 ) strcpy(text, "Przycisk 25"); + if ( num == SDLK_BUTTON26 ) strcpy(text, "Przycisk 26"); + if ( num == SDLK_BUTTON27 ) strcpy(text, "Przycisk 27"); + if ( num == SDLK_BUTTON28 ) strcpy(text, "Przycisk 28"); + if ( num == SDLK_BUTTON29 ) strcpy(text, "Przycisk 29"); + if ( num == SDLK_BUTTON30 ) strcpy(text, "Przycisk 30"); + if ( num == SDLK_BUTTON31 ) strcpy(text, "Przycisk 31"); + if ( num == SDLK_BUTTON32 ) strcpy(text, "Przycisk 32"); + if ( num == SDLK_WHEELUP ) strcpy(text, "K�ko w g�r�"); + if ( num == SDLK_WHEELDOWN ) strcpy(text, "K�ko w d�"); + } +#endif + + return ( text[0] != 0 ); +} + + diff --git a/src/common/restext.h b/src/common/restext.h index 624803b..44bc6b4 100644 --- a/src/common/restext.h +++ b/src/common/restext.h @@ -18,38 +18,143 @@ #pragma once -#include "common/restext_ids.h" +//#include "graphics/engine/engine.h" +#include "common/event.h" + +namespace Gfx +{ + class CEngine; +} -class CD3DEngine; // Possible types of the text resources. enum ResType { - RES_TEXT = 0, // RT_* - RES_EVENT = 1, // EVENT_* (EventMsg) - RES_OBJECT = 2, // OBJECT_* (ObjectType) - RES_ERR = 3, // ERR_* (Error) - RES_KEY = 4, // VK_* (keys) - RES_CBOT = 5, // TX_* (cbot.dll) + RES_TEXT = 0, // RT_* + RES_EVENT = 1, // EVENT_* (EventType) + RES_OBJECT = 2, // OBJECT_* (ObjectType) + RES_ERR = 3, // ERR_* (Error) + RES_KEY = 4, // VK_* (keys) + RES_CBOT = 5, // TX_* (cbot.dll) }; -extern void SetEngine(CD3DEngine *engine); +// Resources of type RES_TEXT. + +enum ResTextType +{ + RT_VERSION_ID = 1, + RT_DISINFO_TITLE = 2, + RT_WINDOW_MAXIMIZED = 3, + RT_WINDOW_MINIMIZED = 4, + RT_WINDOW_STANDARD = 5, + RT_WINDOW_CLOSE = 6, + + RT_STUDIO_TITLE = 10, + RT_SCRIPT_NEW = 20, + RT_NAME_DEFAULT = 21, + RT_IO_NEW = 22, + RT_KEY_OR = 23, + + RT_TITLE_BASE = 40, + RT_TITLE_INIT = 41, + RT_TITLE_TRAINER = 42, + RT_TITLE_DEFI = 43, + RT_TITLE_MISSION = 44, + RT_TITLE_FREE = 45, + RT_TITLE_PROTO = 46, + RT_TITLE_SETUP = 47, + RT_TITLE_NAME = 48, + RT_TITLE_PERSO = 49, + RT_TITLE_WRITE = 50, + RT_TITLE_READ = 51, + RT_TITLE_USER = 52, + RT_TITLE_TEEN = 53, + + RT_PLAY_CHAPt = 60, + RT_PLAY_CHAPd = 61, + RT_PLAY_CHAPm = 62, + RT_PLAY_CHAPf = 63, + RT_PLAY_CHAPp = 64, + RT_PLAY_LISTt = 65, + RT_PLAY_LISTd = 66, + RT_PLAY_LISTm = 67, + RT_PLAY_LISTf = 68, + RT_PLAY_LISTp = 69, + RT_PLAY_RESUME = 70, + RT_PLAY_CHAPu = 71, + RT_PLAY_LISTu = 72, + RT_PLAY_CHAPte = 73, + RT_PLAY_LISTk = 74, + + RT_SETUP_DEVICE = 80, + RT_SETUP_MODE = 81, + RT_SETUP_KEY1 = 82, + RT_SETUP_KEY2 = 83, + + RT_PERSO_FACE = 90, + RT_PERSO_GLASSES = 91, + RT_PERSO_HAIR = 92, + RT_PERSO_COMBI = 93, + RT_PERSO_BAND = 94, + + RT_DIALOG_TITLE = 100, + RT_DIALOG_ABORT = 101, + RT_DIALOG_QUIT = 102, + RT_DIALOG_YES = 103, + RT_DIALOG_NO = 104, + RT_DIALOG_DELOBJ = 105, + RT_DIALOG_DELGAME = 106, + RT_DIALOG_YESDEL = 107, + RT_DIALOG_NODEL = 108, + RT_DIALOG_LOADING = 109, + RT_DIALOG_YESQUIT = 110, + RT_DIALOG_NOQUIT = 111, + + RT_STUDIO_LISTTT = 120, + RT_STUDIO_COMPOK = 121, + RT_STUDIO_PROGSTOP = 122, + + RT_SATCOM_LIST = 140, + RT_SATCOM_BOT = 141, + RT_SATCOM_BUILDING = 142, + RT_SATCOM_FRET = 143, + RT_SATCOM_ALIEN = 144, + RT_SATCOM_NULL = 145, + RT_SATCOM_ERROR1 = 146, + RT_SATCOM_ERROR2 = 147, + + RT_IO_OPEN = 150, + RT_IO_SAVE = 151, + RT_IO_LIST = 152, + RT_IO_NAME = 153, + RT_IO_DIR = 154, + RT_IO_PRIVATE = 155, + RT_IO_PUBLIC = 156, + + RT_GENERIC_DEV1 = 170, + RT_GENERIC_DEV2 = 171, + RT_GENERIC_EDIT1 = 172, + RT_GENERIC_EDIT2 = 173, + + RT_INTERFACE_REC = 180, + + RT_MESSAGE_WIN = 200, + RT_MESSAGE_LOST = 201, +}; + + +static Gfx::CEngine* g_engine = 0; +static char g_gamerName[100]; + +extern void SetEngine(Gfx::CEngine *engine); extern void SetGlobalGamerName(char *name); extern bool SearchKey(char *cmd, KeyRank &key); +extern void PutKeyName(char* dst, char* src); extern bool GetResource(ResType type, int num, char* text); +extern bool GetResourceBase(ResType type, int num, char* text); + -extern const char * const strings_text[]; -extern const char * const strings_event[]; -extern const char * const strings_object[]; -extern const char * const strings_err[]; -extern const char * const strings_cbot[]; - -extern const int strings_text_len; -extern const int strings_event_len; -extern const int strings_object_len; -extern const int strings_err_len; -extern const int strings_cbot_len; diff --git a/src/common/singleton.h b/src/common/singleton.h index 4df7878..f631ed4 100644 --- a/src/common/singleton.h +++ b/src/common/singleton.h @@ -29,26 +29,26 @@ template<typename T> class CSingleton public: static T& GetInstance() { - assert(mInstance != NULL); + assert(mInstance != nullptr); return *mInstance; } static T* GetInstancePointer() { - assert(mInstance != NULL); + assert(mInstance != nullptr); return mInstance; } static bool IsCreated() { - return mInstance != NULL; + return mInstance != nullptr; } CSingleton() { - assert(mInstance == NULL); + assert(mInstance == nullptr); mInstance = static_cast<T *>(this); } virtual ~CSingleton() { - mInstance = NULL; + mInstance = nullptr; } private: diff --git a/src/graphics/core/color.h b/src/graphics/core/color.h index ff8a2eb..bcd0af1 100644 --- a/src/graphics/core/color.h +++ b/src/graphics/core/color.h @@ -35,7 +35,7 @@ struct Color float r, g, b, a; //! Constructor; default values are (0,0,0,0) = black - Color(float aR = 0.0f, float aG = 0.0f, float aB = 0.0f, float aA = 0.0f) + explicit Color(float aR = 0.0f, float aG = 0.0f, float aB = 0.0f, float aA = 0.0f) : r(aR), g(aG), b(aB), a(aA) {} inline Gfx::Color Inverse() const diff --git a/src/graphics/core/vertex.h b/src/graphics/core/vertex.h index 53dd642..a99d618 100644 --- a/src/graphics/core/vertex.h +++ b/src/graphics/core/vertex.h @@ -47,9 +47,9 @@ struct Vertex Math::Vector normal; Math::Point texCoord; - Vertex(Math::Vector aCoord = Math::Vector(), - Math::Vector aNormal = Math::Vector(), - Math::Point aTexCoord = Math::Point()) + explicit Vertex(Math::Vector aCoord = Math::Vector(), + Math::Vector aNormal = Math::Vector(), + Math::Point aTexCoord = Math::Point()) : coord(aCoord), normal(aNormal), texCoord(aTexCoord) {} @@ -83,10 +83,10 @@ struct VertexCol Gfx::Color specular; Math::Point texCoord; - VertexCol(Math::Vector aCoord = Math::Vector(), - Gfx::Color aColor = Gfx::Color(), - Gfx::Color aSpecular = Gfx::Color(), - Math::Point aTexCoord = Math::Point()) + explicit VertexCol(Math::Vector aCoord = Math::Vector(), + Gfx::Color aColor = Gfx::Color(), + Gfx::Color aSpecular = Gfx::Color(), + Math::Point aTexCoord = Math::Point()) : coord(aCoord), color(aColor), specular(aSpecular), texCoord(aTexCoord) {} //! Returns a string "(c: [...], col: [...], sp: [...], tc: [...])" @@ -115,10 +115,10 @@ struct VertexTex2 Math::Point texCoord; Math::Point texCoord2; - VertexTex2(Math::Vector aCoord = Math::Vector(), - Math::Vector aNormal = Math::Vector(), - Math::Point aTexCoord = Math::Point(), - Math::Point aTexCoord2 = Math::Point()) + explicit VertexTex2(Math::Vector aCoord = Math::Vector(), + Math::Vector aNormal = Math::Vector(), + Math::Point aTexCoord = Math::Point(), + Math::Point aTexCoord2 = Math::Point()) : coord(aCoord), normal(aNormal), texCoord(aTexCoord), texCoord2(aTexCoord2) {} //! Sets the fields from Gfx::Vertex with texCoord2 = (0,0) diff --git a/src/graphics/engine/camera.cpp b/src/graphics/engine/camera.cpp index 2db6398..034c5ea 100644 --- a/src/graphics/engine/camera.cpp +++ b/src/graphics/engine/camera.cpp @@ -1272,14 +1272,14 @@ bool Gfx::CCamera::EventFrameFree(const Event &event) m_heightEye -= event.rTime * factor * m_speed; } - m_terrain->ValidPosition(m_eyePt, 10.0f); + m_terrain->AdjustToBounds(m_eyePt, 10.0f); - if (m_terrain->MoveOnFloor(m_eyePt, true)) + if (m_terrain->AdjustToFloor(m_eyePt, true)) { m_eyePt.y += m_heightEye; Math::Vector pos = m_eyePt; - if (m_terrain->MoveOnFloor(pos, true)) + if (m_terrain->AdjustToFloor(pos, true)) { pos.y -= 2.0f; if (m_eyePt.y < pos.y) @@ -1290,7 +1290,7 @@ bool Gfx::CCamera::EventFrameFree(const Event &event) Math::Vector lookatPt = Math::LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f); - if (m_terrain->MoveOnFloor(lookatPt, true)) + if (m_terrain->AdjustToFloor(lookatPt, true)) lookatPt.y += m_heightLookat; SetViewTime(m_eyePt, lookatPt, event.rTime); @@ -1314,14 +1314,14 @@ bool Gfx::CCamera::EventFrameEdit(const Event &event) m_fixDirectionH = Math::NormAngle(m_fixDirectionH); } - m_terrain->ValidPosition(m_eyePt, 10.0f); + m_terrain->AdjustToBounds(m_eyePt, 10.0f); - if (m_terrain->MoveOnFloor(m_eyePt, false)) + if (m_terrain->AdjustToFloor(m_eyePt, false)) { m_eyePt.y += m_editHeight; Math::Vector pos = m_eyePt; - if (m_terrain->MoveOnFloor(pos, false)) + if (m_terrain->AdjustToFloor(pos, false)) { pos.y += 2.0f; if (m_eyePt.y < pos.y) @@ -1332,7 +1332,7 @@ bool Gfx::CCamera::EventFrameEdit(const Event &event) Math::Vector lookatPt = Math::LookatPoint( m_eyePt, m_directionH, m_directionV, 50.0f ); - if ( m_terrain->MoveOnFloor(lookatPt, true)) + if ( m_terrain->AdjustToFloor(lookatPt, true)) lookatPt.y += m_heightLookat; SetViewTime(m_eyePt, lookatPt, event.rTime); @@ -1483,7 +1483,7 @@ bool Gfx::CCamera::EventFrameBack(const Event &event) if ( (physics != NULL) && physics->GetLand() ) // ground? { Math::Vector pos = lookatPt + (lookatPt - m_eyePt); - float floor = m_terrain->GetFloorHeight(pos) - 4.0f; + float floor = m_terrain->GetHeightToFloor(pos) - 4.0f; if (floor > 0.0f) m_eyePt.y += floor; // shows the descent in front } @@ -1551,14 +1551,14 @@ bool Gfx::CCamera::EventFrameExplo(const Event &event) if (m_mouseDirH != 0.0f) m_directionH -= m_mouseDirH * event.rTime * 0.7f * m_speed; - m_terrain->ValidPosition(m_eyePt, 10.0f); + m_terrain->AdjustToBounds(m_eyePt, 10.0f); - if ( m_terrain->MoveOnFloor(m_eyePt, false) ) + if ( m_terrain->AdjustToFloor(m_eyePt, false) ) { m_eyePt.y += m_heightEye; Math::Vector pos = m_eyePt; - if ( m_terrain->MoveOnFloor(pos, false) ) + if ( m_terrain->AdjustToFloor(pos, false) ) { pos.y += 2.0f; if ( m_eyePt.y < pos.y ) @@ -1569,7 +1569,7 @@ bool Gfx::CCamera::EventFrameExplo(const Event &event) Math::Vector lookatPt = Math::LookatPoint(m_eyePt, m_directionH, m_directionV, 50.0f); - if (m_terrain->MoveOnFloor(lookatPt, true)) + if (m_terrain->AdjustToFloor(lookatPt, true)) lookatPt.y += m_heightLookat; SetViewTime(m_eyePt, lookatPt, event.rTime); @@ -1680,7 +1680,7 @@ Math::Vector Gfx::CCamera::ExcludeTerrain(Math::Vector eye, Math::Vector lookat, float &angleH, float &angleV) { Math::Vector pos = eye; - if (m_terrain->MoveOnFloor(pos)) + if (m_terrain->AdjustToFloor(pos)) { float dist = Math::DistanceProjected(lookat, pos); pos.y += 2.0f+dist*0.1f; @@ -1719,3 +1719,4 @@ Math::Vector Gfx::CCamera::ExcludeObject(Math::Vector eye, Math::Vector lookat, return eye;*/ } + diff --git a/src/graphics/engine/cloud.cpp b/src/graphics/engine/cloud.cpp index 6f6bc57..26a75ab 100644 --- a/src/graphics/engine/cloud.cpp +++ b/src/graphics/engine/cloud.cpp @@ -28,7 +28,8 @@ const int CLOUD_LINE_PREALLOCATE_COUNT = 100; -const int DIMEXPAND = 4; // extension of the dimensions +//! Extension of the bricks dimensions +const int CLOUD_SIZE_EXPAND = 4; Gfx::CCloud::CCloud(CInstanceManager* iMan, Gfx::CEngine* engine) @@ -42,7 +43,7 @@ Gfx::CCloud::CCloud(CInstanceManager* iMan, Gfx::CEngine* engine) m_level = 0.0f; m_wind = Math::Vector(0.0f, 0.0f, 0.0f); m_subdiv = 8; - m_enable = true; + m_enabled = true; m_lines.reserve(CLOUD_LINE_PREALLOCATE_COUNT); } @@ -77,8 +78,8 @@ bool Gfx::CCloud::EventFrame(const Event &event) return true; } -void Gfx::CCloud::AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, - Math::Point &uv1, Math::Point &uv2) +void Gfx::CCloud::AdjustLevel(Math::Vector& pos, Math::Vector& eye, float deep, + Math::Point& uv1, Math::Point& uv2) { uv1.x = (pos.x+20000.0f)/1280.0f; uv1.y = (pos.z+20000.0f)/1280.0f; @@ -95,14 +96,14 @@ void Gfx::CCloud::AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, void Gfx::CCloud::Draw() { - if (! m_enable) return; + if (! m_enabled) return; if (m_level == 0.0f) return; if (m_lines.empty()) return; - std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2()); + std::vector<Gfx::VertexTex2> vertices((m_brickCount+2)*2, Gfx::VertexTex2()); float iDeep = m_engine->GetDeepView(); - float deep = (m_brick*m_size)/2.0f; + float deep = (m_brickCount*m_brickSize)/2.0f; m_engine->SetDeepView(deep); m_engine->SetFocus(m_engine->GetFocus()); m_engine->UpdateMatProj(); // increases the depth of view @@ -132,7 +133,7 @@ void Gfx::CCloud::Draw() matrix.LoadIdentity(); device->SetTransform(Gfx::TRANSFORM_WORLD, matrix); - float size = m_size/2.0f; + float size = m_brickSize/2.0f; Math::Vector eye = m_engine->GetEyePt(); Math::Vector n = Math::Vector(0.0f, -1.0f, 0.0f); @@ -195,17 +196,17 @@ void Gfx::CCloud::CreateLine(int x, int y, int len) line.y = y; line.len = len; - float offset = m_brick*m_size/2.0f - m_size/2.0f; + float offset = m_brickCount*m_brickSize/2.0f - m_brickSize/2.0f; - line.px1 = m_size* line.x - offset; - line.px2 = m_size*(line.x+line.len) - offset; - line.pz = m_size* line.y - offset; + line.px1 = m_brickSize* line.x - offset; + line.px2 = m_brickSize*(line.x+line.len) - offset; + line.pz = m_brickSize* line.y - offset; m_lines.push_back(line); } void Gfx::CCloud::Create(const std::string& fileName, - Gfx::Color diffuse, Gfx::Color ambient, + const Gfx::Color& diffuse, const Gfx::Color& ambient, float level) { m_diffuse = diffuse; @@ -223,18 +224,18 @@ void Gfx::CCloud::Create(const std::string& fileName, m_wind = m_terrain->GetWind(); - m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic()*DIMEXPAND; - m_size = m_terrain->GetSize(); + m_brickCount = m_terrain->GetBrickCount()*m_terrain->GetMosaicCount()*CLOUD_SIZE_EXPAND; + m_brickSize = m_terrain->GetBrickSize(); - m_brick /= m_subdiv*DIMEXPAND; - m_size *= m_subdiv*DIMEXPAND; + m_brickCount /= m_subdiv*CLOUD_SIZE_EXPAND; + m_brickSize *= m_subdiv*CLOUD_SIZE_EXPAND; if (m_level == 0.0f) return; m_lines.clear(); - for (int y = 0; y < m_brick; y++) - CreateLine(0, y, m_brick); + for (int y = 0; y < m_brickCount; y++) + CreateLine(0, y, m_brickCount); return; } @@ -257,12 +258,12 @@ float Gfx::CCloud::GetLevel() return m_level; } -void Gfx::CCloud::SetEnable(bool enable) +void Gfx::CCloud::SetEnabled(bool enabled) { - m_enable = enable; + m_enabled = enabled; } -bool Gfx::CCloud::GetEnable() +bool Gfx::CCloud::GetEnabled() { - return m_enable; + return m_enabled; } diff --git a/src/graphics/engine/cloud.h b/src/graphics/engine/cloud.h index abfaf26..a9109fa 100644 --- a/src/graphics/engine/cloud.h +++ b/src/graphics/engine/cloud.h @@ -79,29 +79,32 @@ public: CCloud(CInstanceManager* iMan, CEngine* engine); ~CCloud(); - bool EventProcess(const Event &event); + bool EventProcess(const Event& event); //! Removes all the clouds void Flush(); //! Creates all areas of cloud - void Create(const std::string& fileName, Gfx::Color diffuse, Gfx::Color ambient, float level); + void Create(const std::string& fileName, const Gfx::Color& diffuse, const Gfx::Color& ambient, float level); //! Draw the clouds void Draw(); - //! Modifies the cloud level + //! Management of cloud level + //@{ void SetLevel(float level); - //! Returns the current level of clouds float GetLevel(); + //@} - //! Activate management of clouds - void SetEnable(bool enable); - bool GetEnable(); + //! Management of clouds + //@{ + void SetEnabled(bool enable); + bool GetEnabled(); + //@} protected: //! Makes the clouds evolve bool EventFrame(const Event &event); //! Adjusts the position to normal, to imitate the clouds at movement - void AdjustLevel(Math::Vector &pos, Math::Vector &eye, float deep, - Math::Point &uv1, Math::Point &uv2); + void AdjustLevel(Math::Vector& pos, Math::Vector& eye, float deep, + Math::Point& uv1, Math::Point& uv2); //! Updates the positions, relative to the ground void CreateLine(int x, int y, int len); @@ -110,9 +113,11 @@ protected: Gfx::CEngine* m_engine; Gfx::CTerrain* m_terrain; - std::string m_fileName; + bool m_enabled; //! Overall level float m_level; + //! Texture + std::string m_fileName; //! Feedrate (wind) Math::Point m_speed; //! Diffuse color @@ -126,13 +131,11 @@ protected: //! Wind speed Math::Vector m_wind; //! Brick mosaic - int m_brick; + int m_brickCount; //! Size of a brick element - float m_size; + float m_brickSize; std::vector<Gfx::CloudLine> m_lines; - - bool m_enable; }; diff --git a/src/graphics/engine/engine.cpp b/src/graphics/engine/engine.cpp index 3187dde..068687a 100644 --- a/src/graphics/engine/engine.cpp +++ b/src/graphics/engine/engine.cpp @@ -142,14 +142,14 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_eyeDirH = 0.0f; m_eyeDirV = 0.0f; m_backgroundName = ""; // no background image - m_backgroundColorUp = 0; - m_backgroundColorDown = 0; - m_backgroundCloudUp = 0; - m_backgroundCloudDown = 0; + m_backgroundColorUp = Gfx::Color(); + m_backgroundColorDown = Gfx::Color(); + m_backgroundCloudUp = Gfx::Color(); + m_backgroundCloudDown = Gfx::Color(); m_backgroundFull = false; m_backgroundQuarter = false; m_overFront = true; - m_overColor = 0; + m_overColor = Gfx::Color(); m_overMode = ENG_RSTATE_TCOLOR_BLACK; m_highlightRank[0] = -1; // empty list m_highlightTime = 0.0f; @@ -208,7 +208,7 @@ Gfx::CEngine::CEngine(CInstanceManager *iMan, CApplication *app) m_mouseVisible = false; m_texPath = "textures/"; - m_defaultTexParams.format = Gfx::TEX_IMG_RGB; + m_defaultTexParams.format = Gfx::TEX_IMG_AUTO; m_defaultTexParams.mipmap = true; m_defaultTexParams.minFilter = Gfx::TEX_MIN_FILTER_LINEAR_MIPMAP_LINEAR; m_defaultTexParams.magFilter = Gfx::TEX_MAG_FILTER_LINEAR; @@ -260,6 +260,8 @@ bool Gfx::CEngine::Create() m_lightning = new Gfx::CLightning(m_iMan, this); m_planet = new Gfx::CPlanet(m_iMan, this); + m_lightMan->SetDevice(m_device); + m_text->SetDevice(m_device); if (! m_text->Create()) { @@ -979,7 +981,7 @@ Gfx::EngineObjLevel4* Gfx::CEngine::FindTriangles(int objRank, const Gfx::Materi for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if (p3.min != min || p3.max != max) continue; @@ -1031,7 +1033,7 @@ int Gfx::CEngine::GetPartialTriangles(int objRank, float min, float max, float p for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if (p3.min != min || p3.max != max) continue; @@ -1126,7 +1128,7 @@ void Gfx::CEngine::ChangeLOD() for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if ( Math::IsEqual(p3.min, 0.0f ) && @@ -1620,7 +1622,7 @@ void Gfx::CEngine::UpdateGeometry() for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++) @@ -1712,7 +1714,7 @@ int Gfx::CEngine::DetectObject(Math::Point mouse) for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if (p3.min != 0.0f) continue; // LOD B or C? @@ -2099,7 +2101,8 @@ void Gfx::CEngine::SetViewParams(const Math::Vector& eyePt, const Math::Vector& if (m_sound == nullptr) m_sound = static_cast<CSoundInterface*>( m_iMan->SearchInstance(CLASS_SOUND) ); - m_sound->SetListener(eyePt, lookatPt); + if (m_sound != nullptr) + m_sound->SetListener(eyePt, lookatPt); } Gfx::Texture Gfx::CEngine::CreateTexture(const std::string& texName, const Gfx::TextureCreateParams& params) @@ -2315,7 +2318,7 @@ void Gfx::CEngine::SetFocus(float focus) m_focus = focus; m_size = m_app->GetVideoConfig().size; - float aspect = (static_cast<float>(m_size.y)) / m_size.x; + float aspect = (static_cast<float>(m_size.x)) / m_size.y; Math::LoadProjectionMatrix(m_matProj, m_focus, aspect, 0.5f, m_deepView[0]); } @@ -2837,7 +2840,7 @@ void Gfx::CEngine::Render() m_statisticTriangle = 0; m_lastState = -1; - m_lastColor = 999; + m_lastColor = Gfx::Color(-1.0f); m_lastMaterial = Gfx::Material(); m_lightMan->UpdateLights(); @@ -2889,6 +2892,8 @@ void Gfx::CEngine::Draw3DScene() if (m_shadowVisible) { + m_lightMan->UpdateLightsEnableState(Gfx::ENG_OBJTYPE_TERRAIN); + // Draw the terrain for (int l1 = 0; l1 < static_cast<int>( m_objectTree.size() ); l1++) @@ -2911,13 +2916,19 @@ void Gfx::CEngine::Draw3DScene() if (! m_objects[objRank].drawWorld) continue; + m_device->SetTransform(Gfx::TRANSFORM_WORLD, m_objects[objRank].transform); + + if (! IsVisible(objRank)) + continue; + for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if ( m_objects[objRank].distance < p3.min || - m_objects[objRank].distance >= p3.max ) continue; + m_objects[objRank].distance >= p3.max ) + continue; for (int l4 = 0; l4 < static_cast<int>( p3.next.size() ); l4++) { @@ -2985,7 +2996,7 @@ void Gfx::CEngine::Draw3DScene() for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if ( m_objects[objRank].distance < p3.min || @@ -3074,7 +3085,7 @@ void Gfx::CEngine::Draw3DScene() for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if ( m_objects[objRank].distance < p3.min || @@ -3189,7 +3200,7 @@ void Gfx::CEngine::DrawInterface() for (int l3 = 0; l3 < static_cast<int>( p2.next.size() ); l3++) { - Gfx::EngineObjLevel3& p3 = p2.next[l1]; + Gfx::EngineObjLevel3& p3 = p2.next[l3]; if (! p3.used) continue; if ( m_objects[objRank].distance < p3.min || diff --git a/src/graphics/engine/engine.h b/src/graphics/engine/engine.h index b3a576a..705c83a 100644 --- a/src/graphics/engine/engine.h +++ b/src/graphics/engine/engine.h @@ -807,6 +807,9 @@ public: float min, float max, Gfx::EngineTextureMapping mode, float pos, float factor, float tl, float ts, float tt); + //! Detects the target object that is selected with the mouse + /** Returns the rank of the object or -1. */ + int DetectObject(Math::Point mouse); //! Creates a shadow for the given object bool CreateShadow(int objRank); @@ -1197,10 +1200,6 @@ protected: //! Compute and return the 2D box on screen of any object bool GetBBox2D(int objRank, Math::Point& min, Math::Point& max); - //! Detects the target object that is selected with the mouse - /** Returns the rank of the object or -1. */ - int DetectObject(Math::Point mouse); - //! Detects whether the mouse is in a triangle. bool DetectTriangle(Math::Point mouse, Gfx::VertexTex2* triangle, int objRank, float& dist); diff --git a/src/graphics/engine/lightman.cpp b/src/graphics/engine/lightman.cpp index 9e15b5a..46000d7 100644 --- a/src/graphics/engine/lightman.cpp +++ b/src/graphics/engine/lightman.cpp @@ -65,6 +65,7 @@ void Gfx::LightProgression::SetTarget(float value) Gfx::DynamicLight::DynamicLight() { used = enabled = false; + includeType = excludeType = Gfx::ENG_OBJTYPE_NULL; } @@ -147,8 +148,6 @@ bool Gfx::CLightManager::DeleteLight(int lightRank) return true; } -// Specifies a light. - bool Gfx::CLightManager::SetLight(int lightRank, const Gfx::Light &light) { if ( (lightRank < 0) || (lightRank >= static_cast<int>( m_dynLights.size() )) ) diff --git a/src/graphics/engine/modelfile.cpp b/src/graphics/engine/modelfile.cpp index 9d7a389..2049749 100644 --- a/src/graphics/engine/modelfile.cpp +++ b/src/graphics/engine/modelfile.cpp @@ -23,120 +23,42 @@ #include "common/ioutils.h" #include "common/logger.h" #include "common/stringutils.h" +#include "graphics/engine/engine.h" #include "math/geometry.h" #include <string.h> #include <fstream> +#include <sstream> -//! How big the triangle vector is by default -const int TRIANGLE_PREALLOCATE_COUNT = 2000; - -/** - \struct ModelHeader - \brief Header info for model file +/* + * NOTE: #ifndef checking for MODELFILE_NO_ENGINE + * is provided in this module to conditionally + * disable dependence on CEngine. */ -struct ModelHeader -{ - //! Revision number - int revision; - //! Version number - int version; - //! Total number of vertices - int totalVertices; - //! Reserved area - int reserved[10]; - - ModelHeader() - { - memset(this, 0, sizeof(*this)); - } -}; -struct OldModelTriangle1 -{ - char used; - char selected; - Gfx::Vertex p1; - Gfx::Vertex p2; - Gfx::Vertex p3; - Gfx::Material material; - char texName[20]; - float min; - float max; - - OldModelTriangle1() - { - memset(this, 0, sizeof(*this)); - } -}; - -struct OldModelTriangle2 -{ - char used; - char selected; - Gfx::Vertex p1; - Gfx::Vertex p2; - Gfx::Vertex p3; - Gfx::Material material; - char texName[20]; - float min; - float max; - long state; - short reserved1; - short reserved2; - short reserved3; - short reserved4; - OldModelTriangle2() - { - memset(this, 0, sizeof(*this)); - } -}; - - -struct NewModelTriangle -{ - char used; - char selected; - Gfx::VertexTex2 p1; - Gfx::VertexTex2 p2; - Gfx::VertexTex2 p3; - Gfx::Material material; - char texName[20]; - float min; - float max; - long state; - short texNum2; - short reserved2; - short reserved3; - short reserved4; +//! How big the triangle vector is by default +const int TRIANGLE_PREALLOCATE_COUNT = 2000; - NewModelTriangle() - { - memset(this, 0, sizeof(*this)); - } -}; -Gfx::Vertex ReadBinaryVertex(std::istream &stream) +bool ReadBinaryVertex(std::istream& stream, Gfx::Vertex& vertex) { - Gfx::Vertex result; - - result.coord.x = IOUtils::ReadBinaryFloat(stream); - result.coord.y = IOUtils::ReadBinaryFloat(stream); - result.coord.z = IOUtils::ReadBinaryFloat(stream); - result.normal.x = IOUtils::ReadBinaryFloat(stream); - result.normal.y = IOUtils::ReadBinaryFloat(stream); - result.normal.z = IOUtils::ReadBinaryFloat(stream); - result.texCoord.x = IOUtils::ReadBinaryFloat(stream); - result.texCoord.y = IOUtils::ReadBinaryFloat(stream); - - return result; + vertex.coord.x = IOUtils::ReadBinaryFloat(stream); + vertex.coord.y = IOUtils::ReadBinaryFloat(stream); + vertex.coord.z = IOUtils::ReadBinaryFloat(stream); + vertex.normal.x = IOUtils::ReadBinaryFloat(stream); + vertex.normal.y = IOUtils::ReadBinaryFloat(stream); + vertex.normal.z = IOUtils::ReadBinaryFloat(stream); + vertex.texCoord.x = IOUtils::ReadBinaryFloat(stream); + vertex.texCoord.y = IOUtils::ReadBinaryFloat(stream); + + return !stream.fail(); } -void WriteBinaryVertex(Gfx::Vertex vertex, std::ostream &stream) +bool WriteBinaryVertex(Gfx::Vertex vertex, std::ostream& stream) { IOUtils::WriteBinaryFloat(vertex.coord.x, stream); IOUtils::WriteBinaryFloat(vertex.coord.y, stream); @@ -146,27 +68,27 @@ void WriteBinaryVertex(Gfx::Vertex vertex, std::ostream &stream) IOUtils::WriteBinaryFloat(vertex.normal.z, stream); IOUtils::WriteBinaryFloat(vertex.texCoord.x, stream); IOUtils::WriteBinaryFloat(vertex.texCoord.y, stream); + + return !stream.fail(); } -Gfx::VertexTex2 ReadBinaryVertexTex2(std::istream &stream) +bool ReadBinaryVertexTex2(std::istream& stream, Gfx::VertexTex2& vertex) { - Gfx::VertexTex2 result; - - result.coord.x = IOUtils::ReadBinaryFloat(stream); - result.coord.y = IOUtils::ReadBinaryFloat(stream); - result.coord.z = IOUtils::ReadBinaryFloat(stream); - result.normal.x = IOUtils::ReadBinaryFloat(stream); - result.normal.y = IOUtils::ReadBinaryFloat(stream); - result.normal.z = IOUtils::ReadBinaryFloat(stream); - result.texCoord.x = IOUtils::ReadBinaryFloat(stream); - result.texCoord.y = IOUtils::ReadBinaryFloat(stream); - result.texCoord2.x = IOUtils::ReadBinaryFloat(stream); - result.texCoord2.y = IOUtils::ReadBinaryFloat(stream); - - return result; + vertex.coord.x = IOUtils::ReadBinaryFloat(stream); + vertex.coord.y = IOUtils::ReadBinaryFloat(stream); + vertex.coord.z = IOUtils::ReadBinaryFloat(stream); + vertex.normal.x = IOUtils::ReadBinaryFloat(stream); + vertex.normal.y = IOUtils::ReadBinaryFloat(stream); + vertex.normal.z = IOUtils::ReadBinaryFloat(stream); + vertex.texCoord.x = IOUtils::ReadBinaryFloat(stream); + vertex.texCoord.y = IOUtils::ReadBinaryFloat(stream); + vertex.texCoord2.x = IOUtils::ReadBinaryFloat(stream); + vertex.texCoord2.y = IOUtils::ReadBinaryFloat(stream); + + return !stream.fail(); } -void WriteBinaryVertexTex2(Gfx::VertexTex2 vertex, std::ostream &stream) +bool WriteBinaryVertexTex2(Gfx::VertexTex2 vertex, std::ostream& stream) { IOUtils::WriteBinaryFloat(vertex.coord.x, stream); IOUtils::WriteBinaryFloat(vertex.coord.y, stream); @@ -178,38 +100,83 @@ void WriteBinaryVertexTex2(Gfx::VertexTex2 vertex, std::ostream &stream) IOUtils::WriteBinaryFloat(vertex.texCoord.y, stream); IOUtils::WriteBinaryFloat(vertex.texCoord2.x, stream); IOUtils::WriteBinaryFloat(vertex.texCoord2.y, stream); + + return !stream.fail(); } -Gfx::Material ReadBinaryMaterial(std::istream &stream) +bool ReadTextVertexTex2(const std::string& text, Gfx::VertexTex2& vertex) { - Gfx::Material result; + std::stringstream stream; + stream.str(text); - result.diffuse.r = IOUtils::ReadBinaryFloat(stream); - result.diffuse.g = IOUtils::ReadBinaryFloat(stream); - result.diffuse.b = IOUtils::ReadBinaryFloat(stream); - result.diffuse.a = IOUtils::ReadBinaryFloat(stream); + std::string what; - result.ambient.r = IOUtils::ReadBinaryFloat(stream); - result.ambient.g = IOUtils::ReadBinaryFloat(stream); - result.ambient.b = IOUtils::ReadBinaryFloat(stream); - result.ambient.a = IOUtils::ReadBinaryFloat(stream); + stream >> what; + if (what != "c") + return false; - result.specular.r = IOUtils::ReadBinaryFloat(stream); - result.specular.g = IOUtils::ReadBinaryFloat(stream); - result.specular.b = IOUtils::ReadBinaryFloat(stream); - result.specular.a = IOUtils::ReadBinaryFloat(stream); + stream >> vertex.coord.x >> vertex.coord.y >> vertex.coord.z; - /* emissive.r = */ IOUtils::ReadBinaryFloat(stream); - /* emissive.g = */ IOUtils::ReadBinaryFloat(stream); - /* emissive.b = */ IOUtils::ReadBinaryFloat(stream); - /* emissive.a = */ IOUtils::ReadBinaryFloat(stream); + stream >> what; + if (what != "n") + return false; + + stream >> vertex.normal.x >> vertex.normal.y >> vertex.normal.z; + + stream >> what; + if (what != "t1") + return false; - /* power = */ IOUtils::ReadBinaryFloat(stream); + stream >> vertex.texCoord.x >> vertex.texCoord.y; - return result; + stream >> what; + if (what != "t2") + return false; + + stream >> vertex.texCoord2.x >> vertex.texCoord2.y; + + return !stream.fail(); +} + +bool WriteTextVertexTex2(const Gfx::VertexTex2& vertex, std::ostream& stream) +{ + stream << "c " << vertex.coord.x << " " << vertex.coord.y << " " << vertex.coord.z; + stream << " n " << vertex.normal.x << " " << vertex.normal.y << " " << vertex.normal.z; + stream << " t1 " << vertex.texCoord.x << " " << vertex.texCoord.y; + stream << " t2 " << vertex.texCoord2.x << " " << vertex.texCoord2.y; + stream << std::endl; + + return !stream.fail(); +} + +bool ReadBinaryMaterial(std::istream& stream, Gfx::Material& material) +{ + material.diffuse.r = IOUtils::ReadBinaryFloat(stream); + material.diffuse.g = IOUtils::ReadBinaryFloat(stream); + material.diffuse.b = IOUtils::ReadBinaryFloat(stream); + material.diffuse.a = IOUtils::ReadBinaryFloat(stream); + + material.ambient.r = IOUtils::ReadBinaryFloat(stream); + material.ambient.g = IOUtils::ReadBinaryFloat(stream); + material.ambient.b = IOUtils::ReadBinaryFloat(stream); + material.ambient.a = IOUtils::ReadBinaryFloat(stream); + + material.specular.r = IOUtils::ReadBinaryFloat(stream); + material.specular.g = IOUtils::ReadBinaryFloat(stream); + material.specular.b = IOUtils::ReadBinaryFloat(stream); + material.specular.a = IOUtils::ReadBinaryFloat(stream); + + /* emissive.r = */ IOUtils::ReadBinaryFloat(stream); + /* emissive.g = */ IOUtils::ReadBinaryFloat(stream); + /* emissive.b = */ IOUtils::ReadBinaryFloat(stream); + /* emissive.a = */ IOUtils::ReadBinaryFloat(stream); + + /* power = */ IOUtils::ReadBinaryFloat(stream); + + return !stream.fail(); } -void WriteBinaryMaterial(Gfx::Material material, std::ostream &stream) +bool WriteBinaryMaterial(const Gfx::Material& material, std::ostream& stream) { IOUtils::WriteBinaryFloat(material.diffuse.r, stream); IOUtils::WriteBinaryFloat(material.diffuse.g, stream); @@ -232,13 +199,120 @@ void WriteBinaryMaterial(Gfx::Material material, std::ostream &stream) /* emissive.a */ IOUtils::WriteBinaryFloat(0.0f, stream); /* power */ IOUtils::WriteBinaryFloat(0.0f, stream); + + return !stream.fail(); +} + +bool ReadTextMaterial(const std::string& text, Gfx::Material& material) +{ + std::stringstream stream; + stream.str(text); + + std::string what; + + stream >> what; + if (what != "dif") + return false; + + stream >> material.diffuse.r + >> material.diffuse.g + >> material.diffuse.b + >> material.diffuse.a; + + stream >> what; + if (what != "amb") + return false; + + stream >> material.ambient.r + >> material.ambient.g + >> material.ambient.b + >> material.ambient.a; + + stream >> what; + if (what != "spc") + return false; + + stream >> material.specular.r + >> material.specular.g + >> material.specular.b + >> material.specular.a; + + return !stream.fail(); +} + +bool WriteTextMaterial(const Gfx::Material& material, std::ostream& stream) +{ + stream << "dif " << material.diffuse.r + << " " << material.diffuse.g + << " " << material.diffuse.b + << " " << material.diffuse.a; + + stream << " amb " << material.ambient.r + << " " << material.ambient.g + << " " << material.ambient.b + << " " << material.ambient.a; + + stream << " spc " << material.specular.r + << " " << material.specular.g << " " + << material.specular.b << " " + << material.specular.a; + + stream << std::endl; + + return !stream.fail(); } -Gfx::ModelTriangle::ModelTriangle() +template<typename T> +bool ReadLineValue(std::istream& stream, const std::string& prefix, T& value) { - min = 0.0f; - max = 0.0f; - state = 0L; + std::string line; + while (true) + { + if (stream.eof() || stream.fail()) + return false; + + std::getline(stream, line); + if (!line.empty() && line[0] != '#') + break; + } + + std::stringstream s; + s.str(line); + + std::string what; + s >> what; + if (what != prefix) + return false; + + s >> value; + + return true; +} + +bool ReadLineString(std::istream& stream, const std::string& prefix, std::string& value) +{ + std::string line; + while (true) + { + if (stream.eof() || stream.fail()) + return false; + + std::getline(stream, line); + if (!line.empty() && line[0] != '#') + break; + } + + std::stringstream s; + s.str(line); + + std::string what; + s >> what; + if (what != prefix) + return false; + + std::getline(s, value); + + return true; } @@ -246,7 +320,9 @@ Gfx::CModelFile::CModelFile(CInstanceManager* iMan) { m_iMan = iMan; +#ifndef MODELFILE_NO_ENGINE m_engine = static_cast<CEngine*>(m_iMan->SearchInstance(CLASS_ENGINE)); +#endif m_triangles.reserve(TRIANGLE_PREALLOCATE_COUNT); } @@ -255,71 +331,171 @@ Gfx::CModelFile::~CModelFile() { } -std::string Gfx::CModelFile::GetError() + +/******************************************************* + Deprecated formats + *******************************************************/ + +/** + * \struct OldModelHeader + * \brief Colobot binary model header info + * + * @deprecated + */ +struct OldModelHeader { - return m_error; -} + //! Revision number + int revision; + //! Version number + int version; + //! Total number of triangles + int totalTriangles; + //! Reserved area + int reserved[10]; + + OldModelHeader() + { + memset(this, 0, sizeof(*this)); + } +}; + + +/** + * \struct OldModelTriangle1 + * \brief Colobot binary model file version 1 + * + * @deprecated + */ +struct OldModelTriangle1 +{ + char used; + char selected; + Gfx::Vertex p1; + Gfx::Vertex p2; + Gfx::Vertex p3; + Gfx::Material material; + char texName[20]; + float min; + float max; + OldModelTriangle1() + { + memset(this, 0, sizeof(*this)); + } +}; + +/** + * \struct OldModelTriangle2 + * \brief Colobot binary model file version 2 + * + * @deprecated + */ +struct OldModelTriangle2 +{ + char used; + char selected; + Gfx::Vertex p1; + Gfx::Vertex p2; + Gfx::Vertex p3; + Gfx::Material material; + char texName[20]; + float min; + float max; + long state; + short reserved1; + short reserved2; + short reserved3; + short reserved4; + OldModelTriangle2() + { + memset(this, 0, sizeof(*this)); + } +}; + +/** + * \struct OldModelTriangle3 + * \brief Colobot binary model file version 3 + * + * @deprecated + */ +struct OldModelTriangle3 +{ + char used; + char selected; + Gfx::VertexTex2 p1; + Gfx::VertexTex2 p2; + Gfx::VertexTex2 p3; + Gfx::Material material; + char texName[20]; + float min; + float max; + long state; + short texNum2; + short reserved2; + short reserved3; + short reserved4; + + OldModelTriangle3() + { + memset(this, 0, sizeof(*this)); + } +}; -bool Gfx::CModelFile::ReadModel(const std::string &filename, bool edit, bool meta) +bool Gfx::CModelFile::ReadModel(const std::string& fileName) { m_triangles.clear(); - m_error = ""; std::ifstream stream; - stream.open(filename.c_str(), std::ios_base::in | std::ios_base::binary); - if (! stream.good()) + stream.open(fileName.c_str(), std::ios_base::in | std::ios_base::binary); + if (!stream.good()) { - m_error = std::string("Could not open file '") + filename + std::string("'"); + GetLogger()->Error("Could not open file '%s'\n", fileName.c_str()); return false; } - return ReadModel(stream, edit, meta); + return ReadModel(stream); } -bool Gfx::CModelFile::ReadModel(std::istream &stream, bool edit, bool meta) +bool Gfx::CModelFile::ReadModel(std::istream& stream) { m_triangles.clear(); - m_error = ""; - // FIXME: for now, reading models only from files, not metafile - - ModelHeader header; + OldModelHeader header; header.revision = IOUtils::ReadBinary<4, int>(stream); header.version = IOUtils::ReadBinary<4, int>(stream); - header.totalVertices = IOUtils::ReadBinary<4, int>(stream); + header.totalTriangles = IOUtils::ReadBinary<4, int>(stream); for (int i = 0; i < 10; ++i) header.reserved[i] = IOUtils::ReadBinary<4, int>(stream); - if (! stream.good()) + if (!stream.good()) { - m_error = "Error reading model file header"; + GetLogger()->Error("Error reading model file header\n"); return false; } // Old model version #1 if ( (header.revision == 1) && (header.version == 0) ) { - for (int i = 0; i < header.totalVertices; ++i) + for (int i = 0; i < header.totalTriangles; ++i) { OldModelTriangle1 t; t.used = IOUtils::ReadBinary<1, char>(stream); t.selected = IOUtils::ReadBinary<1, char>(stream); - t.p1 = ReadBinaryVertex(stream); - t.p2 = ReadBinaryVertex(stream); - t.p3 = ReadBinaryVertex(stream); + ReadBinaryVertex(stream, t.p1); + ReadBinaryVertex(stream, t.p2); + ReadBinaryVertex(stream, t.p3); - t.material = ReadBinaryMaterial(stream); + ReadBinaryMaterial(stream, t.material); stream.read(t.texName, 20); t.min = IOUtils::ReadBinaryFloat(stream); t.max = IOUtils::ReadBinaryFloat(stream); - if (! stream.good()) + if (stream.fail()) { - m_error = "Error reading model data"; + GetLogger()->Error("Error reading model data\n"); return false; } @@ -338,17 +514,17 @@ bool Gfx::CModelFile::ReadModel(std::istream &stream, bool edit, bool meta) } else if ( header.revision == 1 && header.version == 1 ) { - for (int i = 0; i < header.totalVertices; ++i) + for (int i = 0; i < header.totalTriangles; ++i) { OldModelTriangle2 t; t.used = IOUtils::ReadBinary<1, char>(stream); t.selected = IOUtils::ReadBinary<1, char>(stream); - t.p1 = ReadBinaryVertex(stream); - t.p2 = ReadBinaryVertex(stream); - t.p3 = ReadBinaryVertex(stream); + ReadBinaryVertex(stream, t.p1); + ReadBinaryVertex(stream, t.p2); + ReadBinaryVertex(stream, t.p3); - t.material = ReadBinaryMaterial(stream); + ReadBinaryMaterial(stream, t.material); stream.read(t.texName, 20); t.min = IOUtils::ReadBinaryFloat(stream); t.max = IOUtils::ReadBinaryFloat(stream); @@ -359,9 +535,9 @@ bool Gfx::CModelFile::ReadModel(std::istream &stream, bool edit, bool meta) t.reserved3 = IOUtils::ReadBinary<2, short>(stream); t.reserved4 = IOUtils::ReadBinary<2, short>(stream); - if (! stream.good()) + if (stream.fail()) { - m_error = "Error reading model data"; + GetLogger()->Error("Error reading model data\n"); return false; } @@ -381,19 +557,19 @@ bool Gfx::CModelFile::ReadModel(std::istream &stream, bool edit, bool meta) } else { - for (int i = 0; i < header.totalVertices; ++i) + for (int i = 0; i < header.totalTriangles; ++i) { - NewModelTriangle t; + OldModelTriangle3 t; t.used = IOUtils::ReadBinary<1, char>(stream); t.selected = IOUtils::ReadBinary<1, char>(stream); /* padding */ IOUtils::ReadBinary<2, unsigned int>(stream); - t.p1 = ReadBinaryVertexTex2(stream); - t.p2 = ReadBinaryVertexTex2(stream); - t.p3 = ReadBinaryVertexTex2(stream); + ReadBinaryVertexTex2(stream, t.p1); + ReadBinaryVertexTex2(stream, t.p2); + ReadBinaryVertexTex2(stream, t.p3); - t.material = ReadBinaryMaterial(stream); + ReadBinaryMaterial(stream, t.material); stream.read(t.texName, 20); t.min = IOUtils::ReadBinaryFloat(stream); t.max = IOUtils::ReadBinaryFloat(stream); @@ -404,9 +580,9 @@ bool Gfx::CModelFile::ReadModel(std::istream &stream, bool edit, bool meta) t.reserved3 = IOUtils::ReadBinary<2, short>(stream); t.reserved4 = IOUtils::ReadBinary<2, short>(stream); - if (! stream.good()) + if (stream.fail()) { - m_error = "Error reading model data"; + GetLogger()->Error("Error reading model data\n"); return false; } @@ -417,15 +593,26 @@ bool Gfx::CModelFile::ReadModel(std::istream &stream, bool edit, bool meta) triangle.material = t.material; triangle.tex1Name = std::string(t.texName); - char tex2Name[20] = { 0 }; triangle.min = t.min; triangle.max = t.max; triangle.state = t.state; + triangle.variableTex2 = t.texNum2 == 1; + + if (triangle.tex1Name == "plant.png") + triangle.state |= Gfx::ENG_RSTATE_ALPHA; + + if (!triangle.variableTex2 && t.texNum2 != 0) + { + if (t.texNum2 >= 1 && t.texNum2 <= 10) + triangle.state |= Gfx::ENG_RSTATE_DUAL_BLACK; - if (t.texNum2 != 0) - sprintf(tex2Name, "dirty%.2d.tga", t.texNum2); // hardcoded as in the original code + if (t.texNum2 >= 11 && t.texNum2 <= 20) + triangle.state |= Gfx::ENG_RSTATE_DUAL_WHITE; - triangle.tex2Name = std::string(tex2Name); + char tex2Name[20] = { 0 }; + sprintf(tex2Name, "dirty%.2d.png", t.texNum2); // hardcoded as in original code + triangle.tex2Name = tex2Name; + } m_triangles.push_back(triangle); } @@ -433,97 +620,70 @@ bool Gfx::CModelFile::ReadModel(std::istream &stream, bool edit, bool meta) for (int i = 0; i < static_cast<int>( m_triangles.size() ); ++i) { - m_triangles[i].tex1Name = StrUtils::Replace(m_triangles[i].tex1Name, "bmp", "tga"); + // All extensions are now png + m_triangles[i].tex1Name = StrUtils::Replace(m_triangles[i].tex1Name, "bmp", "png"); + m_triangles[i].tex1Name = StrUtils::Replace(m_triangles[i].tex1Name, "tga", "png"); + + m_triangles[i].tex2Name = StrUtils::Replace(m_triangles[i].tex2Name, "bmp", "png"); + m_triangles[i].tex2Name = StrUtils::Replace(m_triangles[i].tex2Name, "tga", "png"); - GetLogger()->Info("ModelTriangle %d\n", i+1); + GetLogger()->Trace("ModelTriangle %d\n", i+1); std::string s1 = m_triangles[i].p1.ToString(); - GetLogger()->Info(" p1: %s\n", s1.c_str()); + GetLogger()->Trace(" p1: %s\n", s1.c_str()); std::string s2 = m_triangles[i].p2.ToString(); - GetLogger()->Info(" p2: %s\n", s2.c_str()); + GetLogger()->Trace(" p2: %s\n", s2.c_str()); std::string s3 = m_triangles[i].p3.ToString(); - GetLogger()->Info(" p3: %s\n", s3.c_str()); + GetLogger()->Trace(" p3: %s\n", s3.c_str()); std::string d = m_triangles[i].material.diffuse.ToString(); std::string a = m_triangles[i].material.ambient.ToString(); std::string s = m_triangles[i].material.specular.ToString(); - GetLogger()->Info(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); + GetLogger()->Trace(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); - GetLogger()->Info(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].tex2Name.c_str()); - GetLogger()->Info(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); - GetLogger()->Info(" state: %ld\n", m_triangles[i].state); + GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), + m_triangles[i].variableTex2 ? "(variable)" : m_triangles[i].tex2Name.c_str()); + GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); } - /* - if (! edit) - { - float limit[2]; - limit[0] = m_engine->RetLimitLOD(0); // frontier AB as config - limit[1] = m_engine->RetLimitLOD(1); // frontier BC as config - - // Standard frontiers -> config. - for (int i = 0; i < m_triangles.size(); ++i) - { - if ( m_triangles[i].min == 0.0f && - m_triangles[i].max == 100.0f ) // resolution A ? - { - m_triangles[i].max = limit[0]; - } - else if ( m_triangles[i].min == 100.0f && - m_triangles[i].max == 200.0f ) // resolution B ? - { - m_triangles[i].min = limit[0]; - m_triangles[i].max = limit[1]; - } - else if ( m_triangles[i].min == 200.0f && - m_triangles[i].max == 1000000.0f ) // resolution C ? - { - m_triangles[i].min = limit[1]; - } - } - }*/ - return true; } -bool Gfx::CModelFile::WriteModel(const std::string &filename) +bool Gfx::CModelFile::WriteModel(const std::string& fileName) { - m_error = ""; - std::ofstream stream; - stream.open(filename.c_str(), std::ios_base::out | std::ios_base::binary); - if (! stream.good()) + stream.open(fileName.c_str(), std::ios_base::out | std::ios_base::binary); + if (!stream.good()) { - m_error = std::string("Could not open file '") + filename + std::string("'"); + GetLogger()->Error("Could not open file '%s'\n", fileName.c_str()); return false; } return WriteModel(stream); } -bool Gfx::CModelFile::WriteModel(std::ostream &stream) +bool Gfx::CModelFile::WriteModel(std::ostream& stream) { - m_error = ""; - if (m_triangles.size() == 0) { - m_error = "Empty model"; + GetLogger()->Error("Empty model\n"); return false; } - ModelHeader header; + OldModelHeader header; header.revision = 1; header.version = 2; - header.totalVertices = m_triangles.size(); + header.totalTriangles = m_triangles.size(); IOUtils::WriteBinary<4, int>(header.revision, stream); IOUtils::WriteBinary<4, int>(header.version, stream); - IOUtils::WriteBinary<4, int>(header.totalVertices, stream); + IOUtils::WriteBinary<4, int>(header.totalTriangles, stream); for (int i = 0; i < 10; ++i) IOUtils::WriteBinary<4, int>(header.reserved[i], stream); for (int i = 0; i < static_cast<int>( m_triangles.size() ); ++i) { - NewModelTriangle t; + OldModelTriangle3 t; t.used = true; @@ -536,14 +696,21 @@ bool Gfx::CModelFile::WriteModel(std::ostream &stream) t.min = m_triangles[i].min; t.max = m_triangles[i].max; t.state = m_triangles[i].state; + int no = 0; - sscanf(m_triangles[i].tex2Name.c_str(), "dirty%d.tga", &no); // hardcoded as in the original code + if (m_triangles[i].variableTex2) + no = 1; + else + sscanf(m_triangles[i].tex2Name.c_str(), "dirty%d.png", &no); // hardcoded as in the original code + t.texNum2 = no; IOUtils::WriteBinary<1, char>(t.used, stream); IOUtils::WriteBinary<1, char>(t.selected, stream); + /* padding */ IOUtils::WriteBinary<2, unsigned int>(0, stream); + WriteBinaryVertexTex2(t.p1, stream); WriteBinaryVertexTex2(t.p2, stream); WriteBinaryVertexTex2(t.p3, stream); @@ -563,215 +730,489 @@ bool Gfx::CModelFile::WriteModel(std::ostream &stream) return true; } -bool Gfx::CModelFile::ReadDXF(const std::string &filename, float min, float max) + +/******************************************************* + New formats + *******************************************************/ + +/** + * \struct NewModelHeader + * \brief Header for new binary model file + */ +struct NewModelHeader { - m_triangles.clear(); - m_error = ""; + //! File version (1, 2, ...) + int version; + //! Total number of triangles + int totalTriangles; + NewModelHeader() + { + version = 0; + totalTriangles = 0; + } +}; + +/** + * \struct NewModelTriangle1 + * \brief Triangle of new binary model file + * + * NOTE: at this time, it is identical to ModelTriangle struct, but it may change + * independently in the future. + */ +struct NewModelTriangle1 +{ + //! 1st vertex + Gfx::VertexTex2 p1; + //! 2nd vertex + Gfx::VertexTex2 p2; + //! 3rd vertex + Gfx::VertexTex2 p3; + //! Material + Gfx::Material material; + //! Name of 1st texture + std::string tex1Name; + //! Name of 2nd texture + std::string tex2Name; + //! If true, 2nd texture will be taken from current engine setting + bool variableTex2; + //! Min LOD threshold + float min; + //! Max LOD threshold + float max; + //! Rendering state to be set + int state; + + NewModelTriangle1() + { + variableTex2 = true; + min = max = 0.0f; + state = 0; + } +}; + + +bool Gfx::CModelFile::ReadTextModel(const std::string& fileName) +{ std::ifstream stream; - stream.open(filename.c_str(), std::ios_base::in); - if (! stream.good()) + stream.open(fileName.c_str(), std::ios_base::in); + if (!stream.good()) { - m_error = std::string("Couldn't open file '") + filename + std::string("'"); + GetLogger()->Error("Could not open file '%s'\n", fileName.c_str()); return false; } - return ReadDXF(stream, min, max); + return ReadTextModel(stream); } -bool Gfx::CModelFile::ReadDXF(std::istream &stream, float min, float max) +bool Gfx::CModelFile::ReadTextModel(std::istream& stream) { m_triangles.clear(); - m_error = ""; - if (! stream.good()) + NewModelHeader header; + + bool headOk = ReadLineValue<int>(stream, "version", header.version) && + ReadLineValue<int>(stream, "total_triangles", header.totalTriangles); + + if (!headOk || !stream.good()) { - m_error = "Invalid stream"; + GetLogger()->Error("Error reading model file header\n"); return false; } - // Input state - bool waitNumVertex = false; - bool waitNumFace = false; - bool waitVertexX = false; - bool waitVertexY = false; - bool waitVertexZ = false; - bool waitFaceX = false; - bool waitFaceY = false; - bool waitFaceZ = false; - - // Vertex array - std::vector<Math::Vector> vertices; - vertices.reserve(TRIANGLE_PREALLOCATE_COUNT); - - // Number of vertices & faces of the primitive to be read - int vertexNum = 0, faceNum = 0; - // Vertex coords - Math::Vector coords; - // Indexes of face (triangle) points - int p1 = 0, p2 = 0, p3 = 0; - - // Input line - std::string line; - while (! stream.eof() ) + // New model version 1 + if (header.version == 1) { - // Read line with command - std::getline(stream, line); - int command = StrUtils::FromString<int>(line); + for (int i = 0; i < header.totalTriangles; ++i) + { + NewModelTriangle1 t; + + std::string p1Text, p2Text, p3Text; + std::string matText; + char varTex2Ch = 0; + + bool triOk = ReadLineString(stream, "p1", p1Text) && + ReadTextVertexTex2(p1Text, t.p1) && + ReadLineString(stream, "p2", p2Text) && + ReadTextVertexTex2(p2Text, t.p2) && + ReadLineString(stream, "p3", p3Text) && + ReadTextVertexTex2(p3Text, t.p3) && + ReadLineString(stream, "mat", matText) && + ReadTextMaterial(matText, t.material) && + ReadLineValue<std::string>(stream, "tex1", t.tex1Name) && + ReadLineValue<std::string>(stream, "tex2", t.tex2Name) && + ReadLineValue<char>(stream, "var_tex2", varTex2Ch) && + ReadLineValue<float>(stream, "min", t.min) && + ReadLineValue<float>(stream, "max", t.max) && + ReadLineValue<int>(stream, "state", t.state); + + if (!triOk || stream.fail()) + { + GetLogger()->Error("Error reading model file header\n"); + return false; + } - // Read line with param - std::getline(stream, line); + t.variableTex2 = varTex2Ch == 'Y'; - bool ok = true; + Gfx::ModelTriangle triangle; + triangle.p1 = t.p1; + triangle.p2 = t.p2; + triangle.p3 = t.p3; + triangle.material = t.material; + triangle.tex1Name = t.tex1Name; + triangle.tex2Name = t.tex2Name; + triangle.variableTex2 = t.variableTex2; + triangle.min = t.min; + triangle.max = t.max; + triangle.state = t.state; - if (command == 66) - { - waitNumVertex = true; - } + m_triangles.push_back(triangle); - if ( command == 71 && waitNumVertex ) - { - waitNumVertex = false; - vertexNum = StrUtils::FromString<int>(line, &ok); - waitNumFace = true; + continue; } + } + else + { + GetLogger()->Error("Unknown model file version\n"); + return false; + } - if ( command == 72 && waitNumFace ) - { - waitNumFace = false; - faceNum = StrUtils::FromString<int>(line, &ok); - waitVertexX = true; - } + for (int i = 0; i < static_cast<int>( m_triangles.size() ); ++i) + { + GetLogger()->Trace("ModelTriangle %d\n", i+1); + std::string s1 = m_triangles[i].p1.ToString(); + GetLogger()->Trace(" p1: %s\n", s1.c_str()); + std::string s2 = m_triangles[i].p2.ToString(); + GetLogger()->Trace(" p2: %s\n", s2.c_str()); + std::string s3 = m_triangles[i].p3.ToString(); + GetLogger()->Trace(" p3: %s\n", s3.c_str()); - if ( command == 10 && waitVertexX ) - { - waitVertexX = false; - coords.x = StrUtils::FromString<float>(line, &ok); - waitVertexY = true; - } + std::string d = m_triangles[i].material.diffuse.ToString(); + std::string a = m_triangles[i].material.ambient.ToString(); + std::string s = m_triangles[i].material.specular.ToString(); + GetLogger()->Trace(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); + + GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].tex2Name.c_str()); + GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); + } + + return true; +} + +bool Gfx::CModelFile::WriteTextModel(const std::string &fileName) +{ + std::ofstream stream; + stream.open(fileName.c_str(), std::ios_base::out); + if (!stream.good()) + { + GetLogger()->Error("Could not open file '%s'\n", fileName.c_str()); + return false; + } - if ( command == 20 && waitVertexY ) + return WriteTextModel(stream); +} + +bool Gfx::CModelFile::WriteTextModel(std::ostream& stream) +{ + if (m_triangles.size() == 0) + { + GetLogger()->Error("Empty model\n"); + return false; + } + + NewModelHeader header; + + header.version = 1; + header.totalTriangles = m_triangles.size(); + + stream << "# Colobot text model" << std::endl; + stream << std::endl; + stream << "### HEAD" << std::endl; + stream << "version " << header.version << std::endl; + stream << "total_triangles " << header.totalTriangles << std::endl; + stream << std::endl; + stream << "### TRIANGLES" << std::endl; + + for (int i = 0; i < static_cast<int>( m_triangles.size() ); ++i) + { + NewModelTriangle1 t; + + t.p1 = m_triangles[i].p1; + t.p2 = m_triangles[i].p2; + t.p3 = m_triangles[i].p3; + t.material = m_triangles[i].material; + t.tex1Name = m_triangles[i].tex1Name; + t.tex2Name = m_triangles[i].tex2Name; + t.variableTex2 = m_triangles[i].variableTex2; + t.min = m_triangles[i].min; + t.max = m_triangles[i].max; + t.state = m_triangles[i].state; + + stream << "p1 "; + WriteTextVertexTex2(t.p1, stream); + stream << "p2 "; + WriteTextVertexTex2(t.p2, stream); + stream << "p3 "; + WriteTextVertexTex2(t.p3, stream); + stream << "mat "; + WriteTextMaterial(t.material, stream); + + stream << "tex1 " << t.tex1Name << std::endl; + stream << "tex2 " << t.tex2Name << std::endl; + stream << "var_tex2 " << (t.variableTex2 ? 'Y' : 'N') << std::endl; + stream << "min " << t.min << std::endl; + stream << "max " << t.max << std::endl; + stream << "state " << t.state << std::endl; + + stream << std::endl; + + if (stream.fail()) { - waitVertexY = false; - coords.y = StrUtils::FromString<float>(line, &ok); - waitVertexZ = true; + GetLogger()->Error("Error writing model file\n"); + return false; } + } - if ( command == 30 && waitVertexZ ) + return true; +} + +bool Gfx::CModelFile::ReadBinaryModel(const std::string& fileName) +{ + std::ifstream stream; + stream.open(fileName.c_str(), std::ios_base::in | std::ios_base::binary); + if (!stream.good()) + { + GetLogger()->Error("Could not open file '%s'\n", fileName.c_str()); + return false; + } + + return ReadBinaryModel(stream); +} + +bool Gfx::CModelFile::ReadBinaryModel(std::istream& stream) +{ + m_triangles.clear(); + + NewModelHeader header; + + header.version = IOUtils::ReadBinary<4, int>(stream); + header.totalTriangles = IOUtils::ReadBinary<4, int>(stream); + + if (!stream.good()) + { + GetLogger()->Error("Error reading model file header\n"); + return false; + } + + // New model version 1 + if (header.version == 1) + { + for (int i = 0; i < header.totalTriangles; ++i) { - waitVertexZ = false; - coords.z = StrUtils::FromString<float>(line, &ok); + NewModelTriangle1 t; + + ReadBinaryVertexTex2(stream, t.p1); + ReadBinaryVertexTex2(stream, t.p2); + ReadBinaryVertexTex2(stream, t.p3); + ReadBinaryMaterial(stream, t.material); + t.tex1Name = IOUtils::ReadBinaryString<1>(stream); + t.tex2Name = IOUtils::ReadBinaryString<1>(stream); + t.variableTex2 = IOUtils::ReadBinaryBool(stream); + t.min = IOUtils::ReadBinaryFloat(stream); + t.max = IOUtils::ReadBinaryFloat(stream); + t.state = IOUtils::ReadBinary<4, unsigned int>(stream); - vertexNum --; - if ( vertexNum >= 0 ) - { - Math::Vector p(coords.x, coords.z, coords.y); // permutation of Y and Z! - vertices.push_back(p); - waitVertexX = true; - } - else + if (stream.fail()) { - waitFaceX = true; + GetLogger()->Error("Error reading model data\n"); + return false; } - } - if ( command == 71 && waitFaceX ) - { - waitFaceX = false; - p1 = StrUtils::FromString<int>(line, &ok); - if ( p1 < 0 ) p1 = -p1; - waitFaceY = true; - } + Gfx::ModelTriangle triangle; + triangle.p1 = t.p1; + triangle.p2 = t.p2; + triangle.p3 = t.p3; + triangle.material = t.material; + triangle.tex1Name = t.tex1Name; + triangle.tex2Name = t.tex2Name; + triangle.variableTex2 = t.variableTex2; + triangle.min = t.min; + triangle.max = t.max; + triangle.state = t.state; - if ( command == 72 && waitFaceY ) - { - waitFaceY = false; - p2 = StrUtils::FromString<int>(line, &ok); - if ( p2 < 0 ) p2 = -p2; - waitFaceZ = true; + m_triangles.push_back(triangle); } + } + else + { + GetLogger()->Error("Unknown model file version\n"); + return false; + } - if ( command == 73 && waitFaceZ ) - { - waitFaceZ = false; - p3 = StrUtils::FromString<int>(line, &ok); - if ( p3 < 0 ) p3 = -p3; + for (int i = 0; i < static_cast<int>( m_triangles.size() ); ++i) + { + GetLogger()->Trace("ModelTriangle %d\n", i+1); + std::string s1 = m_triangles[i].p1.ToString(); + GetLogger()->Trace(" p1: %s\n", s1.c_str()); + std::string s2 = m_triangles[i].p2.ToString(); + GetLogger()->Trace(" p2: %s\n", s2.c_str()); + std::string s3 = m_triangles[i].p3.ToString(); + GetLogger()->Trace(" p3: %s\n", s3.c_str()); - faceNum --; - if ( faceNum >= 0 ) - { - assert( (p1-1 >= 0) && (p1-1 < static_cast<int>(vertices.size())) ); - assert( (p2-1 >= 0) && (p2-1 < static_cast<int>(vertices.size())) ); - assert( (p3-1 >= 0) && (p3-1 < static_cast<int>(vertices.size())) ); + std::string d = m_triangles[i].material.diffuse.ToString(); + std::string a = m_triangles[i].material.ambient.ToString(); + std::string s = m_triangles[i].material.specular.ToString(); + GetLogger()->Trace(" mat: d: %s a: %s s: %s\n", d.c_str(), a.c_str(), s.c_str()); - CreateTriangle(vertices[p3-1], vertices[p2-1], vertices[p1-1], min, max); - waitFaceX = true; - } - } + GetLogger()->Trace(" tex1: %s tex2: %s\n", m_triangles[i].tex1Name.c_str(), m_triangles[i].tex2Name.c_str()); + GetLogger()->Trace(" min: %.2f max: %.2f\n", m_triangles[i].min, m_triangles[i].max); + GetLogger()->Trace(" state: %ld\n", m_triangles[i].state); + } - if (! ok) + return true; +} + +bool Gfx::CModelFile::WriteBinaryModel(const std::string& fileName) +{ + std::ofstream stream; + stream.open(fileName.c_str(), std::ios_base::out | std::ios_base::binary); + if (!stream.good()) + { + GetLogger()->Error("Could not open file '%s'\n", fileName.c_str()); + return false; + } + + return WriteBinaryModel(stream); +} + +bool Gfx::CModelFile::WriteBinaryModel(std::ostream& stream) +{ + if (m_triangles.size() == 0) + { + GetLogger()->Error("Empty model\n"); + return false; + } + + NewModelHeader header; + + header.version = 1; + header.totalTriangles = m_triangles.size(); + + IOUtils::WriteBinary<4, int>(header.version, stream); + IOUtils::WriteBinary<4, int>(header.totalTriangles, stream); + + for (int i = 0; i < static_cast<int>( m_triangles.size() ); ++i) + { + NewModelTriangle1 t; + + t.p1 = m_triangles[i].p1; + t.p2 = m_triangles[i].p2; + t.p3 = m_triangles[i].p3; + t.material = m_triangles[i].material; + t.tex1Name = m_triangles[i].tex1Name; + t.tex2Name = m_triangles[i].tex2Name; + t.variableTex2 = m_triangles[i].variableTex2; + t.min = m_triangles[i].min; + t.max = m_triangles[i].max; + t.state = m_triangles[i].state; + + WriteBinaryVertexTex2(t.p1, stream); + WriteBinaryVertexTex2(t.p2, stream); + WriteBinaryVertexTex2(t.p3, stream); + WriteBinaryMaterial(t.material, stream); + IOUtils::WriteBinaryString<1>(t.tex1Name, stream); + IOUtils::WriteBinaryString<1>(t.tex2Name, stream); + IOUtils::WriteBinaryBool(t.variableTex2, stream); + IOUtils::WriteBinaryFloat(t.min, stream); + IOUtils::WriteBinaryFloat(t.max, stream); + IOUtils::WriteBinary<4, unsigned int>(t.state, stream); + + if (stream.fail()) { - m_error = "Error reading data"; + GetLogger()->Error("Error writing model file\n"); return false; } - } return true; } -bool Gfx::CModelFile::CreateEngineObject(int objRank, int addState) + +/******************************************************* + Other stuff + *******************************************************/ + +#ifndef MODELFILE_NO_ENGINE + +bool Gfx::CModelFile::CreateEngineObject(int objRank) { + std::vector<Gfx::VertexTex2> vs(3, Gfx::VertexTex2()); + + float limit[2]; + limit[0] = m_engine->GetLimitLOD(0); // frontier AB as config + limit[1] = m_engine->GetLimitLOD(1); // frontier BC as config + for (int i = 0; i < static_cast<int>( m_triangles.size() ); i++) { - int state = m_triangles[i].state; + // TODO move this to CEngine - /* TODO ??? - if (texName1 == "plant.png") - state |= Gfx::ENG_RSTATE_ALPHA; + float min = m_triangles[i].min; + float max = m_triangles[i].max; - if (m_triangles[i].tex2Name.empty()) + // Standard frontiers -> config + if (min == 0.0f && max == 100.0f) // resolution A ? + { + max = limit[0]; + } + else if (min == 100.0f && max == 200.0f) // resolution B ? { - int texNum = 0; + min = limit[0]; + max = limit[1]; + } + else if (min == 200.0f && max == 1000000.0f) // resolution C ? + { + min = limit[1]; + } - if ( m_triangles[i].texNum2 == 1 ) - { - texNum = m_engine->RetSecondTexture(); - } - else - { - texNum = m_triangles[i].texNum2; - } + int state = m_triangles[i].state; + std::string tex2Name = m_triangles[i].tex2Name; - if ( texNum >= 1 && texNum <= 10 ) - { - state |= D3DSTATEDUALb; - } - if ( texNum >= 11 && texNum <= 20 ) - { - state |= D3DSTATEDUALw; - } - sprintf(texName2, "dirty%.2d.tga", texNum); // ??? - }*/ + if (m_triangles[i].variableTex2) + { + int texNum = m_engine->GetSecondTexture(); - std::vector<Gfx::VertexTex2> vs; - vs.push_back(m_triangles[i].p1); - vs.push_back(m_triangles[i].p2); - vs.push_back(m_triangles[i].p3); + if (texNum >= 1 && texNum <= 10) + state |= Gfx::ENG_RSTATE_DUAL_BLACK; - m_engine->AddTriangles(objRank, vs, - m_triangles[i].material, - state + addState, - m_triangles[i].tex1Name, - m_triangles[i].tex2Name, - m_triangles[i].min, - m_triangles[i].max, false); + if (texNum >= 11 && texNum <= 20) + state |= Gfx::ENG_RSTATE_DUAL_WHITE; + + char name[20] = { 0 }; + sprintf(name, "dirty%.2d.png", texNum); + tex2Name = name; + } + + vs[0] = m_triangles[i].p1; + vs[1] = m_triangles[i].p2; + vs[2] = m_triangles[i].p3; + + bool ok = m_engine->AddTriangles(objRank, vs, + m_triangles[i].material, + state, + m_triangles[i].tex1Name, + tex2Name, + min, max, false); + if (!ok) + return false; } return true; } +#endif + void Gfx::CModelFile::Mirror() { for (int i = 0; i < static_cast<int>( m_triangles.size() ); i++) @@ -790,7 +1231,7 @@ void Gfx::CModelFile::Mirror() } } -std::vector<Gfx::ModelTriangle>& Gfx::CModelFile::GetTriangles() +const std::vector<Gfx::ModelTriangle>& Gfx::CModelFile::GetTriangles() { return m_triangles; } diff --git a/src/graphics/engine/modelfile.h b/src/graphics/engine/modelfile.h index fab190f..833cdf6 100644 --- a/src/graphics/engine/modelfile.h +++ b/src/graphics/engine/modelfile.h @@ -20,7 +20,6 @@ * \brief Model loading - Gfx::CModelFile class (aka modfile) */ -#include "graphics/engine/engine.h" #include "graphics/core/vertex.h" #include "graphics/core/material.h" #include "math/vector.h" @@ -35,6 +34,9 @@ class CInstanceManager; namespace Gfx { +class CEngine; + + /** \struct ModelTriangle \brief Triangle of a 3D model @@ -53,14 +55,21 @@ struct ModelTriangle std::string tex1Name; //! Name of 2nd texture std::string tex2Name; + //! If true, 2nd texture will be taken from current engine setting + bool variableTex2; //! Min LOD threshold float min; //! Max LOD threshold float max; //! Rendering state to be set - long state; - - ModelTriangle(); + int state; + + ModelTriangle() + { + variableTex2 = true; + min = max = 0.0f; + state = 0; + } }; @@ -75,27 +84,45 @@ public: CModelFile(CInstanceManager* iMan); ~CModelFile(); - //! Returns the last error encountered - std::string GetError(); + //! Reads a model in text format from file + bool ReadTextModel(const std::string &fileName); + //! Reads a model in text format from stream + bool ReadTextModel(std::istream &stream); + + //! Writes the model in text format to a file + bool WriteTextModel(const std::string &fileName); + //! Writes the model in text format to a stream + bool WriteTextModel(std::ostream &stream); + + //! Reads a model in new binary format from file + bool ReadBinaryModel(const std::string &fileName); + //! Reads a model in new binary format from stream + bool ReadBinaryModel(std::istream &stream); + + //! Writes the model in binary format to a file + bool WriteBinaryModel(const std::string &fileName); + //! Writes the model in binary format to a stream + bool WriteBinaryModel(std::ostream &stream); //! Reads a binary Colobot model from file - bool ReadModel(const std::string &filename, bool edit = false, bool meta = true); + //! @deprecated + bool ReadModel(const std::string &fileName); //! Reads a binary Colobot model from stream - bool ReadModel(std::istream &stream, bool edit = false, bool meta = true); + //! @deprecated + bool ReadModel(std::istream &stream); //! Writes the model to Colobot binary model file - bool WriteModel(const std::string &filename); + //! @deprecated + bool WriteModel(const std::string &fileName); //! Writes the model to Colobot binary model file + //! @deprecated bool WriteModel(std::ostream &stream); - //! Reads a DXF model from file - bool ReadDXF(const std::string &filename, float min, float max); - //! Reads a DXF model from stream - bool ReadDXF(std::istream &stream, float min, float max); - //! Returns the number of triangles in model int GetTriangleCount(); + //! Returns the triangle vector - std::vector<Gfx::ModelTriangle>& GetTriangles(); + const std::vector<Gfx::ModelTriangle>& GetTriangles(); + //! Returns the height of model -- closest point to X and Z coords of \a pos float GetHeight(Math::Vector pos); @@ -103,7 +130,7 @@ public: void Mirror(); //! Creates an object in the graphics engine from the model - bool CreateEngineObject(int objRank, int addState = 0); + bool CreateEngineObject(int objRank); protected: //! Adds a triangle to the list @@ -113,9 +140,6 @@ protected: CInstanceManager* m_iMan; Gfx::CEngine* m_engine; - //! Last error - std::string m_error; - //! Model triangles std::vector<Gfx::ModelTriangle> m_triangles; }; diff --git a/src/graphics/engine/terrain.cpp b/src/graphics/engine/terrain.cpp index 6b26281..3e70719 100644 --- a/src/graphics/engine/terrain.cpp +++ b/src/graphics/engine/terrain.cpp @@ -44,111 +44,88 @@ Gfx::CTerrain::CTerrain(CInstanceManager* iMan) m_engine = static_cast<Gfx::CEngine*>( m_iMan->SearchInstance(CLASS_ENGINE) ); m_water = static_cast<Gfx::CWater*>( m_iMan->SearchInstance(CLASS_WATER) ); - m_mosaic = 20; - m_brick = 1 << 4; - m_size = 10.0f; - m_vision = 200.0f; - m_scaleMapping = 0.01f; - m_scaleRelief = 1.0f; - m_subdivMapping = 1; - m_depth = 2; - m_levelMatMax = 0; - m_multiText = true; - m_levelText = false; - m_wind = Math::Vector(0.0f, 0.0f, 0.0f); - m_defHardness = 0.5f; - - m_levelMats.reserve(LEVEL_MAT_PREALLOCATE_COUNT); + m_mosaicCount = 20; + m_brickCount = 1 << 4; + m_brickSize = 10.0f; + m_vision = 200.0f; + m_textureScale = 0.01f; + m_scaleRelief = 1.0f; + m_textureSubdivCount = 1; + m_depth = 2; + m_maxMaterialID = 0; + m_wind = Math::Vector(0.0f, 0.0f, 0.0f); + m_defaultHardness = 0.5f; + m_useMaterials = false; + + m_materials.reserve(LEVEL_MAT_PREALLOCATE_COUNT); m_flyingLimits.reserve(FLYING_LIMIT_PREALLOCATE_COUNT); m_buildingLevels.reserve(BUILDING_LEVEL_PREALLOCATE_COUNT); + + FlushBuildingLevel(); + FlushFlyingLimit(); + FlushMaterials(); } Gfx::CTerrain::~CTerrain() { } -/** - The terrain is composed of mosaics, themselves composed of bricks. - Each brick is composed of two triangles. - mosaic: number of mosaics along the axes X and Z - brick: number of bricks (power of 2) - size: size of a brick along the axes X and Z - vision: vision before a change of resolution - scaleMapping: scale textures for mapping - -\verbatim - ^ z - | <---> brick*size - +---+---+---+---+ - | | | |_|_| mosaic = 4 - | | | | | | brick = 2 (brickP2=1) - +---+---+---+---+ - |\ \| | | | - |\ \| | | | - +---+---o---+---+---> x - | | | | | - | | | | | - +---+---+---+---+ - | | | | | The land is viewed from above here. - | | | | | - +---+---+---+---+ - <---------------> mosaic*brick*size -\endverbatim */ -bool Gfx::CTerrain::Generate(int mosaic, int brickPow2, float size, float vision, - int depth, float hardness) +bool Gfx::CTerrain::Generate(int mosaicCount, int brickCountPow2, float brickSize, + float vision, int depth, float hardness) { - m_mosaic = mosaic; - m_brick = 1 << brickPow2; - m_size = size; + m_mosaicCount = mosaicCount; + m_brickCount = 1 << brickCountPow2; + m_brickSize = brickSize; m_vision = vision; m_depth = depth; - m_defHardness = hardness; + m_defaultHardness = hardness; m_engine->SetTerrainVision(vision); - m_multiText = true; - m_levelText = false; - m_scaleMapping = 1.0f / (m_brick*m_size); - m_subdivMapping = 1; + m_textureScale = 1.0f / (m_brickCount*m_brickSize); + m_textureSubdivCount = 1; + + m_useMaterials = false; int dim = 0; - dim = (m_mosaic*m_brick+1)*(m_mosaic*m_brick+1); + dim = (m_mosaicCount*m_brickCount+1)*(m_mosaicCount*m_brickCount+1); std::vector<float>(dim).swap(m_relief); - dim = m_mosaic*m_subdivMapping*m_mosaic*m_subdivMapping; - std::vector<int>(dim).swap(m_texture); + dim = m_mosaicCount*m_textureSubdivCount*m_mosaicCount*m_textureSubdivCount; + std::vector<int>(dim).swap(m_textures); - dim = m_mosaic*m_mosaic; - std::vector<int>(dim).swap(m_objRank); + dim = m_mosaicCount*m_mosaicCount; + std::vector<int>(dim).swap(m_objRanks); return true; } -int Gfx::CTerrain::GetMosaic() +int Gfx::CTerrain::GetMosaicCount() { - return m_mosaic; + return m_mosaicCount; } -int Gfx::CTerrain::GetBrick() +int Gfx::CTerrain::GetBrickCount() { - return m_brick; + return m_brickCount; } -float Gfx::CTerrain::GetSize() +float Gfx::CTerrain::GetBrickSize() { - return m_size; + return m_brickSize; } -float Gfx::CTerrain::GetScaleRelief() +float Gfx::CTerrain::GetReliefScale() { return m_scaleRelief; } bool Gfx::CTerrain::InitTextures(const std::string& baseName, int* table, int dx, int dy) { - m_levelText = false; + m_useMaterials = false; + m_texBaseName = baseName; size_t pos = baseName.find('.'); if (pos == baseName.npos) @@ -161,69 +138,60 @@ bool Gfx::CTerrain::InitTextures(const std::string& baseName, int* table, int dx m_texBaseExt = m_texBaseName.substr(pos); } - for (int y = 0; y < m_mosaic*m_subdivMapping; y++) + for (int y = 0; y < m_mosaicCount*m_textureSubdivCount; y++) { - for (int x = 0; x < m_mosaic*m_subdivMapping; x++) + for (int x = 0; x < m_mosaicCount*m_textureSubdivCount; x++) { - m_texture[x+y*m_mosaic] = table[(x%dx)+(y%dy)*dx]; + m_textures[x+y*m_mosaicCount] = table[(x%dx)+(y%dy)*dx]; } } return true; } -void Gfx::CTerrain::LevelFlush() +void Gfx::CTerrain::FlushMaterials() { - m_levelMats.clear(); - m_levelMatMax = 0; - m_levelID = 1000; - LevelCloseTable(); + m_materials.clear(); + m_maxMaterialID = 0; + m_materialAutoID = 1000; + FlushMaterialPoints(); } -void Gfx::CTerrain::LevelMaterial(int id, std::string& baseName, float u, float v, - int up, int right, int down, int left, - float hardness) +void Gfx::CTerrain::AddMaterial(int id, const std::string& texName, const Math::Point &uv, + int up, int right, int down, int left, + float hardness) { - LevelOpenTable(); + InitMaterialPoints(); if (id == 0) - id = m_levelID++; // puts an ID internal standard + id = m_materialAutoID++; Gfx::TerrainMaterial tm; - tm.texName = baseName; + tm.texName = texName; tm.id = id; - tm.u = u; - tm.v = v; + tm.uv = uv; tm.mat[0] = up; tm.mat[1] = right; tm.mat[2] = down; tm.mat[3] = left; tm.hardness = hardness; - m_levelMats.push_back(tm); + m_materials.push_back(tm); - if (m_levelMatMax < up+1 ) m_levelMatMax = up+1; - if (m_levelMatMax < right+1) m_levelMatMax = right+1; - if (m_levelMatMax < down+1 ) m_levelMatMax = down+1; - if (m_levelMatMax < left+1 ) m_levelMatMax = left+1; + if (m_maxMaterialID < up+1 ) m_maxMaterialID = up+1; + if (m_maxMaterialID < right+1) m_maxMaterialID = right+1; + if (m_maxMaterialID < down+1 ) m_maxMaterialID = down+1; + if (m_maxMaterialID < left+1 ) m_maxMaterialID = left+1; - m_levelText = true; - m_subdivMapping = 4; + m_useMaterials = true; + m_textureSubdivCount = 4; } /** - The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. - The image must be 24 bits/pixel - - Converts coordinated image (x;y) -> world (x;-;z) : - Wx = 5*Ix-400 - Wz = -(5*Iy-400) - - Converts coordinated world (x;-;z) -> image (x;y) : - Ix = (400+Wx)/5 - Iy = (400-Wz)/5 */ -bool Gfx::CTerrain::ResFromPNG(const std::string& fileName) + * The image must be 24 bits/pixel and grayscale and dx x dy in size + * with dx = dy = (mosaic*brick)+1 */ +bool Gfx::CTerrain::LoadResources(const std::string& fileName) { CImage img; if (! img.Load(CApplication::GetInstance().GetDataFilePath(m_engine->GetTextureDir(), fileName))) @@ -231,7 +199,7 @@ bool Gfx::CTerrain::ResFromPNG(const std::string& fileName) ImageData *data = img.GetData(); - int size = (m_mosaic*m_brick)+1; + int size = (m_mosaicCount*m_brickCount)+1; m_resources.clear(); @@ -241,8 +209,13 @@ bool Gfx::CTerrain::ResFromPNG(const std::string& fileName) (data->surface->format->BytesPerPixel != 3) ) return false; - // Assuming the data format is compatible - memcpy(&m_resources[0], data->surface->pixels, 3*size*size); + unsigned char* pixels = static_cast<unsigned char*>(data->surface->pixels); + int pitch = data->surface->pitch; + + for (int y = 0; y < size; y++) + { + memcpy(&m_resources[3*size*y], &pixels[pitch*y], 3*size); + } return true; } @@ -252,14 +225,14 @@ Gfx::TerrainRes Gfx::CTerrain::GetResource(const Math::Vector &p) if (m_resources.empty()) return Gfx::TR_NULL; - int x = static_cast<int>((p.x + (m_mosaic*m_brick*m_size)/2.0f)/m_size); - int y = static_cast<int>((p.z + (m_mosaic*m_brick*m_size)/2.0f)/m_size); + int x = static_cast<int>((p.x + (m_mosaicCount*m_brickCount*m_brickSize)/2.0f)/m_brickSize); + int y = static_cast<int>((p.z + (m_mosaicCount*m_brickCount*m_brickSize)/2.0f)/m_brickSize); - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) + if ( x < 0 || x > m_mosaicCount*m_brickCount || + y < 0 || y > m_mosaicCount*m_brickCount ) return Gfx::TR_NULL; - int size = (m_mosaic*m_brick)+1; + int size = (m_mosaicCount*m_brickCount)+1; int resR = m_resources[3*x+3*size*(size-y-1)]; int resG = m_resources[3*x+3*size*(size-y-1)+1]; @@ -284,20 +257,10 @@ void Gfx::CTerrain::FlushRelief() } /** - The size of the image must be dimension dx and dy with dx=dy=(mosaic*brick)+1. - The image must be 24 bits/pixel, but gray scale: - white = ground (y=0) - black = mountain (y=255*scaleRelief) - - Converts coordinated image(x;y) -> world (x;-;z) : - Wx = 5*Ix-400 - Wz = -(5*Iy-400) - - Converts coordinated world (x;-;z) -> image (x;y) : - Ix = (400+Wx)/5 - Iy = (400-Wz)/5 */ -bool Gfx::CTerrain::ReliefFromPNG(const std::string &fileName, float scaleRelief, - bool adjustBorder) + * The image must be 24 bits/pixel and dx x dy in size + * with dx = dy = (mosaic*brick)+1 */ +bool Gfx::CTerrain::LoadRelief(const std::string &fileName, float scaleRelief, + bool adjustBorder) { m_scaleRelief = scaleRelief; @@ -307,20 +270,21 @@ bool Gfx::CTerrain::ReliefFromPNG(const std::string &fileName, float scaleRelief ImageData *data = img.GetData(); - int size = (m_mosaic*m_brick)+1; + int size = (m_mosaicCount*m_brickCount)+1; if ( (data->surface->w != size) || (data->surface->h != size) || (data->surface->format->BytesPerPixel != 3) ) return false; unsigned char* pixels = static_cast<unsigned char*>(data->surface->pixels); + int pitch = data->surface->pitch; float limit = 0.9f; for (int y = 0; y < size; y++) { for (int x = 0; x < size; x++) { - float level = (255 - pixels[3*x+3*size*(size-y-1)]) * scaleRelief; + float level = (255 - pixels[3*x+pitch*(size-y-1)]) * scaleRelief; float dist = Math::Max(fabs(static_cast<float>(x-size/2)), fabs(static_cast<float>(y-size/2))); @@ -340,13 +304,13 @@ bool Gfx::CTerrain::ReliefFromPNG(const std::string &fileName, float scaleRelief return true; } -bool Gfx::CTerrain::ReliefAddDot(Math::Vector pos, float scaleRelief) +bool Gfx::CTerrain::AddReliefPoint(Math::Vector pos, float scaleRelief) { - float dim = (m_mosaic*m_brick*m_size)/2.0f; - int size = (m_mosaic*m_brick)+1; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; + int size = (m_mosaicCount*m_brickCount)+1; - pos.x = (pos.x+dim)/m_size; - pos.z = (pos.z+dim)/m_size; + pos.x = (pos.x+dim)/m_brickSize; + pos.z = (pos.z+dim)/m_brickSize; int x = static_cast<int>(pos.x); int y = static_cast<int>(pos.z); @@ -360,33 +324,20 @@ bool Gfx::CTerrain::ReliefAddDot(Math::Vector pos, float scaleRelief) return true; } -void Gfx::CTerrain::LimitPos(Math::Vector &pos) -{ -// TODO: #if _TEEN -// dim = (m_mosaic*m_brick*m_size)/2.0f*0.98f; - - float dim = (m_mosaic*m_brick*m_size)/2.0f*0.92f; - - if (pos.x < -dim) pos.x = -dim; - if (pos.x > dim) pos.x = dim; - if (pos.z < -dim) pos.z = -dim; - if (pos.z > dim) pos.z = dim; -} - void Gfx::CTerrain::AdjustRelief() { - if (m_depth == 1) return; + if (m_depth == 1) return; - int ii = m_mosaic*m_brick+1; + int ii = m_mosaicCount*m_brickCount+1; int b = 1 << (m_depth-1); - for (int y = 0; y < m_mosaic*m_brick; y += b) + for (int y = 0; y < m_mosaicCount*m_brickCount; y += b) { - for (int x = 0; x < m_mosaic*m_brick; x += b) + for (int x = 0; x < m_mosaicCount*m_brickCount; x += b) { int xx = 0; int yy = 0; - if ((y+yy)%m_brick == 0) + if ((y+yy)%m_brickCount == 0) { float level1 = m_relief[(x+0)+(y+yy)*ii]; float level2 = m_relief[(x+b)+(y+yy)*ii]; @@ -397,7 +348,7 @@ void Gfx::CTerrain::AdjustRelief() } yy = b; - if ((y+yy)%m_brick == 0) + if ((y+yy)%m_brickCount == 0) { float level1 = m_relief[(x+0)+(y+yy)*ii]; float level2 = m_relief[(x+b)+(y+yy)*ii]; @@ -408,7 +359,7 @@ void Gfx::CTerrain::AdjustRelief() } xx = 0; - if ((x+xx)%m_brick == 0) + if ((x+xx)%m_brickCount == 0) { float level1 = m_relief[(x+xx)+(y+0)*ii]; float level2 = m_relief[(x+xx)+(y+b)*ii]; @@ -419,7 +370,7 @@ void Gfx::CTerrain::AdjustRelief() } xx = b; - if ((x+xx)%m_brick == 0) + if ((x+xx)%m_brickCount == 0) { float level1 = m_relief[(x+xx)+(y+0)*ii]; float level2 = m_relief[(x+xx)+(y+b)*ii]; @@ -435,14 +386,14 @@ void Gfx::CTerrain::AdjustRelief() Math::Vector Gfx::CTerrain::GetVector(int x, int y) { Math::Vector p; - p.x = x*m_size - (m_mosaic*m_brick*m_size)/2; - p.z = y*m_size - (m_mosaic*m_brick*m_size)/2; + p.x = x*m_brickSize - (m_mosaicCount*m_brickCount*m_brickSize) / 2.0; + p.z = y*m_brickSize - (m_mosaicCount*m_brickCount*m_brickSize) / 2.0; - if ( !m_relief.empty() && - x >= 0 && x <= m_mosaic*m_brick && - y >= 0 && y <= m_mosaic*m_brick ) + if ( !m_relief.empty() && + x >= 0 && x <= m_mosaicCount*m_brickCount && + y >= 0 && y <= m_mosaicCount*m_brickCount ) { - p.y = m_relief[x+y*(m_mosaic*m_brick+1)]; + p.y = m_relief[x+y*(m_mosaicCount*m_brickCount+1)]; } else { @@ -452,7 +403,7 @@ Math::Vector Gfx::CTerrain::GetVector(int x, int y) return p; } -/** Calculates a normal soft, taking into account the six adjacent triangles: +/** Calculates an averaged normal, taking into account the six adjacent triangles: \verbatim ^ y @@ -481,16 +432,16 @@ Gfx::VertexTex2 Gfx::CTerrain::GetVertex(int x, int y, int step) Math::Vector s(0.0f, 0.0f, 0.0f); - if (x-step >= 0 && y+step <= m_mosaic*m_brick+1) + if (x-step >= 0 && y+step <= m_mosaicCount*m_brickCount+1) { s += Math::NormalToPlane(b,a,o); s += Math::NormalToPlane(c,b,o); } - if (x+step <= m_mosaic*m_brick+1 && y+step <= m_mosaic*m_brick+1) + if (x+step <= m_mosaicCount*m_brickCount+1 && y+step <= m_mosaicCount*m_brickCount+1) s += Math::NormalToPlane(d,c,o); - if (x+step <= m_mosaic*m_brick+1 && y-step >= 0) + if (x+step <= m_mosaicCount*m_brickCount+1 && y-step >= 0) { s += Math::NormalToPlane(e,d,o); s += Math::NormalToPlane(f,e,o); @@ -502,19 +453,11 @@ Gfx::VertexTex2 Gfx::CTerrain::GetVertex(int x, int y, int step) s = Normalize(s); v.normal = s; - if (m_multiText) - { - int brick = m_brick/m_subdivMapping; - Math::Vector oo = GetVector((x/brick)*brick, (y/brick)*brick); - o = GetVector(x, y); - v.texCoord.x = (o.x-oo.x)*m_scaleMapping*m_subdivMapping; - v.texCoord.y = 1.0f - (o.z-oo.z)*m_scaleMapping*m_subdivMapping; - } - else - { - v.texCoord.x = o.x*m_scaleMapping; - v.texCoord.y = o.z*m_scaleMapping; - } + int brick = m_brickCount/m_textureSubdivCount; + Math::Vector oo = GetVector((x/brick)*brick, (y/brick)*brick); + o = GetVector(x, y); + v.texCoord.x = (o.x-oo.x)*m_textureScale*m_textureSubdivCount; + v.texCoord.y = 1.0f - (o.z-oo.z)*m_textureScale*m_textureSubdivCount; return v; } @@ -539,7 +482,7 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, if ( step == 1 && m_engine->GetGroundSpot() ) { - int i = (ox/5) + (oy/5)*(m_mosaic/5); + int i = (ox/5) + (oy/5)*(m_mosaicCount/5); std::stringstream s; s << "shadow"; s.width(2); @@ -549,9 +492,9 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, texName2 = s.str(); } - int brick = m_brick/m_subdivMapping; + int brick = m_brickCount/m_textureSubdivCount; - Gfx::VertexTex2 o = GetVertex(ox*m_brick+m_brick/2, oy*m_brick+m_brick/2, step); + Gfx::VertexTex2 o = GetVertex(ox*m_brickCount+m_brickCount/2, oy*m_brickCount+m_brickCount/2, step); int total = ((brick/step)+1)*2; float pixel = 1.0f/256.0f; // 1 pixel cover (*) @@ -559,24 +502,24 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, Math::Point uv; - for (int my = 0; my < m_subdivMapping; my++) + for (int my = 0; my < m_textureSubdivCount; my++) { - for (int mx = 0; mx < m_subdivMapping; mx++) + for (int mx = 0; mx < m_textureSubdivCount; mx++) { - if (m_levelText) + if (m_useMaterials) { - int xx = ox*m_brick + mx*(m_brick/m_subdivMapping); - int yy = oy*m_brick + my*(m_brick/m_subdivMapping); - LevelTextureName(xx, yy, texName1, uv); + int xx = ox*m_brickCount + mx*(m_brickCount/m_textureSubdivCount); + int yy = oy*m_brickCount + my*(m_brickCount/m_textureSubdivCount); + GetTexture(xx, yy, texName1, uv); } else { - int i = (ox*m_subdivMapping+mx)+(oy*m_subdivMapping+my)*m_mosaic; + int i = (ox*m_textureSubdivCount+mx)+(oy*m_textureSubdivCount+my)*m_mosaicCount; std::stringstream s; s << m_texBaseName; s.width(3); s.fill('0'); - s << m_texture[i]; + s << m_textures[i]; s << m_texBaseExt; texName1 = s.str(); } @@ -597,36 +540,33 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, for (int x = 0; x <= brick; x += step) { - Gfx::VertexTex2 p1 = GetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+0 , step); - Gfx::VertexTex2 p2 = GetVertex(ox*m_brick+mx*brick+x, oy*m_brick+my*brick+y+step, step); + Gfx::VertexTex2 p1 = GetVertex(ox*m_brickCount+mx*brick+x, oy*m_brickCount+my*brick+y+0 , step); + Gfx::VertexTex2 p2 = GetVertex(ox*m_brickCount+mx*brick+x, oy*m_brickCount+my*brick+y+step, step); p1.coord.x -= o.coord.x; p1.coord.z -= o.coord.z; p2.coord.x -= o.coord.x; p2.coord.z -= o.coord.z; - if (m_multiText) + if (x == 0) { - if (x == 0) - { - p1.texCoord.x = 0.0f+(0.5f/256.0f); - p2.texCoord.x = 0.0f+(0.5f/256.0f); - } - if (x == brick) - { - p1.texCoord.x = 1.0f-(0.5f/256.0f); - p2.texCoord.x = 1.0f-(0.5f/256.0f); - } - if (y == 0) - p1.texCoord.y = 1.0f-(0.5f/256.0f); - - if (y == brick - step) - p2.texCoord.y = 0.0f+(0.5f/256.0f); + p1.texCoord.x = 0.0f+(0.5f/256.0f); + p2.texCoord.x = 0.0f+(0.5f/256.0f); + } + if (x == brick) + { + p1.texCoord.x = 1.0f-(0.5f/256.0f); + p2.texCoord.x = 1.0f-(0.5f/256.0f); } + if (y == 0) + p1.texCoord.y = 1.0f-(0.5f/256.0f); + + if (y == brick - step) + p2.texCoord.y = 0.0f+(0.5f/256.0f); - if (m_levelText) + if (m_useMaterials) { - p1.texCoord.x /= m_subdivMapping; // 0..1 -> 0..0.25 - p1.texCoord.y /= m_subdivMapping; - p2.texCoord.x /= m_subdivMapping; - p2.texCoord.y /= m_subdivMapping; + p1.texCoord.x /= m_textureSubdivCount; // 0..1 -> 0..0.25 + p1.texCoord.y /= m_textureSubdivCount; + p2.texCoord.x /= m_textureSubdivCount; + p2.texCoord.y /= m_textureSubdivCount; if (x == 0) { @@ -635,11 +575,11 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, } if (x == brick) { - p1.texCoord.x = (1.0f/m_subdivMapping)-dp; - p2.texCoord.x = (1.0f/m_subdivMapping)-dp; + p1.texCoord.x = (1.0f/m_textureSubdivCount)-dp; + p2.texCoord.x = (1.0f/m_textureSubdivCount)-dp; } if (y == 0) - p1.texCoord.y = (1.0f/m_subdivMapping)-dp; + p1.texCoord.y = (1.0f/m_textureSubdivCount)-dp; if (y == brick - step) p2.texCoord.y = 0.0f+dp; @@ -650,12 +590,12 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, p2.texCoord.y += uv.y; } - int xx = mx*(m_brick/m_subdivMapping) + x; - int yy = my*(m_brick/m_subdivMapping) + y; - p1.texCoord2.x = (static_cast<float>(ox%5)*m_brick+xx+0.0f)/(m_brick*5); - p1.texCoord2.y = (static_cast<float>(oy%5)*m_brick+yy+0.0f)/(m_brick*5); - p2.texCoord2.x = (static_cast<float>(ox%5)*m_brick+xx+0.0f)/(m_brick*5); - p2.texCoord2.y = (static_cast<float>(oy%5)*m_brick+yy+1.0f)/(m_brick*5); + int xx = mx*(m_brickCount/m_textureSubdivCount) + x; + int yy = my*(m_brickCount/m_textureSubdivCount) + y; + p1.texCoord2.x = (static_cast<float>(ox%5)*m_brickCount+xx+0.0f)/(m_brickCount*5); + p1.texCoord2.y = (static_cast<float>(oy%5)*m_brickCount+yy+0.0f)/(m_brickCount*5); + p2.texCoord2.x = (static_cast<float>(ox%5)*m_brickCount+xx+0.0f)/(m_brickCount*5); + p2.texCoord2.y = (static_cast<float>(oy%5)*m_brickCount+yy+1.0f)/(m_brickCount*5); // Correction for 1 pixel cover // There is 1 pixel cover around each of the 16 surfaces: @@ -693,40 +633,38 @@ bool Gfx::CTerrain::CreateMosaic(int ox, int oy, int step, int objRank, return true; } -Gfx::TerrainMaterial* Gfx::CTerrain::LevelSearchMat(int id) +Gfx::TerrainMaterial* Gfx::CTerrain::FindMaterial(int id) { - for (int i = 0; i < static_cast<int>( m_levelMats.size() ); i++) + for (int i = 0; i < static_cast<int>( m_materials.size() ); i++) { - if (id == m_levelMats[i].id) - return &m_levelMats[i]; + if (id == m_materials[i].id) + return &m_materials[i]; } return nullptr; } -void Gfx::CTerrain::LevelTextureName(int x, int y, std::string& name, Math::Point &uv) +void Gfx::CTerrain::GetTexture(int x, int y, std::string& name, Math::Point &uv) { - x /= m_brick/m_subdivMapping; - y /= m_brick/m_subdivMapping; + x /= m_brickCount/m_textureSubdivCount; + y /= m_brickCount/m_textureSubdivCount; - TerrainMaterial* tm = LevelSearchMat(m_levelDots[x+y*m_levelDotSize].id); + TerrainMaterial* tm = FindMaterial(m_materialPoints[x+y*m_materialPointCount].id); if (tm == nullptr) { name = "xxx.png"; - uv.x = 0.0f; - uv.y = 0.0f; + uv = Math::Point(0.0f, 0.0f); } else { name = tm->texName; - uv.x = tm->u; - uv.y = tm->v; + uv = tm->uv; } } -float Gfx::CTerrain::LevelGetHeight(int x, int y) +float Gfx::CTerrain::GetHeight(int x, int y) { - int size = (m_mosaic*m_brick+1); + int size = (m_mosaicCount*m_brickCount+1); if (x < 0 ) x = 0; if (x >= size) x = size-1; @@ -736,15 +674,15 @@ float Gfx::CTerrain::LevelGetHeight(int x, int y) return m_relief[x+y*size]; } -bool Gfx::CTerrain::LevelGetDot(int x, int y, float min, float max, float slope) +bool Gfx::CTerrain::CheckMaterialPoint(int x, int y, float min, float max, float slope) { - float hc = LevelGetHeight(x, y); + float hc = GetHeight(x, y); float h[4] = { - LevelGetHeight(x+0, y+1), - LevelGetHeight(x+1, y+0), - LevelGetHeight(x+0, y-1), - LevelGetHeight(x-1, y+0) + GetHeight(x+0, y+1), + GetHeight(x+1, y+0), + GetHeight(x+0, y-1), + GetHeight(x-1, y+0) }; if (hc < min || hc > max) @@ -776,25 +714,22 @@ bool Gfx::CTerrain::LevelGetDot(int x, int y, float min, float max, float slope) return false; } - -/** Returns the index within m_levelMats or -1 if there is not. - m_levelMats[i].id gives the identifier. */ -int Gfx::CTerrain::LevelTestMat(char *mat) +int Gfx::CTerrain::FindMaterialByNeighbors(char *mat) { - for (int i = 0; i < static_cast<int>( m_levelMats.size() ); i++) + for (int i = 0; i < static_cast<int>( m_materials.size() ); i++) { - if ( m_levelMats[i].mat[0] == mat[0] && - m_levelMats[i].mat[1] == mat[1] && - m_levelMats[i].mat[2] == mat[2] && - m_levelMats[i].mat[3] == mat[3] ) return i; + if ( m_materials[i].mat[0] == mat[0] && + m_materials[i].mat[1] == mat[1] && + m_materials[i].mat[2] == mat[2] && + m_materials[i].mat[3] == mat[3] ) return i; } return -1; } -void Gfx::CTerrain::LevelSetDot(int x, int y, int id, char *mat) +void Gfx::CTerrain::SetMaterialPoint(int x, int y, int id, char *mat) { - TerrainMaterial* tm = LevelSearchMat(id); + TerrainMaterial* tm = FindMaterial(id); if (tm == nullptr) return; if ( tm->mat[0] != mat[0] || @@ -802,310 +737,310 @@ void Gfx::CTerrain::LevelSetDot(int x, int y, int id, char *mat) tm->mat[2] != mat[2] || tm->mat[3] != mat[3] ) // id incompatible with mat? { - int ii = LevelTestMat(mat); + int ii = FindMaterialByNeighbors(mat); if (ii == -1) return; - id = m_levelMats[ii].id; // looking for a id compatible with mat + id = m_materials[ii].id; // looking for a id compatible with mat } // Changes the point - m_levelDots[x+y*m_levelDotSize].id = id; - m_levelDots[x+y*m_levelDotSize].mat[0] = mat[0]; - m_levelDots[x+y*m_levelDotSize].mat[1] = mat[1]; - m_levelDots[x+y*m_levelDotSize].mat[2] = mat[2]; - m_levelDots[x+y*m_levelDotSize].mat[3] = mat[3]; + m_materialPoints[x+y*m_materialPointCount].id = id; + m_materialPoints[x+y*m_materialPointCount].mat[0] = mat[0]; + m_materialPoints[x+y*m_materialPointCount].mat[1] = mat[1]; + m_materialPoints[x+y*m_materialPointCount].mat[2] = mat[2]; + m_materialPoints[x+y*m_materialPointCount].mat[3] = mat[3]; // Changes the lower neighbor - if ( (x+0) >= 0 && (x+0) < m_levelDotSize && - (y-1) >= 0 && (y-1) < m_levelDotSize ) + if ( (x+0) >= 0 && (x+0) < m_materialPointCount && + (y-1) >= 0 && (y-1) < m_materialPointCount ) { - int i = (x+0)+(y-1)*m_levelDotSize; - if (m_levelDots[i].mat[0] != mat[2]) + int i = (x+0)+(y-1)*m_materialPointCount; + if (m_materialPoints[i].mat[0] != mat[2]) { - m_levelDots[i].mat[0] = mat[2]; - int ii = LevelTestMat(m_levelDots[i].mat); + m_materialPoints[i].mat[0] = mat[2]; + int ii = FindMaterialByNeighbors(m_materialPoints[i].mat); if (ii != -1) - m_levelDots[i].id = m_levelMats[ii].id; + m_materialPoints[i].id = m_materials[ii].id; } } // Modifies the left neighbor - if ( (x-1) >= 0 && (x-1) < m_levelDotSize && - (y+0) >= 0 && (y+0) < m_levelDotSize ) + if ( (x-1) >= 0 && (x-1) < m_materialPointCount && + (y+0) >= 0 && (y+0) < m_materialPointCount ) { - int i = (x-1)+(y+0)*m_levelDotSize; - if (m_levelDots[i].mat[1] != mat[3]) + int i = (x-1)+(y+0)*m_materialPointCount; + if (m_materialPoints[i].mat[1] != mat[3]) { - m_levelDots[i].mat[1] = mat[3]; - int ii = LevelTestMat(m_levelDots[i].mat); + m_materialPoints[i].mat[1] = mat[3]; + int ii = FindMaterialByNeighbors(m_materialPoints[i].mat); if (ii != -1) - m_levelDots[i].id = m_levelMats[ii].id; + m_materialPoints[i].id = m_materials[ii].id; } } // Changes the upper neighbor - if ( (x+0) >= 0 && (x+0) < m_levelDotSize && - (y+1) >= 0 && (y+1) < m_levelDotSize ) + if ( (x+0) >= 0 && (x+0) < m_materialPointCount && + (y+1) >= 0 && (y+1) < m_materialPointCount ) { - int i = (x+0)+(y+1)*m_levelDotSize; - if (m_levelDots[i].mat[2] != mat[0]) + int i = (x+0)+(y+1)*m_materialPointCount; + if (m_materialPoints[i].mat[2] != mat[0]) { - m_levelDots[i].mat[2] = mat[0]; - int ii = LevelTestMat(m_levelDots[i].mat); + m_materialPoints[i].mat[2] = mat[0]; + int ii = FindMaterialByNeighbors(m_materialPoints[i].mat); if (ii != -1) - m_levelDots[i].id = m_levelMats[ii].id; + m_materialPoints[i].id = m_materials[ii].id; } } // Changes the right neighbor - if ( (x+1) >= 0 && (x+1) < m_levelDotSize && - (y+0) >= 0 && (y+0) < m_levelDotSize ) + if ( (x+1) >= 0 && (x+1) < m_materialPointCount && + (y+0) >= 0 && (y+0) < m_materialPointCount ) { - int i = (x+1)+(y+0)*m_levelDotSize; - if ( m_levelDots[i].mat[3] != mat[1] ) + int i = (x+1)+(y+0)*m_materialPointCount; + if ( m_materialPoints[i].mat[3] != mat[1] ) { - m_levelDots[i].mat[3] = mat[1]; - int ii = LevelTestMat(m_levelDots[i].mat); + m_materialPoints[i].mat[3] = mat[1]; + int ii = FindMaterialByNeighbors(m_materialPoints[i].mat); if (ii != -1) - m_levelDots[i].id = m_levelMats[ii].id; + m_materialPoints[i].id = m_materials[ii].id; } } } -bool Gfx::CTerrain::LevelIfDot(int x, int y, int id, char *mat) +bool Gfx::CTerrain::CondChangeMaterialPoint(int x, int y, int id, char *mat) { char test[4]; // Compatible with lower neighbor? - if ( x+0 >= 0 && x+0 < m_levelDotSize && - y-1 >= 0 && y-1 < m_levelDotSize ) + if ( x+0 >= 0 && x+0 < m_materialPointCount && + y-1 >= 0 && y-1 < m_materialPointCount ) { test[0] = mat[2]; - test[1] = m_levelDots[(x+0)+(y-1)*m_levelDotSize].mat[1]; - test[2] = m_levelDots[(x+0)+(y-1)*m_levelDotSize].mat[2]; - test[3] = m_levelDots[(x+0)+(y-1)*m_levelDotSize].mat[3]; + test[1] = m_materialPoints[(x+0)+(y-1)*m_materialPointCount].mat[1]; + test[2] = m_materialPoints[(x+0)+(y-1)*m_materialPointCount].mat[2]; + test[3] = m_materialPoints[(x+0)+(y-1)*m_materialPointCount].mat[3]; - if ( LevelTestMat(test) == -1 ) return false; + if ( FindMaterialByNeighbors(test) == -1 ) return false; } // Compatible with left neighbor? - if ( x-1 >= 0 && x-1 < m_levelDotSize && - y+0 >= 0 && y+0 < m_levelDotSize ) + if ( x-1 >= 0 && x-1 < m_materialPointCount && + y+0 >= 0 && y+0 < m_materialPointCount ) { - test[0] = m_levelDots[(x-1)+(y+0)*m_levelDotSize].mat[0]; + test[0] = m_materialPoints[(x-1)+(y+0)*m_materialPointCount].mat[0]; test[1] = mat[3]; - test[2] = m_levelDots[(x-1)+(y+0)*m_levelDotSize].mat[2]; - test[3] = m_levelDots[(x-1)+(y+0)*m_levelDotSize].mat[3]; + test[2] = m_materialPoints[(x-1)+(y+0)*m_materialPointCount].mat[2]; + test[3] = m_materialPoints[(x-1)+(y+0)*m_materialPointCount].mat[3]; - if ( LevelTestMat(test) == -1 ) return false; + if ( FindMaterialByNeighbors(test) == -1 ) return false; } // Compatible with upper neighbor? - if ( x+0 >= 0 && x+0 < m_levelDotSize && - y+1 >= 0 && y+1 < m_levelDotSize ) + if ( x+0 >= 0 && x+0 < m_materialPointCount && + y+1 >= 0 && y+1 < m_materialPointCount ) { - test[0] = m_levelDots[(x+0)+(y+1)*m_levelDotSize].mat[0]; - test[1] = m_levelDots[(x+0)+(y+1)*m_levelDotSize].mat[1]; + test[0] = m_materialPoints[(x+0)+(y+1)*m_materialPointCount].mat[0]; + test[1] = m_materialPoints[(x+0)+(y+1)*m_materialPointCount].mat[1]; test[2] = mat[0]; - test[3] = m_levelDots[(x+0)+(y+1)*m_levelDotSize].mat[3]; + test[3] = m_materialPoints[(x+0)+(y+1)*m_materialPointCount].mat[3]; - if ( LevelTestMat(test) == -1 ) return false; + if ( FindMaterialByNeighbors(test) == -1 ) return false; } // Compatible with right neighbor? - if ( x+1 >= 0 && x+1 < m_levelDotSize && - y+0 >= 0 && y+0 < m_levelDotSize ) + if ( x+1 >= 0 && x+1 < m_materialPointCount && + y+0 >= 0 && y+0 < m_materialPointCount ) { - test[0] = m_levelDots[(x+1)+(y+0)*m_levelDotSize].mat[0]; - test[1] = m_levelDots[(x+1)+(y+0)*m_levelDotSize].mat[1]; - test[2] = m_levelDots[(x+1)+(y+0)*m_levelDotSize].mat[2]; + test[0] = m_materialPoints[(x+1)+(y+0)*m_materialPointCount].mat[0]; + test[1] = m_materialPoints[(x+1)+(y+0)*m_materialPointCount].mat[1]; + test[2] = m_materialPoints[(x+1)+(y+0)*m_materialPointCount].mat[2]; test[3] = mat[1]; - if ( LevelTestMat(test) == -1 ) return false; + if ( FindMaterialByNeighbors(test) == -1 ) return false; } - LevelSetDot(x, y, id, mat); // puts the point + SetMaterialPoint(x, y, id, mat); // puts the point return true; } -bool Gfx::CTerrain::LevelPutDot(int x, int y, int id) +bool Gfx::CTerrain::ChangeMaterialPoint(int x, int y, int id) { char mat[4]; - x /= m_brick/m_subdivMapping; - y /= m_brick/m_subdivMapping; + x /= m_brickCount/m_textureSubdivCount; + y /= m_brickCount/m_textureSubdivCount; - if ( x < 0 || x >= m_levelDotSize || - y < 0 || y >= m_levelDotSize ) return false; + if ( x < 0 || x >= m_materialPointCount || + y < 0 || y >= m_materialPointCount ) return false; - TerrainMaterial* tm = LevelSearchMat(id); + TerrainMaterial* tm = FindMaterial(id); if (tm == nullptr) return false; // Tries without changing neighbors. - if ( LevelIfDot(x, y, id, tm->mat) ) return true; + if ( CondChangeMaterialPoint(x, y, id, tm->mat) ) return true; // Tries changing a single neighbor (4x). - for (int up = 0; up < m_levelMatMax; up++) + for (int up = 0; up < m_maxMaterialID; up++) { mat[0] = up; mat[1] = tm->mat[1]; mat[2] = tm->mat[2]; mat[3] = tm->mat[3]; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } - for (int right = 0; right < m_levelMatMax; right++) + for (int right = 0; right < m_maxMaterialID; right++) { mat[0] = tm->mat[0]; mat[1] = right; mat[2] = tm->mat[2]; mat[3] = tm->mat[3]; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } - for (int down = 0; down < m_levelMatMax; down++) + for (int down = 0; down < m_maxMaterialID; down++) { mat[0] = tm->mat[0]; mat[1] = tm->mat[1]; mat[2] = down; mat[3] = tm->mat[3]; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } - for (int left = 0; left < m_levelMatMax; left++) + for (int left = 0; left < m_maxMaterialID; left++) { mat[0] = tm->mat[0]; mat[1] = tm->mat[1]; mat[2] = tm->mat[2]; mat[3] = left; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } // Tries changing two neighbors (6x). - for (int up = 0; up < m_levelMatMax; up++) + for (int up = 0; up < m_maxMaterialID; up++) { - for (int down = 0; down < m_levelMatMax; down++) + for (int down = 0; down < m_maxMaterialID; down++) { mat[0] = up; mat[1] = tm->mat[1]; mat[2] = down; mat[3] = tm->mat[3]; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } } - for (int right = 0; right < m_levelMatMax; right++) + for (int right = 0; right < m_maxMaterialID; right++) { - for (int left = 0; left < m_levelMatMax; left++) + for (int left = 0; left < m_maxMaterialID; left++) { mat[0] = tm->mat[0]; mat[1] = right; mat[2] = tm->mat[2]; mat[3] = left; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } } - for (int up = 0; up < m_levelMatMax; up++) + for (int up = 0; up < m_maxMaterialID; up++) { - for (int right = 0; right < m_levelMatMax; right++) + for (int right = 0; right < m_maxMaterialID; right++) { mat[0] = up; mat[1] = right; mat[2] = tm->mat[2]; mat[3] = tm->mat[3]; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } } - for (int right = 0; right < m_levelMatMax; right++) + for (int right = 0; right < m_maxMaterialID; right++) { - for (int down = 0; down < m_levelMatMax; down++) + for (int down = 0; down < m_maxMaterialID; down++) { mat[0] = tm->mat[0]; mat[1] = right; mat[2] = down; mat[3] = tm->mat[3]; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } } - for (int down = 0; down < m_levelMatMax; down++) + for (int down = 0; down < m_maxMaterialID; down++) { - for (int left = 0; left < m_levelMatMax; left++) + for (int left = 0; left < m_maxMaterialID; left++) { mat[0] = tm->mat[0]; mat[1] = tm->mat[1]; mat[2] = down; mat[3] = left; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } } - for (int up = 0; up < m_levelMatMax; up++) + for (int up = 0; up < m_maxMaterialID; up++) { - for (int left = 0; left < m_levelMatMax; left++) + for (int left = 0; left < m_maxMaterialID; left++) { mat[0] = up; mat[1] = tm->mat[1]; mat[2] = tm->mat[2]; mat[3] = left; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } } // Tries changing all the neighbors. - for (int up = 0; up < m_levelMatMax; up++) + for (int up = 0; up < m_maxMaterialID; up++) { - for (int right = 0; right < m_levelMatMax; right++) + for (int right = 0; right < m_maxMaterialID; right++) { - for (int down = 0; down < m_levelMatMax; down++) + for (int down = 0; down < m_maxMaterialID; down++) { - for (int left = 0; left < m_levelMatMax; left++) + for (int left = 0; left < m_maxMaterialID; left++) { mat[0] = up; mat[1] = right; mat[2] = down; mat[3] = left; - if (LevelIfDot(x, y, id, mat)) return true; + if (CondChangeMaterialPoint(x, y, id, mat)) return true; } } } } - GetLogger()->Error("LevelPutDot error\n"); + GetLogger()->Error("AddMaterialPoint error\n"); return false; } -bool Gfx::CTerrain::LevelInit(int id) +bool Gfx::CTerrain::InitMaterials(int id) { - TerrainMaterial* tm = LevelSearchMat(id); + TerrainMaterial* tm = FindMaterial(id); if (tm == nullptr) return false; - for (int i = 0; i < m_levelDotSize*m_levelDotSize; i++) + for (int i = 0; i < m_materialPointCount*m_materialPointCount; i++) { - m_levelDots[i].id = id; + m_materialPoints[i].id = id; for (int j = 0; j < 4; j++) - m_levelDots[i].mat[j] = tm->mat[j]; + m_materialPoints[i].mat[j] = tm->mat[j]; } return true; } -bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max, - float slope, float freq, - Math::Vector center, float radius) +bool Gfx::CTerrain::GenerateMaterials(int *id, float min, float max, + float slope, float freq, + Math::Vector center, float radius) { static char random[100] = { @@ -1124,40 +1059,40 @@ bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max, TerrainMaterial* tm = nullptr; int i = 0; - while ( id[i] != 0 ) + while (id[i] != 0) { - tm = LevelSearchMat(id[i++]); - if (tm == nullptr) return false; + tm = FindMaterial(id[i++]); + if (tm == nullptr) return false; } int numID = i; - int group = m_brick / m_subdivMapping; + int group = m_brickCount / m_textureSubdivCount; if (radius > 0.0f && radius < 5.0f) // just a square? { - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; - int xx = static_cast<int>((center.x+dim)/m_size); - int yy = static_cast<int>((center.z+dim)/m_size); + int xx = static_cast<int>((center.x+dim)/m_brickSize); + int yy = static_cast<int>((center.z+dim)/m_brickSize); int x = xx/group; int y = yy/group; - tm = LevelSearchMat(id[0]); + tm = FindMaterial(id[0]); if (tm != nullptr) - LevelSetDot(x, y, id[0], tm->mat); // puts the point + SetMaterialPoint(x, y, id[0], tm->mat); // puts the point } else { - for (int y = 0; y < m_levelDotSize; y++) + for (int y = 0; y < m_materialPointCount; y++) { - for (int x = 0; x < m_levelDotSize; x++) + for (int x = 0; x < m_materialPointCount; x++) { if (radius != 0.0f) { Math::Vector pos; - pos.x = (static_cast<float>(x)-m_levelDotSize/2.0f)*group*m_size; - pos.z = (static_cast<float>(y)-m_levelDotSize/2.0f)*group*m_size; + pos.x = (static_cast<float>(x)-m_materialPointCount/2.0f)*group*m_brickSize; + pos.z = (static_cast<float>(y)-m_materialPointCount/2.0f)*group*m_brickSize; if (Math::DistanceProjected(pos, center) > radius) continue; } @@ -1170,11 +1105,11 @@ bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max, int xx = x*group + group/2; int yy = y*group + group/2; - if (LevelGetDot(xx, yy, min, max, slope)) + if (CheckMaterialPoint(xx, yy, min, max, slope)) { int rnd = random[(x%10)+(y%10)*10]; int ii = rnd % numID; - LevelPutDot(xx, yy, id[ii]); + ChangeMaterialPoint(xx, yy, id[ii]); } } } @@ -1183,66 +1118,59 @@ bool Gfx::CTerrain::LevelGenerate(int *id, float min, float max, return true; } -void Gfx::CTerrain::LevelOpenTable() +void Gfx::CTerrain::InitMaterialPoints() { - if (! m_levelText) return; - if (! m_levelDots.empty()) return; // already allocated + if (! m_useMaterials) return; + if (! m_materialPoints.empty()) return; // already allocated - m_levelDotSize = (m_mosaic*m_brick)/(m_brick/m_subdivMapping)+1; - std::vector<Gfx::DotLevel>(m_levelDotSize*m_levelDotSize).swap(m_levelDots); + m_materialPointCount = (m_mosaicCount*m_brickCount)/(m_brickCount/m_textureSubdivCount)+1; + std::vector<Gfx::TerrainMaterialPoint>(m_materialPointCount*m_materialPointCount).swap(m_materialPoints); - for (int i = 0; i < m_levelDotSize * m_levelDotSize; i++) + for (int i = 0; i < m_materialPointCount * m_materialPointCount; i++) { for (int j = 0; j < 4; j++) - m_levelDots[i].mat[j] = 0; + m_materialPoints[i].mat[j] = 0; } } -void Gfx::CTerrain::LevelCloseTable() +void Gfx::CTerrain::FlushMaterialPoints() { - m_levelDots.clear(); + m_materialPoints.clear(); } -bool Gfx::CTerrain::CreateSquare(bool multiRes, int x, int y) +bool Gfx::CTerrain::CreateSquare(int x, int y) { Gfx::Material mat; mat.diffuse = Gfx::Color(1.0f, 1.0f, 1.0f); mat.ambient = Gfx::Color(0.0f, 0.0f, 0.0f); int objRank = m_engine->CreateObject(); - m_engine->SetObjectType(objRank, Gfx::ENG_OBJTYPE_TERRAIN); // it is a terrain + m_engine->SetObjectType(objRank, Gfx::ENG_OBJTYPE_TERRAIN); - m_objRank[x+y*m_mosaic] = objRank; + m_objRanks[x+y*m_mosaicCount] = objRank; - if (multiRes) + float min = 0.0f; + float max = m_vision; + max *= m_engine->GetClippingDistance(); + for (int step = 0; step < m_depth; step++) { - float min = 0.0f; - float max = m_vision; - max *= m_engine->GetClippingDistance(); - for (int step = 0; step < m_depth; step++) - { - CreateMosaic(x, y, 1 << step, objRank, mat, min, max); - min = max; - max *= 2; - if (step == m_depth-1) max = Math::HUGE_NUM; - } - } - else - { - CreateMosaic(x, y, 1, objRank, mat, 0.0f, Math::HUGE_NUM); + CreateMosaic(x, y, 1 << step, objRank, mat, min, max); + min = max; + max *= 2; + if (step == m_depth-1) max = Math::HUGE_NUM; } return true; } -bool Gfx::CTerrain::CreateObjects(bool multiRes) +bool Gfx::CTerrain::CreateObjects() { AdjustRelief(); - for (int y = 0; y < m_mosaic; y++) + for (int y = 0; y < m_mosaicCount; y++) { - for (int x = 0; x < m_mosaic; x++) - CreateSquare(multiRes, x, y); + for (int x = 0; x < m_mosaicCount; x++) + CreateSquare(x, y); } return true; @@ -1251,29 +1179,29 @@ bool Gfx::CTerrain::CreateObjects(bool multiRes) /** ATTENTION: ok only with m_depth = 2! */ bool Gfx::CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, float height) { - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; Math::IntPoint tp1, tp2; - tp1.x = static_cast<int>((p1.x+dim+m_size/2.0f)/m_size); - tp1.y = static_cast<int>((p1.z+dim+m_size/2.0f)/m_size); - tp2.x = static_cast<int>((p2.x+dim+m_size/2.0f)/m_size); - tp2.y = static_cast<int>((p2.z+dim+m_size/2.0f)/m_size); + tp1.x = static_cast<int>((p1.x+dim+m_brickSize/2.0f)/m_brickSize); + tp1.y = static_cast<int>((p1.z+dim+m_brickSize/2.0f)/m_brickSize); + tp2.x = static_cast<int>((p2.x+dim+m_brickSize/2.0f)/m_brickSize); + tp2.y = static_cast<int>((p2.z+dim+m_brickSize/2.0f)/m_brickSize); if (tp1.x > tp2.x) { - int x = tp1.x; + int x = tp1.x; tp1.x = tp2.x; tp2.x = x; } if (tp1.y > tp2.y) { - int y = tp1.y; + int y = tp1.y; tp1.y = tp2.y; tp2.y = y; } - int size = (m_mosaic*m_brick)+1; + int size = (m_mosaicCount*m_brickCount)+1; // Calculates the current average height float avg = 0.0f; @@ -1295,13 +1223,13 @@ bool Gfx::CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, fl { m_relief[x+y*size] = avg+height; - if (x % m_brick == 0 && y % m_depth != 0) + if (x % m_brickCount == 0 && y % m_depth != 0) { m_relief[(x+0)+(y-1)*size] = avg+height; m_relief[(x+0)+(y+1)*size] = avg+height; } - if (y % m_brick == 0 && x % m_depth != 0) + if (y % m_brickCount == 0 && x % m_depth != 0) { m_relief[(x-1)+(y+0)*size] = avg+height; m_relief[(x+1)+(y+0)*size] = avg+height; @@ -1311,22 +1239,22 @@ bool Gfx::CTerrain::Terraform(const Math::Vector &p1, const Math::Vector &p2, fl AdjustRelief(); Math::IntPoint pp1, pp2; - pp1.x = (tp1.x-2)/m_brick; - pp1.y = (tp1.y-2)/m_brick; - pp2.x = (tp2.x+1)/m_brick; - pp2.y = (tp2.y+1)/m_brick; + pp1.x = (tp1.x-2)/m_brickCount; + pp1.y = (tp1.y-2)/m_brickCount; + pp2.x = (tp2.x+1)/m_brickCount; + pp2.y = (tp2.y+1)/m_brickCount; - if (pp1.x < 0 ) pp1.x = 0; - if (pp1.x >= m_mosaic) pp1.x = m_mosaic-1; - if (pp1.y < 0 ) pp1.y = 0; - if (pp1.y >= m_mosaic) pp1.y = m_mosaic-1; + if (pp1.x < 0 ) pp1.x = 0; + if (pp1.x >= m_mosaicCount) pp1.x = m_mosaicCount-1; + if (pp1.y < 0 ) pp1.y = 0; + if (pp1.y >= m_mosaicCount) pp1.y = m_mosaicCount-1; for (int y = pp1.y; y <= pp2.y; y++) { for (int x = pp1.x; x <= pp2.x; x++) { - m_engine->DeleteObject(m_objRank[x+y*m_mosaic]); - CreateSquare(m_multiText, x, y); // recreates the square + m_engine->DeleteObject(m_objRanks[x+y*m_mosaicCount]); + CreateSquare(x, y); // recreates the square } } m_engine->Update(); @@ -1355,37 +1283,37 @@ float Gfx::CTerrain::GetCoarseSlope(const Math::Vector &pos) { if (m_relief.empty()) return 0.0f; - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; - int x = static_cast<int>((pos.x+dim)/m_size); - int y = static_cast<int>((pos.z+dim)/m_size); + int x = static_cast<int>((pos.x+dim)/m_brickSize); + int y = static_cast<int>((pos.z+dim)/m_brickSize); - if ( x < 0 || x >= m_mosaic*m_brick || - y < 0 || y >= m_mosaic*m_brick ) return 0.0f; + if ( x < 0 || x >= m_mosaicCount*m_brickCount || + y < 0 || y >= m_mosaicCount*m_brickCount ) return 0.0f; float level[4] = { - m_relief[(x+0)+(y+0)*(m_mosaic*m_brick+1)], - m_relief[(x+1)+(y+0)*(m_mosaic*m_brick+1)], - m_relief[(x+0)+(y+1)*(m_mosaic*m_brick+1)], - m_relief[(x+1)+(y+1)*(m_mosaic*m_brick+1)], + m_relief[(x+0)+(y+0)*(m_mosaicCount*m_brickCount+1)], + m_relief[(x+1)+(y+0)*(m_mosaicCount*m_brickCount+1)], + m_relief[(x+0)+(y+1)*(m_mosaicCount*m_brickCount+1)], + m_relief[(x+1)+(y+1)*(m_mosaicCount*m_brickCount+1)], }; float min = Math::Min(level[0], level[1], level[2], level[3]); float max = Math::Max(level[0], level[1], level[2], level[3]); - return atanf((max-min)/m_size); + return atanf((max-min)/m_brickSize); } bool Gfx::CTerrain::GetNormal(Math::Vector &n, const Math::Vector &p) { - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; - int x = static_cast<int>((p.x+dim)/m_size); - int y = static_cast<int>((p.z+dim)/m_size); + int x = static_cast<int>((p.x+dim)/m_brickSize); + int y = static_cast<int>((p.z+dim)/m_brickSize); - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return false; + if ( x < 0 || x > m_mosaicCount*m_brickCount || + y < 0 || y > m_mosaicCount*m_brickCount ) return false; Math::Vector p1 = GetVector(x+0, y+0); Math::Vector p2 = GetVector(x+1, y+0); @@ -1400,23 +1328,23 @@ bool Gfx::CTerrain::GetNormal(Math::Vector &n, const Math::Vector &p) return true; } -float Gfx::CTerrain::GetFloorLevel(const Math::Vector &p, bool brut, bool water) +float Gfx::CTerrain::GetFloorLevel(const Math::Vector &pos, bool brut, bool water) { - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; - int x = static_cast<int>((p.x+dim)/m_size); - int y = static_cast<int>((p.z+dim)/m_size); + int x = static_cast<int>((pos.x+dim)/m_brickSize); + int y = static_cast<int>((pos.z+dim)/m_brickSize); - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return false; + if ( x < 0 || x > m_mosaicCount*m_brickCount || + y < 0 || y > m_mosaicCount*m_brickCount ) return false; Math::Vector p1 = GetVector(x+0, y+0); Math::Vector p2 = GetVector(x+1, y+0); Math::Vector p3 = GetVector(x+0, y+1); Math::Vector p4 = GetVector(x+1, y+1); - Math::Vector ps = p; - if ( fabs(p.z-p2.z) < fabs(p.x-p2.x) ) + Math::Vector ps = pos; + if ( fabs(pos.z-p2.z) < fabs(pos.x-p2.x) ) { if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; } @@ -1436,25 +1364,23 @@ float Gfx::CTerrain::GetFloorLevel(const Math::Vector &p, bool brut, bool water) return ps.y; } - -/** This height is positive when you are above the ground */ -float Gfx::CTerrain::GetFloorHeight(const Math::Vector &p, bool brut, bool water) +float Gfx::CTerrain::GetHeightToFloor(const Math::Vector &pos, bool brut, bool water) { - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; - int x = static_cast<int>((p.x+dim)/m_size); - int y = static_cast<int>((p.z+dim)/m_size); + int x = static_cast<int>((pos.x+dim)/m_brickSize); + int y = static_cast<int>((pos.z+dim)/m_brickSize); - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return false; + if ( x < 0 || x > m_mosaicCount*m_brickCount || + y < 0 || y > m_mosaicCount*m_brickCount ) return false; Math::Vector p1 = GetVector(x+0, y+0); Math::Vector p2 = GetVector(x+1, y+0); Math::Vector p3 = GetVector(x+0, y+1); Math::Vector p4 = GetVector(x+1, y+1); - Math::Vector ps = p; - if ( fabs(p.z-p2.z) < fabs(p.x-p2.x) ) + Math::Vector ps = pos; + if ( fabs(pos.z-p2.z) < fabs(pos.x-p2.x) ) { if ( !IntersectY(p1, p2, p3, ps) ) return 0.0f; } @@ -1468,76 +1394,114 @@ float Gfx::CTerrain::GetFloorHeight(const Math::Vector &p, bool brut, bool water if (water) // not going underwater? { float level = m_water->GetLevel(); - if ( ps.y < level ) ps.y = level; // not under water + if (ps.y < level ) ps.y = level; // not under water } - return p.y-ps.y; + return pos.y-ps.y; } -bool Gfx::CTerrain::MoveOnFloor(Math::Vector &p, bool brut, bool water) +bool Gfx::CTerrain::AdjustToFloor(Math::Vector &pos, bool brut, bool water) { - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; - int x = static_cast<int>((p.x + dim) / m_size); - int y = static_cast<int>((p.z + dim) / m_size); + int x = static_cast<int>((pos.x + dim) / m_brickSize); + int y = static_cast<int>((pos.z + dim) / m_brickSize); - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return false; + if ( x < 0 || x > m_mosaicCount*m_brickCount || + y < 0 || y > m_mosaicCount*m_brickCount ) return false; Math::Vector p1 = GetVector(x+0, y+0); Math::Vector p2 = GetVector(x+1, y+0); Math::Vector p3 = GetVector(x+0, y+1); Math::Vector p4 = GetVector(x+1, y+1); - if (fabs(p.z - p2.z) < fabs(p.x - p2.x)) + if (fabs(pos.z - p2.z) < fabs(pos.x - p2.x)) { - if (! Math::IntersectY(p1, p2, p3, p)) return false; + if (! Math::IntersectY(p1, p2, p3, pos)) return false; } else { - if (! Math::IntersectY(p2, p4, p3, p)) return false; + if (! Math::IntersectY(p2, p4, p3, pos)) return false; } - if (! brut) AdjustBuildingLevel(p); + if (! brut) AdjustBuildingLevel(pos); if (water) // not going underwater? { float level = m_water->GetLevel(); - if (p.y < level) p.y = level; // not under water + if (pos.y < level) pos.y = level; // not under water } return true; } - -/** Returns false if the initial coordinate was too far */ -bool Gfx::CTerrain::ValidPosition(Math::Vector &p, float marging) +/** + * @returns \c false if the initial coordinate was outside terrain area; \c true otherwise + */ +bool Gfx::CTerrain::AdjustToStandardBounds(Math::Vector& pos) { bool ok = true; - float limit = m_mosaic*m_brick*m_size/2.0f - marging; + // TODO: _TEEN ... * 0.98f; + float limit = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f*0.92f; - if (p.x < -limit) + if (pos.x < -limit) { - p.x = -limit; + pos.x = -limit; ok = false; } - if (p.z < -limit) + if (pos.z < -limit) { - p.z = -limit; + pos.z = -limit; ok = false; } - if (p.x > limit) + if (pos.x > limit) { - p.x = limit; + pos.x = limit; ok = false; } - if (p.z > limit) + if (pos.z > limit) { - p.z = limit; + pos.z = limit; + ok = false; + } + + return ok; +} + +/** + * @param margin margin to the terrain border + * @returns \c false if the initial coordinate was outside terrain area; \c true otherwise + */ +bool Gfx::CTerrain::AdjustToBounds(Math::Vector& pos, float margin) +{ + bool ok = true; + float limit = m_mosaicCount*m_brickCount*m_brickSize/2.0f - margin; + + if (pos.x < -limit) + { + pos.x = -limit; + ok = false; + } + + if (pos.z < -limit) + { + pos.z = -limit; + ok = false; + } + + if (pos.x > limit) + { + pos.x = limit; + ok = false; + } + + if (pos.z > limit) + { + pos.z = limit; ok = false; } @@ -1664,46 +1628,41 @@ void Gfx::CTerrain::AdjustBuildingLevel(Math::Vector &p) } } - -// returns the hardness of the ground in a given place. -// The hardness determines the noise (SOUND_STEP and SOUND_BOUM). - float Gfx::CTerrain::GetHardness(const Math::Vector &p) { float factor = GetBuildingFactor(p); - if (factor != 1.0f) return 1.0f; // on building + if (factor != 1.0f) return 1.0f; // on building level - if (m_levelDots.empty()) return m_defHardness; + if (m_materialPoints.empty()) return m_defaultHardness; - float dim = (m_mosaic*m_brick*m_size)/2.0f; + float dim = (m_mosaicCount*m_brickCount*m_brickSize)/2.0f; int x, y; - x = static_cast<int>((p.x+dim)/m_size); - y = static_cast<int>((p.z+dim)/m_size); + x = static_cast<int>((p.x+dim)/m_brickSize); + y = static_cast<int>((p.z+dim)/m_brickSize); - if ( x < 0 || x > m_mosaic*m_brick || - y < 0 || y > m_mosaic*m_brick ) return m_defHardness; + if ( x < 0 || x > m_mosaicCount*m_brickCount || + y < 0 || y > m_mosaicCount*m_brickCount ) return m_defaultHardness; - x /= m_brick/m_subdivMapping; - y /= m_brick/m_subdivMapping; + x /= m_brickCount/m_textureSubdivCount; + y /= m_brickCount/m_textureSubdivCount; - if ( x < 0 || x >= m_levelDotSize || - y < 0 || y >= m_levelDotSize ) return m_defHardness; + if ( x < 0 || x >= m_materialPointCount || + y < 0 || y >= m_materialPointCount ) return m_defaultHardness; - int id = m_levelDots[x+y*m_levelDotSize].id; - TerrainMaterial* tm = LevelSearchMat(id); - if (tm == nullptr) return m_defHardness; + int id = m_materialPoints[x+y*m_materialPointCount].id; + TerrainMaterial* tm = FindMaterial(id); + if (tm == nullptr) return m_defaultHardness; return tm->hardness; } -void Gfx::CTerrain::GroundFlat(Math::Vector pos) +void Gfx::CTerrain::ShowFlatGround(Math::Vector pos) { - static char table[41*41]; - + static char table[41*41] = { 1 }; - float rapport = 3200.0f/1024.0f; + float radius = 3200.0f/1024.0f; for (int y = 0; y <= 40; y++) { @@ -1713,16 +1672,16 @@ void Gfx::CTerrain::GroundFlat(Math::Vector pos) table[i] = 0; Math::Vector p; - p.x = (x-20)*rapport; - p.z = (y-20)*rapport; + p.x = (x-20)*radius; + p.z = (y-20)*radius; p.y = 0.0f; - if (Math::Point(p.x, p.y).Length() > 20.0f*rapport) + if (Math::Point(p.x, p.y).Length() > 20.0f*radius) continue; float angle = GetFineSlope(pos+p); - if (angle < FLATLIMIT) + if (angle < Gfx::TERRAIN_FLATLIMIT) table[i] = 1; else table[i] = 2; @@ -1735,7 +1694,7 @@ void Gfx::CTerrain::GroundFlat(Math::Vector pos) float Gfx::CTerrain::GetFlatZoneRadius(Math::Vector center, float max) { float angle = GetFineSlope(center); - if (angle >= Gfx::FLATLIMIT) + if (angle >= Gfx::TERRAIN_FLATLIMIT) return 0.0f; float ref = GetFloorLevel(center, true); diff --git a/src/graphics/engine/terrain.h b/src/graphics/engine/terrain.h index 24bd1f9..80eed07 100644 --- a/src/graphics/engine/terrain.h +++ b/src/graphics/engine/terrain.h @@ -35,7 +35,7 @@ class CWater; //! Limit of slope considered a flat piece of land -const short FLATLIMIT = (5.0f*Math::PI/180.0f); +const short TERRAIN_FLATLIMIT = (5.0f*Math::PI/180.0f); /** @@ -61,6 +61,10 @@ enum TerrainRes //@} }; +/** + * \struct BuildingLevel + * \brief Flat level for building + */ struct BuildingLevel { Math::Vector center; @@ -81,29 +85,43 @@ struct BuildingLevel } }; +/** + * \struct TerrainMaterial + * \brief Material for ground surface + */ struct TerrainMaterial { + //! Unique ID short id; + //! Texture std::string texName; - float u,v; + //! UV texture coordinates + Math::Point uv; + //! Terrain hardness (defines e.g. sound of walking) float hardness; - char mat[4]; // up, right, down, left + //! IDs of neighbor materials: up, right, down, left + char mat[4]; TerrainMaterial() { id = 0; - u = v = 0.0f; hardness = 0.0f; mat[0] = mat[1] = mat[2] = mat[3] = 0; } }; -struct DotLevel +/** + * \struct TerrainMaterialPoint + * \brief Material used for terrain point + */ +struct TerrainMaterialPoint { + //! ID of material short id; - char mat[4]; // up, right, down, left + //! IDs of neighbor materials: up, right, down, left + char mat[4]; - DotLevel() + TerrainMaterialPoint() { id = 0; mat[0] = mat[1] = mat[2] = mat[3] = 0; @@ -132,17 +150,73 @@ struct FlyingLimit * \class CTerrain * \brief Terrain loader/generator and manager * + * \section Mapping Terrain mapping + * * Terrain is created from relief textures specifying a XY plane with height * values which are then scaled and translated into XZ surface forming the * terrain of game level. * - * The class also facilitates creating and searching for flat space expanses - * for construction of buildings. + * The basic unit of terrain is called "brick", which is two triangles + * forming a quad. Bricks have constant size (brick size) + * in X and Z direction. + * Points forming the bricks correspond one-to-one to relief data points + * (pixels in relief image). + * + * Bricks are grouped into "mosaics". Mosaic is a square containing + * brickCount x brickCount bricks where brickCount is an even power of 2. + * Each mosaic corresponds to one created engine object. + * + * The whole terrain is also a square formed by mosaicCount * mosaicCount + * of mosaics. + * + * Image coordinates are converted in the following way to world coordinates + * of brick points (Wx, Wy, Wz - world coordinates, Ix, Iy - image coordinates, + * Pxy - pixel value at Ix,Iy): + * + * Wx = (Ix - brickCount*mosaicCount / 2.0f) * brickSize \n + * Wz = (Iy - brickCount*mosaicCount / 2.0f) * brickSize \n + * Wy = (Pxy / 255.0f) * reliefScale + * + * To create and initialize a terrain, you must call Generate() as the first function, + * setting the number of bricks, mosaics etc. + * + * \section Materials Materials and textures + * + * The terrain can be textured in two ways: + * - by applying texture index table + * - by specifying one or more "materials" that cover "material points" + * + * Textures are applied to subdivisions of mosaics (groups of bricks of size + * brickCount / textureSubdivCount). + * + * \subsection TextureIndexes Texture indexes + * + * Texture indexes specify the texture for each textured point by concatenating + * base name of texture, the index number and texture extension. + * + * Texture indexes are specified directly in InitTextures(). + * + * \subsection TerrainMaterials Terrain materials + * + * Terrain materials are more sophisticated system. Each material is a texture, + * applied to one area, but specifying also the textures to use on surrounding areas: + * left, right, bottom and top. * - * The terrain also specifies underground resources loaded from texture - * and flying limits for the player. + * You specify one or more terrain materials in AddMaterial() function. + * The function will add a material for given circle on the ground, with some + * randomized matching of supplied materials and sophisticated logic for ensuring + * that borders between neighboring materials follow the specified rules. * - * ... + * \subsection BuildingLevels Other features + * + * Terrain can have specified building levels - flat space expanses, + * where relief data is specifically adjusted to level space to allow + * construction of buildings. + * + * Undergound resources can be supplied by loading them from image like relief data. + * + * Terrain also specifies flying limits for player: one global level and possible + * additional spherical restrictions. */ class CTerrain { @@ -151,25 +225,32 @@ public: ~CTerrain(); //! Generates a new flat terrain - bool Generate(int mosaic, int brickPow2, float size, float vision, int depth, float hardness); + bool Generate(int mosaicCount, int brickCountPow2, float brickSize, float vision, int depth, float hardness); + //! Initializes the names of textures to use for the land bool InitTextures(const std::string& baseName, int* table, int dx, int dy); - //! Empties level - void LevelFlush(); - //! Initializes the names of textures to use for the land - void LevelMaterial(int id, std::string& baseName, float u, float v, int up, int right, int down, int left, float hardness); - //! Initializes all the ground with a material - bool LevelInit(int id); + + //! Clears all terrain materials + void FlushMaterials(); + //! Adds a terrain material the names of textures to use for the land + void AddMaterial(int id, const std::string& baseName, const Math::Point& uv, + int up, int right, int down, int left, float hardness); + //! Initializes all the ground with one material + bool InitMaterials(int id); //! Generates a level in the terrain - bool LevelGenerate(int *id, float min, float max, float slope, float freq, Math::Vector center, float radius); - //! Initializes a completely flat terrain + bool GenerateMaterials(int *id, float min, float max, float slope, float freq, Math::Vector center, float radius); + + //! Clears the relief data to zero void FlushRelief(); - //! Load relief from a PNG file - bool ReliefFromPNG(const std::string& filename, float scaleRelief, bool adjustBorder); - //! Load resources from a PNG file - bool ResFromPNG(const std::string& filename); + //! Load relief from image + bool LoadRelief(const std::string& fileName, float scaleRelief, bool adjustBorder); + + //! Load resources from image + bool LoadResources(const std::string& fileName); + //! Creates all objects of the terrain within the 3D engine - bool CreateObjects(bool multiRes); + bool CreateObjects(); + //! Modifies the terrain's relief bool Terraform(const Math::Vector& p1, const Math::Vector& p2, float height); @@ -179,24 +260,24 @@ public: Math::Vector GetWind(); //@} - //! Gives the exact slope of the terrain of a place given + //! Gives the exact slope of the terrain at 2D (XZ) position float GetFineSlope(const Math::Vector& pos); - //! Gives the approximate slope of the terrain of a specific location + //! Gives the approximate slope of the terrain at 2D (XZ) position float GetCoarseSlope(const Math::Vector& pos); - //! Gives the normal vector at the position p (x,-,z) of the ground + //! Gives the normal vector at 2D (XZ) position bool GetNormal(Math::Vector& n, const Math::Vector &p); - //! returns the height of the ground - float GetFloorLevel(const Math::Vector& p, bool brut=false, bool water=false); - //! Returns the height to the ground - float GetFloorHeight(const Math::Vector& p, bool brut=false, bool water=false); - //! Modifies the coordinate "y" of point "p" to rest on the ground floor - bool MoveOnFloor(Math::Vector& p, bool brut=false, bool water=false); - //! Modifies a coordinate so that it is on the ground - bool ValidPosition(Math::Vector& p, float marging); - //! Returns the resource type available underground - Gfx::TerrainRes GetResource(const Math::Vector& p); - //! Adjusts a position so that it does not exceed the boundaries - void LimitPos(Math::Vector &pos); + //! Returns the height of the ground level at 2D (XZ) position + float GetFloorLevel(const Math::Vector& pos, bool brut=false, bool water=false); + //! Returns the distance to the ground level from 3D position + float GetHeightToFloor(const Math::Vector& pos, bool brut=false, bool water=false); + //! Modifies the Y coordinate of 3D position to rest on the ground floor + bool AdjustToFloor(Math::Vector& pos, bool brut=false, bool water=false); + //! Adjusts 3D position so that it is within standard terrain boundaries + bool AdjustToStandardBounds(Math::Vector &pos); + //! Adjusts 3D position so that it is within terrain boundaries and the given margin + bool AdjustToBounds(Math::Vector& pos, float margin); + //! Returns the resource type available underground at 2D (XZ) position + Gfx::TerrainRes GetResource(const Math::Vector& pos); //! Empty the table of elevations void FlushBuildingLevel(); @@ -207,16 +288,21 @@ public: //! Removes the elevation for a building when it was destroyed bool DeleteBuildingLevel(Math::Vector center); //! Returns the influence factor whether a position is on a possible rise - float GetBuildingFactor(const Math::Vector& p); - float GetHardness(const Math::Vector& p); - - int GetMosaic(); - int GetBrick(); - float GetSize(); - float GetScaleRelief(); + float GetBuildingFactor(const Math::Vector& pos); + //! Returns the hardness of the ground in a given place + float GetHardness(const Math::Vector& pos); + + //! Returns number of mosaics + int GetMosaicCount(); + //! Returns number of bricks in mosaic + int GetBrickCount(); + //! Returns brick size + float GetBrickSize(); + //! Returns the vertical scale of relief + float GetReliefScale(); //! Shows the flat areas on the ground - void GroundFlat(Math::Vector pos); + void ShowFlatGround(Math::Vector pos); //! Calculates the radius of the largest flat area available float GetFlatZoneRadius(Math::Vector center, float max); @@ -234,7 +320,7 @@ public: protected: //! Adds a point of elevation in the buffer of relief - bool ReliefAddDot(Math::Vector pos, float scaleRelief); + bool AddReliefPoint(Math::Vector pos, float scaleRelief); //! Adjust the edges of each mosaic to be compatible with all lower resolutions void AdjustRelief(); //! Calculates a vector of the terrain @@ -244,28 +330,28 @@ protected: //! Creates all objects of a mosaic bool CreateMosaic(int ox, int oy, int step, int objRank, const Gfx::Material& mat, float min, float max); //! Creates all objects in a mesh square ground - bool CreateSquare(bool multiRes, int x, int y); - - //! Seeks a materials based on theirs identifier - Gfx::TerrainMaterial* LevelSearchMat(int id); - //! Chooses texture to use for a given square - void LevelTextureName(int x, int y, std::string& name, Math::Point &uv); + bool CreateSquare(int x, int y); + + //! Seeks a material based on its ID + Gfx::TerrainMaterial* FindMaterial(int id); + //! Seeks a material based on neighbor values + int FindMaterialByNeighbors(char *mat); + //! Returns the texture name and UV coords to use for a given square + void GetTexture(int x, int y, std::string& name, Math::Point& uv); //! Returns the height of the terrain - float LevelGetHeight(int x, int y); + float GetHeight(int x, int y); //! Decide whether a point is using the materials - bool LevelGetDot(int x, int y, float min, float max, float slope); - //! Seeks if material exists - int LevelTestMat(char *mat); + bool CheckMaterialPoint(int x, int y, float min, float max, float slope); //! Modifies the state of a point and its four neighbors, without testing if possible - void LevelSetDot(int x, int y, int id, char *mat); - //! Tests if a material can give a place, according to its four neighbors. If yes, puts the point. - bool LevelIfDot(int x, int y, int id, char *mat); + void SetMaterialPoint(int x, int y, int id, char *mat); //! Modifies the state of a point - bool LevelPutDot(int x, int y, int id); - //! Initializes a table with empty levels - void LevelOpenTable(); - //! Closes the level table - void LevelCloseTable(); + bool ChangeMaterialPoint(int x, int y, int id); + //! Tests if a material can give a place, according to its four neighbors. If yes, puts the point. + bool CondChangeMaterialPoint(int x, int y, int id, char *mat); + //! Initializes material points array + void InitMaterialPoints(); + //! Clears the material points + void FlushMaterialPoints(); //! Adjusts a position according to a possible rise void AdjustBuildingLevel(Math::Vector &p); @@ -275,39 +361,51 @@ protected: CEngine* m_engine; CWater* m_water; - //! Number of mosaics - int m_mosaic; - //! Number of bricks per mosaics - int m_brick; - int m_levelDotSize; - //! Size of an item in a brick - float m_size; - //! Vision before a change of resolution - float m_vision; - //! Table of the relief + //! Relief data points std::vector<float> m_relief; - //! Table of textures - std::vector<int> m_texture; - //! Table of rows of objects - std::vector<int> m_objRank; - //! Table of resources + //! Resources data std::vector<unsigned char> m_resources; - bool m_multiText; - bool m_levelText; - //! Scale of the mapping - float m_scaleMapping; + //! Texture indices + std::vector<int> m_textures; + //! Object ranks for mosaic objects + std::vector<int> m_objRanks; + + //! Number of mosaics (along one dimension) + int m_mosaicCount; + //! Number of bricks per mosaic (along one dimension) + int m_brickCount; + //! Number of terrain material dots (along one dimension) + int m_materialPointCount; + //! Size of single brick (along X and Z axis) + float m_brickSize; + //! Vertical (relief) scale float m_scaleRelief; - int m_subdivMapping; + //! Subdivision of material points in mosaic + int m_textureSubdivCount; //! Number of different resolutions (1,2,3,4) int m_depth; + //! Scale of texture mapping + float m_textureScale; + //! Vision before a change of resolution + float m_vision; + + //! Base name for single texture std::string m_texBaseName; + //! Extension for single texture std::string m_texBaseExt; - float m_defHardness; - - std::vector<TerrainMaterial> m_levelMats; - std::vector<Gfx::DotLevel> m_levelDots; - int m_levelMatMax; - int m_levelID; + //! Default hardness for level material + float m_defaultHardness; + + //! True if using terrain material mapping + bool m_useMaterials; + //! Terrain materials + std::vector<Gfx::TerrainMaterial> m_materials; + //! Material for terrain points + std::vector<Gfx::TerrainMaterialPoint> m_materialPoints; + //! Maximum level ID (no ID is >= to this) + int m_maxMaterialID; + //! Internal counter for auto generation of material IDs + int m_materialAutoID; std::vector<Gfx::BuildingLevel> m_buildingLevels; diff --git a/src/graphics/engine/test/CMakeLists.txt b/src/graphics/engine/test/CMakeLists.txt index bd83773..4e3263b 100644 --- a/src/graphics/engine/test/CMakeLists.txt +++ b/src/graphics/engine/test/CMakeLists.txt @@ -1,7 +1,26 @@ cmake_minimum_required(VERSION 2.8) set(CMAKE_BUILD_TYPE debug) -set(CMAKE_CXX_FLAGS_DEBUG "-Wall -g -O0") +set(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -Wall -Wold-style-cast -std=gnu++0x") -include_directories(. ../../..) -add_executable(modelfile_test modelfile_test.cpp ../modelfile.cpp ../../../common/logger.cpp ../../../common/stringutils.cpp ../../../common/iman.cpp) +set(MODELFILE_TEST_SOURCES +modelfile_test.cpp +../modelfile.cpp +../../../common/logger.cpp +../../../common/stringutils.cpp +../../../common/iman.cpp +) + +add_definitions(-DMODELFILE_NO_ENGINE) + +include_directories( +. +../../.. +${GTEST_DIR}/include +) + +add_executable(modelfile_test ${MODELFILE_TEST_SOURCES}) + +target_link_libraries(modelfile_test gtest) + +add_test(modelfile_test modelfile_test) diff --git a/src/graphics/engine/test/modelfile_test.cpp b/src/graphics/engine/test/modelfile_test.cpp index f7ed87f..6879a1b 100644 --- a/src/graphics/engine/test/modelfile_test.cpp +++ b/src/graphics/engine/test/modelfile_test.cpp @@ -1,48 +1,273 @@ -#include "graphics/engine/modelfile.h" +// * This file is part of the COLOBOT source code +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + + #include "common/iman.h" +#include "common/logger.h" +#include "graphics/engine/modelfile.h" +#include "math/func.h" + +#include "gtest/gtest.h" + +#include <cassert> +#include <sstream> + +/* Test model file (new text format) */ +const char* const TEXT_MODEL = +"# Colobot text model\n" +"\n" +"### HEAD\n" +"version 1\n" +"total_triangles 2\n" +"\n" +"### TRIANGLES\n" +"p1 c -12.4099 10.0016 -2.54558 n 1 -0 1.87319e-07 t1 0.970703 0.751953 t2 0 0\n" +"p2 c -12.4099 10.0016 2.54558 n 1 -0 1.87319e-07 t1 0.998047 0.751953 t2 0 0\n" +"p3 c -12.4099 4.00165 -2.54558 n 1 -0 1.87319e-07 t1 0.970703 0.998047 t2 0 0\n" +"mat dif 1 1 1 0 amb 0.5 0.5 0.5 0 spc 0 0 0 0\n" +"tex1 lemt.png\n" +"tex2\n" +"var_tex2 N\n" +"min 200\n" +"max 1e+06\n" +"state 1024\n" +"\n" +"p1 c -19 -1 4 n -1 0 0 t1 0.248047 0.123047 t2 0.905224 0.52067\n" +"p2 c -19 4 4 n -1 0 0 t1 0.248047 0.00195312 t2 0.905224 0.614223\n" +"p3 c -19 4 -4 n -1 0 0 t1 0.00195312 0.00195312 t2 0.0947756 0.614223\n" +"mat dif 1 1 1 0 amb 0.5 0.5 0.5 0 spc 0 0 0 0\n" +"tex1 derrick.png\n" +"tex2\n" +"var_tex2 Y\n" +"min 200\n" +"max 1e+06\n" +"state 0\n" +""; + +// Triangles as defined in model file +Gfx::ModelTriangle TRIANGLE_1; +Gfx::ModelTriangle TRIANGLE_2; + +// Sets triangle data +void Init() +{ + + TRIANGLE_1.p1 = Gfx::VertexTex2(Math::Vector(-12.4099, 10.0016, -2.54558), + Math::Vector(1, 0, 1.87319e-07), + Math::Point(0.970703, 0.751953), + Math::Point(0, 0)); + TRIANGLE_1.p2 = Gfx::VertexTex2(Math::Vector(-12.4099, 10.0016, 2.54558), + Math::Vector(1, 0, 1.87319e-07), + Math::Point(0.998047, 0.751953), + Math::Point(0, 0)); + TRIANGLE_1.p3 = Gfx::VertexTex2(Math::Vector(-12.4099, 4.00165, -2.54558), + Math::Vector(1, 0, 1.87319e-07), + Math::Point(0.970703, 0.998047), + Math::Point(0, 0)); + TRIANGLE_1.material.diffuse = Gfx::Color(1, 1, 1, 0); + TRIANGLE_1.material.ambient = Gfx::Color(0.5, 0.5, 0.5, 0); + TRIANGLE_1.material.specular = Gfx::Color(0, 0, 0, 0); + TRIANGLE_1.tex1Name = "lemt.png"; + TRIANGLE_1.variableTex2 = false; + TRIANGLE_1.min = 200.0f; + TRIANGLE_1.max = 1e+06f; + TRIANGLE_1.state = 1024; + + TRIANGLE_2.p1 = Gfx::VertexTex2(Math::Vector(-19, -1, 4), + Math::Vector(-1, 0, 0), + Math::Point(0.248047, 0.123047), + Math::Point(0.905224, 0.52067)); + TRIANGLE_2.p2 = Gfx::VertexTex2(Math::Vector(-19, 4, 4), + Math::Vector(-1, 0, 0), + Math::Point(0.248047, 0.00195312), + Math::Point(0.905224, 0.614223)); + TRIANGLE_2.p3 = Gfx::VertexTex2(Math::Vector(-19, 4, -4), + Math::Vector(-1, 0, 0), + Math::Point(0.00195312, 0.00195312), + Math::Point(0.0947756, 0.614223)); + TRIANGLE_2.material.diffuse = Gfx::Color(1, 1, 1, 0); + TRIANGLE_2.material.ambient = Gfx::Color(0.5, 0.5, 0.5, 0); + TRIANGLE_2.material.specular = Gfx::Color(0, 0, 0, 0); + TRIANGLE_2.tex1Name = "derrick.png"; + TRIANGLE_2.variableTex2 = true; + TRIANGLE_2.min = 200.0f; + TRIANGLE_2.max = 1e+06f; + TRIANGLE_2.state = 0; +} + + +// Compares vertices (within Math::TOLERANCE) +bool CompareVertices(const Gfx::VertexTex2& v1, const Gfx::VertexTex2& v2) +{ + if ( !( Math::IsEqual(v1.coord.x, v2.coord.x) && + Math::IsEqual(v1.coord.y, v2.coord.y) && + Math::IsEqual(v1.coord.z, v2.coord.z) ) ) + return false; + + if ( !( Math::IsEqual(v1.normal.x, v2.normal.x) && + Math::IsEqual(v1.normal.y, v2.normal.y) && + Math::IsEqual(v1.normal.z, v2.normal.z) ) ) + return false; -#include <iostream> + if ( !( Math::IsEqual(v1.texCoord.x, v2.texCoord.x) && + Math::IsEqual(v1.texCoord.y, v2.texCoord.y) ) ) + return false; + if ( !( Math::IsEqual(v1.texCoord2.x, v2.texCoord2.x) && + Math::IsEqual(v1.texCoord2.y, v2.texCoord2.y) ) ) + return false; -int main(int argc, char *argv[]) + return true; +} + +// Compares colors (within Math::TOLERANCE) +bool CompareColors(const Gfx::Color& c1, const Gfx::Color& c2) +{ + return Math::IsEqual(c1.r, c2.r) && + Math::IsEqual(c1.g, c2.g) && + Math::IsEqual(c1.b, c2.b) && + Math::IsEqual(c1.a, c2.a); +} + +// Compares model triangles (within Math::TOLERANCE) +bool CompareTriangles(const Gfx::ModelTriangle& t1, const Gfx::ModelTriangle& t2) { - if (argc != 4) - { - std::cerr << "Usage: " << argv[0] << " {mod|dxf} in_file out_file" << std::endl; - return 1; - } + if (! CompareVertices(t1.p1, t2.p1)) + return false; + + if (! CompareVertices(t1.p2, t2.p2)) + return false; + + if (! CompareVertices(t1.p3, t2.p3)) + return false; + + if (! CompareColors(t1.material.diffuse, t2.material.diffuse)) + return false; + + if (! CompareColors(t1.material.ambient, t2.material.ambient)) + return false; + + if (! CompareColors(t1.material.specular, t2.material.specular)) + return false; + + if (t1.tex1Name != t2.tex1Name) + return false; + + if (t1.tex2Name != t2.tex2Name) + return false; + + if (t1.variableTex2 != t2.variableTex2) + return false; + + if (!Math::IsEqual(t1.min, t2.min)) + return false; + + if (!Math::IsEqual(t1.max, t2.max)) + return false; + + if (t1.state != t2.state) + return false; + + return true; +} + +// Tests reading/writing new text model file +TEST(ModelFileTest, RWTxtModel) +{ + std::stringstream str; + str.str(TEXT_MODEL); CInstanceManager iMan; - Gfx::CModelFile modfile(&iMan); - - std::string mode(argv[1]); - if (mode == "mod") - { - if (! modfile.ReadModel(argv[2], false, false) ) - { - std::cerr << "Read error: " << modfile.GetError() << std::endl; - return 2; - } - } - else if (mode == "dxf") - { - if (! modfile.ReadDXF(argv[2], false, false) ) - { - std::cerr << "Read error: " << modfile.GetError() << std::endl; - return 2; - } - } - else - { - std::cerr << "Usage: " << argv[0] << " {mod|dxf} in_file out_file" << std::endl; - return 1; - } - - if (! modfile.WriteModel(argv[3]) ) - { - std::cerr << "Write error: " << modfile.GetError() << std::endl; - return 3; - } - - return 0; + Gfx::CModelFile modelFile(&iMan); + + EXPECT_TRUE(modelFile.ReadTextModel(str)); + + EXPECT_EQ(modelFile.GetTriangleCount(), 2); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[0], TRIANGLE_1)); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[1], TRIANGLE_2)); + + str.str(""); + + EXPECT_TRUE(modelFile.WriteTextModel(str)); + str.seekg(0); + EXPECT_TRUE(modelFile.ReadTextModel(str)); + + EXPECT_EQ(modelFile.GetTriangleCount(), 2); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[0], TRIANGLE_1)); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[1], TRIANGLE_2)); +} + +// Tests reading/writing new binary model +TEST(ModelFileTest, RWBinModel) +{ + std::stringstream str; + str.str(TEXT_MODEL); + + CInstanceManager iMan; + Gfx::CModelFile modelFile(&iMan); + + EXPECT_TRUE(modelFile.ReadTextModel(str)); + + EXPECT_EQ(modelFile.GetTriangleCount(), 2); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[0], TRIANGLE_1)); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[1], TRIANGLE_2)); + + str.str(""); + + EXPECT_TRUE(modelFile.WriteBinaryModel(str)); + str.seekg(0); + EXPECT_TRUE(modelFile.ReadBinaryModel(str)); + + EXPECT_EQ(modelFile.GetTriangleCount(), 2); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[0], TRIANGLE_1)); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[1], TRIANGLE_2)); +} + +// Tests reading/writing old model file +TEST(ModelFileTest, RWOldModel) +{ + std::stringstream str; + str.str(TEXT_MODEL); + + CInstanceManager iMan; + Gfx::CModelFile modelFile(&iMan); + + EXPECT_TRUE(modelFile.ReadTextModel(str)); + + EXPECT_EQ(modelFile.GetTriangleCount(), 2); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[0], TRIANGLE_1)); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[1], TRIANGLE_2)); + + str.str(""); + + EXPECT_TRUE(modelFile.WriteModel(str)); + str.seekg(0); + EXPECT_TRUE(modelFile.ReadModel(str)); + + EXPECT_EQ(modelFile.GetTriangleCount(), 2); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[0], TRIANGLE_1)); + EXPECT_TRUE(CompareTriangles(modelFile.GetTriangles()[1], TRIANGLE_2)); +} + +int main(int argc, char **argv) +{ + CLogger logger; + + Init(); + + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/src/graphics/engine/water.cpp b/src/graphics/engine/water.cpp index bf2f64d..a2ff081 100644 --- a/src/graphics/engine/water.cpp +++ b/src/graphics/engine/water.cpp @@ -50,7 +50,7 @@ Gfx::CWater::CWater(CInstanceManager* iMan, Gfx::CEngine* engine) m_level = 0.0f; m_draw = true; m_lava = false; - m_color = 0xffffffff; + m_color = Gfx::Color(1.0f, 1.0f, 1.0f, 1.0f); m_subdiv = 4; m_lines.reserve(WATERLINE_PREALLOCATE_COUNT); @@ -330,7 +330,7 @@ void Gfx::CWater::DrawSurf() if (m_type[0] == Gfx::WATER_NULL) return; if (m_lines.empty()) return; - std::vector<Gfx::VertexTex2> vertices((m_brick+2)*2, Gfx::VertexTex2()); + std::vector<Gfx::VertexTex2> vertices((m_brickCount+2)*2, Gfx::VertexTex2()); Math::Vector eye = m_engine->GetEyePt(); @@ -365,7 +365,7 @@ void Gfx::CWater::DrawSurf() device->SetRenderState(Gfx::RENDER_STATE_FOG, true); - float size = m_size/2.0f; + float size = m_brickSize/2.0f; float sizez = 0.0f; if (under) sizez = -size; else sizez = size; @@ -436,8 +436,8 @@ bool Gfx::CWater::GetWater(int x, int y) x *= m_subdiv; y *= m_subdiv; - float size = m_size/m_subdiv; - float offset = m_brick*m_size/2.0f; + float size = m_brickSize/m_subdiv; + float offset = m_brickCount*m_brickSize/2.0f; for (int dy = 0; dy <= m_subdiv; dy++) { @@ -463,11 +463,11 @@ void Gfx::CWater::CreateLine(int x, int y, int len) line.y = y; line.len = len; - float offset = m_brick*m_size/2.0f - m_size/2.0f; + float offset = m_brickCount*m_brickSize/2.0f - m_brickSize/2.0f; - line.px1 = m_size* line.x - offset; - line.px2 = m_size*(line.x+line.len) - offset; - line.pz = m_size* line.y - offset; + line.px1 = m_brickSize* line.x - offset; + line.px2 = m_brickSize*(line.x+line.len) - offset; + line.pz = m_brickSize* line.y - offset; m_lines.push_back(line); } @@ -495,21 +495,21 @@ void Gfx::CWater::Create(Gfx::WaterType type1, Gfx::WaterType type2, const std:: if (m_terrain == nullptr) m_terrain = static_cast<CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN)); - m_brick = m_terrain->GetBrick()*m_terrain->GetMosaic(); - m_size = m_terrain->GetSize(); + m_brickCount = m_terrain->GetBrickCount()*m_terrain->GetMosaicCount(); + m_brickSize = m_terrain->GetBrickSize(); - m_brick /= m_subdiv; - m_size *= m_subdiv; + m_brickCount /= m_subdiv; + m_brickSize *= m_subdiv; if (m_type[0] == WATER_NULL) return; m_lines.clear(); - for (int y = 0; y < m_brick; y++) + for (int y = 0; y < m_brickCount; y++) { int len = 0; - for (int x = 0; x < m_brick; x++) + for (int x = 0; x < m_brickCount; x++) { if (GetWater(x,y)) // water here? { @@ -530,7 +530,7 @@ void Gfx::CWater::Create(Gfx::WaterType type1, Gfx::WaterType type2, const std:: } } if (len != 0) - CreateLine(m_brick - len, y, len); + CreateLine(m_brickCount - len, y, len); } } diff --git a/src/graphics/engine/water.h b/src/graphics/engine/water.h index 371a91f..9b31045 100644 --- a/src/graphics/engine/water.h +++ b/src/graphics/engine/water.h @@ -188,16 +188,16 @@ protected: int m_subdiv; //! Number of brick*mosaics - int m_brick; + int m_brickCount; //! Size of a item in an brick - float m_size; + float m_brickSize; std::vector<WaterLine> m_lines; std::vector<WaterVapor> m_vapors; bool m_draw; bool m_lava; - long m_color; + Gfx::Color m_color; }; }; // namespace Gfx diff --git a/src/graphics/opengl/gldevice.cpp b/src/graphics/opengl/gldevice.cpp index 7221421..a779a5f 100644 --- a/src/graphics/opengl/gldevice.cpp +++ b/src/graphics/opengl/gldevice.cpp @@ -187,6 +187,7 @@ void Gfx::CGLDevice::EndScene() void Gfx::CGLDevice::Clear() { + glDepthMask(GL_TRUE); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } @@ -454,6 +455,55 @@ Gfx::Texture Gfx::CGLDevice::CreateTexture(ImageData *data, const Gfx::TextureCr sourceFormat = GL_BGRA; result.alpha = true; } + else if (params.format == Gfx::TEX_IMG_AUTO) + { + if (data->surface->format->Amask != 0) + { + if ((data->surface->format->Rmask == 0xFF000000) && + (data->surface->format->Gmask == 0x00FF0000) && + (data->surface->format->Bmask == 0x0000FF00) && + (data->surface->format->Amask == 0x000000FF)) + { + sourceFormat = GL_BGRA; + result.alpha = true; + } + else if ((data->surface->format->Bmask == 0xFF000000) && + (data->surface->format->Gmask == 0x00FF0000) && + (data->surface->format->Rmask == 0x0000FF00) && + (data->surface->format->Amask == 0x000000FF)) + { + sourceFormat = GL_RGBA; + result.alpha = true; + } + else + { + GetLogger()->Error("Auto texture format failed\n"); + return Gfx::Texture(); // other format? + } + } + else + { + if ((data->surface->format->Rmask == 0xFF0000) && + (data->surface->format->Gmask == 0x00FF00) && + (data->surface->format->Bmask == 0x0000FF)) + { + sourceFormat = GL_BGR; + result.alpha = false; + } + else if ((data->surface->format->Bmask == 0xFF0000) && + (data->surface->format->Gmask == 0x00FF00) && + (data->surface->format->Rmask == 0x0000FF)) + { + sourceFormat = GL_RGB; + result.alpha = false; + } + else + { + GetLogger()->Error("Auto texture format failed\n"); + return Gfx::Texture(); // other format? + } + } + } else assert(false); diff --git a/src/object/auto/auto.cpp b/src/object/auto/auto.cpp index d112721..509904c 100644 --- a/src/object/auto/auto.cpp +++ b/src/object/auto/auto.cpp @@ -37,22 +37,22 @@ CAuto::CAuto(CInstanceManager* iMan, CObject* object) m_iMan->AddInstance(CLASS_AUTO, this, 100); m_object = object; - m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); - m_planet = (CPlanet*)m_iMan->SearchInstance(CLASS_PLANET); - m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - - m_type = m_object->RetType(); + m_event = static_cast< CEventQueue* >(m_iMan->SearchInstance(CLASS_EVENT)); + m_engine = static_cast< Gfx::CEngine* >(m_iMan->SearchInstance(CLASS_ENGINE)); + m_particle = static_cast< Gfx::CParticle* >(m_iMan->SearchInstance(CLASS_PARTICULE)); + m_lightMan = static_cast< Gfx::CLightManager* >(m_iMan->SearchInstance(CLASS_LIGHT)); + m_terrain = static_cast< Gfx::CTerrain* >(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_water = static_cast< Gfx::CWater* >(m_iMan->SearchInstance(CLASS_WATER)); + m_cloud = static_cast< Gfx::CCloud* >(m_iMan->SearchInstance(CLASS_CLOUD)); + m_planet = static_cast< Gfx::CPlanet* >(m_iMan->SearchInstance(CLASS_PLANET)); + m_lightning = static_cast< Gfx::CLightning* >(m_iMan->SearchInstance(CLASS_BLITZ)); + m_camera = static_cast< Gfx::CCamera* >(m_iMan->SearchInstance(CLASS_CAMERA)); + m_interface = static_cast< Ui::CInterface* >(m_iMan->SearchInstance(CLASS_INTERFACE)); + m_main = static_cast< CRobotMain* >(m_iMan->SearchInstance(CLASS_MAIN)); + m_displayText = static_cast< Ui::CDisplayText* >(m_iMan->SearchInstance(CLASS_DISPLAYTEXT)); + m_sound = static_cast< CSoundInterface* >(m_iMan->SearchInstance(CLASS_SOUND)); + + m_type = m_object->GetType(); m_time = 0.0f; m_lastUpdateTime = 0.0f; m_bMotor = false; @@ -117,14 +117,14 @@ bool CAuto::SetString(char *string) bool CAuto::EventProcess(const Event &event) { - if ( event.event == EVENT_FRAME && - !m_engine->RetPause() ) + if ( event.type == EVENT_FRAME && + !m_engine->GetPause() ) { m_time += event.rTime; UpdateInterface(event.rTime); } - if ( !m_object->RetSelect() ) // robot not selected? + if ( !m_object->GetSelect() ) // robot not selected? { return true; } @@ -151,13 +151,13 @@ bool CAuto::Abort() bool CAuto::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, dim, ddim; float ox, oy, sx, sy; char name[100]; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw != 0 ) + pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw != nullptr ) { pw->Flush(); // destroys the window buttons m_interface->DeleteControl(EVENT_WINDOW0); // destroys the window @@ -171,7 +171,7 @@ bool CAuto::CreateInterface(bool bSelect) //? dim.y = 70.0f/480.0f; dim.y = 86.0f/480.0f; m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; m_object->GetTooltipName(name); @@ -214,7 +214,7 @@ bool CAuto::CreateInterface(bool bSelect) pos.y = oy+sy*0; pw->CreateButton(pos, dim, 19, EVENT_OBJECT_HELP); - if ( m_main->RetSceneSoluce() ) + if ( m_main->GetSceneSoluce() ) { pos.x = ox+sx*13.4f; pos.y = oy+sy*1; @@ -263,62 +263,62 @@ bool CAuto::CreateInterface(bool bSelect) // Change the state of a button interface. -void CAuto::CheckInterface(CWindow *pw, EventMsg event, bool bState) +void CAuto::CheckInterface(Ui::CWindow *pw, EventType event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); - if ( control == 0 ) return; + if ( control == nullptr ) return; - control->SetState(STATE_CHECK, bState); + control->SetState(Ui::STATE_CHECK, bState); } // Change the state of a button interface. -void CAuto::EnableInterface(CWindow *pw, EventMsg event, bool bState) +void CAuto::EnableInterface(Ui::CWindow *pw, EventType event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); - if ( control == 0 ) return; + if ( control == nullptr ) return; - control->SetState(STATE_ENABLE, bState); + control->SetState(Ui::STATE_ENABLE, bState); } // Change the state of a button interface. -void CAuto::VisibleInterface(CWindow *pw, EventMsg event, bool bState) +void CAuto::VisibleInterface(Ui::CWindow *pw, EventType event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); - if ( control == 0 ) return; + if ( control == nullptr ) return; - control->SetState(STATE_VISIBLE, bState); + control->SetState(Ui::STATE_VISIBLE, bState); } // Change the state of a button interface. -void CAuto::DeadInterface(CWindow *pw, EventMsg event, bool bState) +void CAuto::DeadInterface(Ui::CWindow *pw, EventType event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); - if ( control == 0 ) return; + if ( control == nullptr ) return; - control->SetState(STATE_DEAD, !bState); + control->SetState(Ui::STATE_DEAD, !bState); } // Change the state of a button interface. void CAuto::UpdateInterface() { - CWindow* pw; + Ui::CWindow* pw; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; + pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return; VisibleInterface(pw, EVENT_OBJECT_GPROGRESS, m_bBusy); } @@ -328,34 +328,34 @@ void CAuto::UpdateInterface() void CAuto::UpdateInterface(float rTime) { - CWindow* pw; - CGauge* pg; + Ui::CWindow* pw; + Ui::CGauge* pg; if ( m_time < m_lastUpdateTime+0.1f ) return; m_lastUpdateTime = m_time; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; + pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return; - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GSHIELD); - if ( pg != 0 ) + pg = static_cast<Ui::CGauge*>(pw->SearchControl(EVENT_OBJECT_GSHIELD)); + if ( pg != nullptr ) { - pg->SetLevel(m_object->RetShield()); + pg->SetLevel(m_object->GetShield()); } - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GPROGRESS); - if ( pg != 0 ) + pg = static_cast<Ui::CGauge*>(pw->SearchControl(EVENT_OBJECT_GPROGRESS)); + if ( pg != nullptr ) { pg->SetLevel(m_progressTime); } } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAuto::RetError() +Error CAuto::GetError() { return ERR_OK; } @@ -363,7 +363,7 @@ Error CAuto::RetError() // Management of the occupation. -bool CAuto::RetBusy() +bool CAuto::GetBusy() { return m_bBusy; } @@ -387,7 +387,7 @@ void CAuto::EventProgress(float rTime) // Engine management. -bool CAuto::RetMotor() +bool CAuto::GetMotor() { return m_bMotor; } @@ -422,11 +422,11 @@ bool CAuto::Write(char *line) return false; } -// Return all settings to the controller. +// Geturn all settings to the controller. bool CAuto::Read(char *line) { - m_type = (ObjectType)OpInt(line, "aType", OBJECT_NULL); + m_type = static_cast<ObjectType>(OpInt(line, "aType", OBJECT_NULL)); m_bBusy = OpInt(line, "aBusy", 0); m_time = OpFloat(line, "aTime", 0.0f); m_progressTime = OpFloat(line, "aProgressTime", 0.0f); diff --git a/src/object/auto/auto.h b/src/object/auto/auto.h index 09efdd9..be7e66b 100644 --- a/src/object/auto/auto.h +++ b/src/object/auto/auto.h @@ -24,22 +24,27 @@ class CInstanceManager; -class CD3DEngine; -class CParticule; -class CLight; -class CTerrain; -class CWater; -class CCloud; -class CPlanet; -class CBlitz; -class CCamera; -class CInterface; class CRobotMain; +class CSoundInterface; + +namespace Ui { class CDisplayText; +class CInterface; class CWindow; -class CSound; +} /* Ui */ +namespace Gfx { +class CEngine; +class CParticle; +class CLightManager; +class CTarrain; +class CWater; +class CCloud; +class CCamera; +class CPlanet; +class CLightning; +} /* Gfx */ class CAuto @@ -61,44 +66,44 @@ public: virtual bool SetString(char *string); virtual bool CreateInterface(bool bSelect); - virtual Error RetError(); + virtual Error GetError(); - virtual bool RetBusy(); + virtual bool GetBusy(); virtual void SetBusy(bool bBuse); virtual void InitProgressTotal(float total); virtual void EventProgress(float rTime); - virtual bool RetMotor(); + virtual bool GetMotor(); virtual void SetMotor(bool bMotor); virtual bool Write(char *line); virtual bool Read(char *line); protected: - void CheckInterface(CWindow *pw, EventMsg event, bool bState); - void EnableInterface(CWindow *pw, EventMsg event, bool bState); - void VisibleInterface(CWindow *pw, EventMsg event, bool bState); - void DeadInterface(CWindow *pw, EventMsg event, bool bState); + void CheckInterface(Ui::CWindow *pw, EventType event, bool bState); + void EnableInterface(Ui::CWindow *pw, EventType event, bool bState); + void VisibleInterface(Ui::CWindow *pw, EventType event, bool bState); + void DeadInterface(Ui::CWindow *pw, EventType event, bool bState); void UpdateInterface(); void UpdateInterface(float rTime); protected: - CInstanceManager* m_iMan; - CEvent* m_event; - CD3DEngine* m_engine; - CParticule* m_particule; - CLight* m_light; - CTerrain* m_terrain; - CWater* m_water; - CCloud * m_cloud; - CPlanet * m_planet; - CBlitz* m_blitz; - CCamera* m_camera; - CInterface* m_interface; - CRobotMain* m_main; - CDisplayText* m_displayText; - CObject* m_object; - CSound* m_sound; + CInstanceManager* m_iMan; + CEventQueue* m_event; + Gfx::CEngine* m_engine; + Gfx::CParticle* m_particle; + Gfx::CLightManager* m_lightMan; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + Gfx::CCloud * m_cloud; + Gfx::CPlanet * m_planet; + Gfx::CLightning* m_lightning; + Gfx::CCamera* m_camera; + Ui::CInterface* m_interface; + Ui::CDisplayText* m_displayText; + CRobotMain* m_main; + CObject* m_object; + CSoundInterface* m_sound; ObjectType m_type; bool m_bBusy; diff --git a/src/object/auto/autobase.cpp b/src/object/auto/autobase.cpp index 19382b7..d5e8608 100644 --- a/src/object/auto/autobase.cpp +++ b/src/object/auto/autobase.cpp @@ -20,10 +20,10 @@ #include "object/auto/autobase.h" #include "common/iman.h" -#include "old/terrain.h" -#include "old/cloud.h" -#include "old/planet.h" -#include "old/blitz.h" +#include "graphics/engine/terrain.h" +#include "graphics/engine/cloud.h" +#include "graphics/engine/planet.h" +#include "graphics/engine/lightning.h" #include "math/geometry.h" #include "object/robotmain.h" #include "physics/physics.h" @@ -50,8 +50,8 @@ const float BASE_TRANSIT_TIME = 15.0f; // transit duration CAutoBase::CAutoBase(CInstanceManager* iMan, CObject* object) : CAuto(iMan, object) { - m_fogStart = m_engine->RetFogStart(); - m_deepView = m_engine->RetDeepView(); + m_fogStart = m_engine->GetFogStart(); + m_deepView = m_engine->GetDeepView(); Init(); m_phase = ABP_WAIT; m_soundChannel = -1; @@ -85,10 +85,10 @@ void CAutoBase::Init() { m_bOpen = false; m_time = 0.0f; - m_lastParticule = 0.0f; - m_lastMotorParticule = 0.0f; + m_lastParticle = 0.0f; + m_lastMotorParticle = 0.0f; - m_pos = m_object->RetPosition(0); + m_pos = m_object->GetPosition(0); m_lastPos = m_pos; m_phase = ABP_WAIT; @@ -124,10 +124,10 @@ bool CAutoBase::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; begin: - iPos = m_object->RetPosition(0); + iPos = m_object->GetPosition(0); if ( m_phase == ABP_START ) { @@ -152,17 +152,17 @@ begin: m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, 11.5f)); } - pObj = m_main->RetSelectObject(); + pObj = m_main->GetSelectObject(); m_main->SelectObject(pObj); m_camera->SetObject(pObj); if ( pObj == 0 ) { - m_camera->SetType(CAMERA_BACK); + m_camera->SetType(Gfx::CAM_TYPE_BACK); } else { - m_camera->SetType(pObj->RetCameraType()); - m_camera->SetDist(pObj->RetCameraDist()); + m_camera->SetType(pObj->GetCameraType()); + m_camera->SetDist(pObj->GetCameraDist()); } m_main->StartMusic(); @@ -193,7 +193,7 @@ begin: m_main->SetMovieLock(true); // blocks everything until the end of the landing m_bMotor = true; // lights the jet engine - m_camera->SetType(CAMERA_SCRIPT); + m_camera->SetType(Gfx::CAM_TYPE_SCRIPT); pos = m_pos; pos.x -= 150.0f; @@ -202,7 +202,7 @@ begin: m_camera->SetScriptEye(pos); m_posSound = pos; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 300.0f+50.0f; m_camera->SetScriptLookat(pos); @@ -223,7 +223,7 @@ begin: if ( m_param == PARAM_PORTICO ) // gate on the porch? { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); m_finalPos = pos; pos.z += BASE_PORTICO_TIME_MOVE*5.0f; // back pos.y += 10.0f; // rises (the gate) @@ -246,7 +246,7 @@ begin: m_speed = 1.0f/BASE_TRANSIT_TIME; m_object->SetAngleZ(0, -Math::PI/2.0f); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 10000.0f; // in space m_finalPos = pos; m_object->SetPosition(0, pos); @@ -254,7 +254,7 @@ begin: m_main->SetMovieLock(true); // blocks everything until the end of the landing m_bMotor = true; // lights the jet engine - m_camera->SetType(CAMERA_SCRIPT); + m_camera->SetType(Gfx::CAM_TYPE_SCRIPT); pos.x += 1000.0f; pos.z -= 60.0f; pos.y += 80.0f; @@ -265,34 +265,34 @@ begin: BeginTransit(); - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 10.0f; dim.y = dim.x; pos = Math::Vector(42.0f, -2.0f, 17.0f); pos = Transform(*mat, pos); - m_partiChannel[0] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[0] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); pos = Math::Vector(17.0f, -2.0f, 42.0f); pos = Transform(*mat, pos); - m_partiChannel[1] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[1] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); pos = Math::Vector(42.0f, -2.0f, -17.0f); pos = Transform(*mat, pos); - m_partiChannel[2] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[2] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); pos = Math::Vector(17.0f, -2.0f, -42.0f); pos = Transform(*mat, pos); - m_partiChannel[3] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[3] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); pos = Math::Vector(-42.0f, -2.0f, 17.0f); pos = Transform(*mat, pos); - m_partiChannel[4] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[4] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); pos = Math::Vector(-17.0f, -2.0f, 42.0f); pos = Transform(*mat, pos); - m_partiChannel[5] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[5] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); pos = Math::Vector(-42.0f, -2.0f, -17.0f); pos = Transform(*mat, pos); - m_partiChannel[6] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[6] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); pos = Math::Vector(-17.0f, -2.0f, -42.0f); pos = Transform(*mat, pos); - m_partiChannel[7] = m_particule->CreateParticule(pos, speed, dim, PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); + m_partiChannel[7] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f); if ( m_soundChannel == -1 ) { @@ -303,12 +303,12 @@ begin: } } - if ( event.event == EVENT_UPDINTERFACE ) + if ( event.type == EVENT_UPDINTERFACE ) { - if ( m_object->RetSelect() ) CreateInterface(true); + if ( m_object->GetSelect() ) CreateInterface(true); } - if ( event.event == EVENT_OBJECT_BTAKEOFF ) + if ( event.type == EVENT_OBJECT_BTAKEOFF ) { err = CheckCloseDoor(); if ( err != ERR_OK ) @@ -328,10 +328,10 @@ begin: m_main->SetMovieLock(true); // blocks everything until the end m_main->DeselectAll(); - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + newEvent.type = EVENT_UPDINTERFACE; m_event->AddEvent(newEvent); - m_camera->SetType(CAMERA_SCRIPT); + m_camera->SetType(Gfx::CAM_TYPE_SCRIPT); pos = m_pos; pos.x -= 110.0f; @@ -340,7 +340,7 @@ begin: m_camera->SetScriptEye(pos); m_posSound = pos; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 50.0f; m_camera->SetScriptLookat(pos); @@ -356,7 +356,7 @@ begin: return true; } - if ( event.event != EVENT_FRAME ) return true; + if ( event.type != EVENT_FRAME ) return true; if ( m_phase == ABP_WAIT ) return true; m_progress += event.rTime*m_speed; @@ -386,15 +386,15 @@ begin: pos.y += 10.0f; m_camera->SetScriptEye(pos); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 50.0f; m_camera->SetScriptLookat(pos); m_engine->SetFocus(1.0f+(1.0f-m_progress)); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; // Dust thrown to the ground. pos = m_pos; @@ -410,19 +410,19 @@ begin: dim.y = dim.x; if ( dim.x >= 1.0f ) { - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 2.0f); } // Particles are ejected from the jet engine. - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 6.0f; - h = m_terrain->RetFloorHeight(pos)/300.0f; + h = m_terrain->GetFloorHeight(pos)/300.0f; speed.x = (Math::Rand()-0.5f)*(80.0f-50.0f*h); speed.z = (Math::Rand()-0.5f)*(80.0f-50.0f*h); speed.y = -(Math::Rand()*(h+1.0f)*40.0f+(h+1.0f)*40.0f); dim.x = Math::Rand()*2.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 2.0f, 10.0f, 2.0f); // Black smoke from the jet engine. if ( m_progress > 0.8f ) @@ -436,7 +436,7 @@ begin: speed.y = 0.0f; dim.x = Math::Rand()*4.0f+4.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f, 0.0f, 2.0f); } } } @@ -449,7 +449,7 @@ begin: MoveCargo(); // all cargo moves // Impact with the ground. - max = (int)(50.0f*m_engine->RetParticuleDensity()); + max = static_cast<int>(50.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { angle = Math::Rand()*(Math::PI*2.0f); @@ -461,11 +461,11 @@ begin: dim.x = Math::Rand()*10.0f+10.0f; dim.y = dim.x; time = Math::Rand()*2.0f+1.5f; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time, 0.0f, 2.0f); } //? m_camera->StartEffect(CE_CRASH, m_pos, 1.0f); - m_camera->StartEffect(CE_EXPLO, m_pos, 2.0f); + m_camera->StartEffect(Gfx::CAM_EFFECT_EXPLO, m_pos, 2.0f); m_engine->SetFocus(1.0f); m_sound->Play(SOUND_BOUM, m_posSound, 0.6f, 0.5f); @@ -479,9 +479,9 @@ begin: { if ( m_progress < 1.0f ) { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; // Black smoke from the reactor. pos = m_pos; @@ -493,7 +493,7 @@ begin: speed.y = 0.0f; dim.x = Math::Rand()*4.0f+4.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f, 0.0f, 2.0f); } } else @@ -542,7 +542,7 @@ begin: } // Clash the doors with the ground. - max = (int)(20.0f*m_engine->RetParticuleDensity()); + max = static_cast<int>(20.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { angle = Math::Rand()*(20.0f*Math::PI/180.0f)-(10.0f*Math::PI/180.0f); @@ -555,7 +555,7 @@ begin: dim.x = Math::Rand()*8.0f+8.0f; dim.y = dim.x; time = Math::Rand()*2.0f+1.5f; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time, 0.0f, 2.0f); } m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, true); @@ -622,19 +622,19 @@ begin: { m_main->SetMovieLock(false); // you can play! - pObj = m_main->RetSelectObject(); + pObj = m_main->GetSelectObject(); m_main->SelectObject(pObj); m_camera->SetObject(pObj); if ( pObj == 0 ) { - m_camera->SetType(CAMERA_BACK); + m_camera->SetType(Gfx::CAM_TYPE_BACK); } else { - m_camera->SetType(pObj->RetCameraType()); - m_camera->SetDist(pObj->RetCameraDist()); + m_camera->SetType(pObj->GetCameraType()); + m_camera->SetDist(pObj->GetCameraDist()); } - m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); + m_sound->Play(SOUND_BOUM, m_object->GetPosition(0)); m_soundChannel = -1; m_engine->SetFogStart(m_fogStart); @@ -700,7 +700,7 @@ begin: m_bMotor = true; // lights the jet engine // Shock of the closing doors. - max = (int)(20.0f*m_engine->RetParticuleDensity()); + max = static_cast<int>(20.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { angle = Math::Rand()*Math::PI*2.0f; @@ -713,9 +713,9 @@ begin: dim.x = Math::Rand()*3.0f+3.0f; dim.y = dim.x; time = Math::Rand()*1.0f+1.0f; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time); } - m_sound->Play(SOUND_BOUM, m_object->RetPosition(0)); + m_sound->Play(SOUND_BOUM, m_object->GetPosition(0)); m_soundChannel = -1; m_bOpen = false; @@ -742,19 +742,19 @@ begin: vibCir *= m_progress*1.0f; m_object->SetCirVibration(vibCir); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; // Particles are ejected from the reactor. - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 6.0f; speed.x = (Math::Rand()-0.5f)*160.0f; speed.z = (Math::Rand()-0.5f)*160.0f; speed.y = -(Math::Rand()*10.0f+10.0f); dim.x = Math::Rand()*2.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 2.0f, 10.0f, 2.0f); } m_engine->SetFogStart(m_fogStart+(0.9f-m_fogStart)*m_progress); @@ -789,15 +789,15 @@ begin: pos.y += 10.0f; m_camera->SetScriptEye(pos); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 50.0f; m_camera->SetScriptLookat(pos); m_engine->SetFocus(1.0f+m_progress); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; // Dust thrown to the ground. pos = m_pos; @@ -813,11 +813,11 @@ begin: dim.y = dim.x; if ( dim.x >= 1.0f ) { - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 2.0f); } // Particles are ejected from the reactor. - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 6.0f; speed.x = (Math::Rand()-0.5f)*40.0f; speed.z = (Math::Rand()-0.5f)*40.0f; @@ -826,23 +826,23 @@ begin: time = 2.0f+m_progress*12.0f; dim.x = Math::Rand()*time+time; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 2.0f, 10.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 2.0f, 10.0f, 2.0f); // Black smoke from the reactor. - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 3.0f; speed.x = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); speed.z = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f); speed.y = 0.0f; dim.x = Math::Rand()*20.0f+20.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 10.0f, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 10.0f, 0.0f, 2.0f); } } else { m_soundChannel = -1; - m_event->MakeEvent(newEvent, EVENT_WIN); + newEvent.type = EVENT_WIN; m_event->AddEvent(newEvent); m_phase = ABP_WAIT; @@ -855,7 +855,7 @@ begin: { if ( m_progress < 1.0f ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.z -= event.rTime*5.0f; m_object->SetPosition(0, pos); MoveCargo(); // all cargo moves @@ -882,7 +882,7 @@ begin: { if ( m_progress < 1.0f ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y -= event.rTime*(10.0f/BASE_PORTICO_TIME_DOWN); m_object->SetPosition(0, pos); MoveCargo(); // all cargo moves @@ -890,7 +890,7 @@ begin: else { // Impact with the ground. - max = (int)(50.0f*m_engine->RetParticuleDensity()); + max = static_cast<int>(50.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { angle = Math::Rand()*(Math::PI*2.0f); @@ -902,7 +902,7 @@ begin: dim.x = Math::Rand()*10.0f+10.0f; dim.y = dim.x; time = Math::Rand()*2.0f+1.5f; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, time, 0.0f, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time, 0.0f, 2.0f); } m_phase = ABP_PORTICO_WAIT2; @@ -938,7 +938,7 @@ begin: { if ( m_progress < 1.0f ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += event.rTime*(2000.0f/BASE_TRANSIT_TIME); m_object->SetPosition(0, pos); pos.x += 60.0f; @@ -967,11 +967,11 @@ begin: if ( m_bMotor ) { - if ( m_lastMotorParticule+m_engine->ParticuleAdapt(0.02f) <= m_time ) + if ( m_lastMotorParticle+m_engine->ParticleAdapt(0.02f) <= m_time ) { - m_lastMotorParticule = m_time; + m_lastMotorParticle = m_time; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); if ( event.rTime == 0.0f ) { @@ -979,7 +979,7 @@ begin: } else { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); if ( m_phase == ABP_TRANSIT_MOVE ) { vSpeed = (pos.x-iPos.x)/event.rTime; @@ -1003,7 +1003,7 @@ begin: dim.x = 4.0f+Math::Rand()*4.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBASE, 3.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBASE, 3.0f, 0.0f, 0.0f); if ( m_phase == ABP_TRANSIT_MOVE ) { @@ -1013,7 +1013,7 @@ begin: pos = Math::Vector(0.0f, 7.0f, 0.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 1.0f, 0.0f, 0.0f); speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 4.0f; @@ -1021,67 +1021,67 @@ begin: pos = Math::Vector(42.0f, 0.0f, 17.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(17.0f, 0.0f, 42.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(42.0f, 0.0f, -17.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(17.0f, 0.0f, -42.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(-42.0f, 0.0f, 17.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(-17.0f, 0.0f, 42.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(-42.0f, 0.0f, -17.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(-17.0f, 0.0f, -42.0f); pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; pos = Transform(*mat, pos); - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f); pos = Math::Vector(42.0f, -2.0f, 17.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[0], pos); + m_particle->SetPosition(m_partiChannel[0], pos); pos = Math::Vector(17.0f, -2.0f, 42.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[1], pos); + m_particle->SetPosition(m_partiChannel[1], pos); pos = Math::Vector(42.0f, -2.0f, -17.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[2], pos); + m_particle->SetPosition(m_partiChannel[2], pos); pos = Math::Vector(17.0f, -2.0f, -42.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[3], pos); + m_particle->SetPosition(m_partiChannel[3], pos); pos = Math::Vector(-42.0f, -2.0f, 17.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[4], pos); + m_particle->SetPosition(m_partiChannel[4], pos); pos = Math::Vector(-17.0f, -2.0f, 42.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[5], pos); + m_particle->SetPosition(m_partiChannel[5], pos); pos = Math::Vector(-42.0f, -2.0f, -17.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[6], pos); + m_particle->SetPosition(m_partiChannel[6], pos); pos = Math::Vector(-17.0f, -2.0f, -42.0f); pos = Transform(*mat, pos); - m_particule->SetPosition(m_partiChannel[7], pos); + m_particle->SetPosition(m_partiChannel[7], pos); } } } if ( m_soundChannel != -1 ) { - pos = m_engine->RetEyePt(); + pos = m_engine->GetEyePt(); m_sound->Position(m_soundChannel, pos); } @@ -1154,17 +1154,17 @@ bool CAutoBase::Abort() m_main->SetMovieLock(false); // you can play! - pObj = m_main->RetSelectObject(); + pObj = m_main->GetSelectObject(); m_main->SelectObject(pObj); m_camera->SetObject(pObj); if ( pObj == 0 ) { - m_camera->SetType(CAMERA_BACK); + m_camera->SetType(Gfx::CAM_TYPE_BACK); } else { - m_camera->SetType(pObj->RetCameraType()); - m_camera->SetDist(pObj->RetCameraDist()); + m_camera->SetType(pObj->GetCameraType()); + m_camera->SetDist(pObj->GetCameraDist()); } m_engine->SetFogStart(m_fogStart); @@ -1175,7 +1175,7 @@ bool CAutoBase::Abort() m_phase == ABP_TOWAIT || m_phase == ABP_TAKEOFF ) // off? { - m_event->MakeEvent(newEvent, EVENT_WIN); + newEvent.type = EVENT_WIN; m_event->AddEvent(newEvent); } } @@ -1198,9 +1198,9 @@ bool CAutoBase::Abort() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoBase::RetError() +Error CAutoBase::GetError() { return ERR_OK; } @@ -1210,7 +1210,7 @@ Error CAutoBase::RetError() bool CAutoBase::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, dim, ddim; float ox, oy, sx, sy; float sleep, delay, magnetic, progress; @@ -1219,8 +1219,8 @@ bool CAutoBase::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return false; + pw = static_cast<Ui::CWindow*>(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return false; dim.x = 33.0f/640.0f; dim.y = 33.0f/480.0f; @@ -1240,7 +1240,7 @@ bool CAutoBase::CreateInterface(bool bSelect) pos.y = oy+sy*0.25f; pw->CreateButton(pos, ddim, 28, EVENT_OBJECT_BTAKEOFF); - if ( m_blitz->GetStatus(sleep, delay, magnetic, progress) ) + if ( m_lightning->GetStatus(sleep, delay, magnetic, progress) ) { pos.x = ox+sx*10.2f; pos.y = oy+sy*0.5f; @@ -1264,13 +1264,13 @@ bool CAutoBase::CreateInterface(bool bSelect) void CAutoBase::UpdateInterface() { - CWindow* pw; +// Ui::CWindow* pw; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; CAuto::UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); +// pw = static_cast< Ui::CWindow* >( m_interface->SearchControl(EVENT_WINDOW0)); } @@ -1286,15 +1286,15 @@ void CAutoBase::FreezeCargo(bool bFreeze) for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; pObj->SetCargo(false); if ( pObj == m_object ) continue; // yourself? - if ( pObj->RetTruck() != 0 ) continue; // transport object? + if ( pObj->GetTruck() != 0 ) continue; // transport object? - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(m_pos, oPos); if ( dist < 32.0f ) { @@ -1303,7 +1303,7 @@ void CAutoBase::FreezeCargo(bool bFreeze) pObj->SetCargo(true); } - physics = pObj->RetPhysics(); + physics = pObj->GetPhysics(); if ( physics != 0 ) { physics->SetFreeze(bFreeze); @@ -1320,18 +1320,18 @@ void CAutoBase::MoveCargo() Math::Vector oPos, sPos; int i; - sPos = m_object->RetPosition(0); + sPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast < CObject* > (m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( !pObj->RetCargo() ) continue; + if ( !pObj->GetCargo() ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); oPos.y = sPos.y+30.0f; - oPos.y += pObj->RetCharacter()->height; + oPos.y += pObj->GetCharacter()->height; oPos.x += sPos.x-m_lastPos.x; oPos.z += sPos.z-m_lastPos.z; pObj->SetPosition(0, oPos); @@ -1353,13 +1353,13 @@ Error CAutoBase::CheckCloseDoor() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* > (m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; if ( pObj == m_object ) continue; // yourself? - if ( !pObj->RetActif() ) continue; // inactive? + if ( !pObj->GetActif() ) continue; // inactive? - type = pObj->RetType(); + type = pObj->GetType(); if ( type == OBJECT_PORTICO ) continue; j = 0; @@ -1391,18 +1391,18 @@ void CAutoBase::BeginTransit() if ( m_param == PARAM_TRANSIT2 ) { - strcpy(m_bgBack, "back01.tga"); // clouds orange / blue + m_bgBack = "back01.tga"; // clouds orange / blue } else if ( m_param == PARAM_TRANSIT3 ) { - strcpy(m_bgBack, "back22.tga"); // blueberries clouds + m_bgBack = "back22.tga"; // blueberries clouds } else { #if _DEMO - strcpy(m_bgBack, "back46b.tga"); // paintings + m_bgBack = "back46b.tga"; // paintings #else - strcpy(m_bgBack, "back46.tga"); // paintings + m_bgBack = "back46.tga"; // paintings #endif } @@ -1410,8 +1410,8 @@ void CAutoBase::BeginTransit() m_engine->SetDeepView(2000.0f); // we see very far m_engine->ApplyChange(); - m_engine->RetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, bFull, bQuarter); - m_engine->FreeTexture(m_bgName); + m_engine->GetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown, bFull, bQuarter); + m_engine->DeleteTexture(m_bgName); m_engine->SetBackground(m_bgBack, 0x00000000, 0x00000000, 0x00000000, 0x00000000); m_engine->LoadTexture(m_bgBack); @@ -1428,7 +1428,7 @@ void CAutoBase::EndTransit() m_engine->SetDeepView(m_deepView); // gives initial depth m_engine->ApplyChange(); - m_engine->FreeTexture(m_bgBack); + m_engine->DeleteTexture(m_bgBack); m_engine->SetBackground(m_bgName, m_bgUp, m_bgDown, m_bgCloudUp, m_bgCloudDown); m_engine->LoadTexture(m_bgName); diff --git a/src/object/auto/autobase.h b/src/object/auto/autobase.h index eb47a93..439d414 100644 --- a/src/object/auto/autobase.h +++ b/src/object/auto/autobase.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -73,7 +74,7 @@ public: void Start(int param); bool EventProcess(const Event &event); bool Abort(); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -90,23 +91,23 @@ protected: bool m_bOpen; float m_progress; float m_speed; - float m_lastParticule; - float m_lastMotorParticule; + float m_lastParticle; + float m_lastMotorParticle; float m_fogStart; float m_deepView; - Math::Vector m_pos; - Math::Vector m_posSound; - Math::Vector m_finalPos; - Math::Vector m_lastPos; + Math::Vector m_pos; + Math::Vector m_posSound; + Math::Vector m_finalPos; + Math::Vector m_lastPos; int m_param; int m_soundChannel; int m_partiChannel[8]; - char m_bgBack[100]; - char m_bgName[100]; - D3DCOLOR m_bgUp; - D3DCOLOR m_bgDown; - D3DCOLOR m_bgCloudUp; - D3DCOLOR m_bgCloudDown; + std::string m_bgBack; + std::string m_bgName; + Gfx::Color m_bgUp; + Gfx::Color m_bgDown; + Gfx::Color m_bgCloudUp; + Gfx::Color m_bgCloudDown; }; diff --git a/src/object/auto/autoconvert.cpp b/src/object/auto/autoconvert.cpp index b5ad43a..14fa4cf 100644 --- a/src/object/auto/autoconvert.cpp +++ b/src/object/auto/autoconvert.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -83,7 +84,7 @@ void CAutoConvert::Init() m_speed = 1.0f/2.0f; m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; CAuto::Init(); } @@ -100,13 +101,13 @@ bool CAutoConvert::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -146,7 +147,7 @@ bool CAutoConvert::EventProcess(const Event &event) InitProgressTotal(3.0f+10.0f+1.5f); UpdateInterface(); - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.0f); + m_sound->Play(SOUND_OPEN, m_object->GetPosition(0), 1.0f, 1.0f); m_bSoundClose = false; m_phase = ACP_CLOSE; @@ -163,7 +164,7 @@ bool CAutoConvert::EventProcess(const Event &event) if ( m_progress >= 0.8f && !m_bSoundClose ) { m_bSoundClose = true; - m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 0.8f); + m_sound->Play(SOUND_CLOSE, m_object->GetPosition(0), 1.0f, 0.8f); } angle = -Math::PI*0.35f*(1.0f-Math::Bounce(m_progress, 0.85f, 0.05f)); m_object->SetAngleX(2, angle); @@ -174,7 +175,7 @@ bool CAutoConvert::EventProcess(const Event &event) m_object->SetAngleX(2, 0.0f); m_object->SetAngleX(3, 0.0f); - m_soundChannel = m_sound->Play(SOUND_CONVERT, m_object->RetPosition(0), 0.0f, 0.25f, true); + m_soundChannel = m_sound->Play(SOUND_CONVERT, m_object->GetPosition(0), 0.0f, 0.25f, true); m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 0.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.00f, 4.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.25f, 4.5f, SOPER_CONTINUE); @@ -202,11 +203,11 @@ bool CAutoConvert::EventProcess(const Event &event) m_object->SetAngleY(2, angle); m_object->SetAngleY(3, angle+Math::PI); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); c.x = pos.x; c.y = pos.z; p.x = c.x; @@ -218,7 +219,7 @@ bool CAutoConvert::EventProcess(const Event &event) speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = Math::Rand()*2.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGAS, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 1.0f, 0.0f, 0.0f); } } else @@ -230,13 +231,13 @@ bool CAutoConvert::EventProcess(const Event &event) fret = SearchStone(OBJECT_STONE); if ( fret != 0 ) { - m_bResetDelete = ( fret->RetResetCap() != RESET_NONE ); + m_bResetDelete = ( fret->GetResetCap() != RESET_NONE ); fret->DeleteObject(); // destroy the stone delete fret; } CreateMetal(); // Create the metal - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.5f); + m_sound->Play(SOUND_OPEN, m_object->GetPosition(0), 1.0f, 1.5f); m_phase = ACP_OPEN; m_progress = 0.0f; @@ -253,18 +254,18 @@ bool CAutoConvert::EventProcess(const Event &event) m_object->SetAngleX(3, angle); if ( m_progress < 0.9f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*6.0f; pos.z += (Math::Rand()-0.5f)*6.0f; pos.y += Math::Rand()*4.0f; speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = Math::Rand()*4.0f+3.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBLUE, 1.0f, 0.0f, 0.0f); } } else @@ -285,11 +286,11 @@ bool CAutoConvert::EventProcess(const Event &event) return true; } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoConvert::RetError() +Error CAutoConvert::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -330,7 +331,7 @@ bool CAutoConvert::Abort() bool CAutoConvert::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -338,8 +339,8 @@ bool CAutoConvert::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return false; + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return false; ox = 3.0f/640.0f; oy = 3.0f/480.0f; @@ -390,11 +391,11 @@ bool CAutoConvert::Read(char *line) CAuto::Read(line); - m_phase = (AutoConvertPhase)OpInt(line, "aPhase", ACP_WAIT); + m_phase = static_cast< AutoConvertPhase >(OpInt(line, "aPhase", ACP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } @@ -410,18 +411,18 @@ CObject* CAutoConvert::SearchStone(ObjectType type) float dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType != type ) continue; - if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->GetTruck() != 0 ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, cPos); if ( dist <= 5.0f ) return pObj; @@ -440,14 +441,14 @@ bool CAutoConvert::SearchVehicle() float oRadius, dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_HUMAN && type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && @@ -506,8 +507,8 @@ void CAutoConvert::CreateMetal() float angle; CObject* fret; - pos = m_object->RetPosition(0); - angle = m_object->RetAngleY(0); + pos = m_object->GetPosition(0); + angle = m_object->GetAngleY(0); fret = new CObject(m_iMan); if ( !fret->CreateResource(pos, angle, OBJECT_METAL) ) diff --git a/src/object/auto/autoconvert.h b/src/object/auto/autoconvert.h index c2042cf..b21690f 100644 --- a/src/object/auto/autoconvert.h +++ b/src/object/auto/autoconvert.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool Abort(); bool CreateInterface(bool bSelect); @@ -62,7 +63,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; bool m_bResetDelete; bool m_bSoundClose; int m_soundChannel; diff --git a/src/object/auto/autoderrick.cpp b/src/object/auto/autoderrick.cpp index 3f1cda5..a560bc8 100644 --- a/src/object/auto/autoderrick.cpp +++ b/src/object/auto/autoderrick.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -20,7 +21,7 @@ #include "object/auto/autoderrick.h" #include "common/iman.h" -#include "old/terrain.h" +#include "graphics/engine/terrain.h" #include "math/geometry.h" #include "script/cmdtoken.h" #include "ui/interface.h" @@ -62,7 +63,7 @@ void CAutoDerrick::DeleteObject(bool bAll) if ( !bAll ) { fret = SearchFret(); - if ( fret != 0 && fret->RetLock() ) + if ( fret != 0 && fret->GetLock() ) { fret->DeleteObject(); delete fret; @@ -86,25 +87,25 @@ void CAutoDerrick::Init() { Math::Matrix* mat; Math::Vector pos; - TerrainRes res; + Gfx::TerrainRes res; - pos = m_object->RetPosition(0); - res = m_terrain->RetResource(pos); + pos = m_object->GetPosition(0); + res = m_terrain->GetResource(pos); - if ( res == TR_STONE || - res == TR_URANIUM || - res == TR_KEYa || - res == TR_KEYb || - res == TR_KEYc || - res == TR_KEYd ) + if ( res == Gfx::TR_STONE || + res == Gfx::TR_URANIUM || + res == Gfx::TR_KEY_A || + res == Gfx::TR_KEY_B || + res == Gfx::TR_KEY_C || + res == Gfx::TR_KEY_D ) { m_type = OBJECT_FRET; - if ( res == TR_STONE ) m_type = OBJECT_STONE; - if ( res == TR_URANIUM ) m_type = OBJECT_URANIUM; - if ( res == TR_KEYa ) m_type = OBJECT_KEYa; - if ( res == TR_KEYb ) m_type = OBJECT_KEYb; - if ( res == TR_KEYc ) m_type = OBJECT_KEYc; - if ( res == TR_KEYd ) m_type = OBJECT_KEYd; + if ( res == Gfx::TR_STONE ) m_type = OBJECT_STONE; + if ( res == Gfx::TR_URANIUM ) m_type = OBJECT_URANIUM; + if ( res == Gfx::TR_KEY_A ) m_type = OBJECT_KEYa; + if ( res == Gfx::TR_KEY_B ) m_type = OBJECT_KEYb; + if ( res == Gfx::TR_KEY_C ) m_type = OBJECT_KEYc; + if ( res == Gfx::TR_KEY_D ) m_type = OBJECT_KEYd; m_phase = ADP_EXCAVATE; m_progress = 0.0f; @@ -119,11 +120,11 @@ void CAutoDerrick::Init() m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_lastTrack = 0.0f; pos = Math::Vector(7.0f, 0.0f, 0.0f); - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Math::Transform(*mat, pos); m_terrain->MoveOnFloor(pos); m_fretPos = pos; @@ -141,14 +142,14 @@ bool CAutoDerrick::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; if ( m_phase == ADP_WAIT ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -176,7 +177,7 @@ bool CAutoDerrick::EventProcess(const Event &event) { factor = 1.0f; } - m_soundChannel = m_sound->Play(SOUND_DERRICK, m_object->RetPosition(0), 1.0f, 0.5f, true); + m_soundChannel = m_sound->Play(SOUND_DERRICK, m_object->GetPosition(0), 1.0f, 0.5f, true); m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 4.0f*factor, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.3f, 6.0f*factor, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 1.0f, SOPER_CONTINUE); @@ -184,25 +185,25 @@ bool CAutoDerrick::EventProcess(const Event &event) } if ( m_progress >= 6.0f/16.0f && // penetrates into the ground? - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); speed.x = (Math::Rand()-0.5f)*10.0f; speed.z = (Math::Rand()-0.5f)*10.0f; speed.y = Math::Rand()*5.0f; dim.x = Math::Rand()*3.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f); } if ( m_progress >= 6.0f/16.0f && // penetrates into the ground? - m_lastTrack+m_engine->ParticuleAdapt(0.5f) <= m_time ) + m_lastTrack+m_engine->ParticleAdapt(0.5f) <= m_time ) { m_lastTrack = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); speed.x = (Math::Rand()-0.5f)*12.0f; speed.z = (Math::Rand()-0.5f)*12.0f; speed.y = Math::Rand()*10.0f+10.0f; @@ -210,7 +211,7 @@ bool CAutoDerrick::EventProcess(const Event &event) dim.y = dim.x; pos.y += dim.y; duration = Math::Rand()*2.0f+2.0f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK5, duration, Math::Rand()*10.0f+15.0f, duration*0.2f, 1.0f); } @@ -222,7 +223,7 @@ bool CAutoDerrick::EventProcess(const Event &event) pos.y = -m_progress*16.0f; m_object->SetPosition(1, pos); // down the drill - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle += event.rTime*8.0f; m_object->SetAngleY(1, angle); // rotates the drill } @@ -237,25 +238,25 @@ bool CAutoDerrick::EventProcess(const Event &event) if ( m_phase == ADP_ASCEND ) { if ( m_progress <= 7.0f/16.0f && - m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); speed.x = (Math::Rand()-0.5f)*10.0f; speed.z = (Math::Rand()-0.5f)*10.0f; speed.y = Math::Rand()*5.0f; dim.x = Math::Rand()*3.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f); } if ( m_progress <= 4.0f/16.0f && - m_lastTrack+m_engine->ParticuleAdapt(1.0f) <= m_time ) + m_lastTrack+m_engine->ParticleAdapt(1.0f) <= m_time ) { m_lastTrack = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); speed.x = (Math::Rand()-0.5f)*12.0f; speed.z = (Math::Rand()-0.5f)*12.0f; speed.y = Math::Rand()*10.0f+10.0f; @@ -263,7 +264,7 @@ bool CAutoDerrick::EventProcess(const Event &event) dim.y = dim.x; pos.y += dim.y; duration = Math::Rand()*2.0f+2.0f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK5, + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK5, duration, Math::Rand()*10.0f+15.0f, duration*0.2f, 1.0f); } @@ -275,7 +276,7 @@ bool CAutoDerrick::EventProcess(const Event &event) pos.y = -(1.0f-m_progress)*16.0f; m_object->SetPosition(1, pos); // back the drill - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle -= event.rTime*2.0f; m_object->SetAngleY(1, angle); // rotates the drill } @@ -308,7 +309,7 @@ bool CAutoDerrick::EventProcess(const Event &event) { if ( SearchFree(m_fretPos) ) { - angle = m_object->RetAngleY(0); + angle = m_object->GetAngleY(0); CreateFret(m_fretPos, angle, m_type, 16.0f); } else @@ -324,31 +325,31 @@ bool CAutoDerrick::EventProcess(const Event &event) if ( fret != 0 && m_progress <= 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; if ( m_progress < 0.3f ) { - pos = fret->RetPosition(0); + pos = fret->GetPosition(0); pos.x += (Math::Rand()-0.5f)*5.0f; pos.z += (Math::Rand()-0.5f)*5.0f; pos.y += (Math::Rand()-0.5f)*5.0f; speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 3.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIRE, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFIRE, 1.0f, 0.0f, 0.0f); } else { - pos = fret->RetPosition(0); + pos = fret->GetPosition(0); pos.x += (Math::Rand()-0.5f)*5.0f; pos.z += (Math::Rand()-0.5f)*5.0f; pos.y += Math::Rand()*2.5f; speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 2.0f, 0.0f, 0.0f); } } @@ -356,7 +357,7 @@ bool CAutoDerrick::EventProcess(const Event &event) { if ( fret != 0 ) { - pos = fret->RetPosition(0); + pos = fret->GetPosition(0); pos.y -= event.rTime*20.0f; // grave if ( !m_bSoundFall && pos.y < m_fretPos.y ) { @@ -396,7 +397,7 @@ bool CAutoDerrick::EventProcess(const Event &event) bool CAutoDerrick::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -404,7 +405,7 @@ bool CAutoDerrick::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -455,11 +456,11 @@ bool CAutoDerrick::Read(char *line) CAuto::Read(line); - m_phase = (AutoDerrickPhase)OpInt(line, "aPhase", ADP_WAIT); + m_phase = static_cast< AutoDerrickPhase >(OpInt(line, "aPhase", ADP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } @@ -476,13 +477,13 @@ CObject* CAutoDerrick::SearchFret() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type == OBJECT_DERRICK ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); if ( oPos.x == m_fretPos.x && oPos.z == m_fretPos.z ) return pObj; @@ -503,10 +504,10 @@ bool CAutoDerrick::SearchFree(Math::Vector pos) for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type == OBJECT_DERRICK ) continue; j = 0; @@ -537,12 +538,12 @@ void CAutoDerrick::CreateFret(Math::Vector pos, float angle, ObjectType type, } fret->SetLock(true); // object not yet usable - if ( m_object->RetResetCap() == RESET_MOVE ) + if ( m_object->GetResetCap() == RESET_MOVE ) { fret->SetResetCap(RESET_DELETE); } - pos = fret->RetPosition(0); + pos = fret->GetPosition(0); pos.y += height; fret->SetPosition(0, pos); } @@ -562,10 +563,10 @@ bool CAutoDerrick::ExistKey() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type == m_type ) return true; } @@ -573,11 +574,11 @@ bool CAutoDerrick::ExistKey() } -// Returns an error due the state of the automaton. +// returns an error due the state of the automaton. -Error CAutoDerrick::RetError() +Error CAutoDerrick::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } diff --git a/src/object/auto/autoderrick.h b/src/object/auto/autoderrick.h index 61a1ff1..b52f93b 100644 --- a/src/object/auto/autoderrick.h +++ b/src/object/auto/autoderrick.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -62,7 +63,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; float m_lastTrack; Math::Vector m_fretPos; int m_soundChannel; diff --git a/src/object/auto/autodestroyer.cpp b/src/object/auto/autodestroyer.cpp index b40c374..d91af29 100644 --- a/src/object/auto/autodestroyer.cpp +++ b/src/object/auto/autodestroyer.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -61,7 +62,7 @@ void CAutoDestroyer::Init() m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; CAuto::Init(); } @@ -72,19 +73,19 @@ void CAutoDestroyer::Init() bool CAutoDestroyer::EventProcess(const Event &event) { CObject* scrap; - CPyro* pyro; + Gfx::CPyro* pyro; Math::Vector pos, speed; Math::Point dim; CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -117,7 +118,7 @@ bool CAutoDestroyer::EventProcess(const Event &event) } else { - m_sound->Play(SOUND_PSHHH2, m_object->RetPosition(0), 1.0f, 1.0f); + m_sound->Play(SOUND_PSHHH2, m_object->GetPosition(0), 1.0f, 1.0f); m_phase = ADEP_DOWN; m_progress = 0.0f; @@ -133,10 +134,10 @@ bool CAutoDestroyer::EventProcess(const Event &event) if ( m_progress >= 0.3f-0.05f && !m_bExplo ) { scrap = SearchPlastic(); - if ( scrap != 0 ) + if ( scrap != nullptr ) { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, scrap); + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_FRAGT, scrap); } m_bExplo = true; } @@ -150,7 +151,7 @@ bool CAutoDestroyer::EventProcess(const Event &event) else { m_object->SetPosition(1, Math::Vector(0.0f, -10.0f, 0.0f)); - m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); + m_sound->Play(SOUND_REPAIR, m_object->GetPosition(0)); m_phase = ADEP_REPAIR; m_progress = 0.0f; @@ -165,7 +166,7 @@ bool CAutoDestroyer::EventProcess(const Event &event) } else { - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + m_sound->Play(SOUND_OPEN, m_object->GetPosition(0), 1.0f, 0.8f); m_phase = ADEP_UP; m_progress = 0.0f; @@ -199,7 +200,7 @@ bool CAutoDestroyer::EventProcess(const Event &event) bool CAutoDestroyer::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -207,8 +208,8 @@ bool CAutoDestroyer::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return false; + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return false; ox = 3.0f/640.0f; oy = 3.0f/480.0f; @@ -235,23 +236,23 @@ CObject* CAutoDestroyer::SearchPlastic() float dist; int i; - sPos = m_object->RetPosition(0); + sPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); + if ( pObj == nullptr ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_SCRAP4 && type != OBJECT_SCRAP5 ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, sPos); if ( dist <= 5.0f ) return pObj; } - return 0; + return nullptr; } // Seeks if one vehicle is too close. @@ -264,14 +265,14 @@ bool CAutoDestroyer::SearchVehicle() float oRadius, dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); - if ( pObj == 0 ) break; + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); + if ( pObj == nullptr ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_HUMAN && type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && @@ -316,11 +317,11 @@ bool CAutoDestroyer::SearchVehicle() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoDestroyer::RetError() +Error CAutoDestroyer::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -362,11 +363,11 @@ bool CAutoDestroyer::Read(char *line) CAuto::Read(line); - m_phase = (AutoDestroyerPhase)OpInt(line, "aPhase", ADEP_WAIT); + m_phase = static_cast< AutoDestroyerPhase >(OpInt(line, "aPhase", ADEP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autodestroyer.h b/src/object/auto/autodestroyer.h index 88c93ea..50858d3 100644 --- a/src/object/auto/autodestroyer.h +++ b/src/object/auto/autodestroyer.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -43,7 +44,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -59,7 +60,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; bool m_bExplo; }; diff --git a/src/object/auto/autoegg.cpp b/src/object/auto/autoegg.cpp index 4b999a9..04d03f9 100644 --- a/src/object/auto/autoegg.cpp +++ b/src/object/auto/autoegg.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -61,8 +62,8 @@ void CAutoEgg::DeleteObject(bool bAll) if ( alien != 0 ) { // Probably the intended action - // Original code: ( alien->RetZoom(0) == 1.0f ) - if ( alien->RetZoomY(0) == 1.0f ) + // Original code: ( alien->GetZoom(0) == 1.0f ) + if ( alien->GetZoomY(0) == 1.0f ) { alien->SetLock(false); alien->SetActivity(true); // the insect is active @@ -98,7 +99,7 @@ void CAutoEgg::Init() m_speed = 1.0f/5.0f; m_time = 0.0f; - m_type = alien->RetType(); + m_type = alien->GetType(); if ( m_type == OBJECT_ANT || m_type == OBJECT_SPIDER || @@ -164,9 +165,9 @@ bool CAutoEgg::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( event.type != EVENT_FRAME ) return true; if ( m_phase == AEP_NULL ) return true; if ( m_phase == AEP_DELAY ) @@ -175,7 +176,7 @@ bool CAutoEgg::EventProcess(const Event &event) if ( m_progress < 1.0f ) return true; alien = new CObject(m_iMan); - if ( !alien->CreateInsect(m_object->RetPosition(0), m_object->RetAngleY(0), m_type) ) + if ( !alien->CreateInsect(m_object->GetPosition(0), m_object->GetAngleY(0), m_type) ) { delete alien; m_phase = AEP_DELAY; @@ -213,7 +214,7 @@ bool CAutoEgg::EventProcess(const Event &event) Error CAutoEgg::IsEnded() { CObject* alien; - CPyro* pyro; + Gfx::CPyro* pyro; if ( m_phase == AEP_DELAY ) { @@ -236,8 +237,8 @@ Error CAutoEgg::IsEnded() { if ( m_progress < 1.0f ) return ERR_CONTINUE; - pyro = new CPyro(m_iMan); - pyro->Create(PT_EGG, m_object); // exploding egg + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_EGG, m_object); // exploding egg alien->SetZoom(0, 1.0f); // this is a big boy now @@ -258,9 +259,9 @@ Error CAutoEgg::IsEnded() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoEgg::RetError() +Error CAutoEgg::GetError() { return ERR_OK; } @@ -277,23 +278,23 @@ CObject* CAutoEgg::SearchAlien() float dist, min; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); min = 100000.0f; pBest = 0; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->GetTruck() != 0 ) continue; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_ANT && type != OBJECT_BEE && type != OBJECT_SPIDER && type != OBJECT_WORM ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(oPos, cPos); if ( dist < 8.0f && dist < min ) { @@ -347,7 +348,7 @@ bool CAutoEgg::Read(char *line) CAuto::Read(line); - m_phase = (AutoEggPhase)OpInt(line, "aPhase", AEP_NULL); + m_phase = static_cast< AutoEggPhase >(OpInt(line, "aPhase", AEP_NULL)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); m_type = OpTypeObject(line, "aParamType", OBJECT_NULL); diff --git a/src/object/auto/autoegg.h b/src/object/auto/autoegg.h index 443dff6..fec07a6 100644 --- a/src/object/auto/autoegg.h +++ b/src/object/auto/autoegg.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -45,7 +46,7 @@ public: void Start(int param); bool EventProcess(const Event &event); Error IsEnded(); - Error RetError(); + Error GetError(); bool SetType(ObjectType type); bool SetValue(int rank, float value); diff --git a/src/object/auto/autoenergy.cpp b/src/object/auto/autoenergy.cpp index 409e282..d0117ab 100644 --- a/src/object/auto/autoenergy.cpp +++ b/src/object/auto/autoenergy.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -20,7 +21,7 @@ #include "object/auto/autoenergy.h" #include "common/iman.h" -#include "old/terrain.h" +#include "graphics/engine/terrain.h" #include "math/geometry.h" #include "script/cmdtoken.h" #include "ui/interface.h" @@ -60,7 +61,7 @@ void CAutoEnergy::DeleteObject(bool bAll) if ( m_partiSphere != -1 ) { - m_particule->DeleteParticule(m_partiSphere); + m_particle->DeleteParticle(m_partiSphere); m_partiSphere = -1; } @@ -92,7 +93,7 @@ void CAutoEnergy::Init() m_time = 0.0f; m_timeVirus = 0.0f; m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_phase = AENP_WAIT; // waiting ... m_progress = 0.0f; @@ -109,35 +110,35 @@ bool CAutoEnergy::EventProcess(const Event &event) CObject* fret; Math::Vector pos, ppos, speed; Math::Point dim, c, p; - TerrainRes res; + Gfx::TerrainRes res; float big; bool bGO; CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { m_timeVirus = 0.1f+Math::Rand()*0.3f; - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; - pos = m_object->RetPosition(0); + m_lastParticle = m_time; + pos = m_object->GetPosition(0); pos.y += 10.0f; speed.x = (Math::Rand()-0.5f)*10.0f; speed.z = (Math::Rand()-0.5f)*10.0f; speed.y = -7.0f; dim.x = Math::Rand()*0.5f+0.5f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFIREZ, 1.0f, 0.0f, 0.0f); } } return true; @@ -146,10 +147,10 @@ bool CAutoEnergy::EventProcess(const Event &event) UpdateInterface(event.rTime); EventProgress(event.rTime); - big = m_object->RetEnergy(); + big = m_object->GetEnergy(); - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res == TR_POWER ) + res = m_terrain->GetResource(m_object->GetPosition(0)); + if ( res == Gfx::TR_POWER ) { big += event.rTime*0.01f; // recharges the big pile } @@ -162,7 +163,7 @@ bool CAutoEnergy::EventProcess(const Event &event) fret = SearchMetal(); // transform metal? if ( fret != 0 ) { - if ( fret->RetType() == OBJECT_METAL ) + if ( fret->GetType() == OBJECT_METAL ) { if ( big > ENERGY_POWER ) bGO = true; } @@ -174,7 +175,7 @@ bool CAutoEnergy::EventProcess(const Event &event) if ( bGO ) { - if ( fret->RetType() == OBJECT_METAL ) + if ( fret->GetType() == OBJECT_METAL ) { fret->SetLock(true); // usable metal CreatePower(); // creates the battery @@ -184,12 +185,12 @@ bool CAutoEnergy::EventProcess(const Event &event) InitProgressTotal(ENERGY_DELAY); CAuto::UpdateInterface(); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 4.0f; speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 3.0f; dim.y = dim.x; - m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE1, ENERGY_DELAY, 0.0f, 0.0f); + m_partiSphere = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE1, ENERGY_DELAY, 0.0f, 0.0f); m_phase = AENP_CREATE; m_progress = 0.0f; @@ -217,17 +218,17 @@ bool CAutoEnergy::EventProcess(const Event &event) { if ( m_progress < 1.0f && big > 0.01f ) { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; - pos = m_object->RetPosition(0); + m_lastParticle = m_time; + pos = m_object->GetPosition(0); pos.y += 10.0f; speed.x = (Math::Rand()-0.5f)*1.0f; speed.z = (Math::Rand()-0.5f)*1.0f; speed.y = -7.0f; dim.x = Math::Rand()*0.5f+0.5f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFIREZ, 1.0f, 0.0f, 0.0f); } } else @@ -245,7 +246,7 @@ bool CAutoEnergy::EventProcess(const Event &event) fret = SearchMetal(); if ( fret != 0 ) { - if ( fret->RetType() == OBJECT_METAL ) + if ( fret->GetType() == OBJECT_METAL ) { big -= event.rTime/ENERGY_DELAY*ENERGY_POWER; } @@ -262,11 +263,11 @@ bool CAutoEnergy::EventProcess(const Event &event) fret->SetZoom(0, m_progress); } - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); c.x = pos.x; c.y = pos.z; p.x = c.x; @@ -278,27 +279,27 @@ bool CAutoEnergy::EventProcess(const Event &event) speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = Math::Rand()*2.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 1.0f, 0.0f, 0.0f); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 3.0f; speed.x = (Math::Rand()-0.5f)*30.0f; speed.z = (Math::Rand()-0.5f)*30.0f; speed.y = Math::Rand()*20.0f+10.0f; dim.x = Math::Rand()*0.4f+0.4f; dim.y = dim.x; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, 2.0f, 50.0f, 1.2f, 1.2f); + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK2, 2.0f, 50.0f, 1.2f, 1.2f); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 10.0f; speed.x = (Math::Rand()-0.5f)*1.5f; speed.z = (Math::Rand()-0.5f)*1.5f; speed.y = -6.0f; dim.x = Math::Rand()*1.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFIREZ, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFIREZ, 1.0f, 0.0f, 0.0f); - m_sound->Play(SOUND_ENERGY, m_object->RetPosition(0), + m_sound->Play(SOUND_ENERGY, m_object->GetPosition(0), 1.0f, 1.0f+Math::Rand()*1.5f); } } @@ -337,11 +338,11 @@ bool CAutoEnergy::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 17.0f; pos.x += (Math::Rand()-0.5f)*3.0f; pos.z += (Math::Rand()-0.5f)*3.0f; @@ -350,7 +351,7 @@ bool CAutoEnergy::EventProcess(const Event &event) speed.y = 6.0f+Math::Rand()*6.0f; dim.x = Math::Rand()*1.5f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f); } } else @@ -376,10 +377,10 @@ CObject* CAutoEnergy::SearchMetal() CObject* pObj; ObjectType type; - pObj = m_object->RetPower(); + pObj = m_object->GetPower(); if ( pObj == 0 ) return 0; - type = pObj->RetType(); + type = pObj->GetType(); if ( type == OBJECT_METAL || type == OBJECT_SCRAP1 || type == OBJECT_SCRAP2 || @@ -398,14 +399,14 @@ bool CAutoEnergy::SearchVehicle() float oRadius, dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_HUMAN && type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && @@ -457,8 +458,8 @@ void CAutoEnergy::CreatePower() Math::Vector pos; float angle; - pos = m_object->RetPosition(0); - angle = m_object->RetAngleY(0); + pos = m_object->GetPosition(0); + angle = m_object->GetAngleY(0); power = new CObject(m_iMan); if ( !power->CreateResource(pos, angle, OBJECT_POWER) ) @@ -469,7 +470,7 @@ void CAutoEnergy::CreatePower() } power->SetLock(true); // battery not yet usable - pos = power->RetPosition(0); + pos = power->GetPosition(0); pos.y += 3.0f; power->SetPosition(0, pos); } @@ -483,19 +484,19 @@ CObject* CAutoEnergy::SearchPower() ObjectType type; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( !pObj->RetLock() ) continue; + if ( !pObj->GetLock() ) continue; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_POWER ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); if ( oPos.x == cPos.x && oPos.z == cPos.z ) { @@ -507,15 +508,15 @@ CObject* CAutoEnergy::SearchPower() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoEnergy::RetError() +Error CAutoEnergy::GetError() { CObject* pObj; ObjectType type; - TerrainRes res; + Gfx::TerrainRes res; - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -523,14 +524,14 @@ Error CAutoEnergy::RetError() if ( m_phase != AENP_WAIT && m_phase != AENP_BLITZ ) return ERR_OK; - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res != TR_POWER ) return ERR_ENERGY_NULL; + res = m_terrain->GetResource(m_object->GetPosition(0)); + if ( res != Gfx::TR_POWER ) return ERR_ENERGY_NULL; - if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_ENERGY_LOW; + if ( m_object->GetEnergy() < ENERGY_POWER ) return ERR_ENERGY_LOW; - pObj = m_object->RetPower(); + pObj = m_object->GetPower(); if ( pObj == 0 ) return ERR_ENERGY_EMPTY; - type = pObj->RetType(); + type = pObj->GetType(); if ( type == OBJECT_POWER ) return ERR_OK; if ( type != OBJECT_METAL && type != OBJECT_SCRAP1 && @@ -545,7 +546,7 @@ Error CAutoEnergy::RetError() bool CAutoEnergy::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -553,7 +554,7 @@ bool CAutoEnergy::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -581,23 +582,23 @@ bool CAutoEnergy::CreateInterface(bool bSelect) void CAutoEnergy::UpdateInterface(float rTime) { - CWindow* pw; - CGauge* pg; + Ui::CWindow* pw; + Ui::CGauge* pg; CAuto::UpdateInterface(rTime); if ( m_time < m_lastUpdateTime+0.1f ) return; m_lastUpdateTime = m_time; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); if ( pg != 0 ) { - pg->SetLevel(m_object->RetEnergy()); + pg->SetLevel(m_object->GetEnergy()); } } @@ -636,12 +637,12 @@ bool CAutoEnergy::Read(char *line) CAuto::Read(line); - m_phase = (AutoEnergyPhase)OpInt(line, "aPhase", AENP_WAIT); + m_phase = static_cast< AutoEnergyPhase >(OpInt(line, "aPhase", AENP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autoenergy.h b/src/object/auto/autoenergy.h index 727f2c3..53d47b6 100644 --- a/src/object/auto/autoenergy.h +++ b/src/object/auto/autoenergy.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -65,7 +66,7 @@ protected: float m_speed; float m_timeVirus; float m_lastUpdateTime; - float m_lastParticule; + float m_lastParticle; int m_partiSphere; }; diff --git a/src/object/auto/autofactory.cpp b/src/object/auto/autofactory.cpp index f02195c..8e7d480 100644 --- a/src/object/auto/autofactory.cpp +++ b/src/object/auto/autofactory.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -95,9 +96,9 @@ void CAutoFactory::Init() m_speed = 1.0f/2.0f; m_time = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; - m_fretPos = m_object->RetPosition(0); + m_fretPos = m_object->GetPosition(0); CAuto::Init(); } @@ -119,37 +120,37 @@ bool CAutoFactory::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; - if ( m_object->RetSelect() ) // factory selected? + if ( m_object->GetSelect() ) // factory selected? { - if ( event.event == EVENT_UPDINTERFACE ) + if ( event.type == EVENT_UPDINTERFACE ) { CreateInterface(true); } type = OBJECT_NULL; - if ( event.event == EVENT_OBJECT_FACTORYwa ) type = OBJECT_MOBILEwa; - if ( event.event == EVENT_OBJECT_FACTORYta ) type = OBJECT_MOBILEta; - if ( event.event == EVENT_OBJECT_FACTORYfa ) type = OBJECT_MOBILEfa; - if ( event.event == EVENT_OBJECT_FACTORYia ) type = OBJECT_MOBILEia; - if ( event.event == EVENT_OBJECT_FACTORYws ) type = OBJECT_MOBILEws; - if ( event.event == EVENT_OBJECT_FACTORYts ) type = OBJECT_MOBILEts; - if ( event.event == EVENT_OBJECT_FACTORYfs ) type = OBJECT_MOBILEfs; - if ( event.event == EVENT_OBJECT_FACTORYis ) type = OBJECT_MOBILEis; - if ( event.event == EVENT_OBJECT_FACTORYwc ) type = OBJECT_MOBILEwc; - if ( event.event == EVENT_OBJECT_FACTORYtc ) type = OBJECT_MOBILEtc; - if ( event.event == EVENT_OBJECT_FACTORYfc ) type = OBJECT_MOBILEfc; - if ( event.event == EVENT_OBJECT_FACTORYic ) type = OBJECT_MOBILEic; - if ( event.event == EVENT_OBJECT_FACTORYwi ) type = OBJECT_MOBILEwi; - if ( event.event == EVENT_OBJECT_FACTORYti ) type = OBJECT_MOBILEti; - if ( event.event == EVENT_OBJECT_FACTORYfi ) type = OBJECT_MOBILEfi; - if ( event.event == EVENT_OBJECT_FACTORYii ) type = OBJECT_MOBILEii; - if ( event.event == EVENT_OBJECT_FACTORYrt ) type = OBJECT_MOBILErt; - if ( event.event == EVENT_OBJECT_FACTORYrc ) type = OBJECT_MOBILErc; - if ( event.event == EVENT_OBJECT_FACTORYrr ) type = OBJECT_MOBILErr; - if ( event.event == EVENT_OBJECT_FACTORYrs ) type = OBJECT_MOBILErs; - if ( event.event == EVENT_OBJECT_FACTORYsa ) type = OBJECT_MOBILEsa; + if ( event.type == EVENT_OBJECT_FACTORYwa ) type = OBJECT_MOBILEwa; + if ( event.type == EVENT_OBJECT_FACTORYta ) type = OBJECT_MOBILEta; + if ( event.type == EVENT_OBJECT_FACTORYfa ) type = OBJECT_MOBILEfa; + if ( event.type == EVENT_OBJECT_FACTORYia ) type = OBJECT_MOBILEia; + if ( event.type == EVENT_OBJECT_FACTORYws ) type = OBJECT_MOBILEws; + if ( event.type == EVENT_OBJECT_FACTORYts ) type = OBJECT_MOBILEts; + if ( event.type == EVENT_OBJECT_FACTORYfs ) type = OBJECT_MOBILEfs; + if ( event.type == EVENT_OBJECT_FACTORYis ) type = OBJECT_MOBILEis; + if ( event.type == EVENT_OBJECT_FACTORYwc ) type = OBJECT_MOBILEwc; + if ( event.type == EVENT_OBJECT_FACTORYtc ) type = OBJECT_MOBILEtc; + if ( event.type == EVENT_OBJECT_FACTORYfc ) type = OBJECT_MOBILEfc; + if ( event.type == EVENT_OBJECT_FACTORYic ) type = OBJECT_MOBILEic; + if ( event.type == EVENT_OBJECT_FACTORYwi ) type = OBJECT_MOBILEwi; + if ( event.type == EVENT_OBJECT_FACTORYti ) type = OBJECT_MOBILEti; + if ( event.type == EVENT_OBJECT_FACTORYfi ) type = OBJECT_MOBILEfi; + if ( event.type == EVENT_OBJECT_FACTORYii ) type = OBJECT_MOBILEii; + if ( event.type == EVENT_OBJECT_FACTORYrt ) type = OBJECT_MOBILErt; + if ( event.type == EVENT_OBJECT_FACTORYrc ) type = OBJECT_MOBILErc; + if ( event.type == EVENT_OBJECT_FACTORYrr ) type = OBJECT_MOBILErr; + if ( event.type == EVENT_OBJECT_FACTORYrs ) type = OBJECT_MOBILErs; + if ( event.type == EVENT_OBJECT_FACTORYsa ) type = OBJECT_MOBILEsa; if ( type != OBJECT_NULL ) { @@ -186,7 +187,7 @@ bool CAutoFactory::EventProcess(const Event &event) } } - if ( event.event != EVENT_FRAME ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; EventProgress(event.rTime); @@ -249,7 +250,7 @@ bool CAutoFactory::EventProcess(const Event &event) m_object->SetAngleZ(10+i, 0.0f); } - m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->RetPosition(0), 0.0f, 1.0f, true); + m_channelSound = m_sound->Play(SOUND_FACTORY, m_object->GetPosition(0), 0.0f, 1.0f, true); m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 11.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); @@ -300,7 +301,7 @@ bool CAutoFactory::EventProcess(const Event &event) { prog = 1.0f-m_progress; } - angle = powf(prog*10.0f, 2.0f)+m_object->RetAngleY(0); + angle = powf(prog*10.0f, 2.0f)+m_object->GetAngleY(0); vehicle = SearchVehicle(); if ( vehicle != 0 ) @@ -315,9 +316,9 @@ bool CAutoFactory::EventProcess(const Event &event) fret->SetZoom(0, 1.0f-m_progress); } - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; #if 0 pos = m_fretPos; @@ -329,9 +330,9 @@ bool CAutoFactory::EventProcess(const Event &event) speed.y = Math::Rand()*12.0f; dim.x = Math::Rand()*12.0f+10.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); #else - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Math::Vector(-12.0f, 20.0f, -4.0f); // position of chimney pos = Math::Transform(*mat, pos); pos.y += 2.0f; @@ -342,7 +343,7 @@ bool CAutoFactory::EventProcess(const Event &event) speed.y = 6.0f+Math::Rand()*6.0f; dim.x = Math::Rand()*1.5f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f); #endif } } @@ -361,15 +362,15 @@ bool CAutoFactory::EventProcess(const Event &event) vehicle = SearchVehicle(); if ( vehicle != 0 ) { - physics = vehicle->RetPhysics(); + physics = vehicle->GetPhysics(); if ( physics != 0 ) { physics->SetFreeze(false); // can move } vehicle->SetLock(false); // vehicle useable -//? vehicle->RetPhysics()->RetBrain()->StartTaskAdvance(16.0f); - vehicle->SetAngleY(0, m_object->RetAngleY(0)+Math::PI); +//? vehicle->GetPhysics()->GetBrain()->StartTaskAdvance(16.0f); + vehicle->SetAngleY(0, m_object->GetAngleY(0)+Math::PI); vehicle->SetZoom(0, 1.0f); } @@ -392,9 +393,9 @@ bool CAutoFactory::EventProcess(const Event &event) m_object->SetAngleZ(10+i, -angle); } - if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; pos = m_fretPos; pos.x += (Math::Rand()-0.5f)*10.0f; @@ -403,7 +404,7 @@ bool CAutoFactory::EventProcess(const Event &event) speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 2.0f, 0.0f, 0.0f); } } else @@ -435,9 +436,9 @@ bool CAutoFactory::EventProcess(const Event &event) m_object->SetZoomZ(10+i, zoom); } - if ( m_lastParticule+m_engine->ParticuleAdapt(0.1f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.1f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; pos = m_fretPos; pos.x += (Math::Rand()-0.5f)*10.0f; @@ -446,7 +447,7 @@ bool CAutoFactory::EventProcess(const Event &event) speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 2.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 2.0f, 0.0f, 0.0f); } } else @@ -503,12 +504,12 @@ bool CAutoFactory::Read(char *line) CAuto::Read(line); - m_phase = (AutoFactoryPhase)OpInt(line, "aPhase", AFP_WAIT); + m_phase = static_cast< AutoFactoryPhase >(OpInt(line, "aPhase", AFP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; - m_fretPos = m_object->RetPosition(0); + m_lastParticle = 0.0f; + m_fretPos = m_object->GetPosition(0); return true; } @@ -526,14 +527,14 @@ CObject* CAutoFactory::SearchFret() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_METAL ) continue; - if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->GetTruck() != 0 ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, m_fretPos); if ( dist < 8.0f ) return pObj; @@ -552,14 +553,14 @@ bool CAutoFactory::NearestVehicle() float oRadius, dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_HUMAN && type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && @@ -616,9 +617,9 @@ bool CAutoFactory::CreateVehicle() char* name; int i; - angle = m_object->RetAngleY(0); + angle = m_object->GetAngleY(0); - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); if ( m_type == OBJECT_MOBILErt || m_type == OBJECT_MOBILErc || m_type == OBJECT_MOBILErr || @@ -643,7 +644,7 @@ bool CAutoFactory::CreateVehicle() vehicle->SetLock(true); // not usable vehicle->SetRange(30.0f); - physics = vehicle->RetPhysics(); + physics = vehicle->GetPhysics(); if ( physics != 0 ) { physics->SetFreeze(true); // it doesn't move @@ -651,7 +652,7 @@ bool CAutoFactory::CreateVehicle() for ( i=0 ; i<10 ; i++ ) { - name = m_main->RetNewScriptName(m_type, i); + name = m_main->GetNewScriptName(m_type, i); if ( name == 0 ) break; vehicle->ReadProgram(i, name); } @@ -671,16 +672,16 @@ CObject* CAutoFactory::SearchVehicle() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( !pObj->RetLock() ) continue; + if ( !pObj->GetLock() ) continue; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != m_type ) continue; - if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->GetTruck() != 0 ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, m_fretPos); if ( dist < 8.0f ) return pObj; @@ -694,7 +695,7 @@ CObject* CAutoFactory::SearchVehicle() bool CAutoFactory::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, dim, ddim; float ox, oy, sx, sy; @@ -702,8 +703,8 @@ bool CAutoFactory::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return false; + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return false; dim.x = 33.0f/640.0f; dim.y = 33.0f/480.0f; @@ -786,13 +787,13 @@ bool CAutoFactory::CreateInterface(bool bSelect) void CAutoFactory::UpdateInterface() { - CWindow* pw; + Ui::CWindow* pw; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; CAuto::UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); UpdateButton(pw, EVENT_OBJECT_FACTORYwa, m_bBusy); UpdateButton(pw, EVENT_OBJECT_FACTORYta, m_bBusy); @@ -819,7 +820,7 @@ void CAutoFactory::UpdateInterface() // Updates the status of one interface button. -void CAutoFactory::UpdateButton(CWindow *pw, EventMsg event, bool bBusy) +void CAutoFactory::UpdateButton(Ui::CWindow *pw, EventType event, bool bBusy) { bool bEnable = true; @@ -933,7 +934,7 @@ void CAutoFactory::SoundManip(float time, float amplitude, float frequency) { int i; - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, true); + i = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 0.0f, 0.3f*frequency, true); m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); diff --git a/src/object/auto/autofactory.h b/src/object/auto/autofactory.h index acbdf40..f62080d 100644 --- a/src/object/auto/autofactory.h +++ b/src/object/auto/autofactory.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -54,7 +55,7 @@ public: protected: void UpdateInterface(); - void UpdateButton(CWindow *pw, EventMsg event, bool bBusy); + void UpdateButton(Ui::CWindow *pw, EventType event, bool bBusy); CObject* SearchFret(); bool NearestVehicle(); @@ -67,7 +68,7 @@ protected: AutoFactoryPhase m_phase; float m_progress; float m_speed; - float m_lastParticule; + float m_lastParticle; Math::Vector m_fretPos; int m_channelSound; }; diff --git a/src/object/auto/autoflag.cpp b/src/object/auto/autoflag.cpp index ea74b17..acab2d0 100644 --- a/src/object/auto/autoflag.cpp +++ b/src/object/auto/autoflag.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -20,7 +21,7 @@ #include "object/auto/autoflag.h" #include "math/geometry.h" -#include "old/terrain.h" +#include "graphics/engine/terrain.h" @@ -68,7 +69,7 @@ void CAutoFlag::Init() m_param = 0; m_progress = 0.0f; - wind = m_terrain->RetWind(); + wind = m_terrain->GetWind(); angle = Math::RotateAngle(wind.x, -wind.z); m_object->SetAngleY(0, angle); // directs the flag in the wind @@ -98,7 +99,7 @@ bool CAutoFlag::EventProcess(const Event &event) CAuto::EventProcess(event); #if ADJUST_ANGLE - if ( event.event == EVENT_KEYDOWN ) + if ( event.type == EVENT_KEYDOWN ) { if ( event.param == 'E' ) g_flag1 += 0.1f; if ( event.param == 'D' ) g_flag1 -= 0.1f; @@ -109,8 +110,8 @@ bool CAutoFlag::EventProcess(const Event &event) } #endif - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; if ( m_param == 1 ) // shakes? { @@ -152,9 +153,9 @@ bool CAutoFlag::EventProcess(const Event &event) } -// Returns an error due the state of the automation +// Geturns an error due the state of the automation -Error CAutoFlag::RetError() +Error CAutoFlag::GetError() { return ERR_OK; } diff --git a/src/object/auto/autoflag.h b/src/object/auto/autoflag.h index fdec682..3c6cf99 100644 --- a/src/object/auto/autoflag.h +++ b/src/object/auto/autoflag.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -34,7 +35,7 @@ public: void Init(); void Start(int param); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); protected: diff --git a/src/object/auto/autohuston.cpp b/src/object/auto/autohuston.cpp index a96bcb8..1dd92f0 100644 --- a/src/object/auto/autohuston.cpp +++ b/src/object/auto/autohuston.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -38,11 +39,11 @@ CAutoHuston::CAutoHuston(CInstanceManager* iMan, CObject* object) m_lens[i].parti = -1; } - pos = m_object->RetPosition(0); - m_lens[0].type = PARTISELR; - m_lens[1].type = PARTISELR; - m_lens[2].type = PARTISELR; - m_lens[3].type = PARTISELR; + pos = m_object->GetPosition(0); + m_lens[0].type = Gfx::PARTISELR; + m_lens[1].type = Gfx::PARTISELR; + m_lens[2].type = Gfx::PARTISELR; + m_lens[3].type = Gfx::PARTISELR; m_lens[0].pos = pos+Math::Vector(0.0f+13.0f, 34.0f, 30.0f ); m_lens[1].pos = pos+Math::Vector(0.0f-13.0f, 34.0f, 30.0f ); m_lens[2].pos = pos+Math::Vector(0.0f , 34.0f, 30.0f+13.0f); @@ -62,46 +63,46 @@ CAutoHuston::CAutoHuston(CInstanceManager* iMan, CObject* object) // Part under the radar. i = 4; - m_lens[i].type = PARTISELR; + m_lens[i].type = Gfx::PARTISELR; m_lens[i].pos = pos+Math::Vector(-7.0f, 9.9f, 40.1f); m_lens[i].dim = 1.8f; m_lens[i].total = 0.4f; m_lens[i].off = 0.2f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-7.0f, 7.2f, 34.8f); m_lens[i].dim = 0.4f; m_lens[i].total = 0.7f; m_lens[i].off = 0.3f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 34.3f); m_lens[i].dim = 0.4f; m_lens[i].total = 0.7f; m_lens[i].off = 0.3f; i ++; - m_lens[i].type = PARTISELR; + m_lens[i].type = Gfx::PARTISELR; m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.4f); m_lens[i].dim = 0.4f; m_lens[i].total = 0.0f; m_lens[i].off = 0.0f; i ++; - m_lens[i].type = PARTISELR; + m_lens[i].type = Gfx::PARTISELR; m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.0f); m_lens[i].dim = 0.4f; m_lens[i].total = 1.0f; m_lens[i].off = 0.5f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-7.0f, 8.5f, 14.0f); m_lens[i].dim = 1.2f; m_lens[i].total = 0.8f; m_lens[i].off = 0.2f; i ++; - m_lens[i].type = PARTISELR; + m_lens[i].type = Gfx::PARTISELR; m_lens[i].pos = pos+Math::Vector(4.0f, 6.0f, 8.6f); m_lens[i].dim = 1.0f; m_lens[i].total = 0.9f; @@ -109,53 +110,53 @@ CAutoHuston::CAutoHuston(CInstanceManager* iMan, CObject* object) i ++; // Part with three windows. - m_lens[i].type = PARTISELR; + m_lens[i].type = Gfx::PARTISELR; m_lens[i].pos = pos+Math::Vector(-7.0f, 9.9f, -19.9f); m_lens[i].dim = 1.0f; m_lens[i].total = 0.6f; m_lens[i].off = 0.3f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-7.0f, 7.2f, 34.8f-60.0f); m_lens[i].dim = 0.4f; m_lens[i].total = 0.7f; m_lens[i].off = 0.3f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 34.3f-60.0f); m_lens[i].dim = 0.4f; m_lens[i].total = 0.0f; m_lens[i].off = 0.0f; i ++; - m_lens[i].type = PARTISELR; + m_lens[i].type = Gfx::PARTISELR; m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.4f-60.0f); m_lens[i].dim = 0.4f; m_lens[i].total = 0.6f; m_lens[i].off = 0.4f; i ++; - m_lens[i].type = PARTISELR; + m_lens[i].type = Gfx::PARTISELR; m_lens[i].pos = pos+Math::Vector(-7.0f, 6.5f, 33.0f-60.0f); m_lens[i].dim = 0.4f; m_lens[i].total = 0.8f; m_lens[i].off = 0.2f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-6.5f, 13.5f, -37.0f); m_lens[i].dim = 1.0f; m_lens[i].total = 0.0f; m_lens[i].off = 0.0f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-7.0f, 12.2f, -39.8f); m_lens[i].dim = 1.8f; m_lens[i].total = 1.5f; m_lens[i].off = 0.5f; i ++; - m_lens[i].type = PARTISELY; + m_lens[i].type = Gfx::PARTISELY; m_lens[i].pos = pos+Math::Vector(-7.0f, 8.5f, -47.0f); m_lens[i].dim = 0.6f; m_lens[i].total = 0.7f; @@ -211,14 +212,14 @@ bool CAutoHuston::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; angle = -m_time*1.0f; m_object->SetAngleY(1, angle); // rotates the radar angle = sinf(m_time*4.0f)*0.3f; m_object->SetAngleX(2, angle); - if ( event.event != EVENT_FRAME ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; @@ -231,7 +232,7 @@ bool CAutoHuston::EventProcess(const Event &event) { if ( m_lens[i].parti != -1 ) { - m_particule->DeleteParticule(m_lens[i].parti); + m_particle->DeleteParticle(m_lens[i].parti); m_lens[i].parti = -1; } } @@ -241,7 +242,7 @@ bool CAutoHuston::EventProcess(const Event &event) { dim.x = m_lens[i].dim; dim.y = dim.x; - m_lens[i].parti = m_particule->CreateParticule(m_lens[i].pos, speed, dim, m_lens[i].type, 1.0f, 0.0f, 0.0f); + m_lens[i].parti = m_particle->CreateParticle(m_lens[i].pos, speed, dim, m_lens[i].type, 1.0f, 0.0f, 0.0f); } } } @@ -261,7 +262,7 @@ bool CAutoHuston::Abort() bool CAutoHuston::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -269,8 +270,8 @@ bool CAutoHuston::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return false; + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return false; ox = 3.0f/640.0f; oy = 3.0f/480.0f; @@ -287,9 +288,9 @@ bool CAutoHuston::CreateInterface(bool bSelect) } -// Returns an error due to state of the automation. +// Geturns an error due to state of the automation. -Error CAutoHuston::RetError() +Error CAutoHuston::GetError() { return ERR_OK; } diff --git a/src/object/auto/autohuston.h b/src/object/auto/autohuston.h index a59f8f2..27b016b 100644 --- a/src/object/auto/autohuston.h +++ b/src/object/auto/autohuston.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -20,18 +21,18 @@ #include "object/auto/auto.h" -#include "old/particule.h" +#include "graphics/engine/particle.h" struct HustonLens { - int parti; - ParticuleType type; + int parti; + Gfx::ParticleType type; Math::Vector pos; - float dim; - float total; - float off; + float dim; + float total; + float off; }; @@ -50,7 +51,7 @@ public: void Start(int param); bool EventProcess(const Event &event); bool Abort(); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); diff --git a/src/object/auto/autoinfo.cpp b/src/object/auto/autoinfo.cpp index 56fd8c7..1edd5e0 100644 --- a/src/object/auto/autoinfo.cpp +++ b/src/object/auto/autoinfo.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -90,8 +91,8 @@ void CAutoInfo::Start(int param) m_speed = 1.0f/2.0f; } - m_lastParticule = 0; - m_goal = m_object->RetPosition(0); + m_lastParticle = 0; + m_goal = m_object->GetPosition(0); if ( m_phase == AIP_EMETTE ) { @@ -100,7 +101,7 @@ void CAutoInfo::Start(int param) speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 30.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISPHERE4, 1.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE4, 1.5f, 0.0f, 0.0f); m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); } @@ -111,7 +112,7 @@ void CAutoInfo::Start(int param) speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 50.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISPHERE6, 1.5f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISPHERE6, 1.5f, 0.0f, 0.0f); m_sound->Play(SOUND_LABO, pos, 1.0f, 2.0f); } @@ -133,18 +134,18 @@ bool CAutoInfo::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { m_timeVirus = 0.1f+Math::Rand()*0.3f; - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle += Math::Rand()*0.3f; m_object->SetAngleY(1, angle); @@ -170,7 +171,7 @@ bool CAutoInfo::EventProcess(const Event &event) } else { - if ( m_object->RetInfoUpdate() ) + if ( m_object->GetInfoUpdate() ) { UpdateList(); // updates the list } @@ -184,9 +185,9 @@ bool CAutoInfo::EventProcess(const Event &event) if ( m_phase == AIP_EMETTE ) // instruction "receive" ? { if ( m_progress < 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; for ( i=0 ; i<4 ; i++ ) { @@ -199,7 +200,7 @@ bool CAutoInfo::EventProcess(const Event &event) dim.x = 0.6f; dim.y = dim.x; duration = Math::Rand()*0.5f+0.5f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK6, duration, 0.0f, duration*0.9f, 0.7f); } @@ -230,9 +231,9 @@ bool CAutoInfo::EventProcess(const Event &event) if ( m_phase == AIP_RECEIVE ) // instruction "send" ? { if ( m_progress < 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; for ( i=0 ; i<4 ; i++ ) { @@ -247,7 +248,7 @@ bool CAutoInfo::EventProcess(const Event &event) dim.x = 0.6f; dim.y = dim.x; duration = Math::Rand()*0.5f+0.5f; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK6, + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK6, duration, 0.0f, duration*0.9f, 0.7f); } @@ -278,9 +279,9 @@ bool CAutoInfo::EventProcess(const Event &event) if ( m_phase == AIP_ERROR ) { if ( m_progress < 0.5f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; pos = m_goal; speed.x = (Math::Rand()-0.5f)*5.0f; @@ -289,7 +290,7 @@ bool CAutoInfo::EventProcess(const Event &event) dim.x = 5.0f+Math::Rand()*5.0f; dim.y = dim.x; duration = Math::Rand()*0.5f+0.5f; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 4.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE1, 4.0f); } if ( m_progress < 1.0f ) @@ -327,7 +328,7 @@ bool CAutoInfo::EventProcess(const Event &event) } } - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle += rTime*0.5f; m_object->SetAngleY(1, angle); @@ -339,11 +340,11 @@ bool CAutoInfo::EventProcess(const Event &event) } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoInfo::RetError() +Error CAutoInfo::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -356,8 +357,8 @@ Error CAutoInfo::RetError() bool CAutoInfo::CreateInterface(bool bSelect) { - CWindow* pw; - CList* pl; + Ui::CWindow* pw; + Ui::CList* pl; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -365,7 +366,7 @@ bool CAutoInfo::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -403,31 +404,31 @@ void CAutoInfo::UpdateInterface(float rTime) void CAutoInfo::UpdateList() { - CWindow* pw; - CList* pl; + Ui::CWindow* pw; + Ui::CList* pl; Info info; int total, i; char text[100]; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); - if ( pw == 0 ) return; + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); + if ( pw == nullptr ) return; - pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); - if ( pl == 0 ) return; + pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_GINFO)); + if ( pl == nullptr ) return; pl->Flush(); - total = m_object->RetInfoTotal(); + total = m_object->GetInfoTotal(); if ( total == 0 ) { - pl->ClearState(STATE_ENABLE); + pl->ClearState(Ui::STATE_ENABLE); } else { - pl->SetState(STATE_ENABLE); + pl->SetState(Ui::STATE_ENABLE); for ( i=0 ; i<total ; i++ ) { - info = m_object->RetInfo(i); + info = m_object->GetInfo(i); sprintf(text, "%s = %.2f", info.name, info.value); pl->SetName(i, text); } @@ -440,28 +441,28 @@ void CAutoInfo::UpdateList() void CAutoInfo::UpdateListVirus() { - CWindow* pw; - CList* pl; + Ui::CWindow* pw; + Ui::CList* pl; int i, j, max; char text[100]; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pl = (CList*)pw->SearchControl(EVENT_OBJECT_GINFO); + pl = static_cast< Ui::CList* >(pw->SearchControl(EVENT_OBJECT_GINFO)); if ( pl == 0 ) return; - pl->SetState(STATE_ENABLE); + pl->SetState(Ui::STATE_ENABLE); pl->Flush(); for ( i=0 ; i<4 ; i++ ) { - max = (int)(2.0f+Math::Rand()*10.0f); + max = static_cast< int >(2.0f+Math::Rand()*10.0f); for ( j=0 ; j<max ; j++ ) { do { - text[j] = ' '+(int)(Math::Rand()*94.0f); + text[j] = ' '+static_cast< int >(Math::Rand()*94.0f); } while ( text[j] == '\\' ); } @@ -505,11 +506,11 @@ bool CAutoInfo::Read(char *line) CAuto::Read(line); - m_phase = (AutoInfoPhase)OpInt(line, "aPhase", AIP_WAIT); + m_phase = static_cast< AutoInfoPhase > (OpInt(line, "aPhase", AIP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autoinfo.h b/src/object/auto/autoinfo.h index cfe3c1b..30481bb 100644 --- a/src/object/auto/autoinfo.h +++ b/src/object/auto/autoinfo.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); void Start(int param); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -61,7 +62,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; Math::Vector m_goal; bool m_bLastVirus; }; diff --git a/src/object/auto/autojostle.cpp b/src/object/auto/autojostle.cpp index 3944297..68fe6d1 100644 --- a/src/object/auto/autojostle.cpp +++ b/src/object/auto/autojostle.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -71,7 +72,7 @@ void CAutoJostle::Start(int param, float force) m_time = 0.0f; m_error = ERR_CONTINUE; - type = m_object->RetType(); + type = m_object->GetType(); if ( type >= OBJECT_PLANT5 && type <= OBJECT_PLANT7 ) // clover? { @@ -89,8 +90,8 @@ bool CAutoJostle::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; if ( m_progress < 1.0f ) { diff --git a/src/object/auto/autojostle.h b/src/object/auto/autojostle.h index 70bb5e6..c156893 100644 --- a/src/object/auto/autojostle.h +++ b/src/object/auto/autojostle.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012 Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -42,7 +43,7 @@ protected: float m_force; float m_progress; float m_speed; - float m_lastParticule; + float m_lastParticle; Error m_error; }; diff --git a/src/object/auto/autokid.cpp b/src/object/auto/autokid.cpp index e5987cc..0ffbd7f 100644 --- a/src/object/auto/autokid.cpp +++ b/src/object/auto/autokid.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -19,8 +20,8 @@ #include "object/auto/autokid.h" -#include "old/particule.h" -#include "old/water.h" +#include "graphics/engine/particle.h" +#include "graphics/engine/water.h" @@ -62,18 +63,18 @@ void CAutoKid::Init() m_speed = 1.0f/1.0f; m_progress = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; if ( m_type == OBJECT_TEEN36 ) // trunk ? { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); m_speed = 1.0f/(1.0f+(Math::Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f)); m_progress = Math::Mod(pos.x/10.0f, 1.0f); } if ( m_type == OBJECT_TEEN37 ) // boat? { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); m_speed = 1.0f/(1.0f+(Math::Mod(pos.x/10.0f-0.5f, 1.0f)*0.2f))*2.5f; m_progress = Math::Mod(pos.x/10.0f, 1.0f); } @@ -82,7 +83,7 @@ void CAutoKid::Init() { if ( m_soundChannel == -1 ) { -//? m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.5f, true); +//? m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 1.0f, 0.5f, true); m_bSilent = false; } } @@ -100,7 +101,7 @@ bool CAutoKid::EventProcess(const Event &event) if ( m_soundChannel != -1 ) { - if ( m_engine->RetPause() ) + if ( m_engine->GetPause() ) { if ( !m_bSilent ) { @@ -118,8 +119,8 @@ bool CAutoKid::EventProcess(const Event &event) } } - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; @@ -135,12 +136,12 @@ bool CAutoKid::EventProcess(const Event &event) vib.z = sinf(m_progress*0.5f)*0.05f; m_object->SetCirVibration(vib); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.15f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); - pos.y = m_water->RetLevel()+1.0f; + pos = m_object->GetPosition(0); + pos.y = m_water->GetLevel()+1.0f; pos.x += (Math::Rand()-0.5f)*50.0f; pos.z += (Math::Rand()-0.5f)*50.0f; speed.y = 0.0f; @@ -148,7 +149,7 @@ bool CAutoKid::EventProcess(const Event &event) speed.z = 0.0f; dim.x = 50.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFLIC, 3.0f, 0.0f, 0.0f); } } @@ -164,12 +165,12 @@ bool CAutoKid::EventProcess(const Event &event) vib.z = sinf(m_progress*0.5f)*0.15f; m_object->SetCirVibration(vib); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.15f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.15f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); - pos.y = m_water->RetLevel()+1.0f; + pos = m_object->GetPosition(0); + pos.y = m_water->GetLevel()+1.0f; pos.x += (Math::Rand()-0.5f)*20.0f; pos.z += (Math::Rand()-0.5f)*20.0f; speed.y = 0.0f; @@ -177,7 +178,7 @@ bool CAutoKid::EventProcess(const Event &event) speed.z = 0.0f; dim.x = 20.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFLIC, 3.0f, 0.0f, 0.0f); } } @@ -191,9 +192,9 @@ bool CAutoKid::EventProcess(const Event &event) } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoKid::RetError() +Error CAutoKid::GetError() { return ERR_OK; } diff --git a/src/object/auto/autokid.h b/src/object/auto/autokid.h index 6d4258f..3e2fba7 100644 --- a/src/object/auto/autokid.h +++ b/src/object/auto/autokid.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -33,14 +34,14 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); protected: protected: float m_speed; float m_progress; - float m_lastParticule; + float m_lastParticle; int m_soundChannel; bool m_bSilent; }; diff --git a/src/object/auto/autolabo.cpp b/src/object/auto/autolabo.cpp index 270ec09..c5e4c82 100644 --- a/src/object/auto/autolabo.cpp +++ b/src/object/auto/autolabo.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -69,14 +70,14 @@ void CAutoLabo::DeleteObject(bool bAll) { if ( m_partiRank[i] != -1 ) { - m_particule->DeleteParticule(m_partiRank[i]); + m_particle->DeleteParticle(m_partiRank[i]); m_partiRank[i] = -1; } } if ( m_partiSphere != -1 ) { - m_particule->DeleteParticule(m_partiSphere); + m_particle->DeleteParticle(m_partiSphere); m_partiSphere = -1; } @@ -97,7 +98,7 @@ void CAutoLabo::Init() { m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_phase = ALAP_WAIT; // waiting ... m_progress = 0.0f; @@ -119,23 +120,23 @@ bool CAutoLabo::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; - if ( event.event == EVENT_UPDINTERFACE ) + if ( event.type == EVENT_UPDINTERFACE ) { - if ( m_object->RetSelect() ) CreateInterface(true); + if ( m_object->GetSelect() ) CreateInterface(true); } - if ( m_object->RetSelect() && // center selected? - (event.event == EVENT_OBJECT_RiPAW || - event.event == EVENT_OBJECT_RiGUN) ) + if ( m_object->GetSelect() && // center selected? + (event.type == EVENT_OBJECT_RiPAW || + event.type == EVENT_OBJECT_RiGUN) ) { if ( m_phase != ALAP_WAIT ) { return false; } - m_research = event.event; + m_research = event.type; if ( TestResearch(m_research) ) { @@ -143,13 +144,13 @@ bool CAutoLabo::EventProcess(const Event &event) return false; } - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power == 0 ) { m_displayText->DisplayError(ERR_LABO_NULL, m_object); return false; } - if ( power->RetType() != OBJECT_BULLET ) + if ( power->GetType() != OBJECT_BULLET ) { m_displayText->DisplayError(ERR_LABO_BAD, m_object); return false; @@ -168,12 +169,12 @@ bool CAutoLabo::EventProcess(const Event &event) return true; } - if ( event.event != EVENT_FRAME ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -247,31 +248,32 @@ bool CAutoLabo::EventProcess(const Event &event) { m_object->SetAngleZ(1, 0.0f); - goal = m_object->RetPosition(0); + goal = m_object->GetPosition(0); goal.y += 3.0f; pos = goal; pos.x -= 4.0f; pos.y += 4.0f; for ( i=0 ; i<3 ; i++ ) { - m_partiRank[i] = m_particule->CreateRay(pos, goal, - PARTIRAY2, + m_partiRank[i] = m_particle->CreateRay(pos, goal, + Gfx::PARTIRAY2, Math::Point(2.9f, 2.9f), LABO_DELAY); } - m_soundChannel = m_sound->Play(SOUND_LABO, m_object->RetPosition(0), 0.0f, 0.25f, true); + m_soundChannel = m_sound->Play(SOUND_LABO, m_object->GetPosition(0), 0.0f, 0.25f, true); m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 2.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 2.00f, 8.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.60f, 8.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.25f, 2.0f, SOPER_STOP); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 4.0f; speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 4.0f; dim.y = dim.x; - m_partiSphere = m_particule->CreateParticule(pos, speed, dim, PARTISPHERE2, LABO_DELAY, 0.0f, 0.0f); + m_partiSphere = m_particle->CreateParticle(pos, speed, + dim, Gfx::PARTISPHERE2, LABO_DELAY, 0.0f, 0.0f); m_phase = ALAP_ANALYSE; m_progress = 0.0f; @@ -283,13 +285,13 @@ bool CAutoLabo::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { power->SetZoom(0, 1.0f-m_progress); } - angle = m_object->RetAngleY(2); + angle = m_object->GetAngleY(2); if ( m_progress < 0.5f ) { angle -= event.rTime*m_progress*20.0f; @@ -300,27 +302,27 @@ bool CAutoLabo::EventProcess(const Event &event) } m_object->SetAngleY(2, angle); // rotates the analyzer - angle += m_object->RetAngleY(0); + angle += m_object->GetAngleY(0); for ( i=0 ; i<3 ; i++ ) { rot = Math::RotatePoint(-angle, -4.0f); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += rot.x; pos.z += rot.y; pos.y += 3.0f+4.0f;; - m_particule->SetPosition(m_partiRank[i], pos); // adjusts ray + m_particle->SetPosition(m_partiRank[i], pos); // adjusts ray angle += Math::PI*2.0f/3.0f; } - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; if ( m_progress > 0.25f && m_progress < 0.80f ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 3.0f; pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; @@ -329,7 +331,7 @@ bool CAutoLabo::EventProcess(const Event &event) speed.z = (Math::Rand()-0.5f)*10.0f; dim.x = Math::Rand()*0.4f*m_progress+1.0f; dim.y = dim.x; - m_particule->CreateTrack(pos, speed, dim, PARTITRACK2, + m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK2, 2.0f+2.0f*m_progress, 10.0f, 1.5f, 1.4f); } } @@ -338,7 +340,7 @@ bool CAutoLabo::EventProcess(const Event &event) { SetResearch(m_research); // research done - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { m_object->SetPower(0); @@ -421,21 +423,21 @@ bool CAutoLabo::EventProcess(const Event &event) } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoLabo::RetError() +Error CAutoLabo::GetError() { CObject* pObj; ObjectType type; - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } - pObj = m_object->RetPower(); + pObj = m_object->GetPower(); if ( pObj == 0 ) return ERR_LABO_NULL; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_BULLET ) return ERR_LABO_BAD; return ERR_OK; @@ -446,7 +448,7 @@ Error CAutoLabo::RetError() bool CAutoLabo::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, dim, ddim; float ox, oy, sx, sy; @@ -454,7 +456,7 @@ bool CAutoLabo::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; dim.x = 33.0f/640.0f; @@ -487,13 +489,13 @@ bool CAutoLabo::CreateInterface(bool bSelect) void CAutoLabo::UpdateInterface() { - CWindow* pw; + Ui::CWindow* pw; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; CAuto::UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; DeadInterface(pw, EVENT_OBJECT_RiPAW, g_researchEnable&RESEARCH_iPAW); @@ -508,20 +510,20 @@ void CAutoLabo::UpdateInterface() // Indicates the research conducted for a button. -void CAutoLabo::OkayButton(CWindow *pw, EventMsg event) +void CAutoLabo::OkayButton(Ui::CWindow *pw, EventType event) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); if ( control == 0 ) return; - control->SetState(STATE_OKAY, TestResearch(event)); + control->SetState(Ui::STATE_OKAY, TestResearch(event)); } // Test whether a search has already been done. -bool CAutoLabo::TestResearch(EventMsg event) +bool CAutoLabo::TestResearch(EventType event) { if ( event == EVENT_OBJECT_RiPAW ) return (g_researchDone & RESEARCH_iPAW); if ( event == EVENT_OBJECT_RiGUN ) return (g_researchDone & RESEARCH_iGUN); @@ -531,16 +533,17 @@ bool CAutoLabo::TestResearch(EventMsg event) // Indicates a search as made. -void CAutoLabo::SetResearch(EventMsg event) +void CAutoLabo::SetResearch(EventType event) { - Event newEvent; + if ( event == EVENT_OBJECT_RiPAW ) g_researchDone |= RESEARCH_iPAW; if ( event == EVENT_OBJECT_RiGUN ) g_researchDone |= RESEARCH_iGUN; m_main->WriteFreeParam(); - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + Event newEvent(EVENT_UPDINTERFACE); +// m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); m_event->AddEvent(newEvent); UpdateInterface(); } @@ -551,7 +554,7 @@ void CAutoLabo::SoundManip(float time, float amplitude, float frequency) { int i; - i = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f*frequency, true); + i = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 0.0f, 0.3f*frequency, true); m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, 0.1f, SOPER_CONTINUE); m_sound->AddEnvelope(i, 0.5f*amplitude, 1.0f*frequency, time-0.1f, SOPER_CONTINUE); m_sound->AddEnvelope(i, 0.0f, 0.3f*frequency, 0.1f, SOPER_STOP); @@ -597,12 +600,12 @@ bool CAutoLabo::Read(char *line) CAuto::Read(line); - m_phase = (AutoLaboPhase)OpInt(line, "aPhase", ALAP_WAIT); + m_phase = static_cast< AutoLaboPhase >(OpInt(line, "aPhase", ALAP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_research = (EventMsg)OpInt(line, "aResearch", 0); + m_research = static_cast< EventType >(OpInt(line, "aResearch", 0)); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autolabo.h b/src/object/auto/autolabo.h index 244e633..8225462 100644 --- a/src/object/auto/autolabo.h +++ b/src/object/auto/autolabo.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -47,7 +48,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -56,9 +57,9 @@ public: protected: void UpdateInterface(); - void OkayButton(CWindow *pw, EventMsg event); - bool TestResearch(EventMsg event); - void SetResearch(EventMsg event); + void OkayButton(Ui::CWindow *pw, EventType event); + bool TestResearch(EventType event); + void SetResearch(EventType event); void SoundManip(float time, float amplitude, float frequency); protected: @@ -66,8 +67,8 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; - EventMsg m_research; + float m_lastParticle; + EventType m_research; int m_partiRank[3]; int m_partiSphere; int m_soundChannel; diff --git a/src/object/auto/automush.cpp b/src/object/auto/automush.cpp index c3eaaaf..0b1608b 100644 --- a/src/object/auto/automush.cpp +++ b/src/object/auto/automush.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -57,7 +58,7 @@ void CAutoMush::Init() m_speed = 1.0f/4.0f; m_time = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; } @@ -72,8 +73,8 @@ bool CAutoMush::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; @@ -122,7 +123,7 @@ bool CAutoMush::EventProcess(const Event &event) } else { - m_sound->Play(SOUND_MUSHROOM, m_object->RetPosition(0)); + m_sound->Play(SOUND_MUSHROOM, m_object->GetPosition(0)); m_phase = AMP_FIRE; m_progress = 0.0f; @@ -137,21 +138,21 @@ bool CAutoMush::EventProcess(const Event &event) factor = 1.0f-m_progress; size = 1.0f+(1.0f-m_progress)*0.3f; - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; for ( i=0 ; i<10 ; i++ ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 5.0f; speed.x = (Math::Rand()-0.5f)*200.0f; speed.z = (Math::Rand()-0.5f)*200.0f; speed.y = -(20.0f+Math::Rand()*20.0f); dim.x = 1.0f; dim.y = dim.x; - channel = m_particule->CreateParticule(pos, speed, dim, PARTIGUN2, 2.0f, 100.0f, 0.0f); - m_particule->SetObjectFather(channel, m_object); + channel = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGUN2, 2.0f, 100.0f, 0.0f); + m_particle->SetObjectFather(channel, m_object); } } } @@ -167,18 +168,18 @@ bool CAutoMush::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 5.0f; speed.x = (Math::Rand()-0.5f)*4.0f; speed.z = (Math::Rand()-0.5f)*4.0f; speed.y = -(0.5f+Math::Rand()*0.5f); dim.x = Math::Rand()*2.5f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f, 0.0f, 0.0f); } } else @@ -226,16 +227,16 @@ bool CAutoMush::SearchTarget() float dist; int i; - iPos = m_object->RetPosition(0); + iPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( pObj->RetLock() ) continue; + if ( pObj->GetLock() ) continue; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && type != OBJECT_MOBILEwa && @@ -279,7 +280,7 @@ bool CAutoMush::SearchTarget() type != OBJECT_PARA && type != OBJECT_HUMAN ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, iPos); if ( dist < 50.0f ) return true; } @@ -288,9 +289,9 @@ bool CAutoMush::SearchTarget() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoMush::RetError() +Error CAutoMush::GetError() { return ERR_OK; } @@ -332,11 +333,11 @@ bool CAutoMush::Read(char *line) CAuto::Read(line); - m_phase = (AutoMushPhase)OpInt(line, "aPhase", AMP_WAIT); + m_phase = static_cast< AutoMushPhase >(OpInt(line, "aPhase", AMP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/automush.h b/src/object/auto/automush.h index 113d22f..245393a 100644 --- a/src/object/auto/automush.h +++ b/src/object/auto/automush.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool Write(char *line); bool Read(char *line); @@ -56,6 +57,6 @@ protected: AutoMushPhase m_phase; float m_progress; float m_speed; - float m_lastParticule; + float m_lastParticle; }; diff --git a/src/object/auto/autonest.cpp b/src/object/auto/autonest.cpp index f3c70fb..9658e23 100644 --- a/src/object/auto/autonest.cpp +++ b/src/object/auto/autonest.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -20,7 +21,7 @@ #include "object/auto/autonest.h" #include "common/iman.h" -#include "old/terrain.h" +#include "graphics/engine/terrain.h" #include "script/cmdtoken.h" @@ -72,9 +73,9 @@ void CAutoNest::Init() m_speed = 1.0f/4.0f; m_time = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); m_terrain->MoveOnFloor(pos); m_fretPos = pos; } @@ -88,8 +89,8 @@ bool CAutoNest::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; @@ -154,10 +155,10 @@ bool CAutoNest::SearchFree(Math::Vector pos) for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type == OBJECT_NEST ) continue; j = 0; @@ -199,15 +200,15 @@ CObject* CAutoNest::SearchFret() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( !pObj->RetLock() ) continue; + if ( !pObj->GetLock() ) continue; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_BULLET ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); if ( oPos.x == m_fretPos.x && oPos.z == m_fretPos.z ) { @@ -219,9 +220,9 @@ CObject* CAutoNest::SearchFret() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoNest::RetError() +Error CAutoNest::GetError() { return ERR_OK; } @@ -263,11 +264,11 @@ bool CAutoNest::Read(char *line) CAuto::Read(line); - m_phase = (AutoNestPhase)OpInt(line, "aPhase", ANP_WAIT); + m_phase = static_cast< AutoNestPhase >(OpInt(line, "aPhase", ANP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autonest.h b/src/object/auto/autonest.h index 612551d..1009457 100644 --- a/src/object/auto/autonest.h +++ b/src/object/auto/autonest.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -41,7 +42,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool Write(char *line); bool Read(char *line); @@ -55,7 +56,7 @@ protected: AutoNestPhase m_phase; float m_progress; float m_speed; - float m_lastParticule; - Math::Vector m_fretPos; + float m_lastParticle; + Math::Vector m_fretPos; }; diff --git a/src/object/auto/autonuclear.cpp b/src/object/auto/autonuclear.cpp index 05f0b29..d8a3bdf 100644 --- a/src/object/auto/autonuclear.cpp +++ b/src/object/auto/autonuclear.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -84,9 +85,9 @@ void CAutoNuclear::Init() m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); m_pos = Math::Transform(*mat, Math::Vector(22.0f, 4.0f, 0.0f)); m_phase = ANUP_WAIT; // waiting ... @@ -110,13 +111,13 @@ bool CAutoNuclear::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -146,7 +147,7 @@ bool CAutoNuclear::EventProcess(const Event &event) InitProgressTotal(1.5f+NUCLEAR_DELAY+1.5f); UpdateInterface(); - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); + m_sound->Play(SOUND_OPEN, m_object->GetPosition(0), 1.0f, 1.4f); m_phase = ANUP_CLOSE; m_progress = 0.0f; @@ -166,8 +167,8 @@ bool CAutoNuclear::EventProcess(const Event &event) { m_object->SetAngleZ(1, 0.0f); - mat = m_object->RetWorldMatrix(0); - max = (int)(10.0f*m_engine->RetParticuleDensity()); + mat = m_object->GetWorldMatrix(0); + max = static_cast< int >(10.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { pos.x = 27.0f; @@ -179,12 +180,12 @@ bool CAutoNuclear::EventProcess(const Event &event) speed.z = 0.0f; dim.x = Math::Rand()*1.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH); } - m_sound->Play(SOUND_CLOSE, m_object->RetPosition(0), 1.0f, 1.0f); + m_sound->Play(SOUND_CLOSE, m_object->GetPosition(0), 1.0f, 1.0f); - m_channelSound = m_sound->Play(SOUND_NUCLEAR, m_object->RetPosition(0), 1.0f, 0.1f, true); + m_channelSound = m_sound->Play(SOUND_NUCLEAR, m_object->GetPosition(0), 1.0f, 0.1f, true); m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, NUCLEAR_DELAY-1.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); @@ -198,11 +199,11 @@ bool CAutoNuclear::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 30.0f; pos.x += (Math::Rand()-0.5f)*6.0f; pos.z += (Math::Rand()-0.5f)*6.0f; @@ -211,7 +212,7 @@ bool CAutoNuclear::EventProcess(const Event &event) speed.z = 0.0f; dim.x = Math::Rand()*8.0f+8.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH); pos = m_pos; speed.x = (Math::Rand()-0.5f)*20.0f; @@ -219,7 +220,7 @@ bool CAutoNuclear::EventProcess(const Event &event) speed.z = (Math::Rand()-0.5f)*20.0f; dim.x = 2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBLITZ, 1.0f, 0.0f, 0.0f); } } else @@ -234,7 +235,7 @@ bool CAutoNuclear::EventProcess(const Event &event) CreatePower(); // creates the atomic cell - max = (int)(20.0f*m_engine->RetParticuleDensity()); + max = static_cast< int >(20.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { pos = m_pos; @@ -246,10 +247,10 @@ bool CAutoNuclear::EventProcess(const Event &event) speed.z = 0.0f; dim.x = Math::Rand()*2.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, Math::Rand()*5.0f+5.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBLUE, Math::Rand()*5.0f+5.0f, 0.0f, 0.0f); } - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 1.4f); + m_sound->Play(SOUND_OPEN, m_object->GetPosition(0), 1.0f, 1.4f); m_phase = ANUP_OPEN; m_progress = 0.0f; @@ -287,7 +288,7 @@ bool CAutoNuclear::EventProcess(const Event &event) bool CAutoNuclear::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -295,7 +296,7 @@ bool CAutoNuclear::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -319,9 +320,9 @@ CObject* CAutoNuclear::SearchUranium() { CObject* pObj; - pObj = m_object->RetPower(); + pObj = m_object->GetPower(); if ( pObj == 0 ) return 0; - if ( pObj->RetType() == OBJECT_URANIUM ) return pObj; + if ( pObj->GetType() == OBJECT_URANIUM ) return pObj; return 0; } @@ -337,10 +338,10 @@ bool CAutoNuclear::SearchVehicle() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_HUMAN && type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && @@ -392,8 +393,8 @@ void CAutoNuclear::CreatePower() Math::Vector pos; float angle; - pos = m_object->RetPosition(0); - angle = m_object->RetAngleY(0); + pos = m_object->GetPosition(0); + angle = m_object->GetAngleY(0); power = new CObject(m_iMan); if ( !power->CreateResource(pos, angle, OBJECT_ATOMIC) ) @@ -409,28 +410,28 @@ void CAutoNuclear::CreatePower() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoNuclear::RetError() +Error CAutoNuclear::GetError() { CObject* pObj; ObjectType type; //? TerrainRes res; - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } -//? res = m_terrain->RetResource(m_object->RetPosition(0)); +//? res = m_terrain->GetResource(m_object->GetPosition(0)); //? if ( res != TR_POWER ) return ERR_NUCLEAR_NULL; -//? if ( m_object->RetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW; +//? if ( m_object->GetEnergy() < ENERGY_POWER ) return ERR_NUCLEAR_LOW; - pObj = m_object->RetPower(); + pObj = m_object->GetPower(); if ( pObj == 0 ) return ERR_NUCLEAR_EMPTY; - if ( pObj->RetLock() ) return ERR_OK; - type = pObj->RetType(); + if ( pObj->GetLock() ) return ERR_OK; + type = pObj->GetType(); if ( type == OBJECT_ATOMIC ) return ERR_OK; if ( type != OBJECT_URANIUM ) return ERR_NUCLEAR_BAD; @@ -472,11 +473,11 @@ bool CAutoNuclear::Read(char *line) CAuto::Read(line); - m_phase = (AutoNuclearPhase)OpInt(line, "aPhase", ANUP_WAIT); + m_phase = static_cast< AutoNuclearPhase >(OpInt(line, "aPhase", ANUP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autonuclear.h b/src/object/auto/autonuclear.h index 8a4b0da..06a99af 100644 --- a/src/object/auto/autonuclear.h +++ b/src/object/auto/autonuclear.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -61,7 +62,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; Math::Vector m_pos; int m_channelSound; }; diff --git a/src/object/auto/autopara.cpp b/src/object/auto/autopara.cpp index 80ce90a..973a847 100644 --- a/src/object/auto/autopara.cpp +++ b/src/object/auto/autopara.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -68,9 +69,9 @@ void CAutoPara::Init() m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); m_pos = Math::Transform(*mat, Math::Vector(22.0f, 4.0f, 0.0f)); m_phase = APAP_WAIT; // waiting ... @@ -83,9 +84,9 @@ void CAutoPara::Init() // Reception of lightning. -void CAutoPara::StartBlitz() +void CAutoPara::StartLightning() { - m_phase = APAP_BLITZ; + m_phase = APAP_LIGHTNING; m_progress = 0.0f; m_speed = 1.0f/2.0f; } @@ -101,13 +102,13 @@ bool CAutoPara::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -118,17 +119,17 @@ bool CAutoPara::EventProcess(const Event &event) EventProgress(event.rTime); - if ( m_phase == APAP_BLITZ ) + if ( m_phase == APAP_LIGHTNING ) { if ( m_progress < 1.0f ) { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; for ( i=0 ; i<10 ; i++ ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*m_progress*40.0f; pos.z += (Math::Rand()-0.5f)*m_progress*40.0f; pos.y += 50.0f-m_progress*50.0f; @@ -137,7 +138,7 @@ bool CAutoPara::EventProcess(const Event &event) speed.y = 5.0f+Math::Rand()*5.0f; dim.x = 2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 20.0f, 0.5f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBLITZ, 1.0f, 20.0f, 0.5f); } } } @@ -153,20 +154,20 @@ bool CAutoPara::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; for ( i=0 ; i<2 ; i++ ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 16.0f; speed.x = (Math::Rand()-0.5f)*10.0f; speed.z = (Math::Rand()-0.5f)*10.0f; speed.y = -Math::Rand()*30.0f; dim.x = 1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBLITZ, 1.0f, 0.0f, 0.0f); } } @@ -188,7 +189,7 @@ bool CAutoPara::EventProcess(const Event &event) bool CAutoPara::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -196,7 +197,7 @@ bool CAutoPara::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -220,11 +221,11 @@ bool CAutoPara::CreateInterface(bool bSelect) } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoPara::RetError() +Error CAutoPara::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -242,38 +243,38 @@ void CAutoPara::ChargeObject(float rTime) float dist, energy; int i; - sPos = m_object->RetPosition(0); + sPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, sPos); if ( dist > 20.0f ) continue; - if ( pObj->RetTruck() == 0 && pObj->RetType() == OBJECT_POWER ) + if ( pObj->GetTruck() == 0 && pObj->GetType() == OBJECT_POWER ) { - energy = pObj->RetEnergy(); + energy = pObj->GetEnergy(); energy += rTime/2.0f; if ( energy > 1.0f ) energy = 1.0f; pObj->SetEnergy(energy); } - power = pObj->RetPower(); - if ( power != 0 && power->RetType() == OBJECT_POWER ) + power = pObj->GetPower(); + if ( power != 0 && power->GetType() == OBJECT_POWER ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); energy += rTime/2.0f; if ( energy > 1.0f ) energy = 1.0f; power->SetEnergy(energy); } - power = pObj->RetFret(); - if ( power != 0 && power->RetType() == OBJECT_POWER ) + power = pObj->GetFret(); + if ( power != 0 && power->GetType() == OBJECT_POWER ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); energy += rTime/2.0f; if ( energy > 1.0f ) energy = 1.0f; power->SetEnergy(energy); @@ -315,11 +316,11 @@ bool CAutoPara::Read(char *line) CAuto::Read(line); - m_phase = (AutoParaPhase)OpInt(line, "aPhase", APAP_WAIT); + m_phase = static_cast< AutoParaPhase >(OpInt(line, "aPhase", APAP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autopara.h b/src/object/auto/autopara.h index b230fd2..10a33a8 100644 --- a/src/object/auto/autopara.h +++ b/src/object/auto/autopara.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -26,7 +27,7 @@ enum AutoParaPhase { APAP_WAIT = 1, - APAP_BLITZ = 2, + APAP_LIGHTNING = 2, APAP_CHARGE = 3, }; @@ -42,8 +43,8 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); - void StartBlitz(); + Error GetError(); + void StartLightning(); bool CreateInterface(bool bSelect); @@ -58,7 +59,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; Math::Vector m_pos; int m_channelSound; }; diff --git a/src/object/auto/autoportico.cpp b/src/object/auto/autoportico.cpp index 5665556..3d93411 100644 --- a/src/object/auto/autoportico.cpp +++ b/src/object/auto/autoportico.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -90,7 +91,7 @@ void CAutoPortico::DeleteObject(bool bAll) void CAutoPortico::Init() { m_time = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_posTrack = 0.0f; m_phase = APOP_WAIT; @@ -108,7 +109,7 @@ void CAutoPortico::Start(int param) { Math::Vector pos; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); m_finalPos = pos; pos.z += PORTICO_TIME_MOVE*5.0f; // back to start m_object->SetPosition(0, pos); @@ -140,15 +141,15 @@ bool CAutoPortico::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; if ( m_phase == APOP_START ) { if ( m_param == PARAM_DEPOSE ) // deposits the ship? { - m_startPos = m_object->RetPosition(0); + m_startPos = m_object->GetPosition(0); - m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, true); + m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->GetPosition(0), 0.0f, 0.3f, true); m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_MOVE-0.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); @@ -159,7 +160,7 @@ bool CAutoPortico::EventProcess(const Event &event) m_main->SetMovieLock(true); // blocks everything until the end of the landing - m_camera->SetType(CAMERA_SCRIPT); + m_camera->SetType(Gfx::CAM_TYPE_SCRIPT); pos = m_startPos; pos.x += -100.0f; @@ -167,7 +168,7 @@ bool CAutoPortico::EventProcess(const Event &event) pos.z += -200.0f; m_camera->SetScriptEye(pos); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += 0.0f; pos.y += 10.0f; pos.z += -40.0f; @@ -187,7 +188,7 @@ bool CAutoPortico::EventProcess(const Event &event) angle = sinf(m_time*4.0f)*0.3f; m_object->SetAngleX(11, angle); - if ( event.event != EVENT_FRAME ) return true; + if ( event.type != EVENT_FRAME ) return true; if ( m_phase == APOP_WAIT ) return true; m_progress += event.rTime*m_speed; @@ -197,7 +198,7 @@ bool CAutoPortico::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.z -= event.rTime*5.0f; // advance m_object->SetPosition(0, pos); @@ -216,7 +217,7 @@ bool CAutoPortico::EventProcess(const Event &event) { if ( m_progress >= 1.0f ) { - m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.3f, true); + m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 0.0f, 0.3f, true); m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.5f, 1.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.6f, PORTICO_TIME_DOWN-1.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP); @@ -253,12 +254,12 @@ bool CAutoPortico::EventProcess(const Event &event) { if ( m_progress >= 1.0f ) { - m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 0.0f, 0.5f, true); + m_soundChannel = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 0.0f, 0.5f, true); m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, 0.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.5f, 1.0f, PORTICO_TIME_OPEN/2.0f-0.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 0.5f, SOPER_STOP); - m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->RetPosition(0), 0.0f, 0.3f, true); + m_soundChannel = m_sound->Play(SOUND_MOTORr, m_object->GetPosition(0), 0.0f, 0.3f, true); m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, 0.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.5f, 0.6f, PORTICO_TIME_OPEN-0.5f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 0.5f, SOPER_STOP); @@ -273,7 +274,7 @@ bool CAutoPortico::EventProcess(const Event &event) { if ( m_progress < 1.0f ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.z += event.rTime*5.3f; // back m_object->SetPosition(0, pos); @@ -309,7 +310,7 @@ bool CAutoPortico::EventProcess(const Event &event) pObj = m_main->SearchHuman(); m_main->SelectObject(pObj); m_camera->SetObject(pObj); - m_camera->SetType(CAMERA_BACK); + m_camera->SetType(Gfx::CAM_TYPE_BACK); m_phase = APOP_WAIT; m_progress = 0.0f; @@ -319,8 +320,8 @@ bool CAutoPortico::EventProcess(const Event &event) if ( m_soundChannel != -1 ) { -//? m_sound->Position(m_soundChannel, m_object->RetPosition(0)); - pos = m_engine->RetEyePt(); +//? m_sound->Position(m_soundChannel, m_object->GetPosition(0)); + pos = m_engine->GetEyePt(); m_sound->Position(m_soundChannel, pos); } @@ -338,7 +339,7 @@ bool CAutoPortico::EventProcess(const Event &event) m_camera->SetScriptEye(pos); } - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += 0.0f; pos.y += 10.0f; pos.z += -40.0f; @@ -368,7 +369,7 @@ bool CAutoPortico::Abort() pObj = m_main->SearchHuman(); m_main->SelectObject(pObj); m_camera->SetObject(pObj); - m_camera->SetType(CAMERA_BACK); + m_camera->SetType(Gfx::CAM_TYPE_BACK); if ( m_soundChannel != -1 ) { @@ -385,9 +386,9 @@ bool CAutoPortico::Abort() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoPortico::RetError() +Error CAutoPortico::GetError() { return ERR_OK; } @@ -397,11 +398,11 @@ Error CAutoPortico::RetError() void CAutoPortico::UpdateTrackMapping(float left, float right) { - D3DMATERIAL7 mat; + Gfx::Material mat; float limit[2]; int rank; - ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); + memset( &mat, 0, sizeof(Gfx::Material)); mat.diffuse.r = 1.0f; mat.diffuse.g = 1.0f; mat.diffuse.b = 1.0f; // blank @@ -409,17 +410,17 @@ void CAutoPortico::UpdateTrackMapping(float left, float right) mat.ambient.g = 0.5f; mat.ambient.b = 0.5f; - rank = m_object->RetObjectRank(0); + rank = m_object->GetObjectRank(0); limit[0] = 0.0f; limit[1] = 1000000.0f; - m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART1, "lemt.tga", "", - limit[0], limit[1], D3DMAPPINGX, + m_engine->TrackTextureMapping(rank, mat, Gfx::ENG_RSTATE_PART1, "lemt.tga", "", + limit[0], limit[1], Gfx::ENG_TEX_MAPPING_X, right, 8.0f, 8.0f, 192.0f, 256.0f); - m_engine->TrackTextureMapping(rank, mat, D3DSTATEPART2, "lemt.tga", "", - limit[0], limit[1], D3DMAPPINGX, + m_engine->TrackTextureMapping(rank, mat, Gfx::ENG_RSTATE_PART2, "lemt.tga", "", + limit[0], limit[1], Gfx::ENG_TEX_MAPPING_X, left, 8.0f, 8.0f, 192.0f, 256.0f); } diff --git a/src/object/auto/autoportico.h b/src/object/auto/autoportico.h index f2cd6d1..c211d37 100644 --- a/src/object/auto/autoportico.h +++ b/src/object/auto/autoportico.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -48,7 +49,7 @@ public: void Start(int param); bool EventProcess(const Event &event); bool Abort(); - Error RetError(); + Error GetError(); protected: void UpdateTrackMapping(float left, float right); @@ -59,7 +60,7 @@ protected: float m_speed; float m_cameraProgress; float m_cameraSpeed; - float m_lastParticule; + float m_lastParticle; Math::Vector m_finalPos; Math::Vector m_startPos; float m_posTrack; diff --git a/src/object/auto/autoradar.cpp b/src/object/auto/autoradar.cpp index 1cb20d6..224246c 100644 --- a/src/object/auto/autoradar.cpp +++ b/src/object/auto/autoradar.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -74,31 +75,31 @@ bool CAutoRadar::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; if ( m_phase == ARAP_WAIT ) return true; m_progress += event.rTime*m_speed; m_aTime += event.rTime; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { m_timeVirus = 0.1f+Math::Rand()*0.3f; - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle += (Math::Rand()-0.2f)*0.5f; m_object->SetAngleY(1, angle); - angle = m_object->RetAngleY(2); + angle = m_object->GetAngleY(2); angle += (Math::Rand()-0.8f)*1.0f; m_object->SetAngleY(2, angle); m_object->SetAngleX(3, (Math::Rand()-0.5f)*0.3f); - m_totalDetect = (int)(Math::Rand()*10.0f); + m_totalDetect = static_cast< int >(Math::Rand()*10.0f); UpdateInterface(); } return true; @@ -109,7 +110,7 @@ bool CAutoRadar::EventProcess(const Event &event) if ( m_progress < 1.0f ) { speed = Math::Min(10.0f, m_progress*50.0f); - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle += event.rTime*speed; m_object->SetAngleY(1, angle); } @@ -123,11 +124,11 @@ bool CAutoRadar::EventProcess(const Event &event) } else { - pos = m_object->RetPosition(0); - m_start = m_object->RetAngleY(1); + pos = m_object->GetPosition(0); + m_start = m_object->GetAngleY(1); m_angle = m_start-Math::NormAngle(m_start)+Math::PI*2.0f; m_angle += Math::RotateAngle(pos.x-ePos.x, ePos.z-pos.z); - m_angle += Math::PI-m_object->RetAngleY(0); + m_angle += Math::PI-m_object->GetAngleY(0); m_phase = ARAP_SHOW; m_progress = 0.0f; @@ -145,7 +146,7 @@ bool CAutoRadar::EventProcess(const Event &event) } else { - m_sound->Play(SOUND_RADAR, m_object->RetPosition(0)); + m_sound->Play(SOUND_RADAR, m_object->GetPosition(0)); m_phase = ARAP_SINUS; m_progress = 0.0f; @@ -182,11 +183,11 @@ bool CAutoRadar::EventProcess(const Event &event) } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoRadar::RetError() +Error CAutoRadar::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -199,7 +200,7 @@ Error CAutoRadar::RetError() bool CAutoRadar::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, dim, ddim; float ox, oy, sx, sy; @@ -207,7 +208,7 @@ bool CAutoRadar::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -235,21 +236,21 @@ bool CAutoRadar::CreateInterface(bool bSelect) void CAutoRadar::UpdateInterface() { - CWindow* pw; - CGauge* pg; + Ui::CWindow* pw; + Ui::CGauge* pg; float level; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; CAuto::UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GRADAR); + pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GRADAR)); if ( pg != 0 ) { - level = (float)m_totalDetect*(1.0f/8.0f); + level = static_cast< float >(m_totalDetect*(1.0f/8.0f)); if ( level > 1.0f ) level = 1.0f; pg->SetLevel(level); } @@ -267,18 +268,18 @@ bool CAutoRadar::SearchEnemy(Math::Vector &pos) float distance, min; int i; - iPos = m_object->RetPosition(0); + iPos = m_object->GetPosition(0); min = 1000000.0f; m_totalDetect = 0; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( !pObj->RetActif() ) continue; + if ( !pObj->GetActif() ) continue; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType != OBJECT_ANT && oType != OBJECT_SPIDER && oType != OBJECT_BEE && @@ -287,7 +288,7 @@ bool CAutoRadar::SearchEnemy(Math::Vector &pos) m_totalDetect ++; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); distance = Math::Distance(oPos, iPos); if ( distance < min ) { @@ -299,7 +300,7 @@ bool CAutoRadar::SearchEnemy(Math::Vector &pos) UpdateInterface(); if ( pBest == 0 ) return false; - pos = pBest->RetPosition(0); + pos = pBest->GetPosition(0); return true; } diff --git a/src/object/auto/autoradar.h b/src/object/auto/autoradar.h index 8b38ff9..e2c9df5 100644 --- a/src/object/auto/autoradar.h +++ b/src/object/auto/autoradar.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); bool CreateInterface(bool bSelect); - Error RetError(); + Error GetError(); protected: void UpdateInterface(); @@ -56,7 +57,7 @@ protected: float m_speed; float m_aTime; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; float m_angle; float m_start; int m_totalDetect; diff --git a/src/object/auto/autorepair.cpp b/src/object/auto/autorepair.cpp index ad5deee..2f679fa 100644 --- a/src/object/auto/autorepair.cpp +++ b/src/object/auto/autorepair.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -60,7 +61,7 @@ void CAutoRepair::Init() m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; CAuto::Init(); } @@ -77,13 +78,13 @@ bool CAutoRepair::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -104,7 +105,7 @@ bool CAutoRepair::EventProcess(const Event &event) } else { - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + m_sound->Play(SOUND_OPEN, m_object->GetPosition(0), 1.0f, 0.8f); m_phase = ARP_DOWN; m_progress = 0.0f; @@ -123,7 +124,7 @@ bool CAutoRepair::EventProcess(const Event &event) else { m_object->SetAngleZ(1, 0.0f); - m_sound->Play(SOUND_REPAIR, m_object->RetPosition(0)); + m_sound->Play(SOUND_REPAIR, m_object->GetPosition(0)); m_phase = ARP_REPAIR; m_progress = 0.0f; @@ -135,21 +136,21 @@ bool CAutoRepair::EventProcess(const Event &event) { vehicule = SearchVehicle(); if ( m_progress < 1.0f || - (vehicule != 0 && vehicule->RetShield() < 1.0f) ) + (vehicule != 0 && vehicule->GetShield() < 1.0f) ) { if ( vehicule != 0 ) { - shield = vehicule->RetShield(); + shield = vehicule->GetShield(); shield += event.rTime*0.2f; if ( shield > 1.0f ) shield = 1.0f; vehicule->SetShield(shield); } - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*5.0f; pos.z += (Math::Rand()-0.5f)*5.0f; pos.y += 1.0f; @@ -158,12 +159,12 @@ bool CAutoRepair::EventProcess(const Event &event) speed.y = Math::Rand()*15.0f; dim.x = Math::Rand()*6.0f+4.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBLUE, 1.0f, 0.0f, 0.0f); } } else { - m_sound->Play(SOUND_OPEN, m_object->RetPosition(0), 1.0f, 0.8f); + m_sound->Play(SOUND_OPEN, m_object->GetPosition(0), 1.0f, 0.8f); m_phase = ARP_UP; m_progress = 0.0f; @@ -196,7 +197,7 @@ bool CAutoRepair::EventProcess(const Event &event) bool CAutoRepair::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -204,7 +205,7 @@ bool CAutoRepair::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -233,14 +234,14 @@ CObject* CAutoRepair::SearchVehicle() float dist; int i; - sPos = m_object->RetPosition(0); + sPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && type != OBJECT_MOBILEwa && @@ -269,10 +270,10 @@ CObject* CAutoRepair::SearchVehicle() type != OBJECT_MOBILEit && type != OBJECT_MOBILEdr ) continue; - physics = pObj->RetPhysics(); - if ( physics != 0 && !physics->RetLand() ) continue; // in flight? + physics = pObj->GetPhysics(); + if ( physics != 0 && !physics->GetLand() ) continue; // in flight? - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, sPos); if ( dist <= 5.0f ) return pObj; } @@ -281,11 +282,11 @@ CObject* CAutoRepair::SearchVehicle() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoRepair::RetError() +Error CAutoRepair::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -327,11 +328,11 @@ bool CAutoRepair::Read(char *line) CAuto::Read(line); - m_phase = (AutoRepairPhase)OpInt(line, "aPhase", ARP_WAIT); + m_phase = static_cast< AutoRepairPhase >(OpInt(line, "aPhase", ARP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autorepair.h b/src/object/auto/autorepair.h index 1279ba3..e8bb0b1 100644 --- a/src/object/auto/autorepair.h +++ b/src/object/auto/autorepair.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -59,7 +60,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; }; diff --git a/src/object/auto/autoresearch.cpp b/src/object/auto/autoresearch.cpp index 410e6ac..c2395e8 100644 --- a/src/object/auto/autoresearch.cpp +++ b/src/object/auto/autoresearch.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -84,7 +85,7 @@ void CAutoResearch::Init() m_time = 0.0f; m_timeVirus = 0.0f; m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; } @@ -100,29 +101,29 @@ bool CAutoResearch::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; - if ( event.event == EVENT_UPDINTERFACE ) + if ( event.type == EVENT_UPDINTERFACE ) { - if ( m_object->RetSelect() ) CreateInterface(true); + if ( m_object->GetSelect() ) CreateInterface(true); } - if ( m_object->RetSelect() && // center selected? - (event.event == EVENT_OBJECT_RTANK || - event.event == EVENT_OBJECT_RFLY || - event.event == EVENT_OBJECT_RTHUMP || - event.event == EVENT_OBJECT_RCANON || - event.event == EVENT_OBJECT_RTOWER || - event.event == EVENT_OBJECT_RPHAZER || - event.event == EVENT_OBJECT_RSHIELD || - event.event == EVENT_OBJECT_RATOMIC ) ) + if ( m_object->GetSelect() && // center selected? + (event.type == EVENT_OBJECT_RTANK || + event.type == EVENT_OBJECT_RFLY || + event.type == EVENT_OBJECT_RTHUMP || + event.type == EVENT_OBJECT_RCANON || + event.type == EVENT_OBJECT_RTOWER || + event.type == EVENT_OBJECT_RPHAZER || + event.type == EVENT_OBJECT_RSHIELD || + event.type == EVENT_OBJECT_RATOMIC ) ) { if ( m_phase != ALP_WAIT ) { return false; } - m_research = event.event; + m_research = event.type; if ( TestResearch(m_research) ) { @@ -130,33 +131,33 @@ bool CAutoResearch::EventProcess(const Event &event) return false; } - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power == 0 ) { m_displayText->DisplayError(ERR_RESEARCH_POWER, m_object); return false; } - if ( power->RetCapacity() > 1.0f ) + if ( power->GetCapacity() > 1.0f ) { m_displayText->DisplayError(ERR_RESEARCH_TYPE, m_object); return false; } - if ( power->RetEnergy() < 1.0f ) + if ( power->GetEnergy() < 1.0f ) { m_displayText->DisplayError(ERR_RESEARCH_ENERGY, m_object); return false; } time = SEARCH_TIME; - if ( event.event == EVENT_OBJECT_RTANK ) time *= 0.3f; - if ( event.event == EVENT_OBJECT_RFLY ) time *= 0.3f; - if ( event.event == EVENT_OBJECT_RATOMIC ) time *= 2.0f; + if ( event.type == EVENT_OBJECT_RTANK ) time *= 0.3f; + if ( event.type == EVENT_OBJECT_RFLY ) time *= 0.3f; + if ( event.type == EVENT_OBJECT_RATOMIC ) time *= 2.0f; SetBusy(true); InitProgressTotal(time); UpdateInterface(); - m_channelSound = m_sound->Play(SOUND_RESEARCH, m_object->RetPosition(0), 0.0f, 1.0f, true); + m_channelSound = m_sound->Play(SOUND_RESEARCH, m_object->GetPosition(0), 0.0f, 1.0f, true); m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, 2.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_channelSound, 1.0f, 1.0f, time-4.0f, SOPER_CONTINUE); m_sound->AddEnvelope(m_channelSound, 0.0f, 1.0f, 2.0f, SOPER_STOP); @@ -167,12 +168,12 @@ bool CAutoResearch::EventProcess(const Event &event) return true; } - if ( event.event != EVENT_FRAME ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -201,7 +202,7 @@ bool CAutoResearch::EventProcess(const Event &event) FireStopUpdate(m_progress, true); // flashes if ( m_progress < 1.0f ) { - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power == 0 ) // more battery? { SetBusy(false); @@ -214,11 +215,11 @@ bool CAutoResearch::EventProcess(const Event &event) } power->SetEnergy(1.0f-m_progress); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*6.0f; pos.z += (Math::Rand()-0.5f)*6.0f; pos.y += 11.0f; @@ -227,7 +228,7 @@ bool CAutoResearch::EventProcess(const Event &event) speed.y = Math::Rand()*20.0f; dim.x = Math::Rand()*1.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIVAPOR); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIVAPOR); } } else @@ -262,9 +263,9 @@ bool CAutoResearch::EventProcess(const Event &event) } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoResearch::RetError() +Error CAutoResearch::GetError() { CObject* power; @@ -273,21 +274,21 @@ Error CAutoResearch::RetError() return ERR_OK; } - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power == 0 ) { return ERR_RESEARCH_POWER; } - if ( power != 0 && power->RetCapacity() > 1.0f ) + if ( power != 0 && power->GetCapacity() > 1.0f ) { return ERR_RESEARCH_TYPE; } - if ( power != 0 && power->RetEnergy() < 1.0f ) + if ( power != 0 && power->GetEnergy() < 1.0f ) { return ERR_RESEARCH_ENERGY; } @@ -300,7 +301,7 @@ Error CAutoResearch::RetError() bool CAutoResearch::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, dim, ddim; float ox, oy, sx, sy; @@ -308,7 +309,7 @@ bool CAutoResearch::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; dim.x = 33.0f/640.0f; @@ -371,13 +372,13 @@ bool CAutoResearch::CreateInterface(bool bSelect) void CAutoResearch::UpdateInterface() { - CWindow* pw; + Ui::CWindow* pw; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; CAuto::UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; DeadInterface(pw, EVENT_OBJECT_RTANK, g_researchEnable&RESEARCH_TANK); @@ -413,8 +414,8 @@ void CAutoResearch::UpdateInterface() void CAutoResearch::UpdateInterface(float rTime) { - CWindow* pw; - CGauge* pg; + Ui::CWindow* pw; + Ui::CGauge* pg; CObject* power; float energy; @@ -423,19 +424,19 @@ void CAutoResearch::UpdateInterface(float rTime) if ( m_time < m_lastUpdateTime+0.1f ) return; m_lastUpdateTime = m_time; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); if ( pg != 0 ) { energy = 0.0f; - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); } pg->SetLevel(energy); } @@ -443,20 +444,20 @@ void CAutoResearch::UpdateInterface(float rTime) // Research shows already performed button. -void CAutoResearch::OkayButton(CWindow *pw, EventMsg event) +void CAutoResearch::OkayButton(Ui::CWindow *pw, EventType event) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); if ( control == 0 ) return; - control->SetState(STATE_OKAY, TestResearch(event)); + control->SetState(Ui::STATE_OKAY, TestResearch(event)); } // Test whether a search has already been done. -bool CAutoResearch::TestResearch(EventMsg event) +bool CAutoResearch::TestResearch(EventType event) { if ( event == EVENT_OBJECT_RTANK ) return (g_researchDone & RESEARCH_TANK ); if ( event == EVENT_OBJECT_RFLY ) return (g_researchDone & RESEARCH_FLY ); @@ -472,9 +473,8 @@ bool CAutoResearch::TestResearch(EventMsg event) // Indicates a search as made. -void CAutoResearch::SetResearch(EventMsg event) +void CAutoResearch::SetResearch(EventType event) { - Event newEvent; if ( event == EVENT_OBJECT_RTANK ) g_researchDone |= RESEARCH_TANK; if ( event == EVENT_OBJECT_RFLY ) g_researchDone |= RESEARCH_FLY; @@ -487,7 +487,7 @@ void CAutoResearch::SetResearch(EventMsg event) m_main->WriteFreeParam(); - m_event->MakeEvent(newEvent, EVENT_UPDINTERFACE); + Event newEvent(EVENT_UPDINTERFACE); m_event->AddEvent(newEvent); UpdateInterface(); } @@ -518,14 +518,14 @@ void CAutoResearch::FireStopUpdate(float progress, bool bLightOn) { if ( m_partiStop[i] != -1 ) { - m_particule->DeleteParticule(m_partiStop[i]); + m_particle->DeleteParticle(m_partiStop[i]); m_partiStop[i] = -1; } } return; } - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 2.0f; @@ -537,7 +537,7 @@ void CAutoResearch::FireStopUpdate(float progress, bool bLightOn) { if ( m_partiStop[i] != -1 ) { - m_particule->DeleteParticule(m_partiStop[i]); + m_particle->DeleteParticle(m_partiStop[i]); m_partiStop[i] = -1; } } @@ -549,8 +549,8 @@ void CAutoResearch::FireStopUpdate(float progress, bool bLightOn) pos.y = 11.5f; pos.z = listpos[i*2+1]; pos = Math::Transform(*mat, pos); - m_partiStop[i] = m_particule->CreateParticule(pos, speed, - dim, PARTISELY, + m_partiStop[i] = m_particle->CreateParticle(pos, speed, + dim, Gfx::PARTISELY, 1.0f, 0.0f, 0.0f); } } @@ -594,13 +594,13 @@ bool CAutoResearch::Read(char *line) CAuto::Read(line); - m_phase = (AutoResearchPhase)OpInt(line, "aPhase", ALP_WAIT); + m_phase = static_cast< AutoResearchPhase >(OpInt(line, "aPhase", ALP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_research = (EventMsg)OpInt(line, "aResearch", 0); + m_research = static_cast< EventType >(OpInt(line, "aResearch", 0)); m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } diff --git a/src/object/auto/autoresearch.h b/src/object/auto/autoresearch.h index b60f4bd..a838e64 100644 --- a/src/object/auto/autoresearch.h +++ b/src/object/auto/autoresearch.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -41,7 +42,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -51,9 +52,9 @@ public: protected: void UpdateInterface(); void UpdateInterface(float rTime); - void OkayButton(CWindow *pw, EventMsg event); - bool TestResearch(EventMsg event); - void SetResearch(EventMsg event); + void OkayButton(Ui::CWindow *pw, EventType event); + bool TestResearch(EventType event); + void SetResearch(EventType event); void FireStopUpdate(float progress, bool bLightOn); protected: @@ -62,8 +63,8 @@ protected: float m_speed; float m_timeVirus; float m_lastUpdateTime; - float m_lastParticule; - EventMsg m_research; + float m_lastParticle; + EventType m_research; int m_partiStop[6]; int m_channelSound; }; diff --git a/src/object/auto/autoroot.cpp b/src/object/auto/autoroot.cpp index 9282a01..b43f40b 100644 --- a/src/object/auto/autoroot.cpp +++ b/src/object/auto/autoroot.cpp @@ -19,8 +19,8 @@ #include "object/auto/autoroot.h" -#include "old/particule.h" -#include "old/terrain.h" +#include "graphics/engine/particle.h" +#include "graphics/engine/terrain.h" #include "math/geometry.h" @@ -58,9 +58,9 @@ void CAutoRoot::Init() Math::Point dim; m_time = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Math::Vector(-5.0f, 28.0f, -4.0f); // peak position pos = Math::Transform(*mat, pos); m_center = pos; @@ -68,7 +68,7 @@ void CAutoRoot::Init() speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 100.0f; dim.y = dim.x; - m_particule->CreateParticule(m_center, speed, dim, PARTISPHERE5, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(m_center, speed, dim, Gfx::PARTISPHERE5, 0.5f, 0.0f, 0.0f); m_terrain->AddFlyingLimit(pos, 100.0f, 80.0f, pos.y-60.0f); } @@ -83,16 +83,16 @@ bool CAutoRoot::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_object->SetZoomX(1, 1.0f+sinf(m_time*2.0f)*0.2f); m_object->SetZoomY(1, 1.0f+sinf(m_time*2.3f)*0.2f); m_object->SetZoomZ(1, 1.0f+sinf(m_time*2.7f)*0.2f); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.10f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; pos = m_center; pos.x += (Math::Rand()-0.5f)*8.0f; @@ -103,16 +103,16 @@ bool CAutoRoot::EventProcess(const Event &event) speed.y = Math::Rand()*12.0f; dim.x = Math::Rand()*6.0f+4.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIROOT, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIROOT, 1.0f, 0.0f, 0.0f); } return true; } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoRoot::RetError() +Error CAutoRoot::GetError() { return ERR_OK; } diff --git a/src/object/auto/autoroot.h b/src/object/auto/autoroot.h index 1ecd5ba..d80abe8 100644 --- a/src/object/auto/autoroot.h +++ b/src/object/auto/autoroot.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -33,12 +34,12 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); protected: protected: - float m_lastParticule; + float m_lastParticle; Math::Vector m_center; }; diff --git a/src/object/auto/autosafe.cpp b/src/object/auto/autosafe.cpp index 11aac18..144f36e 100644 --- a/src/object/auto/autosafe.cpp +++ b/src/object/auto/autosafe.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ CAutoSafe::CAutoSafe(CInstanceManager* iMan, CObject* object) } m_bLock = false; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_channelSound = -1; Init(); } @@ -86,7 +87,7 @@ void CAutoSafe::Init() { m_time = 0.0f; m_timeVirus = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_countKeys = 0; m_actualAngle = 0.0f; @@ -111,13 +112,13 @@ bool CAutoSafe::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_progress += event.rTime*m_speed; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { @@ -158,7 +159,7 @@ bool CAutoSafe::EventProcess(const Event &event) { LockKeys(); - m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, true); + m_channelSound = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 1.0f, 0.25f, true); m_sound->AddEnvelope(m_channelSound, 1.0f, 2.00f, OPEN_DELAY, SOPER_STOP); m_phase = ASAP_OPEN; @@ -168,7 +169,7 @@ bool CAutoSafe::EventProcess(const Event &event) } else { - m_channelSound = m_sound->Play(SOUND_MANIP, m_object->RetPosition(0), 1.0f, 0.25f, true); + m_channelSound = m_sound->Play(SOUND_MANIP, m_object->GetPosition(0), 1.0f, 0.25f, true); m_sound->AddEnvelope(m_channelSound, 1.0f, 0.35f, 0.5f, SOPER_STOP); } } @@ -185,13 +186,13 @@ bool CAutoSafe::EventProcess(const Event &event) { DownKeys(m_progress); - if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; for ( i=0 ; i<10 ; i++ ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*10.0f; pos.z += (Math::Rand()-0.5f)*10.0f; speed.x = (Math::Rand()-0.5f)*4.0f; @@ -199,10 +200,10 @@ bool CAutoSafe::EventProcess(const Event &event) speed.y = Math::Rand()*15.0f; dim.x = Math::Rand()*6.0f+4.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBLUE, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBLUE, 1.0f, 0.0f, 0.0f); } - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*10.0f; pos.z += (Math::Rand()-0.5f)*10.0f; speed.x = (Math::Rand()-0.5f)*4.0f; @@ -210,7 +211,7 @@ bool CAutoSafe::EventProcess(const Event &event) speed.y = Math::Rand()*10.0f; dim.x = Math::Rand()*3.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGLINT, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGLINT, 1.0f, 0.0f, 0.0f); for ( i=0 ; i<4 ; i++ ) { @@ -220,7 +221,7 @@ bool CAutoSafe::EventProcess(const Event &event) speed.y = 1.0f+Math::Rand()*1.0f; dim.x = Math::Rand()*1.5f+1.5f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f, 0.0f, 0.0f); } } } @@ -238,7 +239,7 @@ bool CAutoSafe::EventProcess(const Event &event) m_object->FlushCrashShere(); m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 0.0f); - m_sound->Play(SOUND_FINDING, m_object->RetPosition(0)); + m_sound->Play(SOUND_FINDING, m_object->GetPosition(0)); m_phase = ASAP_FINISH; m_progress = 0.0f; @@ -283,7 +284,7 @@ bool CAutoSafe::EventProcess(const Event &event) { if ( m_keyParti[i] != -1 ) { - m_particule->DeleteParticule(m_keyParti[i]); + m_particle->DeleteParticle(m_keyParti[i]); m_keyParti[i] = -1; } } @@ -293,7 +294,7 @@ bool CAutoSafe::EventProcess(const Event &event) { pos = m_keyPos[i]; pos.y += 2.2f; - m_keyParti[i] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); + m_keyParti[i] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISELY, 1.0f, 0.0f, 0.0f); } } } @@ -306,7 +307,7 @@ bool CAutoSafe::EventProcess(const Event &event) bool CAutoSafe::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -314,7 +315,7 @@ bool CAutoSafe::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -332,11 +333,11 @@ bool CAutoSafe::CreateInterface(bool bSelect) } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoSafe::RetError() +Error CAutoSafe::GetError() { - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } @@ -377,11 +378,11 @@ bool CAutoSafe::Read(char *line) CAuto::Read(line); - m_phase = (AutoSafePhase)OpInt(line, "aPhase", ASAP_WAIT); + m_phase = static_cast< AutoSafePhase >(OpInt(line, "aPhase", ASAP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; return true; } @@ -398,8 +399,8 @@ int CAutoSafe::CountKeys() float dist, angle, limit, cAngle, oAngle; int i, index; - cPos = m_object->RetPosition(0); - cAngle = m_object->RetAngleY(0); + cPos = m_object->GetPosition(0); + cAngle = m_object->GetAngleY(0); for ( index=0 ; index<4 ; index++ ) { @@ -409,18 +410,18 @@ int CAutoSafe::CountKeys() for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; + oType = pObj->GetType(); + if ( pObj->GetTruck() != 0 ) continue; if ( oType != OBJECT_KEYa && oType != OBJECT_KEYb && oType != OBJECT_KEYc && oType != OBJECT_KEYd ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(oPos, cPos); if ( dist > 20.0f ) continue; @@ -482,22 +483,22 @@ void CAutoSafe::LockKeys() float dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; + oType = pObj->GetType(); + if ( pObj->GetTruck() != 0 ) continue; if ( oType != OBJECT_KEYa && oType != OBJECT_KEYb && oType != OBJECT_KEYc && oType != OBJECT_KEYd ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(oPos, cPos); if ( dist > 20.0f ) continue; @@ -515,22 +516,22 @@ void CAutoSafe::DownKeys(float progress) float dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; + oType = pObj->GetType(); + if ( pObj->GetTruck() != 0 ) continue; if ( oType != OBJECT_KEYa && oType != OBJECT_KEYb && oType != OBJECT_KEYc && oType != OBJECT_KEYd ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(oPos, cPos); if ( dist > 20.0f ) continue; @@ -550,25 +551,25 @@ void CAutoSafe::DeleteKeys() int i; bool bDelete; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); do { bDelete = false; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oType = pObj->RetType(); - if ( pObj->RetTruck() != 0 ) continue; + oType = pObj->GetType(); + if ( pObj->GetTruck() != 0 ) continue; if ( oType != OBJECT_KEYa && oType != OBJECT_KEYb && oType != OBJECT_KEYc && oType != OBJECT_KEYd ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(oPos, cPos); if ( dist > 20.0f ) continue; @@ -590,18 +591,18 @@ CObject* CAutoSafe::SearchVehicle() float dist; int i; - cPos = m_object->RetPosition(0); + cPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( pObj == m_object ) continue; - if ( pObj->RetTruck() != 0 ) continue; + if ( pObj->GetTruck() != 0 ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(oPos, cPos); if ( dist <= 4.0f ) return pObj; } diff --git a/src/object/auto/autosafe.h b/src/object/auto/autosafe.h index d17435b..3c0bcce 100644 --- a/src/object/auto/autosafe.h +++ b/src/object/auto/autosafe.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -42,7 +43,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -61,7 +62,7 @@ protected: float m_progress; float m_speed; float m_timeVirus; - float m_lastParticule; + float m_lastParticle; int m_channelSound; bool m_bLock; int m_countKeys; diff --git a/src/object/auto/autostation.cpp b/src/object/auto/autostation.cpp index dba4ed8..3771c0f 100644 --- a/src/object/auto/autostation.cpp +++ b/src/object/auto/autostation.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -20,8 +21,8 @@ #include "object/auto/autostation.h" #include "common/iman.h" -#include "old/particule.h" -#include "old/terrain.h" +#include "graphics/engine/particle.h" +#include "graphics/engine/terrain.h" #include "math/geometry.h" #include "ui/interface.h" #include "ui/gauge.h" @@ -66,7 +67,7 @@ void CAutoStation::Init() m_time = 0.0f; m_timeVirus = 0.0f; m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_soundChannel = -1; m_bLastVirus = false; @@ -83,22 +84,22 @@ bool CAutoStation::EventProcess(const Event &event) Math::Point dim; CObject* vehicule; CObject* power; - TerrainRes res; + Gfx::TerrainRes res; float big, energy, used, add, freq; CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( !m_bLastVirus ) { m_bLastVirus = true; - m_energyVirus = m_object->RetEnergy(); + m_energyVirus = m_object->GetEnergy(); } if ( m_timeVirus <= 0.0f ) @@ -120,10 +121,10 @@ bool CAutoStation::EventProcess(const Event &event) UpdateInterface(event.rTime); - big = m_object->RetEnergy(); + big = m_object->GetEnergy(); - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res == TR_POWER ) + res = m_terrain->GetResource(m_object->GetPosition(0)); + if ( res == Gfx::TR_POWER ) { big += event.rTime*0.01f; // recharges the large battery } @@ -135,10 +136,10 @@ bool CAutoStation::EventProcess(const Event &event) vehicule = SearchVehicle(); if ( vehicule != 0 ) { - power = vehicule->RetPower(); - if ( power != 0 && power->RetCapacity() == 1.0f ) + power = vehicule->GetPower(); + if ( power != 0 && power->GetCapacity() == 1.0f ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); add = event.rTime*0.2f; if ( add > big*4.0f ) add = big*4.0f; if ( add > 1.0f-energy ) add = 1.0f-energy; @@ -148,10 +149,10 @@ bool CAutoStation::EventProcess(const Event &event) big -= add/4.0f; // discharge the large battery } - power = vehicule->RetFret(); - if ( power != 0 && power->RetType() == OBJECT_POWER ) + power = vehicule->GetFret(); + if ( power != 0 && power->GetType() == OBJECT_POWER ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); add = event.rTime*0.2f; if ( add > big*4.0f ) add = big*4.0f; if ( add > 1.0f-energy ) add = 1.0f-energy; @@ -169,7 +170,7 @@ bool CAutoStation::EventProcess(const Event &event) freq = 1.0f+3.0f*freq; if ( m_soundChannel == -1 ) { - m_soundChannel = m_sound->Play(SOUND_STATION, m_object->RetPosition(0), + m_soundChannel = m_sound->Play(SOUND_STATION, m_object->GetPosition(0), 0.3f, freq, true); } m_sound->Frequency(m_soundChannel, freq); @@ -184,11 +185,11 @@ bool CAutoStation::EventProcess(const Event &event) } if ( used != 0.0f && - m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_time ) + m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { - m_lastParticule = m_time; + m_lastParticle = m_time; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Math::Vector(-15.0f, 7.0f, 0.0f); // battery position pos = Math::Transform(*mat, pos); speed.x = (Math::Rand()-0.5f)*20.0f; @@ -199,7 +200,7 @@ bool CAutoStation::EventProcess(const Event &event) ppos.z = pos.z; dim.x = 1.5f; dim.y = 1.5f; - m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTIBLITZ, 1.0f, 0.0f, 0.0f); #if 0 ppos = pos; @@ -211,7 +212,7 @@ bool CAutoStation::EventProcess(const Event &event) speed.y = 2.5f+Math::Rand()*6.0f; dim.x = Math::Rand()*1.5f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(ppos, speed, dim, PARTISMOKE3, 4.0f); + m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTISMOKE3, 4.0f); #else ppos = pos; ppos.y += 1.0f; @@ -222,7 +223,7 @@ bool CAutoStation::EventProcess(const Event &event) speed.y = 2.5f+Math::Rand()*5.0f; dim.x = Math::Rand()*1.0f+0.6f; dim.y = dim.x; - m_particule->CreateParticule(ppos, speed, dim, PARTIVAPOR, 3.0f); + m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTIVAPOR, 3.0f); #endif } @@ -244,14 +245,14 @@ CObject* CAutoStation::SearchVehicle() float dist; int i; - sPos = m_object->RetPosition(0); + sPos = m_object->GetPosition(0); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_HUMAN && type != OBJECT_MOBILEfa && type != OBJECT_MOBILEta && @@ -280,7 +281,7 @@ CObject* CAutoStation::SearchVehicle() type != OBJECT_MOBILEit && type != OBJECT_MOBILEdr ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, sPos); if ( dist <= 5.0f ) return pObj; } @@ -289,19 +290,19 @@ CObject* CAutoStation::SearchVehicle() } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoStation::RetError() +Error CAutoStation::GetError() { - TerrainRes res; + Gfx::TerrainRes res; - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } - res = m_terrain->RetResource(m_object->RetPosition(0)); - if ( res != TR_POWER ) return ERR_STATION_NULL; + res = m_terrain->GetResource(m_object->GetPosition(0)); + if ( res != Gfx::TR_POWER ) return ERR_STATION_NULL; return ERR_OK; } @@ -311,7 +312,7 @@ Error CAutoStation::RetError() bool CAutoStation::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -319,7 +320,7 @@ bool CAutoStation::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -347,23 +348,23 @@ bool CAutoStation::CreateInterface(bool bSelect) void CAutoStation::UpdateInterface(float rTime) { - CWindow* pw; - CGauge* pg; + Ui::CWindow* pw; + Ui::CGauge* pg; CAuto::UpdateInterface(rTime); if ( m_time < m_lastUpdateTime+0.1f ) return; m_lastUpdateTime = m_time; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); if ( pg != 0 ) { - pg->SetLevel(m_object->RetEnergy()); + pg->SetLevel(m_object->GetEnergy()); } } diff --git a/src/object/auto/autostation.h b/src/object/auto/autostation.h index 5bf2b72..cb8be2b 100644 --- a/src/object/auto/autostation.h +++ b/src/object/auto/autostation.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -33,7 +34,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -47,7 +48,7 @@ protected: float m_speed; float m_timeVirus; float m_lastUpdateTime; - float m_lastParticule; + float m_lastParticle; int m_soundChannel; Math::Vector m_fretPos; bool m_bLastVirus; diff --git a/src/object/auto/autotower.cpp b/src/object/auto/autotower.cpp index 5f185fe..8410086 100644 --- a/src/object/auto/autotower.cpp +++ b/src/object/auto/autotower.cpp @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -78,7 +79,7 @@ void CAutoTower::Init() m_time = 0.0f; m_timeVirus = 0.0f; m_lastUpdateTime = 0.0f; - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; } @@ -93,18 +94,18 @@ bool CAutoTower::EventProcess(const Event &event) CAuto::EventProcess(event); - if ( m_engine->RetPause() ) return true; - if ( event.event != EVENT_FRAME ) return true; + if ( m_engine->GetPause() ) return true; + if ( event.type != EVENT_FRAME ) return true; m_timeVirus -= event.rTime; - if ( m_object->RetVirusMode() ) // contaminated by a virus? + if ( m_object->GetVirusMode() ) // contaminated by a virus? { if ( m_timeVirus <= 0.0f ) { m_timeVirus = 0.1f+Math::Rand()*0.3f; - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle += Math::Rand()*0.5f; m_object->SetAngleY(1, angle); @@ -125,10 +126,10 @@ bool CAutoTower::EventProcess(const Event &event) if ( m_progress < 1.0f ) { energy = 0.0f; - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); } if ( energy >= ENERGY_FIRE ) { @@ -153,11 +154,11 @@ bool CAutoTower::EventProcess(const Event &event) quick = 1.0f; //? if ( g_researchDone & RESEARCH_QUICK ) quick = 3.0f; - angle = m_object->RetAngleY(1); + angle = m_object->GetAngleY(1); angle -= event.rTime*quick*2.0f; m_object->SetAngleY(1, angle); - angle = m_object->RetAngleZ(2); + angle = m_object->GetAngleZ(2); angle += event.rTime*quick*0.5f; if ( angle > 0.0f ) angle = 0.0f; m_object->SetAngleZ(2, angle); @@ -165,10 +166,10 @@ bool CAutoTower::EventProcess(const Event &event) else { energy = 0.0f; - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); } target = SearchTarget(m_targetPos); @@ -184,16 +185,16 @@ bool CAutoTower::EventProcess(const Event &event) } else { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 24.5f; m_angleYfinal = Math::RotateAngle(m_targetPos.x-pos.x, pos.z-m_targetPos.z); // CW ! m_angleYfinal += Math::PI*2.0f; - m_angleYfinal -= m_object->RetAngleY(0); - m_angleYactual = Math::NormAngle(m_object->RetAngleY(1)); + m_angleYfinal -= m_object->GetAngleY(0); + m_angleYactual = Math::NormAngle(m_object->GetAngleY(1)); m_angleZfinal = -Math::PI/2.0f; m_angleZfinal -= Math::RotateAngle(Math::DistanceProjected(m_targetPos, pos), pos.y-m_targetPos.y); // CW ! - m_angleZactual = m_object->RetAngleZ(2); + m_angleZactual = m_object->GetAngleZ(2); m_phase = ATP_TURN; m_progress = 0.0f; @@ -218,15 +219,15 @@ bool CAutoTower::EventProcess(const Event &event) m_object->SetAngleY(1, m_angleYfinal); m_object->SetAngleZ(2, m_angleZfinal); - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); - energy -= ENERGY_FIRE/power->RetCapacity(); + energy = power->GetEnergy(); + energy -= ENERGY_FIRE/power->GetCapacity(); power->SetEnergy(energy); } - m_sound->Play(SOUND_GGG, m_object->RetPosition(0)); + m_sound->Play(SOUND_GGG, m_object->GetPosition(0)); m_phase = ATP_FIRE; m_progress = 0.0f; @@ -238,9 +239,9 @@ bool CAutoTower::EventProcess(const Event &event) { if ( m_progress == 0.0f ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y += 24.5f; - m_particule->CreateRay(pos, m_targetPos, PARTIRAY1, + m_particle->CreateRay(pos, m_targetPos, Gfx::PARTIRAY1, Math::Point(5.0f, 5.0f), 1.5f); } if ( m_progress >= 1.0f ) @@ -267,30 +268,30 @@ CObject* CAutoTower::SearchTarget(Math::Vector &impact) float distance, min, radius, speed; int i; - iPos = m_object->RetPosition(0); + iPos = m_object->GetPosition(0); min = 1000000.0f; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast< CObject* >(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType != OBJECT_MOTHER && oType != OBJECT_ANT && oType != OBJECT_SPIDER && oType != OBJECT_BEE && oType != OBJECT_WORM ) continue; - if ( !pObj->RetActif() ) continue; // inactive? + if ( !pObj->GetActif() ) continue; // inactive? //? if ( g_researchDone & RESEARCH_QUICK ) if ( false ) { - physics = pObj->RetPhysics(); + physics = pObj->GetPhysics(); if ( physics != 0 ) { - speed = fabs(physics->RetLinMotionX(MO_REASPEED)); + speed = fabs(physics->GetLinMotionX(MO_REASPEED)); if ( speed > 20.0f ) continue; // moving too fast? } } @@ -306,30 +307,30 @@ CObject* CAutoTower::SearchTarget(Math::Vector &impact) } if ( pBest == 0 ) return 0; - impact = pBest->RetPosition(0); + impact = pBest->GetPosition(0); return pBest; } -// Returns an error due the state of the automation. +// Geturns an error due the state of the automation. -Error CAutoTower::RetError() +Error CAutoTower::GetError() { CObject* power; - if ( m_object->RetVirusMode() ) + if ( m_object->GetVirusMode() ) { return ERR_BAT_VIRUS; } - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power == 0 ) { return ERR_TOWER_POWER; // no battery } else { - if ( power->RetEnergy() < ENERGY_FIRE ) + if ( power->GetEnergy() < ENERGY_FIRE ) { return ERR_TOWER_ENERGY; // not enough energy } @@ -361,14 +362,14 @@ void CAutoTower::FireStopUpdate(float progress, bool bLightOn) { if ( m_partiStop[i] != -1 ) { - m_particule->DeleteParticule(m_partiStop[i]); + m_particle->DeleteParticle(m_partiStop[i]); m_partiStop[i] = -1; } } return; } - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 2.0f; @@ -380,7 +381,7 @@ void CAutoTower::FireStopUpdate(float progress, bool bLightOn) { if ( m_partiStop[i] != -1 ) { - m_particule->DeleteParticule(m_partiStop[i]); + m_particle->DeleteParticle(m_partiStop[i]); m_partiStop[i] = -1; } } @@ -392,8 +393,9 @@ void CAutoTower::FireStopUpdate(float progress, bool bLightOn) pos.y = 18.0f; pos.z = listpos[i*2+1]; pos = Transform(*mat, pos); - m_partiStop[i] = m_particule->CreateParticule(pos, speed, - dim, PARTISELR, + + m_partiStop[i] = m_particle->CreateParticle(pos, speed, + dim, Gfx::PARTISELR, 1.0f, 0.0f, 0.0f); } } @@ -405,7 +407,7 @@ void CAutoTower::FireStopUpdate(float progress, bool bLightOn) bool CAutoTower::CreateInterface(bool bSelect) { - CWindow* pw; + Ui::CWindow* pw; Math::Point pos, ddim; float ox, oy, sx, sy; @@ -413,7 +415,7 @@ bool CAutoTower::CreateInterface(bool bSelect) if ( !bSelect ) return true; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return false; ox = 3.0f/640.0f; @@ -447,8 +449,8 @@ bool CAutoTower::CreateInterface(bool bSelect) void CAutoTower::UpdateInterface(float rTime) { - CWindow* pw; - CGauge* pg; + Ui::CWindow* pw; + Ui::CGauge* pg; CObject* power; float energy; @@ -457,19 +459,19 @@ void CAutoTower::UpdateInterface(float rTime) if ( m_time < m_lastUpdateTime+0.1f ) return; m_lastUpdateTime = m_time; - if ( !m_object->RetSelect() ) return; + if ( !m_object->GetSelect() ) return; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = static_cast< Ui::CWindow* >(m_interface->SearchControl(EVENT_WINDOW0)); if ( pw == 0 ) return; - pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); + pg = static_cast< Ui::CGauge* >(pw->SearchControl(EVENT_OBJECT_GENERGY)); if ( pg != 0 ) { energy = 0.0f; - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); } pg->SetLevel(energy); } @@ -524,7 +526,7 @@ bool CAutoTower::Read(char *line) CAuto::Read(line); - m_phase = (AutoTowerPhase)OpInt(line, "aPhase", ATP_WAIT); + m_phase = static_cast< AutoTowerPhase >(OpInt(line, "aPhase", ATP_WAIT)); m_progress = OpFloat(line, "aProgress", 0.0f); m_speed = OpFloat(line, "aSpeed", 1.0f); m_targetPos = OpDir(line, "aTargetPos"); diff --git a/src/object/auto/autotower.h b/src/object/auto/autotower.h index c9393ff..b29ba85 100644 --- a/src/object/auto/autotower.h +++ b/src/object/auto/autotower.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -44,7 +45,7 @@ public: void Init(); bool EventProcess(const Event &event); - Error RetError(); + Error GetError(); bool CreateInterface(bool bSelect); @@ -63,7 +64,7 @@ protected: float m_speed; float m_timeVirus; float m_lastUpdateTime; - float m_lastParticule; + float m_lastParticle; Math::Vector m_targetPos; float m_angleYactual; float m_angleZactual; diff --git a/src/object/brain.cpp b/src/object/brain.cpp index ef55e73..e322a3d 100644 --- a/src/object/brain.cpp +++ b/src/object/brain.cpp @@ -15,55 +15,55 @@ // * along with this program. If not, see http://www.gnu.org/licenses/. -#include <stdio.h> - +// #include <stdio.h> +// #include "object/brain.h" - -#include "CBot/CBotDll.h" -#include "common/struct.h" -#include "math/geometry.h" -#include "math/const.h" -#include "old/d3dengine.h" -#include "old/d3dmath.h" -#include "common/language.h" -#include "common/global.h" -#include "common/event.h" +// +// #include "CBot/CBotDll.h" +// #include "common/struct.h" +// #include "math/geometry.h" +// #include "math/const.h" +// #include "old/d3dengine.h" +// #include "old/d3dmath.h" +// #include "common/language.h" +// #include "common/global.h" +// #include "common/event.h" #include "common/misc.h" #include "common/iman.h" -#include "common/restext.h" -#include "old/math3d.h" -#include "object/robotmain.h" -#include "old/terrain.h" -#include "old/water.h" -#include "old/camera.h" -#include "object/object.h" -#include "physics/physics.h" -#include "object/motion/motion.h" -#include "object/motion/motionspider.h" -#include "old/pyro.h" +// #include "common/restext.h" +// #include "old/math3d.h" +// #include "object/robotmain.h" +// #include "old/terrain.h" +// #include "old/water.h" +// #include "old/camera.h" +// #include "object/object.h" +// #include "physics/physics.h" +// #include "object/motion/motion.h" +// #include "object/motion/motionspider.h" +// #include "old/pyro.h" #include "object/task/taskmanager.h" -#include "object/task/task.h" -#include "object/task/taskmanip.h" -#include "object/task/taskflag.h" -#include "object/task/taskshield.h" +// #include "object/task/task.h" +// #include "object/task/taskmanip.h" +// #include "object/task/taskflag.h" +// #include "object/task/taskshield.h" #include "script/script.h" -#include "ui/studio.h" -#include "ui/interface.h" -#include "ui/button.h" -#include "ui/color.h" -#include "ui/edit.h" -#include "ui/list.h" -#include "ui/label.h" -#include "ui/group.h" -#include "ui/gauge.h" +// #include "ui/studio.h" +// #include "ui/interface.h" +// #include "ui/button.h" +// #include "ui/color.h" +// #include "ui/edit.h" +// #include "ui/list.h" +// #include "ui/label.h" +// #include "ui/group.h" +// #include "ui/gauge.h" #include "ui/slider.h" -#include "ui/compass.h" -#include "ui/target.h" +// #include "ui/compass.h" +// #include "ui/target.h" #include "ui/window.h" -#include "ui/displaytext.h" -#include "old/text.h" -#include "old/sound.h" -#include "old/particule.h" +// #include "ui/displaytext.h" +// #include "old/text.h" +#include "sound/sound.h" +// #include "old/particule.h" #include "script/cmdtoken.h" @@ -82,20 +82,21 @@ CBrain::CBrain(CInstanceManager* iMan, CObject* object) m_iMan->AddInstance(CLASS_BRAIN, this, 100); m_object = object; - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_engine = static_cast<Gfx::CEngine*>(m_iMan->SearchInstance(CLASS_ENGINE)); + m_terrain = static_cast<Gfx::CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_water = static_cast<Gfx::CWater*>(m_iMan->SearchInstance(CLASS_WATER)); + m_camera = static_cast<Gfx::CCamera*>(m_iMan->SearchInstance(CLASS_CAMERA)); + m_interface = static_cast<CInterface*>(m_iMan->SearchInstance(CLASS_INTERFACE)); + m_displayText = static_cast<CDisplayText*>(m_iMan->SearchInstance(CLASS_DISPLAYTEXT)); + m_main = static_cast<CRobotMain*>(m_iMan->SearchInstance(CLASS_MAIN)); + m_sound = static_cast<CSoundInterface*>(m_iMan->SearchInstance(CLASS_SOUND)); + m_particle = static_cast<CParticle*>(m_iMan->SearchInstance(CLASS_PARTICULE)); m_physics = 0; m_motion = 0; m_primaryTask = 0; m_secondaryTask = 0; - m_studio = 0; + // TODO uncoment when ui/studio will be implemented. + // m_studio = 0; m_program = -1; m_bActivity = true; @@ -142,7 +143,8 @@ CBrain::~CBrain() delete m_primaryTask; delete m_secondaryTask; - delete m_studio; + // TODO uncoment when ui/studio will be implemented. + // delete m_studio; delete m_traceRecordBuffer; m_iMan->DeleteInstance(CLASS_BRAIN, this); } @@ -169,7 +171,8 @@ void CBrain::DeleteObject(bool bAll) } } - if ( m_studio != 0 ) // current edition? + // TODO uncoment when ui/studio will be implemented. + // if ( m_studio != 0 ) // current edition? { StopEditScript(true); } @@ -213,13 +216,13 @@ bool CBrain::Read(char *line) bool CBrain::EventProcess(const Event &event) { - CWindow* pw; - CControl* pc; - CSlider* ps; - EventMsg action; - ObjectType type; - Error err; - float axeX, axeY, axeZ, factor; + Ui::CWindow* pw; + Ui::CControl* pc; + Ui::CSlider* ps; + Event action; + ObjectType type; + Error err; + float axeX, axeY, axeZ, factor; type = m_object->RetType(); @@ -240,7 +243,7 @@ bool CBrain::EventProcess(const Event &event) event.param == m_engine->RetKey(KEYRANK_ACTION, 1) ) && !m_main->RetEditLock() ) { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw != 0 ) { pc = pw->SearchControl(m_defaultEnter); @@ -270,10 +273,11 @@ bool CBrain::EventProcess(const Event &event) EventFrame(event); } + // TODO uncoment when ui/studio will be implemented. if ( m_object->RetSelect() && // robot selected? - m_studio != 0 ) // current issue? + /* m_studio != 0 */ ) // current issue? { - m_studio->EventProcess(event); + // m_studio->EventProcess(event); if ( action == EVENT_OBJECT_PROGRUN ) { @@ -591,10 +595,10 @@ bool CBrain::EventProcess(const Event &event) if ( action == EVENT_OBJECT_DIMSHIELD ) { - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw != 0 ) { - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); + ps = (Ui::CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); if ( ps != 0 ) { m_object->SetParam((ps->RetVisibleValue()-(RADIUS_SHIELD_MIN/g_unit))/((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); @@ -687,7 +691,7 @@ bool CBrain::EventProcess(const Event &event) TraceRecordStart(); } UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw != 0 ) { UpdateScript(pw); @@ -701,7 +705,7 @@ bool CBrain::EventProcess(const Event &event) TraceRecordStop(); } UpdateInterface(); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw != 0 ) { UpdateScript(pw); @@ -765,10 +769,11 @@ bool CBrain::EventFrame(const Event &event) m_sound->Position(m_soundChannelAlarm, m_object->RetPosition(0)); } - if ( m_studio != 0 ) // �urrent edition? - { - m_studio->EventProcess(event); - } + // TODO uncoment when ui/studio will be implemented. + // if ( m_studio != 0 ) // current edition? + // { + // m_studio->EventProcess(event); + // } UpdateInterface(event.rTime); @@ -891,8 +896,9 @@ void CBrain::StartEditScript(int rank, char* name) m_script[rank] = new CScript(m_iMan, m_object, &m_secondaryTask); } - m_studio = new CStudio(m_iMan); - m_studio->StartEditScript(m_script[rank], name, rank); + // TODO uncoment when ui/studio will be implemented. + // m_studio = new CStudio(m_iMan); + // m_studio->StartEditScript(m_script[rank], name, rank); } // End of editing a program. @@ -901,10 +907,11 @@ void CBrain::StopEditScript(bool bCancel) { if ( !bCancel ) SetActiveVirus(false); - if ( !m_studio->StopEditScript(bCancel) ) return; + // TODO uncoment when ui/studio will be implemented. + // if ( !m_studio->StopEditScript(bCancel) ) return; - delete m_studio; - m_studio = 0; + // delete m_studio; + // m_studio = 0; CreateInterface(true); // puts the control buttons } @@ -1209,7 +1216,7 @@ void CBrain::GroundFlat() speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 40.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIGFLAT, 1.0f); + m_particle->CreateParticle(pos, speed, dim, PARTIGFLAT, 1.0f); } @@ -1227,17 +1234,17 @@ void CBrain::ColorFlag(int color) bool CBrain::CreateInterface(bool bSelect) { ObjectType type; - CWindow* pw; + Ui::CWindow* pw; CButton* pb; CColor* pc; - CSlider* ps; + Ui::CSlider* ps; CTarget* pt; CLabel* pl; Math::Point pos, dim, ddim; float ox, oy, sx, sy; char name[100]; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw != 0 ) { pw->Flush(); // destroys the window buttons @@ -1253,7 +1260,7 @@ bool CBrain::CreateInterface(bool bSelect) if ( !m_main->RetShowMap() ) dim.x = 640.0f/640.0f; dim.y = 86.0f/480.0f; m_interface->CreateWindows(pos, dim, 3, EVENT_WINDOW0); - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw == 0 ) return false; m_object->GetTooltipName(name); @@ -1926,7 +1933,7 @@ bool CBrain::CreateInterface(bool bSelect) void CBrain::UpdateInterface(float rTime) { - CWindow* pw; + Ui::CWindow* pw; #if _TEEN CButton* pb; #endif @@ -1956,7 +1963,7 @@ void CBrain::UpdateInterface(float rTime) return; } - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw == 0 ) return; pg = (CGauge*)pw->SearchControl(EVENT_OBJECT_GENERGY); @@ -2130,9 +2137,9 @@ void CBrain::UpdateInterface(float rTime) void CBrain::UpdateInterface() { ObjectType type; - CWindow* pw; + Ui::CWindow* pw; CButton* pb; - CSlider* ps; + Ui::CSlider* ps; #if _TEEN CColor* pc; int color; @@ -2142,7 +2149,7 @@ void CBrain::UpdateInterface() if ( !m_object->RetSelect() ) return; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw == 0 ) return; type = m_object->RetType(); @@ -2235,7 +2242,7 @@ void CBrain::UpdateInterface() DefaultEnter (pw, EVENT_OBJECT_ENDSHIELD, false); } - ps = (CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); + ps = (Ui::CSlider*)pw->SearchControl(EVENT_OBJECT_DIMSHIELD); if ( ps != 0 ) { ps->SetVisibleValue((RADIUS_SHIELD_MIN/g_unit)+m_object->RetParam()*((RADIUS_SHIELD_MAX-RADIUS_SHIELD_MIN)/g_unit)); @@ -2438,7 +2445,7 @@ void CBrain::UpdateInterface() // Updates the list of programs. -void CBrain::UpdateScript(CWindow *pw) +void CBrain::UpdateScript(Ui::CWindow *pw) { CList* pl; char name[100]; @@ -2488,10 +2495,10 @@ void CBrain::UpdateScript(CWindow *pw) int CBrain::RetSelScript() { - CWindow* pw; + Ui::CWindow* pw; CList* pl; - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw == 0 ) return -1; pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); @@ -2504,12 +2511,12 @@ int CBrain::RetSelScript() void CBrain::BlinkScript(bool bEnable) { - CWindow* pw; + Ui::CWindow* pw; CList* pl; if ( !m_object->RetSelect() ) return; // robot not selected? - pw = (CWindow*)m_interface->SearchControl(EVENT_WINDOW0); + pw = (Ui::CWindow*)m_interface->SearchControl(EVENT_WINDOW0); if ( pw == 0 ) return; pl = (CList*)pw->SearchControl(EVENT_OBJECT_PROGLIST); @@ -2520,9 +2527,9 @@ void CBrain::BlinkScript(bool bEnable) // Check the status of a button interface. -void CBrain::CheckInterface(CWindow *pw, EventMsg event, bool bState) +void CBrain::CheckInterface(Ui::CWindow *pw, EventMsg event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); if ( control == 0 ) return; @@ -2532,9 +2539,9 @@ void CBrain::CheckInterface(CWindow *pw, EventMsg event, bool bState) // Changes the state of a button interface. -void CBrain::EnableInterface(CWindow *pw, EventMsg event, bool bState) +void CBrain::EnableInterface(Ui::CWindow *pw, EventMsg event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); if ( control == 0 ) return; @@ -2544,9 +2551,9 @@ void CBrain::EnableInterface(CWindow *pw, EventMsg event, bool bState) // Changes the state of a button on the interface. -void CBrain::DeadInterface(CWindow *pw, EventMsg event, bool bState) +void CBrain::DeadInterface(Ui::CWindow *pw, EventMsg event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); if ( control == 0 ) return; @@ -2556,9 +2563,9 @@ void CBrain::DeadInterface(CWindow *pw, EventMsg event, bool bState) // Change the default input state of a button interface. -void CBrain::DefaultEnter(CWindow *pw, EventMsg event, bool bState) +void CBrain::DefaultEnter(Ui::CWindow *pw, EventMsg event, bool bState) { - CControl* control; + Ui::CControl* control; control = pw->SearchControl(event); if ( control == 0 ) return; @@ -2708,7 +2715,7 @@ bool CBrain::ReadSoluce(char* filename) // Load a script with a text file. -bool CBrain::ReadProgram(int rank, char* filename) +bool CBrain::ReadProgram(int rank, const char* filename) { if ( m_script[rank] == 0 ) { diff --git a/src/object/brain.h b/src/object/brain.h index 0220ffc..b1ef9bc 100644 --- a/src/object/brain.h +++ b/src/object/brain.h @@ -19,7 +19,7 @@ #pragma once -#include <stdio.h> +// #include <stdio.h> #include "common/misc.h" #include "common/event.h" @@ -30,10 +30,6 @@ class CInstanceManager; -class CD3DEngine; -class CTerrain; -class CWater; -class CCamera; class CObject; class CPhysics; class CMotion; @@ -44,8 +40,18 @@ class CDisplayText; class CScript; class CRobotMain; class CStudio; -class CSound; -class CParticule; +class CSoundInterface; +class CParticle; + +namespace Gfx +{ + +class CEngine; +class CTerrain; +class CWater; +class CCamera; + +} /* Gfx */ const int BRAINMAXSCRIPT = 10; @@ -88,29 +94,29 @@ public: bool IsBusy(); void SetActivity(bool bMode); - bool RetActivity(); + bool GetActivity(); bool IsProgram(); bool ProgramExist(int rank); void RunProgram(int rank); int FreeProgram(); - int RetProgram(); + int GetProgram(); void StopProgram(); void StopTask(); bool IntroduceVirus(); void SetActiveVirus(bool bActive); - bool RetActiveVirus(); + bool GetActiveVirus(); void SetScriptRun(int rank); - int RetScriptRun(); + int GetScriptRun(); void SetScriptName(int rank, char *name); - char* RetScriptName(int rank); + char* GetScriptName(int rank); void SetSoluceName(char *name); - char* RetSoluceName(); + char* GetSoluceName(); bool ReadSoluce(char* filename); - bool ReadProgram(int rank, char* filename); - bool RetCompile(int rank); + bool ReadProgram(int rank, const char* filename); + bool GetCompile(int rank); bool WriteProgram(int rank, char* filename); bool ReadStack(FILE *file); bool WriteStack(FILE *file); @@ -144,13 +150,13 @@ protected: void ColorFlag(int color); void UpdateScript(CWindow *pw); - int RetSelScript(); + int GetSelScript(); void BlinkScript(bool bEnable); - void CheckInterface(CWindow *pw, EventMsg event, bool bState); - void EnableInterface(CWindow *pw, EventMsg event, bool bState); - void DeadInterface(CWindow *pw, EventMsg event, bool bState); - void DefaultEnter(CWindow *pw, EventMsg event, bool bState=true); + void CheckInterface(CWindow *pw, EventType event, bool bState); + void EnableInterface(CWindow *pw, EventType event, bool bState); + void DeadInterface(CWindow *pw, EventType event, bool bState); + void DefaultEnter(CWindow *pw, EventType event, bool bState=true); void TraceRecordStart(); void TraceRecordFrame(); @@ -159,60 +165,60 @@ protected: bool TraceRecordPut(char *buffer, int max, TraceOper oper, float param); protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CObject* m_object; - CPhysics* m_physics; - CMotion* m_motion; - CInterface* m_interface; - CDisplayText* m_displayText; - CRobotMain* m_main; - CStudio* m_studio; - CSound* m_sound; - CParticule* m_particule; - CTaskManager* m_primaryTask; - CTaskManager* m_secondaryTask; - - CScript* m_script[BRAINMAXSCRIPT]; - int m_selScript; // rank of the selected script - int m_program; // rank of the executed program / ​​-1 - bool m_bActivity; - bool m_bBurn; - bool m_bActiveVirus; - - int m_scriptRun; - char m_scriptName[BRAINMAXSCRIPT][50]; - char m_soluceName[50]; - - EventMsg m_buttonAxe; - EventMsg m_manipStyle; - EventMsg m_defaultEnter; - EventMsg m_interfaceEvent[100]; - - CObject* m_antTarget; - CObject* m_beeBullet; - float m_beeBulletSpeed; - Math::Vector m_startPos; - float m_time; - float m_burnTime; - float m_lastUpdateTime; - float m_lastHumanTime; - float m_lastSpiderTime; - float m_lastWormTime; - float m_lastBulletTime; - float m_lastAlarmTime; - int m_soundChannelAlarm; - int m_flagColor; - - bool m_bTraceRecord; - TraceOper m_traceOper; - Math::Vector m_tracePos; - float m_traceAngle; - int m_traceColor; - int m_traceRecordIndex; - TraceRecord* m_traceRecordBuffer; + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + Gfx::CCamera* m_camera; + CObject* m_object; + CPhysics* m_physics; + CMotion* m_motion; + CInterface* m_interface; + CDisplayText* m_displayText; + CRobotMain* m_main; + CStudio* m_studio; + CSoundInterface* m_sound; + CParticle* m_particle; + CTaskManager* m_primaryTask; + CTaskManager* m_secondaryTask; + + CScript* m_script[BRAINMAXSCRIPT]; + int m_selScript; // rank of the selected script + int m_program; // rank of the executed program / ​​-1 + bool m_bActivity; + bool m_bBurn; + bool m_bActiveVirus; + + int m_scriptRun; + char m_scriptName[BRAINMAXSCRIPT][50]; + char m_soluceName[50]; + + EventType m_buttonAxe; + EventType m_manipStyle; + EventType m_defaultEnter; + EventType m_interfaceEvent[100]; + + CObject* m_antTarget; + CObject* m_beeBullet; + float m_beeBulletSpeed; + Math::Vector m_startPos; + float m_time; + float m_burnTime; + float m_lastUpdateTime; + float m_lastHumanTime; + float m_lastSpiderTime; + float m_lastWormTime; + float m_lastBulletTime; + float m_lastAlarmTime; + int m_soundChannelAlarm; + int m_flagColor; + + bool m_bTraceRecord; + TraceOper m_traceOper; + Math::Vector m_tracePos; + float m_traceAngle; + int m_traceColor; + int m_traceRecordIndex; + TraceRecord* m_traceRecordBuffer; }; diff --git a/src/object/mainmovie.h b/src/object/mainmovie.h index 23721fb..0c8d51c 100644 --- a/src/object/mainmovie.h +++ b/src/object/mainmovie.h @@ -25,13 +25,15 @@ class CInstanceManager; class CEvent; -class CD3DEngine; class CInterface; class CRobotMain; class CCamera; -class CSound; - +class CSoundInterface; +namespace Gfx +{ + class CEngine; +} /* Gfx */ enum MainMovieType @@ -61,17 +63,17 @@ protected: protected: CInstanceManager* m_iMan; - CEvent* m_event; - CD3DEngine* m_engine; - CInterface* m_interface; - CRobotMain* m_main; - CCamera* m_camera; - CSound* m_sound; - - MainMovieType m_type; - MainMovieType m_stopType; - float m_speed; - float m_progress; + CEvent* m_event; + Gfx::CEngine* m_engine; + CInterface* m_interface; + CRobotMain* m_main; + CCamera* m_camera; + CSoundInterface* m_sound; + + MainMovieType m_type; + MainMovieType m_stopType; + float m_speed; + float m_progress; Math::Vector m_initialEye; Math::Vector m_initialLookat; Math::Vector m_finalEye[2]; diff --git a/src/object/motion/motion.cpp b/src/object/motion/motion.cpp index 6278627..6b22471 100644 --- a/src/object/motion/motion.cpp +++ b/src/object/motion/motion.cpp @@ -95,16 +95,16 @@ bool CMotion::EventProcess(const Event &event) Math::Vector pos, dir; float time; - if ( m_object->RetType() != OBJECT_TOTO && - m_engine->RetPause() ) return true; + if ( m_object->GetType() != OBJECT_TOTO && + m_engine->GetPause() ) return true; if ( event.event != EVENT_FRAME ) return true; m_progress += event.rTime*m_actionTime; if ( m_progress > 1.0f ) m_progress = 1.0f; // (*) - pos = m_object->RetPosition(0); - if ( pos.y < m_water->RetLevel(m_object) ) // underwater? + pos = m_object->GetPosition(0); + if ( pos.y < m_water->GetLevel(m_object) ) // underwater? { time = event.rTime*3.0f; // everything is slower } @@ -113,19 +113,19 @@ bool CMotion::EventProcess(const Event &event) time = event.rTime*10.0f; } - dir = m_object->RetLinVibration(); + dir = m_object->GetLinVibration(); dir.x = Math::Smooth(dir.x, m_linVibration.x, time); dir.y = Math::Smooth(dir.y, m_linVibration.y, time); dir.z = Math::Smooth(dir.z, m_linVibration.z, time); m_object->SetLinVibration(dir); - dir = m_object->RetCirVibration(); + dir = m_object->GetCirVibration(); dir.x = Math::Smooth(dir.x, m_cirVibration.x, time); dir.y = Math::Smooth(dir.y, m_cirVibration.y, time); dir.z = Math::Smooth(dir.z, m_cirVibration.z, time); m_object->SetCirVibration(dir); - dir = m_object->RetInclinaison(); + dir = m_object->GetInclinaison(); dir.x = Math::Smooth(dir.x, m_inclinaison.x, time); dir.y = Math::Smooth(dir.y, m_inclinaison.y, time); dir.z = Math::Smooth(dir.z, m_inclinaison.z, time); @@ -148,9 +148,9 @@ Error CMotion::SetAction(int action, float time) return ERR_OK; } -// Returns the current action. +// Geturns the current action. -int CMotion::RetAction() +int CMotion::GetAction() { return m_actionType; } @@ -163,7 +163,7 @@ bool CMotion::SetParam(int rank, float value) return false; } -float CMotion::RetParam(int rank) +float CMotion::GetParam(int rank) { return 0.0f; } @@ -208,7 +208,7 @@ void CMotion::SetLinVibration(Math::Vector dir) m_linVibration = dir; } -Math::Vector CMotion::RetLinVibration() +Math::Vector CMotion::GetLinVibration() { return m_linVibration; } @@ -220,7 +220,7 @@ void CMotion::SetCirVibration(Math::Vector dir) m_cirVibration = dir; } -Math::Vector CMotion::RetCirVibration() +Math::Vector CMotion::GetCirVibration() { return m_cirVibration; } @@ -232,7 +232,7 @@ void CMotion::SetInclinaison(Math::Vector dir) m_inclinaison = dir; } -Math::Vector CMotion::RetInclinaison() +Math::Vector CMotion::GetInclinaison() { return m_inclinaison; } diff --git a/src/object/motion/motion.h b/src/object/motion/motion.h index 9828283..2ec5c5d 100644 --- a/src/object/motion/motion.h +++ b/src/object/motion/motion.h @@ -51,20 +51,20 @@ public: virtual bool Create(Math::Vector pos, float angle, ObjectType type, float power); virtual bool EventProcess(const Event &event); virtual Error SetAction(int action, float time=0.2f); - virtual int RetAction(); + virtual int GetAction(); virtual bool SetParam(int rank, float value); - virtual float RetParam(int rank); + virtual float GetParam(int rank); virtual bool Write(char *line); virtual bool Read(char *line); virtual void SetLinVibration(Math::Vector dir); - virtual Math::Vector RetLinVibration(); + virtual Math::Vector GetLinVibration(); virtual void SetCirVibration(Math::Vector dir); - virtual Math::Vector RetCirVibration(); + virtual Math::Vector GetCirVibration(); virtual void SetInclinaison(Math::Vector dir); - virtual Math::Vector RetInclinaison(); + virtual Math::Vector GetInclinaison(); protected: diff --git a/src/object/motion/motionvehicle.h b/src/object/motion/motionvehicle.h index 5ca97cd..ca60c1e 100644 --- a/src/object/motion/motionvehicle.h +++ b/src/object/motion/motionvehicle.h @@ -33,11 +33,11 @@ public: bool Create(Math::Vector pos, float angle, ObjectType type, float power); bool EventProcess(const Event &event); - bool RetTraceDown(); + bool GetTraceDown(); void SetTraceDown(bool bDown); - int RetTraceColor(); + int GetTraceColor(); void SetTraceColor(int color); - float RetTraceWidth(); + float GetTraceWidth(); void SetTraceWidth(float width); protected: diff --git a/src/object/object.cpp b/src/object/object.cpp index e2e52e5..c29e59b 100644 --- a/src/object/object.cpp +++ b/src/object/object.cpp @@ -17,76 +17,74 @@ // object.cpp -#include <windows.h> -#include <stdio.h> -#include <d3d.h> - +//---------CBot #include "CBot/CBotDll.h" -#include "common/struct.h" -#include "math/const.h" -#include "math/geometry.h" -#include "old/d3dengine.h" -#include "old/d3dmath.h" -#include "old/d3dutil.h" + +//---------Common #include "common/global.h" -#include "common/event.h" -#include "common/misc.h" #include "common/iman.h" #include "common/restext.h" -#include "old/math3d.h" -#include "object/mainmovie.h" -#include "object/robotmain.h" -#include "old/light.h" -#include "old/terrain.h" -#include "old/water.h" -#include "old/blitz.h" -#include "old/camera.h" -#include "old/particule.h" -#include "physics/physics.h" -#include "object/brain.h" -#include "object/motion/motion.h" -#include "object/motion/motionhuman.h" -#include "object/motion/motiontoto.h" -#include "object/motion/motionvehicle.h" -#include "object/motion/motionmother.h" -#include "object/motion/motionant.h" -#include "object/motion/motionspider.h" -#include "object/motion/motionbee.h" -#include "object/motion/motionworm.h" -#include "old/modfile.h" + +//---------Graphic +#include "graphics/engine/lightman.h" +#include "graphics/engine/lightning.h" +#include "graphics/engine/modelfile.h" +#include "graphics/engine/particle.h" +#include "graphics/engine/pyro.h" +#include "graphics/engine/terrain.h" + +//---------Math +#include "math/geometry.h" + +//---------Object #include "object/auto/auto.h" #include "object/auto/autobase.h" -#include "object/auto/autoportico.h" +#include "object/auto/autoconvert.h" #include "object/auto/autoderrick.h" -#include "object/auto/autofactory.h" -#include "object/auto/autorepair.h" #include "object/auto/autodestroyer.h" -#include "object/auto/autostation.h" -#include "object/auto/autoenergy.h" -#include "object/auto/autoconvert.h" -#include "object/auto/autotower.h" -#include "object/auto/autoresearch.h" -#include "object/auto/autolabo.h" -#include "object/auto/autonuclear.h" -#include "object/auto/autoradar.h" #include "object/auto/autoegg.h" -#include "object/auto/autonest.h" -#include "object/auto/autoroot.h" +#include "object/auto/autoenergy.h" +#include "object/auto/autofactory.h" #include "object/auto/autoflag.h" +#include "object/auto/autohuston.h" #include "object/auto/autoinfo.h" #include "object/auto/autojostle.h" +#include "object/auto/autokid.h" +#include "object/auto/autolabo.h" +#include "object/auto/automush.h" +#include "object/auto/autonest.h" +#include "object/auto/autonuclear.h" #include "object/auto/autopara.h" +#include "object/auto/autoportico.h" +#include "object/auto/autoradar.h" +#include "object/auto/autorepair.h" +#include "object/auto/autoresearch.h" +#include "object/auto/autoroot.h" #include "object/auto/autosafe.h" -#include "object/auto/autohuston.h" -#include "object/auto/automush.h" -#include "object/auto/autokid.h" -#include "object/task/task.h" -#include "old/pyro.h" -#include "ui/displaytext.h" -#include "script/cmdtoken.h" -#include "script/cbottoken.h" -#include "old/sound.h" +#include "object/auto/autostation.h" +#include "object/auto/autotower.h" +#include "object/brain.h" +#include "object/motion/motion.h" +#include "object/motion/motionant.h" +#include "object/motion/motionbee.h" +#include "object/motion/motionhuman.h" +#include "object/motion/motionmother.h" +#include "object/motion/motionspider.h" +#include "object/motion/motiontoto.h" +#include "object/motion/motionvehicle.h" +#include "object/motion/motionworm.h" #include "object/object.h" +#include "object/robotmain.h" + +//---------Physics +#include "physics/physics.h" + +//---------Script +#include "script/cbottoken.h" +#include "script/cmdtoken.h" + +//---------Ui +#include "ui/displaytext.h" @@ -116,7 +114,7 @@ static float debug_arm3 = 0.0f; void uObject(CBotVar* botThis, void* user) { - CObject* object = (CObject*)user; + CObject* object = static_cast<CObject*>(user); CObject* power; CObject* fret; CPhysics* physics; @@ -128,19 +126,19 @@ void uObject(CBotVar* botThis, void* user) if ( object == 0 ) return; - physics = object->RetPhysics(); + physics = object->GetPhysics(); // Updates the object's type. pVar = botThis->GetItemList(); // "category" - type = object->RetType(); - pVar->SetValInt(type, object->RetName()); + type = object->GetType(); + pVar->SetValInt(type, object->GetName()); // Updates the position of the object. pVar = pVar->GetNext(); // "position" - if ( object->RetTruck() == 0 ) + if ( object->GetTruck() == 0 ) { - pos = object->RetPosition(0); - pos.y -= object->RetWaterLevel(); // relative to sea level! + pos = object->GetPosition(0); + pos.y -= object->GetWaterLevel(); // relative to sea level! pSub = pVar->GetItemList(); // "x" pSub->SetValFloat(pos.x/g_unit); pSub = pSub->GetNext(); // "y" @@ -159,8 +157,8 @@ void uObject(CBotVar* botThis, void* user) } // Updates the angle. - pos = object->RetAngle(0); - pos += object->RetInclinaison(); + pos = object->GetAngle(0); + pos += object->GetInclinaison(); pVar = pVar->GetNext(); // "orientation" pVar->SetValFloat(360.0f-Math::Mod(pos.y*180.0f/Math::PI, 360.0f)); pVar = pVar->GetNext(); // "pitch" @@ -170,47 +168,47 @@ void uObject(CBotVar* botThis, void* user) // Updates the energy level of the object. pVar = pVar->GetNext(); // "energyLevel" - value = object->RetEnergy(); + value = object->GetEnergy(); pVar->SetValFloat(value); // Updates the shield level of the object. pVar = pVar->GetNext(); // "shieldLevel" - value = object->RetShield(); + value = object->GetShield(); pVar->SetValFloat(value); // Updates the temperature of the reactor. pVar = pVar->GetNext(); // "temperature" if ( physics == 0 ) value = 0.0f; - else value = 1.0f-physics->RetReactorRange(); + else value = 1.0f-physics->GetReactorRange(); pVar->SetValFloat(value); // Updates the height above the ground. pVar = pVar->GetNext(); // "altitude" if ( physics == 0 ) value = 0.0f; - else value = physics->RetFloorHeight(); + else value = physics->GetFloorHeight(); pVar->SetValFloat(value/g_unit); // Updates the lifetime of the object. pVar = pVar->GetNext(); // "lifeTime" - value = object->RetAbsTime(); + value = object->GetAbsTime(); pVar->SetValFloat(value); // Updates the material of the object. pVar = pVar->GetNext(); // "material" - iValue = object->RetMaterial(); + iValue = object->GetMaterial(); pVar->SetValInt(iValue); // Updates the type of battery. pVar = pVar->GetNext(); // "energyCell" - power = object->RetPower(); + power = object->GetPower(); if ( power == 0 ) pVar->SetPointer(0); - else pVar->SetPointer(power->RetBotVar()); + else pVar->SetPointer(power->GetBotVar()); // Updates the transported object's type. pVar = pVar->GetNext(); // "load" - fret = object->RetFret(); + fret = object->GetFret(); if ( fret == 0 ) pVar->SetPointer(0); - else pVar->SetPointer(fret->RetBotVar()); + else pVar->SetPointer(fret->GetBotVar()); } @@ -225,15 +223,15 @@ CObject::CObject(CInstanceManager* iMan) m_iMan = iMan; m_iMan->AddInstance(CLASS_OBJECT, this, 500); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_engine = static_cast<Gfx::CEngine*>(m_iMan->SearchInstance(CLASS_ENGINE)); + m_lightMan = static_cast<Gfx::CLightManager*>(m_iMan->SearchInstance(CLASS_LIGHT)); + m_terrain = static_cast<Gfx::CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_water = static_cast<Gfx::CWater*>(m_iMan->SearchInstance(CLASS_WATER)); + m_particle = static_cast<Gfx::CParticle*>(m_iMan->SearchInstance(CLASS_PARTICULE)); + m_camera = static_cast<Gfx::CCamera*>(m_iMan->SearchInstance(CLASS_CAMERA)); + m_displayText = static_cast<Ui::CDisplayText*>(m_iMan->SearchInstance(CLASS_DISPLAYTEXT)); + m_main = static_cast<CRobotMain*>(m_iMan->SearchInstance(CLASS_MAIN)); + m_sound = static_cast<CSoundInterface*>(m_iMan->SearchInstance(CLASS_SOUND)); m_physics = 0; m_brain = 0; m_motion = 0; @@ -250,7 +248,7 @@ CObject::CObject(CInstanceManager* iMan) m_linVibration = Math::Vector(0.0f, 0.0f, 0.0f); m_cirVibration = Math::Vector(0.0f, 0.0f, 0.0f); m_inclinaison = Math::Vector(0.0f, 0.0f, 0.0f); - m_lastParticule = 0.0f; + m_lastParticle = 0.0f; m_power = 0; m_fret = 0; @@ -281,7 +279,7 @@ CObject::CObject(CInstanceManager* iMan) m_shotTime = 0.0f; m_bVirusMode = false; m_virusTime = 0.0f; - m_lastVirusParticule = 0.0f; + m_lastVirusParticle = 0.0f; m_totalDesectList = 0; m_bLock = false; m_bExplo = false; @@ -297,7 +295,7 @@ CObject::CObject(CInstanceManager* iMan) m_proxyDistance = 60.0f; m_param = 0.0f; - ZeroMemory(&m_character, sizeof(Character)); + memset(&m_character, 0, sizeof(m_character)); m_character.wheelFront = 1.0f; m_character.wheelBack = 1.0f; m_character.wheelLeft = 1.0f; @@ -309,7 +307,7 @@ CObject::CObject(CInstanceManager* iMan) m_resetAngle = Math::Vector(0.0f, 0.0f, 0.0f); m_resetRun = -1; - m_cameraType = CAMERA_BACK; + m_cameraType = Gfx::CAM_TYPE_BACK; m_cameraDist = 50.0f; m_bCameraLock = false; @@ -376,7 +374,7 @@ CObject::~CObject() void CObject::DeleteObject(bool bAll) { CObject* pObj; - CPyro* pPyro; + Gfx::CPyro* pPyro; int i; if ( m_botVar != 0 ) @@ -384,14 +382,14 @@ void CObject::DeleteObject(bool bAll) m_botVar->SetUserPtr(OBJECTDELETED); } - if ( m_camera->RetObject() == this ) + if ( m_camera->GetObject() == this ) { m_camera->SetObject(0); } for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; pObj->DeleteDeselList(this); @@ -400,29 +398,29 @@ void CObject::DeleteObject(bool bAll) if ( !bAll ) { #if 0 - type = m_camera->RetType(); - if ( (type == CAMERA_BACK || - type == CAMERA_FIX || - type == CAMERA_EXPLO || - type == CAMERA_ONBOARD) && - m_camera->RetObject() == this ) + type = m_camera->GetType(); + if ( (type == Gfx::CAM_TYPE_BACK || + type == Gfx::CAM_TYPE_FIX || + type == Gfx::CAM_TYPE_EXPLO || + type == Gfx::CAM_TYPE_ONBOARD) && + m_camera->GetObject() == this ) { - pObj = m_main->SearchNearest(RetPosition(0), this); + pObj = m_main->SearchNearest(GetPosition(0), this); if ( pObj == 0 ) { m_camera->SetObject(0); - m_camera->SetType(CAMERA_FREE); + m_camera->SetType(Gfx::CAM_TYPE_FREE); } else { m_camera->SetObject(pObj); - m_camera->SetType(CAMERA_BACK); + m_camera->SetType(Gfx::CAM_TYPE_BACK); } } #endif for ( i=0 ; i<1000000 ; i++ ) { - pPyro = (CPyro*)m_iMan->SearchInstance(CLASS_PYRO, i); + pPyro = static_cast<Gfx::CPyro*>(m_iMan->SearchInstance(CLASS_PYRO, i)); if ( pPyro == 0 ) break; pPyro->CutObjectLink(this); // the object no longer exists @@ -453,7 +451,7 @@ void CObject::DeleteObject(bool bAll) m_type == OBJECT_START || m_type == OBJECT_END ) // building? { - m_terrain->DeleteBuildingLevel(RetPosition(0)); // flattens the field + m_terrain->DeleteBuildingLevel(GetPosition(0)); // flattens the field } } @@ -461,19 +459,19 @@ void CObject::DeleteObject(bool bAll) if ( m_partiReactor != -1 ) { - m_particule->DeleteParticule(m_partiReactor); + m_particle->DeleteParticle(m_partiReactor); m_partiReactor = -1; } if ( m_shadowLight != -1 ) { - m_light->DeleteLight(m_shadowLight); + m_lightMan->DeleteLight(m_shadowLight); m_shadowLight = -1; } if ( m_effectLight != -1 ) { - m_light->DeleteLight(m_effectLight); + m_lightMan->DeleteLight(m_effectLight); m_effectLight = -1; } @@ -506,7 +504,7 @@ void CObject::DeleteObject(bool bAll) if ( m_objectPart[i].masterParti != -1 ) { - m_particule->DeleteParticule(m_objectPart[i].masterParti); + m_particle->DeleteParticle(m_objectPart[i].masterParti); m_objectPart[i].masterParti = -1; } } @@ -569,8 +567,8 @@ void CObject::Simplify() bool CObject::ExploObject(ExploType type, float force, float decay) { - PyroType pyroType; - CPyro* pyro; + Gfx::PyroType pyroType; + Gfx::CPyro* pyro; float loss, shield; if ( type == EXPLO_BURN ) @@ -627,7 +625,7 @@ bool CObject::ExploObject(ExploType type, float force, float decay) loss *= decay; // Decreases the power of the shield. - shield = RetShield(); + shield = GetShield(); shield -= loss; if ( shield < 0.0f ) shield = 0.0f; SetShield(shield); @@ -638,26 +636,26 @@ bool CObject::ExploObject(ExploType type, float force, float decay) { if ( m_type == OBJECT_HUMAN ) { - pyroType = PT_SHOTH; + pyroType = Gfx::PT_SHOTH; } else { - pyroType = PT_SHOTW; + pyroType = Gfx::PT_SHOTW; } } else { if ( m_type == OBJECT_HUMAN ) { - pyroType = PT_SHOTH; + pyroType = Gfx::PT_SHOTH; } else if ( m_type == OBJECT_MOTHER ) { - pyroType = PT_SHOTM; + pyroType = Gfx::PT_SHOTM; } else { - pyroType = PT_SHOTT; + pyroType = Gfx::PT_SHOTT; } } } @@ -672,16 +670,16 @@ bool CObject::ExploObject(ExploType type, float force, float decay) m_type == OBJECT_WORM || m_type == OBJECT_BULLET ) { - pyroType = PT_BURNO; + pyroType = Gfx::PT_BURNO; SetBurn(true); } else if ( m_type == OBJECT_HUMAN ) { - pyroType = PT_DEADG; + pyroType = Gfx::PT_DEADG; } else { - pyroType = PT_BURNT; + pyroType = Gfx::PT_BURNT; SetBurn(true); } SetVirusMode(false); @@ -690,11 +688,11 @@ bool CObject::ExploObject(ExploType type, float force, float decay) { if ( m_type == OBJECT_HUMAN ) { - pyroType = PT_DEADW; + pyroType = Gfx::PT_DEADW; } else { - pyroType = PT_FRAGW; + pyroType = Gfx::PT_FRAGW; } } else // explosion? @@ -704,17 +702,17 @@ bool CObject::ExploObject(ExploType type, float force, float decay) m_type == OBJECT_BEE || m_type == OBJECT_WORM ) { - pyroType = PT_EXPLOO; + pyroType = Gfx::PT_EXPLOO; } else if ( m_type == OBJECT_MOTHER || m_type == OBJECT_NEST || m_type == OBJECT_BULLET ) { - pyroType = PT_FRAGO; + pyroType = Gfx::PT_FRAGO; } else if ( m_type == OBJECT_HUMAN ) { - pyroType = PT_DEADG; + pyroType = Gfx::PT_DEADG; } else if ( m_type == OBJECT_BASE || m_type == OBJECT_DERRICK || @@ -737,24 +735,24 @@ bool CObject::ExploObject(ExploType type, float force, float decay) m_type == OBJECT_START || m_type == OBJECT_END ) // building? { - pyroType = PT_FRAGT; + pyroType = Gfx::PT_FRAGT; } else if ( m_type == OBJECT_MOBILEtg || m_type == OBJECT_TEEN28 || // cylinder? m_type == OBJECT_TEEN31 ) // basket? { - pyroType = PT_FRAGT; + pyroType = Gfx::PT_FRAGT; } else { - pyroType = PT_EXPLOT; + pyroType = Gfx::PT_EXPLOT; } } loss = 1.0f; } - pyro = new CPyro(m_iMan); + pyro = new Gfx::CPyro(m_iMan); pyro->Create(pyroType, this, loss); if ( shield == 0.0f ) // dead? @@ -768,10 +766,10 @@ bool CObject::ExploObject(ExploType type, float force, float decay) if ( shield > 0.0f ) return false; // not dead yet - if ( RetSelect() ) + if ( GetSelect() ) { SetSelect(false); // deselects the object - m_camera->SetType(CAMERA_EXPLO); + m_camera->SetType(Gfx::CAM_TYPE_EXPLO); m_main->DeselectAll(); } DeleteDeselList(this); @@ -830,7 +828,7 @@ void CObject::InitPart(int part) } // Creates a new part, and returns its number. -// Returns -1 on error. +// Geturns -1 on error. int CObject::CreatePart() { @@ -855,7 +853,7 @@ void CObject::DeletePart(int part) if ( m_objectPart[part].masterParti != -1 ) { - m_particule->DeleteParticule(m_objectPart[part].masterParti); + m_particle->DeleteParticle(m_objectPart[part].masterParti); m_objectPart[part].masterParti = -1; } @@ -891,9 +889,9 @@ void CObject::SetObjectRank(int part, int objRank) m_objectPart[part].object = objRank; } -// Returns the number of part. +// Geturns the number of part. -int CObject::RetObjectRank(int part) +int CObject::GetObjectRank(int part) { if ( !m_objectPart[part].bUsed ) return -1; return m_objectPart[part].object; @@ -914,7 +912,7 @@ void CObject::SetObjectParent(int part, int parent) void CObject::SetType(ObjectType type) { m_type = type; - strcpy(m_name, RetObjectName(m_type)); + strcpy(m_name, GetObjectName(m_type)); if ( m_type == OBJECT_MOBILErs ) { @@ -940,16 +938,16 @@ void CObject::SetType(ObjectType type) m_type == OBJECT_MOBILEii || m_type == OBJECT_MOBILErc ) // cannon vehicle? { - m_cameraType = CAMERA_ONBOARD; + m_cameraType = Gfx::CAM_TYPE_ONBOARD; } } -ObjectType CObject::RetType() +ObjectType CObject::GetType() { return m_type; } -char* CObject::RetName() +char* CObject::GetName() { return m_name; } @@ -962,7 +960,7 @@ void CObject::SetOption(int option) m_option = option; } -int CObject::RetOption() +int CObject::GetOption() { return m_option; } @@ -980,7 +978,7 @@ void CObject::SetID(int id) } } -int CObject::RetID() +int CObject::GetID() { return m_id; } @@ -996,115 +994,115 @@ bool CObject::Write(char *line) float value; int i; - sprintf(name, " camera=%s", GetCamera(RetCameraType())); + sprintf(name, " camera=%s", GetCamera(GetCameraType())); strcat(line, name); - if ( RetCameraLock() != 0 ) + if ( GetCameraLock() != 0 ) { - sprintf(name, " cameraLock=%d", RetCameraLock()); + sprintf(name, " cameraLock=%d", GetCameraLock()); strcat(line, name); } - if ( RetEnergy() != 0.0f ) + if ( GetEnergy() != 0.0f ) { - sprintf(name, " energy=%.2f", RetEnergy()); + sprintf(name, " energy=%.2f", GetEnergy()); strcat(line, name); } - if ( RetCapacity() != 1.0f ) + if ( GetCapacity() != 1.0f ) { - sprintf(name, " capacity=%.2f", RetCapacity()); + sprintf(name, " capacity=%.2f", GetCapacity()); strcat(line, name); } - if ( RetShield() != 1.0f ) + if ( GetShield() != 1.0f ) { - sprintf(name, " shield=%.2f", RetShield()); + sprintf(name, " shield=%.2f", GetShield()); strcat(line, name); } - if ( RetRange() != 1.0f ) + if ( GetRange() != 1.0f ) { - sprintf(name, " range=%.2f", RetRange()); + sprintf(name, " range=%.2f", GetRange()); strcat(line, name); } - if ( RetSelectable() != 1 ) + if ( GetSelectable() != 1 ) { - sprintf(name, " selectable=%d", RetSelectable()); + sprintf(name, " selectable=%d", GetSelectable()); strcat(line, name); } - if ( RetEnable() != 1 ) + if ( GetEnable() != 1 ) { - sprintf(name, " enable=%d", RetEnable()); + sprintf(name, " enable=%d", GetEnable()); strcat(line, name); } - if ( RetFixed() != 0 ) + if ( GetFixed() != 0 ) { - sprintf(name, " fixed=%d", RetFixed()); + sprintf(name, " fixed=%d", GetFixed()); strcat(line, name); } - if ( RetClip() != 1 ) + if ( GetClip() != 1 ) { - sprintf(name, " clip=%d", RetClip()); + sprintf(name, " clip=%d", GetClip()); strcat(line, name); } - if ( RetLock() != 0 ) + if ( GetLock() != 0 ) { - sprintf(name, " lock=%d", RetLock()); + sprintf(name, " lock=%d", GetLock()); strcat(line, name); } - if ( RetProxyActivate() != 0 ) + if ( GetProxyActivate() != 0 ) { - sprintf(name, " proxyActivate=%d", RetProxyActivate()); + sprintf(name, " proxyActivate=%d", GetProxyActivate()); strcat(line, name); - sprintf(name, " proxyDistance=%.2f", RetProxyDistance()/g_unit); + sprintf(name, " proxyDistance=%.2f", GetProxyDistance()/g_unit); strcat(line, name); } - if ( RetMagnifyDamage() != 1.0f ) + if ( GetMagnifyDamage() != 1.0f ) { - sprintf(name, " magnifyDamage=%.2f", RetMagnifyDamage()); + sprintf(name, " magnifyDamage=%.2f", GetMagnifyDamage()); strcat(line, name); } - if ( RetGunGoalV() != 0.0f ) + if ( GetGunGoalV() != 0.0f ) { - sprintf(name, " aimV=%.2f", RetGunGoalV()); + sprintf(name, " aimV=%.2f", GetGunGoalV()); strcat(line, name); } - if ( RetGunGoalH() != 0.0f ) + if ( GetGunGoalH() != 0.0f ) { - sprintf(name, " aimH=%.2f", RetGunGoalH()); + sprintf(name, " aimH=%.2f", GetGunGoalH()); strcat(line, name); } - if ( RetParam() != 0.0f ) + if ( GetParam() != 0.0f ) { - sprintf(name, " param=%.2f", RetParam()); + sprintf(name, " param=%.2f", GetParam()); strcat(line, name); } - if ( RetResetCap() != 0 ) + if ( GetResetCap() != 0 ) { - sprintf(name, " resetCap=%d", RetResetCap()); + sprintf(name, " resetCap=%d", GetResetCap()); strcat(line, name); - pos = RetResetPosition()/g_unit; + pos = GetResetPosition()/g_unit; sprintf(name, " resetPos=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); strcat(line, name); - pos = RetResetAngle()/(Math::PI/180.0f); + pos = GetResetAngle()/(Math::PI/180.0f); sprintf(name, " resetAngle=%.2f;%.2f;%.2f", pos.x, pos.y, pos.z); strcat(line, name); - sprintf(name, " resetRun=%d", RetResetRun()); + sprintf(name, " resetRun=%d", GetResetRun()); strcat(line, name); } @@ -1123,7 +1121,7 @@ bool CObject::Write(char *line) // Puts information in terminal (OBJECT_INFO). for ( i=0 ; i<m_infoTotal ; i++ ) { - info = RetInfo(i); + info = GetInfo(i); if ( info.name[0] == 0 ) break; sprintf(name, " info%d=\"%s=%.2f\"", i+1, info.name, info.value); @@ -1133,7 +1131,7 @@ bool CObject::Write(char *line) // Sets the parameters of the command line. for ( i=0 ; i<OBJECTMAXCMDLINE ; i++ ) { - value = RetCmdLine(i); + value = GetCmdLine(i); if ( value == NAN ) break; if ( i == 0 ) sprintf(name, " cmdline=%.2f", value); @@ -1164,21 +1162,21 @@ bool CObject::Write(char *line) return true; } -// Returns all parameters of the object. +// Geturns all parameters of the object. bool CObject::Read(char *line) { Math::Vector pos, dir; - Info info; - CameraType cType; - char op[20]; - char text[100]; - char* p; - float value; - int i; + Info info; + Gfx::CameraType cType; + char op[20]; + char text[100]; + char* p; + float value; + int i; cType = OpCamera(line, "camera"); - if ( cType != CAMERA_NULL ) + if ( cType != Gfx::CAM_TYPE_NULL ) { SetCameraType(cType); } @@ -1200,7 +1198,7 @@ bool CObject::Read(char *line) SetGunGoalV(OpFloat(line, "aimV", 0.0f)); SetGunGoalH(OpFloat(line, "aimH", 0.0f)); SetParam(OpFloat(line, "param", 0.0f)); - SetResetCap((ResetCap)OpInt(line, "resetCap", 0)); + SetResetCap(static_cast<ResetCap>(OpInt(line, "resetCap", 0))); SetResetPosition(OpDir(line, "resetPos")*g_unit); SetResetAngle(OpDir(line, "resetAngle")*(Math::PI/180.0f)); SetResetRun(OpInt(line, "resetRun", 0)); @@ -1291,7 +1289,7 @@ int CObject::CreateCrashSphere(Math::Vector pos, float radius, Sound sound, if ( m_crashSphereUsed >= MAXCRASHSPHERE ) return -1; - zoom = RetZoomX(0); + zoom = GetZoomX(0); m_crashSpherePos[m_crashSphereUsed] = pos; m_crashSphereRadius[m_crashSphereUsed] = radius*zoom; m_crashSphereHardness[m_crashSphereUsed] = hardness; @@ -1299,14 +1297,14 @@ int CObject::CreateCrashSphere(Math::Vector pos, float radius, Sound sound, return m_crashSphereUsed++; } -// Returns the number of spheres. +// Geturns the number of spheres. -int CObject::RetCrashSphereTotal() +int CObject::GetCrashSphereTotal() { return m_crashSphereUsed; } -// Returns a sphere for collisions. +// Geturns a sphere for collisions. // The position is absolute in the world. bool CObject::GetCrashSphere(int rank, Math::Vector &pos, float &radius) @@ -1318,7 +1316,7 @@ bool CObject::GetCrashSphere(int rank, Math::Vector &pos, float &radius) return false; } - // Returns to the sphere collisions, + // Geturns to the sphere collisions, // which ignores the inclination of the vehicle. // This is necessary to collisions with vehicles, // so as not to reflect SetInclinaison, for example. @@ -1342,16 +1340,16 @@ bool CObject::GetCrashSphere(int rank, Math::Vector &pos, float &radius) return true; } -// Returns the hardness of a sphere. +// Geturns the hardness of a sphere. -Sound CObject::RetCrashSphereSound(int rank) +Sound CObject::GetCrashSphereSound(int rank) { return m_crashSphereSound[rank]; } -// Returns the hardness of a sphere. +// Geturns the hardness of a sphere. -float CObject::RetCrashSphereHardness(int rank) +float CObject::GetCrashSphereHardness(int rank) { return m_crashSphereHardness[rank]; } @@ -1378,12 +1376,12 @@ void CObject::SetGlobalSphere(Math::Vector pos, float radius) { float zoom; - zoom = RetZoomX(0); + zoom = GetZoomX(0); m_globalSpherePos = pos; m_globalSphereRadius = radius*zoom; } -// Returns the global sphere, in the world. +// Geturns the global sphere, in the world. void CObject::GetGlobalSphere(Math::Vector &pos, float &radius) { @@ -1416,9 +1414,9 @@ void CObject::SetShieldRadius(float radius) m_shieldRadius = radius; } -// Returns the radius of the shield. +// Geturns the radius of the shield. -float CObject::RetShieldRadius() +float CObject::GetShieldRadius() { return m_shieldRadius; } @@ -1431,7 +1429,7 @@ void CObject::SetFloorHeight(float height) Math::Vector pos; pos = m_objectPart[0].position; - m_terrain->MoveOnFloor(pos); + m_terrain->AdjustToFloor(pos); if ( m_physics != 0 ) { @@ -1451,7 +1449,7 @@ void CObject::FloorAdjust() Math::Point nn; float a; - pos = RetPosition(0); + pos = GetPosition(0); if ( m_terrain->GetNormal(n, pos) ) { #if 0 @@ -1459,7 +1457,7 @@ void CObject::FloorAdjust() SetAngleZ(0, -sinf(n.x)); SetAngleY(0, 0.0f); #else - a = RetAngleY(0); + a = GetAngleY(0); nn = Math::RotatePoint(-a, Math::Point(n.z, n.x)); SetAngleX(0, sinf(nn.x)); SetAngleZ(0, -sinf(nn.y)); @@ -1481,7 +1479,7 @@ void CObject::SetLinVibration(Math::Vector dir) } } -Math::Vector CObject::RetLinVibration() +Math::Vector CObject::GetLinVibration() { return m_linVibration; } @@ -1499,7 +1497,7 @@ void CObject::SetCirVibration(Math::Vector dir) } } -Math::Vector CObject::RetCirVibration() +Math::Vector CObject::GetCirVibration() { return m_cirVibration; } @@ -1517,7 +1515,7 @@ void CObject::SetInclinaison(Math::Vector dir) } } -Math::Vector CObject::RetInclinaison() +Math::Vector CObject::GetInclinaison() { return m_inclinaison; } @@ -1539,10 +1537,10 @@ void CObject::SetPosition(int part, const Math::Vector &pos) rank = m_objectPart[0].object; shPos = pos; - m_terrain->MoveOnFloor(shPos, true); + m_terrain->AdjustToFloor(shPos, true); m_engine->SetObjectShadowPos(rank, shPos); - if ( m_physics != 0 && m_physics->RetType() == TYPE_FLYING ) + if ( m_physics != 0 && m_physics->GetType() == TYPE_FLYING ) { height = pos.y-shPos.y; } @@ -1554,7 +1552,7 @@ void CObject::SetPosition(int part, const Math::Vector &pos) // Calculating the normal to the ground in nine strategic locations, // then perform a weighted average (the dots in the center are more important). - radius = m_engine->RetObjectShadowRadius(rank); + radius = m_engine->GetObjectShadowRadius(rank); i = 0; m_terrain->GetNormal(norm, pos); @@ -1619,7 +1617,7 @@ void CObject::SetPosition(int part, const Math::Vector &pos) { norm += n[j]; } - norm /= (float)i; // average vector + norm /= static_cast<float>(i); // average vector m_engine->SetObjectShadowNormal(rank, norm); @@ -1627,14 +1625,14 @@ void CObject::SetPosition(int part, const Math::Vector &pos) { shPos = pos; shPos.y += m_shadowHeight; - m_light->SetLightPos(m_shadowLight, shPos); + m_lightMan->SetLightPos(m_shadowLight, shPos); } if ( m_effectLight != -1 ) { shPos = pos; shPos.y += m_effectHeight; - m_light->SetLightPos(m_effectLight, shPos); + m_lightMan->SetLightPos(m_effectLight, shPos); } if ( m_bShowLimit ) @@ -1644,7 +1642,7 @@ void CObject::SetPosition(int part, const Math::Vector &pos) } } -Math::Vector CObject::RetPosition(int part) +Math::Vector CObject::GetPosition(int part) { return m_objectPart[part].position; } @@ -1662,7 +1660,7 @@ void CObject::SetAngle(int part, const Math::Vector &angle) } } -Math::Vector CObject::RetAngle(int part) +Math::Vector CObject::GetAngle(int part) { return m_objectPart[part].angle; } @@ -1696,17 +1694,17 @@ void CObject::SetAngleZ(int part, float angle) m_objectPart[part].bRotate = true; //it will recalculate the matrices } -float CObject::RetAngleY(int part) +float CObject::GetAngleY(int part) { return m_objectPart[part].angle.y; } -float CObject::RetAngleX(int part) +float CObject::GetAngleX(int part) { return m_objectPart[part].angle.x; } -float CObject::RetAngleZ(int part) +float CObject::GetAngleZ(int part) { return m_objectPart[part].angle.z; } @@ -1736,7 +1734,7 @@ void CObject::SetZoom(int part, Math::Vector zoom) m_objectPart[part].zoom.z != 1.0f ); } -Math::Vector CObject::RetZoom(int part) +Math::Vector CObject::GetZoom(int part) { return m_objectPart[part].zoom; } @@ -1771,27 +1769,27 @@ void CObject::SetZoomZ(int part, float zoom) m_objectPart[part].zoom.z != 1.0f ); } -float CObject::RetZoomX(int part) +float CObject::GetZoomX(int part) { return m_objectPart[part].zoom.x; } -float CObject::RetZoomY(int part) +float CObject::GetZoomY(int part) { return m_objectPart[part].zoom.y; } -float CObject::RetZoomZ(int part) +float CObject::GetZoomZ(int part) { return m_objectPart[part].zoom.z; } -// Returns the water level. +// Geturns the water level. -float CObject::RetWaterLevel() +float CObject::GetWaterLevel() { - return m_water->RetLevel(); + return m_water->GetLevel(); } @@ -1801,11 +1799,11 @@ void CObject::SetTrainer(bool bEnable) if ( m_bTrainer ) // training? { - m_cameraType = CAMERA_FIX; + m_cameraType = Gfx::CAM_TYPE_FIX; } } -bool CObject::RetTrainer() +bool CObject::GetTrainer() { return m_bTrainer; } @@ -1815,7 +1813,7 @@ void CObject::SetToy(bool bEnable) m_bToy = bEnable; } -bool CObject::RetToy() +bool CObject::GetToy() { return m_bToy; } @@ -1825,7 +1823,7 @@ void CObject::SetManual(bool bManual) m_bManual = bManual; } -bool CObject::RetManual() +bool CObject::GetManual() { return m_bManual; } @@ -1835,7 +1833,7 @@ void CObject::SetResetCap(ResetCap cap) m_resetCap = cap; } -ResetCap CObject::RetResetCap() +ResetCap CObject::GetResetCap() { return m_resetCap; } @@ -1845,7 +1843,7 @@ void CObject::SetResetBusy(bool bBusy) m_bResetBusy = bBusy; } -bool CObject::RetResetBusy() +bool CObject::GetResetBusy() { return m_bResetBusy; } @@ -1855,7 +1853,7 @@ void CObject::SetResetPosition(const Math::Vector &pos) m_resetPosition = pos; } -Math::Vector CObject::RetResetPosition() +Math::Vector CObject::GetResetPosition() { return m_resetPosition; } @@ -1865,12 +1863,12 @@ void CObject::SetResetAngle(const Math::Vector &angle) m_resetAngle = angle; } -Math::Vector CObject::RetResetAngle() +Math::Vector CObject::GetResetAngle() { return m_resetAngle; } -int CObject::RetResetRun() +int CObject::GetResetRun() { return m_resetRun; } @@ -1883,12 +1881,12 @@ void CObject::SetResetRun(int run) // Management of the particle master. -void CObject::SetMasterParticule(int part, int parti) +void CObject::SetMasterParticle(int part, int parti) { m_objectPart[part].masterParti = parti; } -int CObject::RetMasterParticule(int part) +int CObject::GetMasterParticle(int part) { return m_objectPart[part].masterParti; } @@ -1901,7 +1899,7 @@ void CObject::SetPower(CObject* power) m_power = power; } -CObject* CObject::RetPower() +CObject* CObject::GetPower() { return m_power; } @@ -1913,7 +1911,7 @@ void CObject::SetFret(CObject* fret) m_fret = fret; } -CObject* CObject::RetFret() +CObject* CObject::GetFret() { return m_fret; } @@ -1928,7 +1926,7 @@ void CObject::SetTruck(CObject* truck) m_engine->SetObjectShadowHide(m_objectPart[0].object, (m_truck != 0)); } -CObject* CObject::RetTruck() +CObject* CObject::GetTruck() { return m_truck; } @@ -1940,7 +1938,7 @@ void CObject::SetTruckPart(int part) m_truckLink = part; } -int CObject::RetTruckPart() +int CObject::GetTruckPart() { return m_truckLink; } @@ -1977,13 +1975,13 @@ void CObject::SetInfo(int rank, Info info) m_bInfoUpdate = true; } -Info CObject::RetInfo(int rank) +Info CObject::GetInfo(int rank) { if ( rank < 0 || rank >= OBJECTMAXINFO ) rank = 0; return m_info[rank]; } -int CObject::RetInfoTotal() +int CObject::GetInfoTotal() { return m_infoTotal; } @@ -1993,7 +1991,7 @@ void CObject::SetInfoReturn(float value) m_infoReturn = value; } -float CObject::RetInfoReturn() +float CObject::GetInfoReturn() { return m_infoReturn; } @@ -2003,7 +2001,7 @@ void CObject::SetInfoUpdate(bool bUpdate) m_bInfoUpdate = bUpdate; } -bool CObject::RetInfoUpdate() +bool CObject::GetInfoUpdate() { return m_bInfoUpdate; } @@ -2016,31 +2014,31 @@ bool CObject::SetCmdLine(int rank, float value) return true; } -float CObject::RetCmdLine(int rank) +float CObject::GetCmdLine(int rank) { if ( rank < 0 || rank >= OBJECTMAXCMDLINE ) return 0.0f; return m_cmdLine[rank]; } -// Returns matrices of an object portion. +// Geturns matrices of an object portion. -Math::Matrix* CObject::RetRotateMatrix(int part) +Math::Matrix* CObject::GetRotateMatrix(int part) { return &m_objectPart[part].matRotate; } -Math::Matrix* CObject::RetTranslateMatrix(int part) +Math::Matrix* CObject::GetTranslateMatrix(int part) { return &m_objectPart[part].matTranslate; } -Math::Matrix* CObject::RetTransformMatrix(int part) +Math::Matrix* CObject::GetTransformMatrix(int part) { return &m_objectPart[part].matTransform; } -Math::Matrix* CObject::RetWorldMatrix(int part) +Math::Matrix* CObject::GetWorldMatrix(int part) { if ( m_objectPart[0].bTranslate || m_objectPart[0].bRotate ) @@ -2062,7 +2060,7 @@ void CObject::SetDrawWorld(bool bDraw) { if ( m_objectPart[i].bUsed ) { - m_engine->SetDrawWorld(m_objectPart[i].object, bDraw); + m_engine->SetObjectDrawWorld(m_objectPart[i].object, bDraw); } } } @@ -2077,7 +2075,7 @@ void CObject::SetDrawFront(bool bDraw) { if ( m_objectPart[i].bUsed ) { - m_engine->SetDrawFront(m_objectPart[i].object, bDraw); + m_engine->SetObjectDrawFront(m_objectPart[i].object, bDraw); } } } @@ -2242,94 +2240,93 @@ bool CObject::CreateInsect(Math::Vector pos, float angle, ObjectType type) // Creates shade under a vehicle as a negative light. -bool CObject::CreateShadowLight(float height, D3DCOLORVALUE color) +bool CObject::CreateShadowLight(float height, Gfx::Color color) { - D3DLIGHT7 light; + Gfx::Light light; Math::Vector pos; - if ( !m_engine->RetLightMode() ) return true; + if ( !m_engine->GetLightMode() ) return true; - pos = RetPosition(0); + pos = GetPosition(0); m_shadowHeight = height; - ZeroMemory( &light, sizeof(light) ); - light.dltType = D3DLIGHT_SPOT; - light.dcvDiffuse.r = color.r; - light.dcvDiffuse.g = color.g; - light.dcvDiffuse.b = color.b; - light.dvPosition.x = pos.x; - light.dvPosition.y = pos.y+height; - light.dvPosition.z = pos.z; - light.dvDirection.x = 0.0f; - light.dvDirection.y = -1.0f; // against the bottom - light.dvDirection.z = 0.0f; - light.dvRange = D3DLIGHT_RANGE_MAX; - light.dvFalloff = 1.0f; - light.dvAttenuation0 = 1.0f; - light.dvAttenuation1 = 0.0f; - light.dvAttenuation2 = 0.0f; - light.dvTheta = 0.0f; - light.dvPhi = Math::PI/4.0f; - - m_shadowLight = m_light->CreateLight(); + light.type = Gfx::LIGHT_SPOT; + light.diffuse.r = color.r; + light.diffuse.g = color.g; + light.diffuse.b = color.b; + light.position.x = pos.x; + light.position.y = pos.y+height; + light.position.z = pos.z; + light.direction.x = 0.0f; + light.direction.y = -1.0f; // against the bottom + light.direction.z = 0.0f; + //TODO Is this value correct + light.spotIntensity = 128; + light.attenuation0 = 1.0f; + light.attenuation1 = 0.0f; + light.attenuation2 = 0.0f; + //TODO Is this value correct + light.spotAngle = 90; + + m_shadowLight = m_lightMan->CreateLight(); if ( m_shadowLight == -1 ) return false; - m_light->SetLight(m_shadowLight, light); + m_lightMan->SetLight(m_shadowLight, light); // Only illuminates the objects on the ground. - m_light->SetLightIncluType(m_shadowLight, TYPETERRAIN); + m_lightMan->SetLightIncludeType(m_shadowLight, Gfx::ENG_OBJTYPE_TERRAIN); return true; } -// Returns the number of negative light shade. +// Geturns the number of negative light shade. -int CObject::RetShadowLight() +int CObject::GetShadowLight() { return m_shadowLight; } // Creates light for the effects of a vehicle. -bool CObject::CreateEffectLight(float height, D3DCOLORVALUE color) +bool CObject::CreateEffectLight(float height, Gfx::Color color) { - D3DLIGHT7 light; + Gfx::Light light; - if ( !m_engine->RetLightMode() ) return true; + if ( !m_engine->GetLightMode() ) return true; m_effectHeight = height; - ZeroMemory( &light, sizeof(light) ); - light.dltType = D3DLIGHT_SPOT; - light.dcvDiffuse.r = color.r; - light.dcvDiffuse.g = color.g; - light.dcvDiffuse.b = color.b; - light.dvPosition.x = 0.0f; - light.dvPosition.y = 0.0f+height; - light.dvPosition.z = 0.0f; - light.dvDirection.x = 0.0f; - light.dvDirection.y = -1.0f; // against the bottom - light.dvDirection.z = 0.0f; - light.dvRange = D3DLIGHT_RANGE_MAX; - light.dvFalloff = 1.0f; - light.dvAttenuation0 = 1.0f; - light.dvAttenuation1 = 0.0f; - light.dvAttenuation2 = 0.0f; - light.dvTheta = 0.0f; - light.dvPhi = Math::PI/4.0f; - - m_effectLight = m_light->CreateLight(); + memset( &light, 0, sizeof(light) ); + light.type = Gfx::LIGHT_SPOT; + light.diffuse.r = color.r; + light.diffuse.g = color.g; + light.diffuse.b = color.b; + light.position.x = 0.0f; + light.position.y = 0.0f+height; + light.position.z = 0.0f; + light.direction.x = 0.0f; + light.direction.y = -1.0f; // against the bottom + light.direction.z = 0.0f; + //TODO Is this value correct + light.spotIntensity = 1.0f; + light.attenuation0 = 1.0f; + light.attenuation1 = 0.0f; + light.attenuation2 = 0.0f; + //TODO Is this value correct + light.spotAngle = 90; + + m_effectLight = m_lightMan->CreateLight(); if ( m_effectLight == -1 ) return false; - m_light->SetLight(m_effectLight, light); - m_light->SetLightIntensity(m_effectLight, 0.0f); + m_lightMan->SetLight(m_effectLight, light); + m_lightMan->SetLightIntensity(m_effectLight, 0.0f); return true; } -// Returns the number of light effects. +// Geturns the number of light effects. -int CObject::RetEffectLight() +int CObject::GetEffectLight() { return m_effectLight; } @@ -2337,15 +2334,15 @@ int CObject::RetEffectLight() // Creates the circular shadow underneath a vehicle. bool CObject::CreateShadowCircle(float radius, float intensity, - D3DShadowType type) + Gfx::EngineShadowType type) { float zoom; if ( intensity == 0.0f ) return true; - zoom = RetZoomX(0); + zoom = GetZoomX(0); - m_engine->ShadowCreate(m_objectPart[0].object); + m_engine->CreateShadow(m_objectPart[0].object); m_engine->SetObjectShadowRadius(m_objectPart[0].object, radius*zoom); m_engine->SetObjectShadowIntensity(m_objectPart[0].object, intensity); @@ -2361,18 +2358,16 @@ bool CObject::CreateShadowCircle(float radius, float intensity, bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, ObjectType type, float power) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; Math::Point p; int rank, i; - if ( m_engine->RetRestCreate() < 20 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); if ( m_type == OBJECT_PORTICO ) @@ -2384,7 +2379,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\portico2.mod"); @@ -2392,7 +2387,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(1, Math::Vector(0.0f, 67.0f, 0.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 1); pModFile->ReadModel("objects\\portico3.mod"); @@ -2401,7 +2396,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(2, 45.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(3, rank); SetObjectParent(3, 2); pModFile->ReadModel("objects\\portico4.mod"); @@ -2410,7 +2405,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(3, -60.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(4, rank); SetObjectParent(4, 3); pModFile->ReadModel("objects\\portico5.mod"); @@ -2419,7 +2414,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(4, -55.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(5, rank); SetObjectParent(5, 1); pModFile->ReadModel("objects\\portico3.mod"); @@ -2428,7 +2423,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(5, -45.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(6, rank); SetObjectParent(6, 5); pModFile->ReadModel("objects\\portico4.mod"); @@ -2437,7 +2432,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(6, 60.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(7, rank); SetObjectParent(7, 6); pModFile->ReadModel("objects\\portico5.mod"); @@ -2446,7 +2441,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(7, 55.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(8, rank); SetObjectParent(8, 0); pModFile->ReadModel("objects\\portico6.mod"); @@ -2456,7 +2451,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetZoom(8, 2.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(9, rank); SetObjectParent(9, 8); pModFile->ReadModel("objects\\portico7.mod"); @@ -2464,7 +2459,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(9, Math::Vector(0.0f, 4.5f, 1.9f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(10, rank); SetObjectParent(10, 0); pModFile->ReadModel("objects\\portico6.mod"); @@ -2474,7 +2469,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetZoom(10, 2.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(11, rank); SetObjectParent(11, 10); pModFile->ReadModel("objects\\portico7.mod"); @@ -2508,7 +2503,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, for ( i=0 ; i<8 ; i++ ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1+i, rank); SetObjectParent(1+i, 0); pModFile->ReadModel("objects\\base2.mod"); @@ -2519,7 +2514,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleZ(1+i, Math::PI/2.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(10+i, rank); SetObjectParent(10+i, 1+i); pModFile->ReadModel("objects\\base4.mod"); @@ -2527,7 +2522,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(10+i, Math::Vector(23.5f, 0.0f, 7.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(18+i, rank); SetObjectParent(18+i, 1+i); pModFile->ReadModel("objects\\base4.mod"); @@ -2537,7 +2532,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, } rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(9, rank); SetObjectParent(9, 0); pModFile->ReadModel("objects\\base3.mod"); // central pillar @@ -2578,7 +2573,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\derrick2.mod"); @@ -2603,7 +2598,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\search2.mod"); @@ -2611,7 +2606,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(1, Math::Vector(0.0f, 13.0f, 0.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 1); pModFile->ReadModel("objects\\search3.mod"); @@ -2638,7 +2633,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\radar2.mod"); @@ -2646,7 +2641,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(1, Math::Vector(0.0f, 5.0f, 0.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 0); pModFile->ReadModel("objects\\radar3.mod"); @@ -2655,7 +2650,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(2, -Math::PI/2.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(3, rank); SetObjectParent(3, 2); pModFile->ReadModel("objects\\radar4.mod"); @@ -2678,7 +2673,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\info2.mod"); @@ -2688,7 +2683,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, for ( i=0 ; i<3 ; i++ ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2+i*2, rank); SetObjectParent(2+i*2, 1); pModFile->ReadModel("objects\\info3.mod"); @@ -2696,7 +2691,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(2+i*2, Math::Vector(0.0f, 4.5f, 0.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(3+i*2, rank); SetObjectParent(3+i*2, 2+i*2); pModFile->ReadModel("objects\\radar4.mod"); @@ -2741,7 +2736,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\labo2.mod"); @@ -2750,7 +2745,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleZ(1, Math::PI/2.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 1); pModFile->ReadModel("objects\\labo3.mod"); @@ -2758,7 +2753,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(2, Math::Vector(9.0f, -1.0f, 0.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(3, rank); SetObjectParent(3, 2); pModFile->ReadModel("objects\\labo4.mod"); @@ -2767,7 +2762,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleZ(3, 80.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(4, rank); SetObjectParent(4, 2); pModFile->ReadModel("objects\\labo4.mod"); @@ -2777,7 +2772,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleY(4, Math::PI*2.0f/3.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(5, rank); SetObjectParent(5, 2); pModFile->ReadModel("objects\\labo4.mod"); @@ -2809,7 +2804,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, for ( i=0 ; i<9 ; i++ ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1+i, rank); SetObjectParent(1+i, 0); pModFile->ReadModel("objects\\factory2.mod"); @@ -2819,7 +2814,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetZoomZ(1+i, 0.30f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(10+i, rank); SetObjectParent(10+i, 0); pModFile->ReadModel("objects\\factory2.mod"); @@ -2832,7 +2827,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, for ( i=0 ; i<2 ; i++ ) { - float s = (float)(i*2-1); + float s = static_cast<float>(i*2-1); CreateCrashSphere(Math::Vector(-10.0f, 2.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector( -3.0f, 2.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector( 3.0f, 2.0f, 11.0f*s), 4.0f, SOUND_BOUMm, 0.45f); @@ -2867,7 +2862,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\repair2.mod"); @@ -2893,7 +2888,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\destroy2.mod"); @@ -2936,7 +2931,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\convert2.mod"); @@ -2944,7 +2939,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetPosition(1, Math::Vector(0.0f, 14.0f, 0.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 0); pModFile->ReadModel("objects\\convert3.mod"); @@ -2953,7 +2948,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleX(2, -Math::PI*0.35f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(3, rank); SetObjectParent(3, 0); pModFile->ReadModel("objects\\convert3.mod"); @@ -2980,7 +2975,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\roller2c.mod"); @@ -2989,7 +2984,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetAngleZ(1, Math::PI/2.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 1); pModFile->ReadModel("objects\\roller3c.mod"); @@ -3006,7 +3001,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, m_character.posPower = Math::Vector(5.0f, 3.0f, 0.0f); CreateShadowCircle(6.0f, 1.0f); - m_showLimitRadius = BLITZPARA; + m_showLimitRadius = Gfx::BLITZPARA; } if ( m_type == OBJECT_NUCLEAR ) @@ -3018,7 +3013,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\nuclear2.mod"); @@ -3059,7 +3054,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetGlobalSphere(Math::Vector(0.0f, 10.0f, 0.0f), 20.0f); CreateShadowCircle(21.0f, 1.0f); - m_showLimitRadius = BLITZPARA; + m_showLimitRadius = Gfx::BLITZPARA; } if ( m_type == OBJECT_SAFE ) @@ -3071,7 +3066,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\safe2.mod"); @@ -3079,7 +3074,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetZoom(1, 1.05f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 0); pModFile->ReadModel("objects\\safe3.mod"); @@ -3103,7 +3098,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\huston2.mod"); @@ -3113,7 +3108,7 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, SetZoom(1, 3.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 1); pModFile->ReadModel("objects\\huston3.mod"); @@ -3223,14 +3218,14 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, pPower->SetType(power<=1.0f?OBJECT_POWER:OBJECT_ATOMIC); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); pPower->SetObjectRank(0, rank); if ( power <= 1.0f ) pModFile->ReadModel("objects\\power.mod"); else pModFile->ReadModel("objects\\atomic.mod"); pModFile->CreateEngineObject(rank); - pPower->SetPosition(0, RetCharacter()->posPower); + pPower->SetPosition(0, GetCharacter()->posPower); pPower->CreateCrashSphere(Math::Vector(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); pPower->SetGlobalSphere(Math::Vector(0.0f, 1.0f, 0.0f), 1.5f); @@ -3242,12 +3237,12 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, } #endif - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); // to display the shadows immediately CreateOtherObject(type); - m_engine->LoadAllTexture(); + m_engine->LoadAllTextures(); delete pModFile; return true; @@ -3258,22 +3253,17 @@ bool CObject::CreateBuilding(Math::Vector pos, float angle, float height, bool CObject::CreateResource(Math::Vector pos, float angle, ObjectType type, float power) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; char name[50]; int rank; float radius, height; - if ( type != OBJECT_SHOW ) - { - if ( m_engine->RetRestCreate() < 1 ) return false; - } - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); SetEnergy(power); @@ -3363,10 +3353,10 @@ bool CObject::CreateResource(Math::Vector pos, float angle, ObjectType type, SetFloorHeight(0.0f); CreateOtherObject(type); - m_engine->LoadAllTexture(); + m_engine->LoadAllTextures(); FloorAdjust(); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); // to display the shadows immediately @@ -3378,13 +3368,11 @@ bool CObject::CreateResource(Math::Vector pos, float angle, ObjectType type, bool CObject::CreateFlag(Math::Vector pos, float angle, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; char name[50]; int rank, i; - if ( m_engine->RetRestCreate() < 1+4 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); @@ -3396,7 +3384,7 @@ bool CObject::CreateFlag(Math::Vector pos, float angle, ObjectType type) if ( type == OBJECT_FLAGv ) strcpy(name, "objects\\flag1v.mod"); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); pModFile->ReadModel(name); pModFile->CreateEngineObject(rank); @@ -3413,7 +3401,7 @@ bool CObject::CreateFlag(Math::Vector pos, float angle, ObjectType type) for ( i=0 ; i<4 ; i++ ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1+i, rank); SetObjectParent(1+i, i); pModFile->ReadModel(name); @@ -3427,10 +3415,10 @@ bool CObject::CreateFlag(Math::Vector pos, float angle, ObjectType type) SetFloorHeight(0.0f); CreateOtherObject(type); - m_engine->LoadAllTexture(); + m_engine->LoadAllTextures(); FloorAdjust(); - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately delete pModFile; @@ -3442,19 +3430,17 @@ bool CObject::CreateFlag(Math::Vector pos, float angle, ObjectType type) bool CObject::CreateBarrier(Math::Vector pos, float angle, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; int rank; - if ( m_engine->RetRestCreate() < 1 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); if ( type == OBJECT_BARRIER0 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\barrier0.mod"); pModFile->CreateEngineObject(rank); @@ -3465,13 +3451,13 @@ bool CObject::CreateBarrier(Math::Vector pos, float angle, float height, CreateCrashSphere(Math::Vector( 0.0f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(6.0f, 0.5f, D3DSHADOWWORM); + CreateShadowCircle(6.0f, 0.5f, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_BARRIER1 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\barrier1.mod"); pModFile->CreateEngineObject(rank); @@ -3484,13 +3470,13 @@ bool CObject::CreateBarrier(Math::Vector pos, float angle, float height, CreateCrashSphere(Math::Vector(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(12.0f, 0.5f, D3DSHADOWWORM); + CreateShadowCircle(12.0f, 0.5f, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_BARRIER2 ) // cardboard? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\barrier2.mod"); pModFile->CreateEngineObject(rank); @@ -3503,13 +3489,13 @@ bool CObject::CreateBarrier(Math::Vector pos, float angle, float height, CreateCrashSphere(Math::Vector(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(12.0f, 0.8f, D3DSHADOWWORM); + CreateShadowCircle(12.0f, 0.8f, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_BARRIER3 ) // match + straw? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\barrier3.mod"); pModFile->CreateEngineObject(rank); @@ -3522,17 +3508,17 @@ bool CObject::CreateBarrier(Math::Vector pos, float angle, float height, CreateCrashSphere(Math::Vector(-3.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector(-8.5f, 3.0f, 0.0f), 0.7f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(10.0f, 0.5f, D3DSHADOWWORM); + CreateShadowCircle(10.0f, 0.5f, Gfx::ENG_SHADOW_WORM); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately SetFloorHeight(0.0f); CreateOtherObject(type); FloorAdjust(); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); @@ -3545,12 +3531,10 @@ bool CObject::CreateBarrier(Math::Vector pos, float angle, float height, bool CObject::CreatePlant(Math::Vector pos, float angle, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; int rank; - if ( m_engine->RetRestCreate() < 1 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); @@ -3561,7 +3545,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, type == OBJECT_PLANT4 ) // standard? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); if ( type == OBJECT_PLANT0 ) pModFile->ReadModel("objects\\plant0.mod"); if ( type == OBJECT_PLANT1 ) pModFile->ReadModel("objects\\plant1.mod"); @@ -3586,7 +3570,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, type == OBJECT_PLANT7 ) // clover? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); if ( type == OBJECT_PLANT5 ) pModFile->ReadModel("objects\\plant5.mod"); if ( type == OBJECT_PLANT6 ) pModFile->ReadModel("objects\\plant6.mod"); @@ -3605,7 +3589,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, type == OBJECT_PLANT9 ) // squash? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); if ( type == OBJECT_PLANT8 ) pModFile->ReadModel("objects\\plant8.mod"); if ( type == OBJECT_PLANT9 ) pModFile->ReadModel("objects\\plant9.mod"); @@ -3626,7 +3610,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, type == OBJECT_PLANT14 ) // succulent? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); if ( type == OBJECT_PLANT10 ) pModFile->ReadModel("objects\\plant10.mod"); if ( type == OBJECT_PLANT11 ) pModFile->ReadModel("objects\\plant11.mod"); @@ -3651,7 +3635,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, type == OBJECT_PLANT19 ) // fern? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); if ( type == OBJECT_PLANT15 ) pModFile->ReadModel("objects\\plant15.mod"); if ( type == OBJECT_PLANT16 ) pModFile->ReadModel("objects\\plant16.mod"); @@ -3675,7 +3659,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, if ( type == OBJECT_TREE0 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\tree0.mod"); pModFile->CreateEngineObject(rank); @@ -3693,7 +3677,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, if ( type == OBJECT_TREE1 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\tree1.mod"); pModFile->CreateEngineObject(rank); @@ -3712,7 +3696,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, if ( type == OBJECT_TREE2 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\tree2.mod"); pModFile->CreateEngineObject(rank); @@ -3731,7 +3715,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, if ( type == OBJECT_TREE3 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\tree3.mod"); pModFile->CreateEngineObject(rank); @@ -3749,7 +3733,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, if ( type == OBJECT_TREE4 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\tree4.mod"); pModFile->CreateEngineObject(rank); @@ -3766,7 +3750,7 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, if ( type == OBJECT_TREE5 ) // giant tree (for the world "teen") { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\tree5.mod"); pModFile->CreateEngineObject(rank); @@ -3780,13 +3764,13 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, CreateShadowCircle(50.0f, 0.5f); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately SetFloorHeight(0.0f); CreateOtherObject(type); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); @@ -3799,19 +3783,17 @@ bool CObject::CreatePlant(Math::Vector pos, float angle, float height, bool CObject::CreateMushroom(Math::Vector pos, float angle, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; int rank; - if ( m_engine->RetRestCreate() < 1 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); if ( type == OBJECT_MUSHROOM1 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\mush1.mod"); pModFile->CreateEngineObject(rank); @@ -3828,7 +3810,7 @@ bool CObject::CreateMushroom(Math::Vector pos, float angle, float height, if ( type == OBJECT_MUSHROOM2 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\mush2.mod"); pModFile->CreateEngineObject(rank); @@ -3842,13 +3824,13 @@ bool CObject::CreateMushroom(Math::Vector pos, float angle, float height, CreateShadowCircle(5.0f, 0.5f); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately SetFloorHeight(0.0f); CreateOtherObject(type); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); @@ -3861,16 +3843,14 @@ bool CObject::CreateMushroom(Math::Vector pos, float angle, float height, bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; Math::Matrix* mat; - D3DCOLORVALUE color; - int rank; - float fShadow; - bool bFloorAdjust = true; - - if ( m_engine->RetRestCreate() < 1 ) return false; + Gfx::Color color; + int rank; + float fShadow; + bool bFloorAdjust = true; - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); @@ -3879,7 +3859,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN0 ) // orange pencil lg=10 { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen0.mod"); pModFile->CreateEngineObject(rank); @@ -3893,13 +3873,13 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateCrashSphere(Math::Vector(-2.5f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector(-5.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(5.0f, 0.8f*fShadow, D3DSHADOWWORM); + CreateShadowCircle(5.0f, 0.8f*fShadow, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_TEEN1 ) // blue pencil lg=14 { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen1.mod"); pModFile->CreateEngineObject(rank); @@ -3915,13 +3895,13 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateCrashSphere(Math::Vector(-4.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector(-6.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(6.0f, 0.8f*fShadow, D3DSHADOWWORM); + CreateShadowCircle(6.0f, 0.8f*fShadow, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_TEEN2 ) // red pencil lg=16 { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen2.mod"); pModFile->CreateEngineObject(rank); @@ -3937,14 +3917,14 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateCrashSphere(Math::Vector(-4.7f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector(-7.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(6.0f, 0.8f*fShadow, D3DSHADOWWORM); + CreateShadowCircle(6.0f, 0.8f*fShadow, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_TEEN3 ) // jar with pencils { rank = m_engine->CreateObject(); -//? m_engine->SetObjectType(rank, TYPEFIX); - m_engine->SetObjectType(rank, TYPEMETAL); +//? m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_METAL); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen3.mod"); pModFile->CreateEngineObject(rank); @@ -3960,7 +3940,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN4 ) // scissors { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen4.mod"); pModFile->CreateEngineObject(rank); @@ -3976,13 +3956,13 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateCrashSphere(Math::Vector( 8.0f, 1.0f, 2.2f), 2.3f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector( 9.4f, 1.0f,-2.0f), 2.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(10.0f, 0.5f*fShadow, D3DSHADOWWORM); + CreateShadowCircle(10.0f, 0.5f*fShadow, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_TEEN5 ) // CD { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen5.mod"); pModFile->CreateEngineObject(rank); @@ -3999,7 +3979,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN6 ) // book 1 { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen6.mod"); pModFile->CreateEngineObject(rank); @@ -4020,7 +4000,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN7 ) // book 2 { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen7.mod"); pModFile->CreateEngineObject(rank); @@ -4041,7 +4021,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN8 ) // a stack of books 1 { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen8.mod"); pModFile->CreateEngineObject(rank); @@ -4063,7 +4043,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN9 ) // a stack of books 2 { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen9.mod"); pModFile->CreateEngineObject(rank); @@ -4085,7 +4065,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN10 ) // bookcase { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen10.mod"); pModFile->CreateEngineObject(rank); @@ -4111,7 +4091,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN11 ) // lamp { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen11.mod"); pModFile->CreateEngineObject(rank); @@ -4120,9 +4100,9 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height SetFloorHeight(0.0f); SetZoom(0, zoom); - mat = RetWorldMatrix(0); + mat = GetWorldMatrix(0); pos = Math::Transform(*mat, Math::Vector(-56.0f, 22.0f, 0.0f)); - m_particule->CreateParticule(pos, Math::Vector(0.0f, 0.0f, 0.0f), Math::Point(20.0f, 20.0f), PARTISELY, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), Math::Point(20.0f, 20.0f), Gfx::PARTISELY, 1.0f, 0.0f, 0.0f); pos = Math::Transform(*mat, Math::Vector(-65.0f, 40.0f, 0.0f)); color.r = 4.0f; @@ -4135,8 +4115,8 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN12 ) // coke { rank = m_engine->CreateObject(); -//? m_engine->SetObjectType(rank, TYPEFIX); - m_engine->SetObjectType(rank, TYPEMETAL); +//? m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_METAL); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen12.mod"); pModFile->CreateEngineObject(rank); @@ -4152,7 +4132,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN13 ) // cardboard farm { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen13.mod"); pModFile->CreateEngineObject(rank); @@ -4177,7 +4157,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN14 ) // open box { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen14.mod"); pModFile->CreateEngineObject(rank); @@ -4202,7 +4182,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN15 ) // stack of cartons { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen15.mod"); pModFile->CreateEngineObject(rank); @@ -4227,7 +4207,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN16 ) // watering can { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen16.mod"); pModFile->CreateEngineObject(rank); @@ -4245,7 +4225,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN17 ) // wheel | { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen17.mod"); pModFile->CreateEngineObject(rank); @@ -4261,7 +4241,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN18 ) // wheel / { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen18.mod"); pModFile->CreateEngineObject(rank); @@ -4277,7 +4257,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN19 ) // wheel = { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen19.mod"); pModFile->CreateEngineObject(rank); @@ -4293,7 +4273,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN20 ) // wall with shelf { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen20.mod"); pModFile->CreateEngineObject(rank); @@ -4314,7 +4294,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN21 ) // wall with window { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen21.mod"); pModFile->CreateEngineObject(rank); @@ -4326,7 +4306,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN22 ) // wall with door and shelf { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen22.mod"); pModFile->CreateEngineObject(rank); @@ -4343,7 +4323,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN23 ) // skateboard on wheels { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen23.mod"); pModFile->CreateEngineObject(rank); @@ -4364,13 +4344,13 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateCrashSphere(Math::Vector( 23.0f, 2.0f, 0.0f), 3.0f, SOUND_BOUMm, 0.45f); CreateCrashSphere(Math::Vector( 23.0f, 2.0f,-7.0f), 3.0f, SOUND_BOUMm, 0.45f); - CreateShadowCircle(35.0f, 0.8f*fShadow, D3DSHADOWWORM); + CreateShadowCircle(35.0f, 0.8f*fShadow, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_TEEN24 ) // skate / { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen24.mod"); pModFile->CreateEngineObject(rank); @@ -4386,7 +4366,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN25 ) // skate / { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen25.mod"); pModFile->CreateEngineObject(rank); @@ -4402,7 +4382,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN26 ) // ceiling lamp { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen26.mod"); pModFile->CreateEngineObject(rank); @@ -4411,9 +4391,9 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height SetZoom(0, zoom); SetFloorHeight(0.0f); - mat = RetWorldMatrix(0); + mat = GetWorldMatrix(0); pos = Math::Transform(*mat, Math::Vector(0.0f, 50.0f, 0.0f)); - m_particule->CreateParticule(pos, Math::Vector(0.0f, 0.0f, 0.0f), Math::Point(100.0f, 100.0f), PARTISELY, 1.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), Math::Point(100.0f, 100.0f), Gfx::PARTISELY, 1.0f, 0.0f, 0.0f); pos = Math::Transform(*mat, Math::Vector(0.0f, 50.0f, 0.0f)); color.r = 4.0f; @@ -4426,7 +4406,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN27 ) // large plant? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen27.mod"); pModFile->CreateEngineObject(rank); @@ -4441,8 +4421,8 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN28 ) // bottle? { rank = m_engine->CreateObject(); -//? m_engine->SetObjectType(rank, TYPEFIX); - m_engine->SetObjectType(rank, TYPEMETAL); +//? m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_METAL); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen28.mod"); pModFile->CreateEngineObject(rank); @@ -4457,7 +4437,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN29 ) // bridge? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen29.mod"); pModFile->CreateEngineObject(rank); @@ -4470,7 +4450,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN30 ) // jump? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen30.mod"); pModFile->CreateEngineObject(rank); @@ -4486,7 +4466,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN31 ) // basket? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen31.mod"); pModFile->CreateEngineObject(rank); @@ -4505,7 +4485,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN32 ) // chair? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen32.mod"); pModFile->CreateEngineObject(rank); @@ -4524,7 +4504,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN33 ) // panel? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen33.mod"); pModFile->CreateEngineObject(rank); @@ -4539,7 +4519,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN34 ) // stone? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen34.mod"); pModFile->CreateEngineObject(rank); @@ -4554,7 +4534,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN35 ) // pipe? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen35.mod"); pModFile->CreateEngineObject(rank); @@ -4567,13 +4547,13 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateCrashSphere(Math::Vector( 0.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); CreateCrashSphere(Math::Vector( 20.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); CreateCrashSphere(Math::Vector( 40.0f, 5.0f, 0.0f), 10.0f, SOUND_BOUM, 0.10f); - CreateShadowCircle(40.0f, 0.8f*fShadow, D3DSHADOWWORM); + CreateShadowCircle(40.0f, 0.8f*fShadow, Gfx::ENG_SHADOW_WORM); } if ( type == OBJECT_TEEN36 ) // trunk? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen36.mod"); pModFile->CreateEngineObject(rank); @@ -4586,7 +4566,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN37 ) // boat? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen37.mod"); pModFile->CreateEngineObject(rank); @@ -4599,7 +4579,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN38 ) // fan? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen38a.mod"); pModFile->CreateEngineObject(rank); @@ -4608,7 +4588,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height SetZoom(0, zoom); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\teen38b.mod"); // engine @@ -4616,7 +4596,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height SetPosition(1, Math::Vector(0.0f, 30.0f, 0.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 1); pModFile->ReadModel("objects\\teen38c.mod"); // propeller @@ -4631,7 +4611,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN39 ) // potted plant? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen39.mod"); pModFile->CreateEngineObject(rank); @@ -4647,7 +4627,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN40 ) // balloon? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen40.mod"); pModFile->CreateEngineObject(rank); @@ -4663,7 +4643,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN41 ) // fence? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen41.mod"); pModFile->CreateEngineObject(rank); @@ -4675,7 +4655,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN42 ) // clover? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen42.mod"); pModFile->CreateEngineObject(rank); @@ -4690,7 +4670,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN43 ) // clover? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen43.mod"); pModFile->CreateEngineObject(rank); @@ -4705,7 +4685,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height if ( type == OBJECT_TEEN44 ) // car? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\teen44.mod"); pModFile->CreateEngineObject(rank); @@ -4718,7 +4698,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateShadowCircle(55.0f, 1.0f*fShadow); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately if ( bFloorAdjust ) @@ -4729,7 +4709,7 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height CreateOtherObject(type); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); @@ -4742,20 +4722,18 @@ bool CObject::CreateTeen(Math::Vector pos, float angle, float zoom, float height bool CObject::CreateQuartz(Math::Vector pos, float angle, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; float radius; int rank; - if ( m_engine->RetRestCreate() < 1 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); if ( type == OBJECT_QUARTZ0 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_QUARTZ); SetObjectRank(0, rank); pModFile->ReadModel("objects\\quartz0.mod"); pModFile->CreateEngineObject(rank); @@ -4770,7 +4748,7 @@ bool CObject::CreateQuartz(Math::Vector pos, float angle, float height, if ( type == OBJECT_QUARTZ1 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_QUARTZ); SetObjectRank(0, rank); pModFile->ReadModel("objects\\quartz1.mod"); pModFile->CreateEngineObject(rank); @@ -4785,7 +4763,7 @@ bool CObject::CreateQuartz(Math::Vector pos, float angle, float height, if ( type == OBJECT_QUARTZ2 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_QUARTZ); SetObjectRank(0, rank); pModFile->ReadModel("objects\\quartz2.mod"); pModFile->CreateEngineObject(rank); @@ -4800,7 +4778,7 @@ bool CObject::CreateQuartz(Math::Vector pos, float angle, float height, if ( type == OBJECT_QUARTZ3 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEQUARTZ); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_QUARTZ); SetObjectRank(0, rank); pModFile->ReadModel("objects\\quartz3.mod"); pModFile->CreateEngineObject(rank); @@ -4813,13 +4791,13 @@ bool CObject::CreateQuartz(Math::Vector pos, float angle, float height, CreateShadowCircle(10.0f, 0.5f); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately SetFloorHeight(0.0f); CreateOtherObject(type); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); @@ -4843,8 +4821,8 @@ bool CObject::CreateQuartz(Math::Vector pos, float angle, float height, pos.y += 16.0f; radius = 8.0f; } - m_particule->CreateParticule(pos, pos, Math::Point(2.0f, 2.0f), PARTIQUARTZ, 0.7f+Math::Rand()*0.7f, radius, 0.0f); - m_particule->CreateParticule(pos, pos, Math::Point(2.0f, 2.0f), PARTIQUARTZ, 0.7f+Math::Rand()*0.7f, radius, 0.0f); + m_particle->CreateParticle(pos, pos, Math::Point(2.0f, 2.0f), Gfx::PARTIQUARTZ, 0.7f+Math::Rand()*0.7f, radius, 0.0f); + m_particle->CreateParticle(pos, pos, Math::Point(2.0f, 2.0f), Gfx::PARTIQUARTZ, 0.7f+Math::Rand()*0.7f, radius, 0.0f); delete pModFile; return true; @@ -4855,19 +4833,17 @@ bool CObject::CreateQuartz(Math::Vector pos, float angle, float height, bool CObject::CreateRoot(Math::Vector pos, float angle, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; int rank; - if ( m_engine->RetRestCreate() < 1 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); if ( type == OBJECT_ROOT0 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\root0.mod"); pModFile->CreateEngineObject(rank); @@ -4889,7 +4865,7 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, if ( type == OBJECT_ROOT1 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\root1.mod"); pModFile->CreateEngineObject(rank); @@ -4911,7 +4887,7 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, if ( type == OBJECT_ROOT2 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\root2.mod"); pModFile->CreateEngineObject(rank); @@ -4932,7 +4908,7 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, if ( type == OBJECT_ROOT3 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\root3.mod"); pModFile->CreateEngineObject(rank); @@ -4955,7 +4931,7 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, if ( type == OBJECT_ROOT4 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\root4.mod"); pModFile->CreateEngineObject(rank); @@ -4980,7 +4956,7 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, if ( type == OBJECT_ROOT5 ) // gravity root ? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\root4.mod"); pModFile->CreateEngineObject(rank); @@ -4989,7 +4965,7 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, SetZoom(0, 2.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\root5.mod"); @@ -5013,13 +4989,13 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, CreateShadowCircle(30.0f, 0.5f); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately SetFloorHeight(0.0f); CreateOtherObject(type); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); @@ -5032,19 +5008,17 @@ bool CObject::CreateRoot(Math::Vector pos, float angle, float height, bool CObject::CreateHome(Math::Vector pos, float angle, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; int rank; - if ( m_engine->RetRestCreate() < 1 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); if ( type == OBJECT_HOME1 ) { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); SetObjectRank(0, rank); pModFile->ReadModel("objects\\home1.mod"); pModFile->CreateEngineObject(rank); @@ -5057,13 +5031,13 @@ bool CObject::CreateHome(Math::Vector pos, float angle, float height, CreateShadowCircle(16.0f, 0.5f); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately SetFloorHeight(0.0f); CreateOtherObject(type); - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); @@ -5076,18 +5050,16 @@ bool CObject::CreateHome(Math::Vector pos, float angle, float height, bool CObject::CreateRuin(Math::Vector pos, float angle, float height, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; char name[50]; int rank; - if ( m_engine->RetRestCreate() < 1+4 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); name[0] = 0; @@ -5115,7 +5087,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, { // Creates the right-back wheel. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(6, rank); SetObjectParent(6, 0); @@ -5127,7 +5099,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, // Creates the left-back wheel. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(7, rank); SetObjectParent(7, 0); @@ -5140,7 +5112,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, // Creates the right-front wheel. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(8, rank); SetObjectParent(8, 0); @@ -5152,7 +5124,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, // Creates the left-front wheel. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(9, rank); SetObjectParent(9, 0); @@ -5173,7 +5145,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, { // Creates the left-back wheel. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(7, rank); SetObjectParent(7, 0); @@ -5186,7 +5158,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, // Creates the left-front wheel. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(9, rank); SetObjectParent(9, 0); @@ -5207,7 +5179,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, { // Creates the cannon. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); @@ -5339,7 +5311,7 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, CreateShadowCircle(30.0f, 1.0f); } - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); //to display the shadows immediately SetFloorHeight(0.0f); @@ -5352,145 +5324,145 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, FloorAdjust(); } - pos = RetPosition(0); + pos = GetPosition(0); pos.y += height; SetPosition(0, pos); //to display the shadows immediately if ( type == OBJECT_RUINmobilew1 ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 0.5f; SetPosition(0, pos); - angle = RetAngleX(0)-0.1f; + angle = GetAngleX(0)-0.1f; SetAngleX(0, angle); } if ( type == OBJECT_RUINmobilew2 ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 1.5f; SetPosition(0, pos); - angle = RetAngleX(0)-0.9f; + angle = GetAngleX(0)-0.9f; SetAngleX(0, angle); - angle = RetAngleZ(0)-0.1f; + angle = GetAngleZ(0)-0.1f; SetAngleZ(0, angle); } if ( type == OBJECT_RUINmobilet1 ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 0.9f; SetPosition(0, pos); - angle = RetAngleX(0)-0.3f; + angle = GetAngleX(0)-0.3f; SetAngleX(0, angle); } if ( type == OBJECT_RUINmobilet2 ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 1.5f; SetPosition(0, pos); - angle = RetAngleX(0)-0.3f; + angle = GetAngleX(0)-0.3f; SetAngleX(0, angle); - angle = RetAngleZ(0)+0.8f; + angle = GetAngleZ(0)+0.8f; SetAngleZ(0, angle); } if ( type == OBJECT_RUINmobiler1 ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y += 4.0f; SetPosition(0, pos); - angle = RetAngleX(0)-Math::PI*0.6f; + angle = GetAngleX(0)-Math::PI*0.6f; SetAngleX(0, angle); - angle = RetAngleZ(0)-0.2f; + angle = GetAngleZ(0)-0.2f; SetAngleZ(0, angle); } if ( type == OBJECT_RUINmobiler2 ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y += 2.0f; SetPosition(0, pos); - angle = RetAngleX(0)-0.1f; + angle = GetAngleX(0)-0.1f; SetAngleX(0, angle); - angle = RetAngleZ(0)-0.3f; + angle = GetAngleZ(0)-0.3f; SetAngleZ(0, angle); } if ( type == OBJECT_RUINdoor ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 0.5f; SetPosition(0, pos); - angle = RetAngleZ(0)-0.1f; + angle = GetAngleZ(0)-0.1f; SetAngleZ(0, angle); } if ( type == OBJECT_RUINsupport ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y += 0.5f; SetPosition(0, pos); -//? angle = RetAngleY(0)+0.1f; +//? angle = GetAngleY(0)+0.1f; //? SetAngleY(0, angle); - angle = RetAngleX(0)+0.1f; + angle = GetAngleX(0)+0.1f; SetAngleX(0, angle); - angle = RetAngleZ(0)+0.1f; + angle = GetAngleZ(0)+0.1f; SetAngleZ(0, angle); } if ( type == OBJECT_RUINradar ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 0.5f; SetPosition(0, pos); - angle = RetAngleX(0)+0.15f; + angle = GetAngleX(0)+0.15f; SetAngleX(0, angle); - angle = RetAngleZ(0)+0.1f; + angle = GetAngleZ(0)+0.1f; SetAngleZ(0, angle); } if ( type == OBJECT_RUINconvert ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 1.0f; SetPosition(0, pos); } if ( type == OBJECT_RUINbase ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y -= 1.0f; SetPosition(0, pos); - angle = RetAngleX(0)+0.15f; + angle = GetAngleX(0)+0.15f; SetAngleX(0, angle); } if ( type == OBJECT_RUINhead ) { - pos = RetPosition(0); + pos = GetPosition(0); pos.y += 8.0f; SetPosition(0, pos); - angle = RetAngleX(0)+Math::PI*0.4f; + angle = GetAngleX(0)+Math::PI*0.4f; SetAngleX(0, angle); } @@ -5502,19 +5474,17 @@ bool CObject::CreateRuin(Math::Vector pos, float angle, float height, bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) { - CModFile* pModFile; + Gfx::CModelFile* pModFile; int rank, i; - if ( m_engine->RetRestCreate() < 6 ) return false; - - pModFile = new CModFile(m_iMan); + pModFile = new Gfx::CModelFile(m_iMan); SetType(type); if ( type == OBJECT_APOLLO1 ) // LEM ? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); pModFile->ReadModel("objects\\apollol1.mod"); pModFile->CreateEngineObject(rank); @@ -5526,7 +5496,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) for ( i=0 ; i<4 ; i++ ) // creates feet { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(i+1, rank); SetObjectParent(i+1, 0); pModFile->ReadModel("objects\\apollol2.mod"); @@ -5535,7 +5505,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) } rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(5, rank); SetObjectParent(5, 0); pModFile->ReadModel("objects\\apollol3.mod"); // ladder @@ -5557,7 +5527,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) if ( type == OBJECT_APOLLO2 ) // jeep { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); //it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); //it is a stationary object SetObjectRank(0, rank); pModFile->ReadModel("objects\\apolloj1.mod"); pModFile->CreateEngineObject(rank); @@ -5567,7 +5537,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) // Wheels. rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\apolloj4.mod"); // wheel @@ -5575,7 +5545,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) SetPosition(1, Math::Vector(-5.75f, 1.65f, -5.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(2, rank); SetObjectParent(2, 0); pModFile->ReadModel("objects\\apolloj4.mod"); // wheel @@ -5583,7 +5553,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) SetPosition(2, Math::Vector(-5.75f, 1.65f, 5.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(3, rank); SetObjectParent(3, 0); pModFile->ReadModel("objects\\apolloj4.mod"); // wheel @@ -5591,7 +5561,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) SetPosition(3, Math::Vector(5.75f, 1.65f, -5.0f)); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(4, rank); SetObjectParent(4, 0); pModFile->ReadModel("objects\\apolloj4.mod"); // wheel @@ -5600,7 +5570,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) // Accessories: rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(5, rank); SetObjectParent(5, 0); pModFile->ReadModel("objects\\apolloj2.mod"); // antenna @@ -5610,7 +5580,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) SetAngleZ(5, 45.0f*Math::PI/180.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(6, rank); SetObjectParent(6, 0); pModFile->ReadModel("objects\\apolloj3.mod"); // camera @@ -5630,7 +5600,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) if ( type == OBJECT_APOLLO3 ) // flag? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); pModFile->ReadModel("objects\\apollof.mod"); pModFile->CreateEngineObject(rank); @@ -5645,7 +5615,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) if ( type == OBJECT_APOLLO4 ) // module? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); pModFile->ReadModel("objects\\apollom.mod"); pModFile->CreateEngineObject(rank); @@ -5662,7 +5632,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) if ( type == OBJECT_APOLLO5 ) // antenna? { rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEFIX); // it is a stationary object + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_FIX); // it is a stationary object SetObjectRank(0, rank); pModFile->ReadModel("objects\\apolloa.mod"); pModFile->CreateEngineObject(rank); @@ -5671,7 +5641,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) SetFloorHeight(0.0f); rank = m_engine->CreateObject(); - m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_engine->SetObjectType(rank, Gfx::ENG_OBJTYPE_DESCENDANT); SetObjectRank(1, rank); SetObjectParent(1, 0); pModFile->ReadModel("objects\\apolloj2.mod"); // antenna @@ -5686,7 +5656,7 @@ bool CObject::CreateApollo(Math::Vector pos, float angle, ObjectType type) CreateOtherObject(type); - pos = RetPosition(0); + pos = GetPosition(0); SetPosition(0, pos); // to display the shadows immediately delete pModFile; @@ -5804,7 +5774,7 @@ void CObject::CreateOtherObject(ObjectType type) // Reads a program. -bool CObject::ReadProgram(int rank, char* filename) +bool CObject::ReadProgram(int rank, const char* filename) { if ( m_brain != 0 ) { @@ -5845,7 +5815,7 @@ bool CObject::RunProgram(int rank) // Calculates the matrix for transforming the object. -// Returns true if the matrix has changed. +// Geturns true if the matrix has changed. // The rotations occur in the order Y, Z and X. bool CObject::UpdateTransformObject(int part, bool bForceUpdate) @@ -5916,7 +5886,7 @@ bool CObject::UpdateTransformObject(int part, bool bForceUpdate) if ( part == 0 && m_truck != 0 ) // transported by a truck? { Math::Matrix* matWorldTruck; - matWorldTruck = m_truck->RetWorldMatrix(m_truckLink); + matWorldTruck = m_truck->GetWorldMatrix(m_truckLink); m_objectPart[part].matWorld = Math::MultiplyMatrices(*matWorldTruck, m_objectPart[part].matTransform); } @@ -6043,7 +6013,7 @@ void CObject::FlatParent() void CObject::UpdateEnergyMapping() { - D3DMATERIAL7 mat; + Gfx::Material mat; float a, b, i, s, au, bu; float limit[6]; int j; @@ -6051,7 +6021,7 @@ void CObject::UpdateEnergyMapping() if ( fabs(m_energy-m_lastEnergy) < 0.01f ) return; m_lastEnergy = m_energy; - ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); + memset(&mat, 0, sizeof(mat)); mat.diffuse.r = 1.0f; mat.diffuse.g = 1.0f; mat.diffuse.b = 1.0f; // white @@ -6083,17 +6053,17 @@ void CObject::UpdateEnergyMapping() bu = s-b*(s-i)/(b-a); limit[0] = 0.0f; - limit[1] = m_engine->RetLimitLOD(0); + limit[1] = m_engine->GetLimitLOD(0); limit[2] = limit[1]; - limit[3] = m_engine->RetLimitLOD(1); + limit[3] = m_engine->GetLimitLOD(1); limit[4] = limit[3]; limit[5] = 1000000.0f; for ( j=0 ; j<3 ; j++ ) { m_engine->ChangeTextureMapping(m_objectPart[0].object, - mat, D3DSTATEPART3, "lemt.tga", "", - limit[j*2+0], limit[j*2+1], D3DMAPPING1Y, + mat, Gfx::ENG_RSTATE_PART3, "lemt.tga", "", + limit[j*2+0], limit[j*2+1], Gfx::ENG_TEX_MAPPING_1Y, au, bu, 1.0f, 0.0f); } } @@ -6103,7 +6073,7 @@ void CObject::UpdateEnergyMapping() bool CObject::EventProcess(const Event &event) { - if ( event.event == EVENT_KEYDOWN ) + if ( event.type == EVENT_KEY_DOWN ) { #if ADJUST_ONBOARD if ( m_bSelect ) @@ -6147,12 +6117,12 @@ bool CObject::EventProcess(const Event &event) { if ( !m_physics->EventProcess(event) ) // object destroyed? { - if ( RetSelect() && + if ( GetSelect() && m_type != OBJECT_ANT && m_type != OBJECT_SPIDER && m_type != OBJECT_BEE ) { - if ( !m_bDead ) m_camera->SetType(CAMERA_EXPLO); + if ( !m_bDead ) m_camera->SetType(Gfx::CAM_TYPE_EXPLO); m_main->DeselectAll(); } return false; @@ -6163,7 +6133,7 @@ bool CObject::EventProcess(const Event &event) { m_auto->EventProcess(event); - if ( event.event == EVENT_FRAME && + if ( event.type == EVENT_FRAME && m_auto->IsEnded() != ERR_CONTINUE ) { m_auto->DeleteObject(); @@ -6177,7 +6147,7 @@ bool CObject::EventProcess(const Event &event) m_motion->EventProcess(event); } - if ( event.event == EVENT_FRAME ) + if ( event.type == EVENT_FRAME ) { return EventFrame(event); } @@ -6190,13 +6160,13 @@ bool CObject::EventProcess(const Event &event) bool CObject::EventFrame(const Event &event) { - if ( m_type == OBJECT_HUMAN && m_main->RetMainMovie() == MM_SATCOMopen ) + if ( m_type == OBJECT_HUMAN && m_main->GetMainMovie() == MM_SATCOMopen ) { UpdateTransformObject(); return true; } - if ( m_type != OBJECT_SHOW && m_engine->RetPause() ) return true; + if ( m_type != OBJECT_SHOW && m_engine->GetPause() ) return true; m_aTime += event.rTime; m_shotTime += event.rTime; @@ -6206,23 +6176,23 @@ bool CObject::EventFrame(const Event &event) UpdateMapping(); UpdateTransformObject(); - UpdateSelectParticule(); + UpdateSelectParticle(); if ( m_bProxyActivate ) // active if it is near? { - CPyro* pyro; + Gfx::CPyro* pyro; Math::Vector eye; float dist; - eye = m_engine->RetLookatPt(); - dist = Math::Distance(eye, RetPosition(0)); + eye = m_engine->GetLookatPt(); + dist = Math::Distance(eye, GetPosition(0)); if ( dist < m_proxyDistance ) { m_bProxyActivate = false; m_main->CreateShortcuts(); m_sound->Play(SOUND_FINDING); - pyro = new CPyro(m_iMan); - pyro->Create(PT_FINDING, this, 0.0f); + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_FINDING, this, 0.0f); m_displayText->DisplayError(INFO_FINDING, this); } } @@ -6248,10 +6218,10 @@ void CObject::UpdateMapping() void CObject::VirusFrame(float rTime) { - ParticuleType type; + Gfx::ParticleType type; Math::Vector pos, speed; Math::Point dim; - int r; + int r; if ( !m_bVirusMode ) return; // healthy object? @@ -6261,23 +6231,23 @@ void CObject::VirusFrame(float rTime) m_bVirusMode = false; // the virus is no longer active } - if ( m_lastVirusParticule+m_engine->ParticuleAdapt(0.2f) <= m_aTime ) + if ( m_lastVirusParticle+m_engine->ParticleAdapt(0.2f) <= m_aTime ) { - m_lastVirusParticule = m_aTime; + m_lastVirusParticle = m_aTime; r = rand()%10; - if ( r == 0 ) type = PARTIVIRUS1; - if ( r == 1 ) type = PARTIVIRUS2; - if ( r == 2 ) type = PARTIVIRUS3; - if ( r == 3 ) type = PARTIVIRUS4; - if ( r == 4 ) type = PARTIVIRUS5; - if ( r == 5 ) type = PARTIVIRUS6; - if ( r == 6 ) type = PARTIVIRUS7; - if ( r == 7 ) type = PARTIVIRUS8; - if ( r == 8 ) type = PARTIVIRUS9; - if ( r == 9 ) type = PARTIVIRUS10; - - pos = RetPosition(0); + if ( r == 0 ) type = Gfx::PARTIVIRUS1; + if ( r == 1 ) type = Gfx::PARTIVIRUS2; + if ( r == 2 ) type = Gfx::PARTIVIRUS3; + if ( r == 3 ) type = Gfx::PARTIVIRUS4; + if ( r == 4 ) type = Gfx::PARTIVIRUS5; + if ( r == 5 ) type = Gfx::PARTIVIRUS6; + if ( r == 6 ) type = Gfx::PARTIVIRUS7; + if ( r == 7 ) type = Gfx::PARTIVIRUS8; + if ( r == 8 ) type = Gfx::PARTIVIRUS9; + if ( r == 9 ) type = Gfx::PARTIVIRUS10; + + pos = GetPosition(0); pos.x += (Math::Rand()-0.5f)*10.0f; pos.z += (Math::Rand()-0.5f)*10.0f; speed.x = (Math::Rand()-0.5f)*2.0f; @@ -6286,7 +6256,7 @@ void CObject::VirusFrame(float rTime) dim.x = Math::Rand()*0.3f+0.3f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, type, 3.0f); + m_particle->CreateParticle(pos, speed, dim, type, 3.0f); } } @@ -6304,7 +6274,7 @@ void CObject::PartiFrame(float rTime) channel = m_objectPart[i].masterParti; if ( channel == -1 ) continue; - if ( !m_particule->GetPosition(channel, pos) ) + if ( !m_particle->GetPosition(channel, pos) ) { m_objectPart[i].masterParti = -1; // particle no longer exists! continue; @@ -6322,7 +6292,7 @@ void CObject::PartiFrame(float rTime) case 4: factor = Math::Vector( 0.4f, 0.1f,-0.7f); break; } - angle = RetAngle(i); + angle = GetAngle(i); angle += rTime*Math::PI*factor; SetAngle(i, angle); } @@ -6334,7 +6304,7 @@ void CObject::PartiFrame(float rTime) void CObject::SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, Math::Vector &lookat, Math::Vector &upVec, - CameraType type) + Gfx::CameraType type) { float speed; int part; @@ -6429,7 +6399,7 @@ void CObject::SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, m_engine->SetInfoText(4, s); #endif - if ( type == CAMERA_BACK ) + if ( type == Gfx::CAM_TYPE_BACK ) { eye.x -= 20.0f; eye.y += 1.0f; @@ -6446,20 +6416,20 @@ void CObject::SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, upVec = Math::Vector(0.0f, 1.0f, 0.0f); if ( m_physics != 0 ) { - if ( m_physics->RetLand() ) // on ground? + if ( m_physics->GetLand() ) // on ground? { - speed = m_physics->RetLinMotionX(MO_REASPEED); + speed = m_physics->GetLinMotionX(MO_REASPEED); lookat.y -= speed*0.002f; - speed = m_physics->RetCirMotionY(MO_REASPEED); + speed = m_physics->GetCirMotionY(MO_REASPEED); upVec.z -= speed*0.04f; } else // in flight? { - speed = m_physics->RetLinMotionX(MO_REASPEED); + speed = m_physics->GetLinMotionX(MO_REASPEED); lookat.y += speed*0.002f; - speed = m_physics->RetCirMotionY(MO_REASPEED); + speed = m_physics->GetCirMotionY(MO_REASPEED); upVec.z += speed*0.08f; } } @@ -6475,23 +6445,23 @@ void CObject::SetViewFromHere(Math::Vector &eye, float &dirH, float &dirV, void CObject::SetCharacter(Character* character) { - CopyMemory(&m_character, character, sizeof(Character)); + memcpy(&m_character, character, sizeof(m_character)); } void CObject::GetCharacter(Character* character) { - CopyMemory(character, &m_character, sizeof(Character)); + memcpy(character, &m_character, sizeof(character)); } -Character* CObject::RetCharacter() +Character* CObject::GetCharacter() { return &m_character; } -// Returns the absolute time. +// Geturns the absolute time. -float CObject::RetAbsTime() +float CObject::GetAbsTime() { return m_aTime; } @@ -6507,7 +6477,7 @@ void CObject::SetEnergy(float level) m_energy = level; } -float CObject::RetEnergy() +float CObject::GetEnergy() { if ( m_type != OBJECT_POWER && m_type != OBJECT_ATOMIC && @@ -6526,7 +6496,7 @@ void CObject::SetCapacity(float capacity) m_capacity = capacity; } -float CObject::RetCapacity() +float CObject::GetCapacity() { return m_capacity; } @@ -6539,7 +6509,7 @@ void CObject::SetShield(float level) m_shield = level; } -float CObject::RetShield() +float CObject::GetShield() { if ( m_type == OBJECT_FRET || m_type == OBJECT_STONE || @@ -6582,7 +6552,7 @@ void CObject::SetRange(float delay) m_range = delay; } -float CObject::RetRange() +float CObject::GetRange() { return m_range; } @@ -6610,7 +6580,7 @@ void CObject::SetTransparency(float value) } } -float CObject::RetTransparency() +float CObject::GetTransparency() { return m_transparency; } @@ -6618,7 +6588,7 @@ float CObject::RetTransparency() // Management of the object matter. -ObjectMaterial CObject::RetMaterial() +ObjectMaterial CObject::GetMaterial() { if ( m_type == OBJECT_HUMAN ) { @@ -6642,7 +6612,7 @@ void CObject::SetGadget(bool bMode) m_bGadget = bMode; } -bool CObject::RetGadget() +bool CObject::GetGadget() { return m_bGadget; } @@ -6655,7 +6625,7 @@ void CObject::SetFixed(bool bFixed) m_bFixed = bFixed; } -bool CObject::RetFixed() +bool CObject::GetFixed() { return m_bFixed; } @@ -6668,7 +6638,7 @@ void CObject::SetClip(bool bClip) m_bClip = bClip; } -bool CObject::RetClip() +bool CObject::GetClip() { return m_bClip; } @@ -6696,7 +6666,7 @@ bool CObject::JostleObject(float force) if ( m_auto != 0 ) return false; m_auto = new CAutoJostle(m_iMan, this); - pa = (CAutoJostle*)m_auto; + pa = static_cast<CAutoJostle*>(m_auto); pa->Start(0, force); } @@ -6712,7 +6682,7 @@ void CObject::StartDetectEffect(CObject *target, bool bFound) Math::Vector pos, goal; Math::Point dim; - mat = RetWorldMatrix(0); + mat = GetWorldMatrix(0); pos = Math::Transform(*mat, Math::Vector(2.0f, 3.0f, 0.0f)); if ( target == 0 ) @@ -6721,24 +6691,24 @@ void CObject::StartDetectEffect(CObject *target, bool bFound) } else { - goal = target->RetPosition(0); + goal = target->GetPosition(0); goal.y += 3.0f; goal = Math::SegmentPoint(pos, goal, Math::Distance(pos, goal)-3.0f); } dim.x = 3.0f; dim.y = dim.x; - m_particule->CreateRay(pos, goal, PARTIRAY2, dim, 0.2f); + m_particle->CreateRay(pos, goal, Gfx::PARTIRAY2, dim, 0.2f); if ( target != 0 ) { - goal = target->RetPosition(0); + goal = target->GetPosition(0); goal.y += 3.0f; goal = Math::SegmentPoint(pos, goal, Math::Distance(pos, goal)-1.0f); dim.x = 6.0f; dim.y = dim.x; - m_particule->CreateParticule(goal, Math::Vector(0.0f, 0.0f, 0.0f), dim, - bFound?PARTIGLINT:PARTIGLINTr, 0.5f); + m_particle->CreateParticle(goal, Math::Vector(0.0f, 0.0f, 0.0f), dim, + bFound?Gfx::PARTIGLINT:Gfx::PARTIGLINTr, 0.5f); } m_sound->Play(bFound?SOUND_BUILD:SOUND_RECOVER); @@ -6761,12 +6731,12 @@ void CObject::SetVirusMode(bool bEnable) } } -bool CObject::RetVirusMode() +bool CObject::GetVirusMode() { return m_bVirusMode; } -float CObject::RetVirusTime() +float CObject::GetVirusTime() { return m_virusTime; } @@ -6774,12 +6744,12 @@ float CObject::RetVirusTime() // Management mode of the camera. -void CObject::SetCameraType(CameraType type) +void CObject::SetCameraType(Gfx::CameraType type) { m_cameraType = type; } -CameraType CObject::RetCameraType() +Gfx::CameraType CObject::GetCameraType() { return m_cameraType; } @@ -6789,7 +6759,7 @@ void CObject::SetCameraDist(float dist) m_cameraDist = dist; } -float CObject::RetCameraDist() +float CObject::GetCameraDist() { return m_cameraDist; } @@ -6799,7 +6769,7 @@ void CObject::SetCameraLock(bool bLock) m_bCameraLock = bLock; } -bool CObject::RetCameraLock() +bool CObject::GetCameraLock() { return m_bCameraLock; } @@ -6827,11 +6797,11 @@ void CObject::SetHilite(bool bMode) } list[j] = -1; // terminate - m_engine->SetHiliteRank(list); // gives the list of selected parts + m_engine->SetHighlightRank(list); // gives the list of selected parts } } -bool CObject::RetHilite() +bool CObject::GetHilite() { return m_bHilite; } @@ -6855,7 +6825,7 @@ void CObject::SetSelect(bool bMode, bool bDisplayError) m_auto->CreateInterface(m_bSelect); } - CreateSelectParticule(); // creates / removes particles + CreateSelectParticle(); // creates / removes particles if ( !m_bSelect ) { @@ -6866,11 +6836,11 @@ void CObject::SetSelect(bool bMode, bool bDisplayError) err = ERR_OK; if ( m_physics != 0 ) { - err = m_physics->RetError(); + err = m_physics->GetError(); } if ( m_auto != 0 ) { - err = m_auto->RetError(); + err = m_auto->GetError(); } if ( err != ERR_OK && bDisplayError ) { @@ -6880,9 +6850,9 @@ void CObject::SetSelect(bool bMode, bool bDisplayError) // Indicates whether the object is selected or not. -bool CObject::RetSelect(bool bReal) +bool CObject::GetSelect(bool bReal) { - if ( !bReal && m_main->RetFixScene() ) return false; + if ( !bReal && m_main->GetFixScene() ) return false; return m_bSelect; } @@ -6896,7 +6866,7 @@ void CObject::SetSelectable(bool bMode) // Indicates whether the object is selecionnable or not. -bool CObject::RetSelectable() +bool CObject::GetSelectable() { return m_bSelectable; } @@ -6912,11 +6882,11 @@ void CObject::SetActivity(bool bMode) } } -bool CObject::RetActivity() +bool CObject::GetActivity() { if ( m_brain != 0 ) { - return m_brain->RetActivity(); + return m_brain->GetActivity(); } return false; } @@ -6931,7 +6901,7 @@ void CObject::SetCheckToken(bool bMode) // Indicates if necessary to check the tokens of the object. -bool CObject::RetCheckToken() +bool CObject::GetCheckToken() { return m_bCheckToken; } @@ -6946,7 +6916,7 @@ void CObject::SetVisible(bool bVisible) m_bVisible = bVisible; } -bool CObject::RetVisible() +bool CObject::GetVisible() { return m_bVisible; } @@ -6962,7 +6932,7 @@ void CObject::SetEnable(bool bEnable) m_bEnable = bEnable; } -bool CObject::RetEnable() +bool CObject::GetEnable() { return m_bEnable; } @@ -6975,7 +6945,7 @@ void CObject::SetProxyActivate(bool bActivate) m_bProxyActivate = bActivate; } -bool CObject::RetProxyActivate() +bool CObject::GetProxyActivate() { return m_bProxyActivate; } @@ -6985,7 +6955,7 @@ void CObject::SetProxyDistance(float distance) m_proxyDistance = distance; } -float CObject::RetProxyDistance() +float CObject::GetProxyDistance() { return m_proxyDistance; } @@ -6998,7 +6968,7 @@ void CObject::SetMagnifyDamage(float factor) m_magnifyDamage = factor; } -float CObject::RetMagnifyDamage() +float CObject::GetMagnifyDamage() { return m_magnifyDamage; } @@ -7011,7 +6981,7 @@ void CObject::SetParam(float value) m_param = value; } -float CObject::RetParam() +float CObject::GetParam() { return m_param; } @@ -7026,7 +6996,7 @@ void CObject::SetLock(bool bLock) m_bLock = bLock; } -bool CObject::RetLock() +bool CObject::GetLock() { return m_bLock; } @@ -7039,7 +7009,7 @@ void CObject::SetExplo(bool bExplo) m_bExplo = bExplo; } -bool CObject::RetExplo() +bool CObject::GetExplo() { return m_bExplo; } @@ -7052,7 +7022,7 @@ void CObject::SetCargo(bool bCargo) m_bCargo = bCargo; } -bool CObject::RetCargo() +bool CObject::GetCargo() { return m_bCargo; } @@ -7071,7 +7041,7 @@ void CObject::SetBurn(bool bBurn) //? } } -bool CObject::RetBurn() +bool CObject::GetBurn() { return m_bBurn; } @@ -7092,17 +7062,17 @@ void CObject::SetDead(bool bDead) //? } } -bool CObject::RetDead() +bool CObject::GetDead() { return m_bDead; } -bool CObject::RetRuin() +bool CObject::GetRuin() { return m_bBurn|m_bFlat; } -bool CObject::RetActif() +bool CObject::GetActif() { return !m_bLock && !m_bBurn && !m_bFlat && m_bVisible && m_bEnable; } @@ -7178,12 +7148,12 @@ void CObject::SetGunGoalH(float gunGoal) m_gunGoalH = gunGoal; } -float CObject::RetGunGoalV() +float CObject::GetGunGoalV() { return m_gunGoalV; } -float CObject::RetGunGoalH() +float CObject::GetGunGoalH() { return m_gunGoalH; } @@ -7196,7 +7166,7 @@ bool CObject::StartShowLimit() { if ( m_showLimitRadius == 0.0f ) return false; - m_main->SetShowLimit(0, PARTILIMIT1, this, RetPosition(0), m_showLimitRadius); + m_main->SetShowLimit(0, Gfx::PARTILIMIT1, this, GetPosition(0), m_showLimitRadius); m_bShowLimit = true; return true; } @@ -7219,7 +7189,7 @@ bool CObject::IsProgram() // Creates or removes particles associated to the object. -void CObject::CreateSelectParticule() +void CObject::CreateSelectParticle() { Math::Vector pos, speed; Math::Point dim; @@ -7230,7 +7200,7 @@ void CObject::CreateSelectParticule() { if ( m_partiSel[i] != -1 ) { - m_particule->DeleteParticule(m_partiSel[i]); + m_particle->DeleteParticle(m_partiSel[i]); m_partiSel[i] = -1; } } @@ -7270,18 +7240,18 @@ void CObject::CreateSelectParticule() speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 0.0f; dim.y = 0.0f; - m_partiSel[0] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); - m_partiSel[1] = m_particule->CreateParticule(pos, speed, dim, PARTISELY, 1.0f, 0.0f, 0.0f); - m_partiSel[2] = m_particule->CreateParticule(pos, speed, dim, PARTISELR, 1.0f, 0.0f, 0.0f); - m_partiSel[3] = m_particule->CreateParticule(pos, speed, dim, PARTISELR, 1.0f, 0.0f, 0.0f); - UpdateSelectParticule(); + m_partiSel[0] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISELY, 1.0f, 0.0f, 0.0f); + m_partiSel[1] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISELY, 1.0f, 0.0f, 0.0f); + m_partiSel[2] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISELR, 1.0f, 0.0f, 0.0f); + m_partiSel[3] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISELR, 1.0f, 0.0f, 0.0f); + UpdateSelectParticle(); } } } // Updates the particles associated to the object. -void CObject::UpdateSelectParticule() +void CObject::UpdateSelectParticle() { Math::Vector pos[4]; Math::Point dim[4]; @@ -7405,7 +7375,7 @@ void CObject::UpdateSelectParticule() pos[3] = Math::Vector(-5.3f, 2.7f, -1.8f); } - angle = RetAngleY(0)/Math::PI; + angle = GetAngleY(0)/Math::PI; zoom[0] = 1.0f; zoom[1] = 1.0f; @@ -7426,7 +7396,7 @@ void CObject::UpdateSelectParticule() { pos[i] = Math::Transform(m_objectPart[0].matWorld, pos[i]); dim[i].y = dim[i].x; - m_particule->SetParam(m_partiSel[i], pos[i], dim[i], zoom[i], angle, 1.0f); + m_particle->SetParam(m_partiSel[i], pos[i], dim[i], zoom[i], angle, 1.0f); } } @@ -7438,42 +7408,42 @@ void CObject::SetRunScript(CScript* script) m_runScript = script; } -CScript* CObject::RetRunScript() +CScript* CObject::GetRunScript() { return m_runScript; } -// Returns the variables of "this" for CBOT. +// Geturns the variables of "this" for CBOT. -CBotVar* CObject::RetBotVar() +CBotVar* CObject::GetBotVar() { return m_botVar; } -// Returns the physics associated to the object. +// Geturns the physics associated to the object. -CPhysics* CObject::RetPhysics() +CPhysics* CObject::GetPhysics() { return m_physics; } -// Returns the brain associated to the object. +// Geturns the brain associated to the object. -CBrain* CObject::RetBrain() +CBrain* CObject::GetBrain() { return m_brain; } -// Returns the movement associated to the object. +// Geturns the movement associated to the object. -CMotion* CObject::RetMotion() +CMotion* CObject::GetMotion() { return m_motion; } -// Returns the controller associated to the object. +// Geturns the controller associated to the object. -CAuto* CObject::RetAuto() +CAuto* CObject::GetAuto() { return m_auto; } @@ -7492,7 +7462,7 @@ void CObject::SetDefRank(int rank) m_defRank = rank; } -int CObject::RetDefRank() +int CObject::GetDefRank() { return m_defRank; } @@ -7555,51 +7525,51 @@ void CObject::DeleteDeselList(CObject* pObj) // Management of the state of the pencil drawing robot. -bool CObject::RetTraceDown() +bool CObject::GetTraceDown() { CMotionVehicle* mv; if ( m_motion == 0 ) return false; - mv = (CMotionVehicle*)m_motion; - return mv->RetTraceDown(); + mv = dynamic_cast<CMotionVehicle*>(m_motion); + return mv->GetTraceDown(); } void CObject::SetTraceDown(bool bDown) { CMotionVehicle* mv; if ( m_motion == 0 ) return; - mv = (CMotionVehicle*)m_motion; + mv = dynamic_cast<CMotionVehicle*>(m_motion); mv->SetTraceDown(bDown); } -int CObject::RetTraceColor() +int CObject::GetTraceColor() { CMotionVehicle* mv; if ( m_motion == 0 ) return 0; - mv = (CMotionVehicle*)m_motion; - return mv->RetTraceColor(); + mv = dynamic_cast<CMotionVehicle*>(m_motion); + return mv->GetTraceColor(); } void CObject::SetTraceColor(int color) { CMotionVehicle* mv; if ( m_motion == 0 ) return; - mv = (CMotionVehicle*)m_motion; + mv = dynamic_cast<CMotionVehicle*>(m_motion); mv->SetTraceColor(color); } -float CObject::RetTraceWidth() +float CObject::GetTraceWidth() { CMotionVehicle* mv; if ( m_motion == 0 ) return 0.0f; - mv = (CMotionVehicle*)m_motion; - return mv->RetTraceWidth(); + mv = dynamic_cast<CMotionVehicle*>(m_motion); + return mv->GetTraceWidth(); } void CObject::SetTraceWidth(float width) { CMotionVehicle* mv; if ( m_motion == 0 ) return; - mv = (CMotionVehicle*)m_motion; + mv = dynamic_cast<CMotionVehicle*>(m_motion); mv->SetTraceWidth(width); } diff --git a/src/object/object.h b/src/object/object.h index 88ae486..1301768 100644 --- a/src/object/object.h +++ b/src/object/object.h @@ -35,7 +35,10 @@ class CRobotMain; class CBotVar; class CScript; - +namespace Ui +{ +class CDisplayText; +} // The father of all parts must always be the part number zero! @@ -46,69 +49,70 @@ const int OBJECTMAXDESELLIST = 10; const int OBJECTMAXINFO = 10; const int OBJECTMAXCMDLINE = 20; + enum ObjectMaterial { - OM_METAL = 0, // metal - OM_PLASTIC = 1, // plastic - OM_HUMAN = 2, // cosmonaut - OM_ANIMAL = 3, // insect - OM_VEGETAL = 4, // plant - OM_MINERAL = 5, // stone + OM_METAL = 0, // metal + OM_PLASTIC = 1, // plastic + OM_HUMAN = 2, // cosmonaut + OM_ANIMAL = 3, // insect + OM_VEGETAL = 4, // plant + OM_MINERAL = 5, // stone }; struct ObjectPart { - char bUsed; - int object; // number of the object in CEngine - int parentPart; // number of father part - int masterParti; // master canal of the particle - Math::Vector position; - Math::Vector angle; - Math::Vector zoom; - char bTranslate; - char bRotate; - char bZoom; - Math::Matrix matTranslate; - Math::Matrix matRotate; - Math::Matrix matTransform; - Math::Matrix matWorld; + char bUsed; + int object; // number of the object in CEngine + int parentPart; // number of father part + int masterParti; // master canal of the particle + Math::Vector position; + Math::Vector angle; + Math::Vector zoom; + char bTranslate; + char bRotate; + char bZoom; + Math::Matrix matTranslate; + Math::Matrix matRotate; + Math::Matrix matTransform; + Math::Matrix matWorld; }; struct Character { - float wheelFront; // position X of the front wheels - float wheelBack; // position X of the back wheels - float wheelLeft; // position Z of the left wheels - float wheelRight; // position Z of the right wheels - float height; // normal height on top of ground - Math::Vector posPower; // position of the battery + float wheelFront; // position X of the front wheels + float wheelBack; // position X of the back wheels + float wheelLeft; // position Z of the left wheels + float wheelRight; // position Z of the right wheels + float height; // normal height on top of ground + Math::Vector posPower; // position of the battery }; struct Info { - char name[20]; // name of the information - float value; // value of the information + char name[20]; // name of the information + float value; // value of the information }; enum ExploType { - EXPLO_BOUM = 1, - EXPLO_BURN = 2, - EXPLO_WATER = 3, + EXPLO_BOUM = 1, + EXPLO_BURN = 2, + EXPLO_WATER = 3, }; enum ResetCap { - RESET_NONE = 0, - RESET_MOVE = 1, - RESET_DELETE = 2, + RESET_NONE = 0, + RESET_MOVE = 1, + RESET_DELETE = 2, }; enum RadarFilter { - FILTER_NONE = 0, - FILTER_ONLYLANDING = 1, - FILTER_ONLYFLYING = 2, + FILTER_NONE = 0, + FILTER_ONLYLANDING = 1, + FILTER_ONLYFLYING = 2, }; @@ -162,7 +166,7 @@ public: bool CreateRuin(Math::Vector pos, float angle, float height, ObjectType type); bool CreateApollo(Math::Vector pos, float angle, ObjectType type); - bool ReadProgram(int rank, char* filename); + bool ReadProgram(int rank, const char* filename); bool WriteProgram(int rank, char* filename); bool RunProgram(int rank); @@ -235,8 +239,8 @@ public: void SetResetRun(int run); int GetResetRun(); - void SetMasterParticule(int part, int parti); - int GetMasterParticule(int part); + void SetMasterParticle(int part, int parti); + int GetMasterParticle(int part); void SetPower(CObject* power); CObject* GetPower(); @@ -252,8 +256,8 @@ public: void SetInfo(int rank, Info info); Info GetInfo(int rank); int GetInfoTotal(); - void SetInfoGeturn(float value); - float GetInfoGeturn(); + void SetInfoReturn(float value); + float GetInfoReturn(); void SetInfoUpdate(bool bUpdate); bool GetInfoUpdate(); @@ -370,7 +374,7 @@ public: void StopShowLimit(); bool IsProgram(); - void CreateSelectParticule(); + void CreateSelectParticle(); void SetRunScript(CScript* script); CScript* GetRunScript(); @@ -414,25 +418,25 @@ protected: void UpdateEnergyMapping(); bool UpdateTransformObject(int part, bool bForceUpdate); bool UpdateTransformObject(); - void UpdateSelectParticule(); + void UpdateSelectParticle(); protected: - CInstanceManager* m_iMan; - Gfx::CEngine* m_engine; - Gfx::CLightManager* m_lightMan; - Gfx::CTerrain* m_terrain; - Gfx::CWater* m_water; - Gfx::CCamera* m_camera; - Gfx::CParticle* m_particle; - CPhysics* m_physics; - CBrain* m_brain; - CMotion* m_motion; - CAuto* m_auto; - CDisplayText* m_displayText; - CRobotMain* m_main; - CSoundInterface* m_sound; - CBotVar* m_botVar; - CScript* m_runScript; + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; + Gfx::CLightManager* m_lightMan; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + Gfx::CCamera* m_camera; + Gfx::CParticle* m_particle; + CPhysics* m_physics; + CBrain* m_brain; + CMotion* m_motion; + CAuto* m_auto; + Ui::CDisplayText* m_displayText; + CRobotMain* m_main; + CSoundInterface* m_sound; + CBotVar* m_botVar; + CScript* m_runScript; ObjectType m_type; // OBJECT_* int m_id; // unique identifier @@ -462,8 +466,8 @@ protected: float m_shotTime; // time since last shot bool m_bVirusMode; // virus activated/triggered float m_virusTime; // lifetime of the virus - float m_lastVirusParticule; - float m_lastParticule; + float m_lastVirusParticle; + float m_lastParticle; bool m_bHilite; bool m_bSelect; // object selected bool m_bSelectable; // selectable object @@ -522,7 +526,7 @@ protected: int m_infoTotal; Info m_info[OBJECTMAXINFO]; - float m_infoGeturn; + float m_infoReturn; bool m_bInfoUpdate; float m_cmdLine[OBJECTMAXCMDLINE]; diff --git a/src/object/robotmain.cpp b/src/object/robotmain.cpp index 0213401..8178ab4 100644 --- a/src/object/robotmain.cpp +++ b/src/object/robotmain.cpp @@ -615,7 +615,7 @@ CRobotMain::CRobotMain(CInstanceManager* iMan) m_event = (CEvent*)m_iMan->SearchInstance(CLASS_EVENT); m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_particle = (CParticle*)m_iMan->SearchInstance(CLASS_PARTICULE); m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); m_cloud = (CCloud*)m_iMan->SearchInstance(CLASS_CLOUD); m_blitz = (CBlitz*)m_iMan->SearchInstance(CLASS_BLITZ); @@ -740,7 +740,7 @@ CRobotMain::CRobotMain(CInstanceManager* iMan) for ( i=0 ; i<OBJECT_MAX ; i++ ) { type = (ObjectType)i; - token = RetObjectName(type); + token = GetObjectName(type); if ( token[0] != 0 ) { CBotProgram::DefineNum(token, type); @@ -913,7 +913,7 @@ void CRobotMain::ChangePhase(Phase phase) m_terrain->FlushBuildingLevel(); m_terrain->FlushFlyingLimit(); m_light->FlushLight(); - m_particule->FlushParticule(); + m_particle->FlushParticule(); m_water->Flush(); m_cloud->Flush(); m_blitz->Flush(); @@ -1323,7 +1323,7 @@ bool CRobotMain::EventProcess(const Event &event) HighlightClear(); if ( event.param == VK_F11 ) { - m_particule->WriteWheelTrace("Savegame\\t.bmp", 256, 256, Math::Vector(16.0f, 0.0f, -368.0f), Math::Vector(140.0f, 0.0f, -248.0f)); + m_particle->WriteWheelTrace("Savegame\\t.bmp", 256, 256, Math::Vector(16.0f, 0.0f, -368.0f), Math::Vector(140.0f, 0.0f, -248.0f)); return false; } if ( m_bEditLock ) // current edition? @@ -2374,7 +2374,7 @@ void CRobotMain::StartDisplayVisit(EventMsg event) m_visitTime = 0.0; m_visitParticule = 0.0f; - m_particule->DeleteParticule(PARTISHOW); + m_particle->DeleteParticule(PARTISHOW); m_camera->StartVisit(m_displayText->GetVisitGoal(event), m_displayText->GetVisitDist(event)); @@ -2412,7 +2412,7 @@ void CRobotMain::FrameVisit(float rTime) speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 30.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISHOW, 2.0f); + m_particle->CreateParticle(pos, speed, dim, PARTISHOW, 2.0f); } } @@ -2434,7 +2434,7 @@ void CRobotMain::StopDisplayVisit() } // Removes particles "arrows". - m_particule->DeleteParticule(PARTISHOW); + m_particle->DeleteParticule(PARTISHOW); m_camera->StopVisit(); m_displayText->ClearVisit(); @@ -3932,7 +3932,7 @@ void CRobotMain::ScenePerso() m_terrain->FlushBuildingLevel(); m_terrain->FlushFlyingLimit(); m_light->FlushLight(); - m_particule->FlushParticule(); + m_particle->FlushParticule(); m_iMan->Flush(CLASS_OBJECT); m_iMan->Flush(CLASS_PHYSICS); m_iMan->Flush(CLASS_BRAIN); @@ -4615,7 +4615,7 @@ void CRobotMain::CreateScene(bool bSoluce, bool bFixScene, bool bResetObject) pos.y += height; dim.x = ddim; dim.y = dim.x; - m_particule->CreateParticule(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, type, delay, 0.0f, 0.0f); + m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, type, delay, 0.0f, 0.0f); } if ( Cmd(line, "CreateLight") && !bResetObject ) @@ -5767,7 +5767,7 @@ void CRobotMain::FlushShowLimit(int i) { if ( m_showLimit[i].parti[j] == 0 ) continue; - m_particule->DeleteParticule(m_showLimit[i].parti[j]); + m_particle->DeleteParticule(m_showLimit[i].parti[j]); m_showLimit[i].parti[j] = 0; } @@ -5811,7 +5811,7 @@ void CRobotMain::SetShowLimit(int i, ParticuleType parti, CObject *pObj, for ( j=0 ; j<m_showLimit[i].total ; j++ ) { - m_showLimit[i].parti[j] = m_particule->CreateParticule(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, parti, duration); + m_showLimit[i].parti[j] = m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, parti, duration); } } @@ -5890,8 +5890,8 @@ void CRobotMain::FrameShowLimit(float rTime) m_terrain->MoveOnFloor(pos, true); if ( m_showLimit[i].radius <= 50.0f ) pos.y += 0.5f; else pos.y += 2.0f; - m_particule->SetPosition(m_showLimit[i].parti[j], pos); -//? m_particule->SetAngle(m_showLimit[i].parti[j], angle-Math::PI/2.0f); + m_particle->SetPosition(m_showLimit[i].parti[j], pos); +//? m_particle->SetAngle(m_showLimit[i].parti[j], angle-Math::PI/2.0f); angle += (2.0f*Math::PI)/m_showLimit[i].total; } @@ -6787,10 +6787,10 @@ void CRobotMain::ResetObject() } // Removes all bullets in progress. - m_particule->DeleteParticule(PARTIGUN1); - m_particule->DeleteParticule(PARTIGUN2); - m_particule->DeleteParticule(PARTIGUN3); - m_particule->DeleteParticule(PARTIGUN4); + m_particle->DeleteParticule(PARTIGUN1); + m_particle->DeleteParticule(PARTIGUN2); + m_particle->DeleteParticule(PARTIGUN3); + m_particle->DeleteParticule(PARTIGUN4); for ( i=0 ; i<1000000 ; i++ ) { @@ -6869,15 +6869,15 @@ void CRobotMain::ResetCreate() SaveAllScript(); // Removes all bullets in progress. - m_particule->DeleteParticule(PARTIGUN1); - m_particule->DeleteParticule(PARTIGUN2); - m_particule->DeleteParticule(PARTIGUN3); - m_particule->DeleteParticule(PARTIGUN4); + m_particle->DeleteParticule(PARTIGUN1); + m_particle->DeleteParticule(PARTIGUN2); + m_particle->DeleteParticule(PARTIGUN3); + m_particle->DeleteParticule(PARTIGUN4); DeselectAll(); // removes the control buttons DeleteAllObjects(); // removes all the current 3D Scene - m_particule->FlushParticule(); + m_particle->FlushParticule(); m_terrain->FlushBuildingLevel(); m_iMan->Flush(CLASS_OBJECT); m_iMan->Flush(CLASS_PHYSICS); @@ -7028,7 +7028,7 @@ Error CRobotMain::CheckEndMission(bool bFrame) // Checks if the mission is finished after displaying a message. -void CRobotMain::CheckEndMessage(char *message) +void CRobotMain::CheckEndMessage(const char *message) { int t; @@ -7062,7 +7062,7 @@ char* CRobotMain::GetObligatoryToken(int i) // Checks if an instruction is part of the obligatory list. -int CRobotMain::IsObligatoryToken(char *token) +int CRobotMain::IsObligatoryToken(const char *token) { int i; @@ -7078,7 +7078,7 @@ int CRobotMain::IsObligatoryToken(char *token) // Checks if an instruction is not part of the banned list. -bool CRobotMain::IsProhibitedToken(char *token) +bool CRobotMain::IsProhibitedToken(const char *token) { int i; diff --git a/src/object/robotmain.h b/src/object/robotmain.h index 684672f..c649aab 100644 --- a/src/object/robotmain.h +++ b/src/object/robotmain.h @@ -22,13 +22,10 @@ #include <stdio.h> #include "common/misc.h" -//#include "old/d3dengine.h" #include "graphics/engine/engine.h" #include "object/object.h" #include "object/mainmovie.h" -//#include "old/camera.h" #include "graphics/engine/camera.h" -//#include "old/particule.h" #include "graphics/engine/particle.h" enum Phase @@ -88,7 +85,7 @@ class CWindow; class CControl; class CDisplayText; class CDisplayInfo; -class CSound; +class CSoundInterface; struct EndTake @@ -189,11 +186,11 @@ public: void ResetObject(); void ResetCreate(); Error CheckEndMission(bool bFrame); - void CheckEndMessage(char *message); + void CheckEndMessage(const char *message); int GetObligatoryToken(); char* GetObligatoryToken(int i); - int IsObligatoryToken(char *token); - bool IsProhibitedToken(char *token); + int IsObligatoryToken(const char *token); + bool IsProhibitedToken(const char *token); void UpdateMap(); bool GetShowMap(); @@ -335,7 +332,7 @@ protected: CMainMap* m_map; CEvent* m_event; CD3DEngine* m_engine; - Gfx::CParticle* m_particule; + Gfx::CParticle* m_particle; CWater* m_water; CCloud* m_cloud; CBlitz* m_blitz; diff --git a/src/object/task/task.cpp b/src/object/task/task.cpp index f910ea2..b310fd5 100644 --- a/src/object/task/task.cpp +++ b/src/object/task/task.cpp @@ -17,7 +17,7 @@ // task.cpp -#include <stdio.h> +// #include <stdio.h> #include "object/task/task.h" @@ -32,20 +32,20 @@ CTask::CTask(CInstanceManager* iMan, CObject* object) { m_iMan = iMan; - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_engine = static_cast<Gfx::CEngine*>(m_iMan->SearchInstance(CLASS_ENGINE)); + m_lightMan = static_cast<Gfx::CLightManager*>(m_iMan->SearchInstance(CLASS_LIGHT)); + m_terrain = static_cast<Gfx::CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_water = static_cast<Gfx::CWater*>(m_iMan->SearchInstance(CLASS_WATER)); + m_particle = static_cast<Gfx::CParticle*>(m_iMan->SearchInstance(CLASS_PARTICULE)); + m_camera = static_cast<Gfx::CCamera*>(m_iMan->SearchInstance(CLASS_CAMERA)); + m_displayText = static_cast<Ui::CDisplayText*>(m_iMan->SearchInstance(CLASS_DISPLAYTEXT)); + m_main = static_cast<CRobotMain*>(m_iMan->SearchInstance(CLASS_MAIN)); + m_sound = static_cast<CSoundInterface*>(m_iMan->SearchInstance(CLASS_SOUND)); m_object = object; - m_physics = m_object->RetPhysics(); - m_brain = m_object->RetBrain(); - m_motion = m_object->RetMotion(); + m_physics = m_object->GetPhysics(); + m_brain = m_object->GetBrain(); + m_motion = m_object->GetMotion(); } // Object's destructor. diff --git a/src/object/task/task.h b/src/object/task/task.h index a3ec62c..a0da9d2 100644 --- a/src/object/task/task.h +++ b/src/object/task/task.h @@ -24,19 +24,25 @@ class CInstanceManager; -class CD3DEngine; -class CLight; -class CParticule; -class CTerrain; -class CWater; -class CCamera; class CBrain; class CPhysics; class CMotion; class CObject; class CRobotMain; +class CSoundInterface; + +namespace Ui { class CDisplayText; -class CSound; +} /* Ui */ + +namespace Gfx { +class CEngine; +class CLightManager; +class CParticle; +class CTerrain; +class CWater; +class CCamera; +} /* Gfx */ const float TAKE_DIST = 6.0f; // distance to an object to pick it @@ -66,21 +72,19 @@ public: virtual bool Abort(); protected: - -protected: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CLight* m_light; - CParticule* m_particule; - CTerrain* m_terrain; - CWater* m_water; - CCamera* m_camera; - CMotion* m_motion; - CBrain* m_brain; - CPhysics* m_physics; - CObject* m_object; - CRobotMain* m_main; - CDisplayText* m_displayText; - CSound* m_sound; + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; + Gfx::CLightManager* m_lightMan; + Gfx::CParticle* m_particle; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + Gfx::CCamera* m_camera; + CMotion* m_motion; + CBrain* m_brain; + CPhysics* m_physics; + CObject* m_object; + CRobotMain* m_main; + Ui::CDisplayText* m_displayText; + CSoundInterface* m_sound; }; diff --git a/src/object/task/taskmanager.cpp b/src/object/task/taskmanager.cpp index d81fb5b..171be1d 100644 --- a/src/object/task/taskmanager.cpp +++ b/src/object/task/taskmanager.cpp @@ -136,7 +136,7 @@ Error CTaskManager::StartTaskSearch() // Reads an information terminal. -Error CTaskManager::StartTaskInfo(char *name, float value, float power, bool bSend) +Error CTaskManager::StartTaskInfo(const char *name, float value, float power, bool bSend) { m_task = new CTaskInfo(m_iMan, m_object); return ((CTaskInfo*)m_task)->Start(name, value, power, bSend); diff --git a/src/object/task/taskmanager.h b/src/object/task/taskmanager.h index 14fc276..6ce023a 100644 --- a/src/object/task/taskmanager.h +++ b/src/object/task/taskmanager.h @@ -43,7 +43,7 @@ public: Error StartTaskFlag(TaskFlagOrder order, int rank); Error StartTaskBuild(ObjectType type); Error StartTaskSearch(); - Error StartTaskInfo(char *name, float value, float power, bool bSend); + Error StartTaskInfo(const char *name, float value, float power, bool bSend); Error StartTaskTerraform(); Error StartTaskPen(bool bDown, int color); Error StartTaskRecover(); diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 873979f..fb9fd44 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -17,35 +17,24 @@ // physics.cpp -#include <windows.h> -#include <stdio.h> -#include <d3d.h> +#include <cstring> -#include "common/struct.h" -#include "math/const.h" #include "math/geometry.h" -#include "old/d3dengine.h" -#include "old/d3dmath.h" -#include "common/language.h" +#include "graphics/engine/engine.h" #include "common/global.h" #include "common/event.h" -#include "common/misc.h" #include "common/iman.h" -#include "old/math3d.h" -#include "old/light.h" -#include "old/particule.h" -#include "old/terrain.h" -#include "old/water.h" -#include "old/camera.h" -#include "object/object.h" -#include "old/pyro.h" +#include "graphics/engine/lightman.h" +#include "graphics/engine/terrain.h" +#include "graphics/engine/water.h" +#include "graphics/engine/camera.h" +#include "graphics/engine/pyro.h" +#include "script/cmdtoken.h" +#include "physics/physics.h" #include "object/brain.h" #include "object/motion/motion.h" #include "object/motion/motionhuman.h" -#include "old/sound.h" #include "object/task/task.h" -#include "script/cmdtoken.h" -#include "physics/physics.h" @@ -64,13 +53,13 @@ CPhysics::CPhysics(CInstanceManager* iMan, CObject* object) m_iMan->AddInstance(CLASS_PHYSICS, this, 100); m_object = object; - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); - m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); - m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + m_engine = static_cast<Gfx::CEngine*>(m_iMan->SearchInstance(CLASS_ENGINE)); + m_lightMan = static_cast<Gfx::CLightManager*>(m_iMan->SearchInstance(CLASS_LIGHT)); + m_particle = static_cast<Gfx::CParticle*>(m_iMan->SearchInstance(CLASS_PARTICULE)); + m_terrain = static_cast<Gfx::CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_water = static_cast<Gfx::CWater*>(m_iMan->SearchInstance(CLASS_WATER)); + m_camera = static_cast<Gfx::CCamera*>(m_iMan->SearchInstance(CLASS_CAMERA)); + m_sound = static_cast<CSoundInterface*>(m_iMan->SearchInstance(CLASS_SOUND)); m_brain = 0; m_motion = 0; @@ -88,14 +77,14 @@ CPhysics::CPhysics(CInstanceManager* iMan, CObject* object) m_linVibrationFactor = 1.0f; m_cirVibrationFactor = 1.0f; m_inclinaisonFactor = 1.0f; - m_lastPowerParticule = 0.0f; - m_lastSlideParticule = 0.0f; - m_lastMotorParticule = 0.0f; - m_lastWaterParticule = 0.0f; - m_lastUnderParticule = 0.0f; - m_lastPloufParticule = 0.0f; - m_lastFlameParticule = 0.0f; - m_bWheelParticuleBrake = false; + m_lastPowerParticle = 0.0f; + m_lastSlideParticle = 0.0f; + m_lastMotorParticle = 0.0f; + m_lastWaterParticle = 0.0f; + m_lastUnderParticle = 0.0f; + m_lastPloufParticle = 0.0f; + m_lastFlameParticle = 0.0f; + m_bWheelParticleBrake = false; m_absorbWater = 0.0f; m_reactorTemperature = 0.0f; m_reactorRange = 1.0f; @@ -103,7 +92,7 @@ CPhysics::CPhysics(CInstanceManager* iMan, CObject* object) m_lastEnergy = 0.0f; m_lastSoundWater = 0.0f; m_lastSoundInsect = 0.0f; - m_restBreakParticule = 0.0f; + m_restBreakParticle = 0.0f; m_floorHeight = 0.0f; m_soundChannel = -1; m_soundChannelSlide = -1; @@ -115,8 +104,8 @@ CPhysics::CPhysics(CInstanceManager* iMan, CObject* object) m_bForceUpdate = true; m_bLowLevel = false; - ZeroMemory(&m_linMotion, sizeof(Motion)); - ZeroMemory(&m_cirMotion, sizeof(Motion)); + memset(&m_linMotion, 0, sizeof(Motion)); + memset(&m_cirMotion, 0,sizeof(Motion)); } // Object's destructor. @@ -164,7 +153,7 @@ void CPhysics::SetType(PhysicsType type) m_type = type; } -PhysicsType CPhysics::RetType() +PhysicsType CPhysics::GetType() { return m_type; } @@ -182,10 +171,10 @@ bool CPhysics::Write(char *line) if ( m_type == TYPE_FLYING ) { - sprintf(name, " reactorRange=%.2f", RetReactorRange()); + sprintf(name, " reactorRange=%.2f", GetReactorRange()); strcat(line, name); - sprintf(name, " land=%d", RetLand()); + sprintf(name, " land=%d", GetLand()); strcat(line, name); } @@ -216,7 +205,7 @@ void CPhysics::SetGravity(float value) m_gravity = value; } -float CPhysics::RetGravity() +float CPhysics::GetGravity() { return m_gravity; } @@ -224,7 +213,7 @@ float CPhysics::RetGravity() // Returns the height above the ground. -float CPhysics::RetFloorHeight() +float CPhysics::GetFloorHeight() { return m_floorHeight; } @@ -238,15 +227,15 @@ void CPhysics::SetMotor(bool bState) m_bMotor = bState; - light = m_object->RetShadowLight(); + light = m_object->GetShadowLight(); if ( light != -1 ) { - m_light->SetLightIntensity(light, m_bMotor?1.0f:0.0f); - m_light->SetLightIntensitySpeed(light, 3.0f); + m_lightMan->SetLightIntensity(light, m_bMotor?1.0f:0.0f); + m_lightMan->SetLightIntensitySpeed(light, 3.0f); } } -bool CPhysics::RetMotor() +bool CPhysics::GetMotor() { return m_bMotor; } @@ -260,7 +249,7 @@ void CPhysics::SetLand(bool bState) SetMotor(!bState); // lights if you leave the reactor in flight } -bool CPhysics::RetLand() +bool CPhysics::GetLand() { return m_bLand; } @@ -277,7 +266,7 @@ void CPhysics::SetSwim(bool bState) m_bSwim = bState; } -bool CPhysics::RetSwim() +bool CPhysics::GetSwim() { return m_bSwim; } @@ -290,7 +279,7 @@ void CPhysics::SetCollision(bool bCollision) m_bCollision = bCollision; } -bool CPhysics::RetCollision() +bool CPhysics::GetCollision() { return m_bCollision; } @@ -303,7 +292,7 @@ void CPhysics::SetFreeze(bool bFreeze) m_bFreeze = bFreeze; } -bool CPhysics::RetFreeze() +bool CPhysics::GetFreeze() { return m_bFreeze; } @@ -316,7 +305,7 @@ void CPhysics::SetReactorRange(float range) m_reactorRange = range; } -float CPhysics::RetReactorRange() +float CPhysics::GetReactorRange() { return m_reactorRange; } @@ -359,22 +348,22 @@ void CPhysics::SetMotorSpeedZ(float speed) m_motorSpeed.z = speed; } -Math::Vector CPhysics::RetMotorSpeed() +Math::Vector CPhysics::GetMotorSpeed() { return m_motorSpeed; } -float CPhysics::RetMotorSpeedX() +float CPhysics::GetMotorSpeedX() { return m_motorSpeed.x; } -float CPhysics::RetMotorSpeedY() +float CPhysics::GetMotorSpeedY() { return m_motorSpeed.y; } -float CPhysics::RetMotorSpeedZ() +float CPhysics::GetMotorSpeedZ() { return m_motorSpeed.z; } @@ -399,7 +388,7 @@ void CPhysics::SetLinMotion(PhysicsMode mode, Math::Vector value) if ( mode == MO_REASPEED ) m_linMotion.realSpeed = value; } -Math::Vector CPhysics::RetLinMotion(PhysicsMode mode) +Math::Vector CPhysics::GetLinMotion(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel; if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel; @@ -432,7 +421,7 @@ void CPhysics::SetLinMotionX(PhysicsMode mode, float value) if ( mode == MO_REASPEED ) m_linMotion.realSpeed.x = value; } -float CPhysics::RetLinMotionX(PhysicsMode mode) +float CPhysics::GetLinMotionX(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.x; if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.x; @@ -467,7 +456,7 @@ void CPhysics::SetLinMotionY(PhysicsMode mode, float value) if ( mode == MO_REASPEED ) m_linMotion.realSpeed.y = value; } -float CPhysics::RetLinMotionY(PhysicsMode mode) +float CPhysics::GetLinMotionY(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.y; if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.y; @@ -502,7 +491,7 @@ void CPhysics::SetLinMotionZ(PhysicsMode mode, float value) if ( mode == MO_REASPEED ) m_linMotion.realSpeed.z = value; } -float CPhysics::RetLinMotionZ(PhysicsMode mode) +float CPhysics::GetLinMotionZ(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_linMotion.advanceAccel.z; if ( mode == MO_RECACCEL ) return m_linMotion.recedeAccel.z; @@ -537,7 +526,7 @@ void CPhysics::SetCirMotion(PhysicsMode mode, Math::Vector value) if ( mode == MO_REASPEED ) m_cirMotion.realSpeed = value; } -Math::Vector CPhysics::RetCirMotion(PhysicsMode mode) +Math::Vector CPhysics::GetCirMotion(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel; if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel; @@ -570,7 +559,7 @@ void CPhysics::SetCirMotionX(PhysicsMode mode, float value) if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.x = value; } -float CPhysics::RetCirMotionX(PhysicsMode mode) +float CPhysics::GetCirMotionX(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.x; if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.x; @@ -605,7 +594,7 @@ void CPhysics::SetCirMotionY(PhysicsMode mode, float value) if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.y = value; } -float CPhysics::RetCirMotionY(PhysicsMode mode) +float CPhysics::GetCirMotionY(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.y; if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.y; @@ -640,7 +629,7 @@ void CPhysics::SetCirMotionZ(PhysicsMode mode, float value) if ( mode == MO_REASPEED ) m_cirMotion.realSpeed.z = value; } -float CPhysics::RetCirMotionZ(PhysicsMode mode) +float CPhysics::GetCirMotionZ(PhysicsMode mode) { if ( mode == MO_ADVACCEL ) return m_cirMotion.advanceAccel.z; if ( mode == MO_RECACCEL ) return m_cirMotion.recedeAccel.z; @@ -664,12 +653,12 @@ float CPhysics::RetCirMotionZ(PhysicsMode mode) // d = ----- // 2a -float CPhysics::RetLinStopLength(PhysicsMode sMode, PhysicsMode aMode) +float CPhysics::GetLinStopLength(PhysicsMode sMode, PhysicsMode aMode) { float speed, accel; - speed = RetLinMotionX(sMode); // MO_ADVSPEED/MO_RECSPEED - accel = RetLinMotionX(aMode); // MO_ADVACCEL/MO_RECACCEL/MO_STOACCEL + speed = GetLinMotionX(sMode); // MO_ADVSPEED/MO_RECSPEED + accel = GetLinMotionX(aMode); // MO_ADVACCEL/MO_RECACCEL/MO_STOACCEL if ( m_type == TYPE_FLYING && m_bLand ) // flying on the ground? { @@ -682,7 +671,7 @@ float CPhysics::RetLinStopLength(PhysicsMode sMode, PhysicsMode aMode) // Returns the angle of circular braking. -float CPhysics::RetCirStopLength() +float CPhysics::GetCirStopLength() { return m_cirMotion.advanceSpeed.y * m_cirMotion.advanceSpeed.y / m_cirMotion.stopAccel.y / 2.0f; @@ -690,7 +679,7 @@ float CPhysics::RetCirStopLength() // Returns the length advanced into a second, on the ground, maximum speed. -float CPhysics::RetLinMaxLength(float dir) +float CPhysics::GetLinMaxLength(float dir) { float dist; @@ -707,36 +696,36 @@ float CPhysics::RetLinMaxLength(float dir) // Returns the time needed to travel some distance. -float CPhysics::RetLinTimeLength(float dist, float dir) +float CPhysics::GetLinTimeLength(float dist, float dir) { float accel, decel, dps; if ( dir > 0.0f ) { - accel = RetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); - decel = RetLinStopLength(MO_ADVSPEED, MO_STOACCEL); + accel = GetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); + decel = GetLinStopLength(MO_ADVSPEED, MO_STOACCEL); } else { - accel = RetLinStopLength(MO_RECSPEED, MO_RECACCEL); - decel = RetLinStopLength(MO_RECSPEED, MO_STOACCEL); + accel = GetLinStopLength(MO_RECSPEED, MO_RECACCEL); + decel = GetLinStopLength(MO_RECSPEED, MO_STOACCEL); } - dps = RetLinMaxLength(dir); + dps = GetLinMaxLength(dir); return (dist+accel+decel)/dps; } // Returns the length for a forward travel some distance, taking into account the accelerations / decelerations. -float CPhysics::RetLinLength(float dist) +float CPhysics::GetLinLength(float dist) { float accDist, desDist; if ( dist > 0.0f ) { - accDist = RetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); - desDist = RetLinStopLength(MO_ADVSPEED, MO_STOACCEL); + accDist = GetLinStopLength(MO_ADVSPEED, MO_ADVACCEL); + desDist = GetLinStopLength(MO_ADVSPEED, MO_STOACCEL); if ( dist > accDist+desDist ) { @@ -749,8 +738,8 @@ float CPhysics::RetLinLength(float dist) else { dist = -dist; - accDist = RetLinStopLength(MO_RECSPEED, MO_RECACCEL); - desDist = RetLinStopLength(MO_RECSPEED, MO_STOACCEL); + accDist = GetLinStopLength(MO_RECSPEED, MO_RECACCEL); + desDist = GetLinStopLength(MO_RECSPEED, MO_STOACCEL); if ( dist > accDist+desDist ) { @@ -768,14 +757,14 @@ float CPhysics::RetLinLength(float dist) bool CPhysics::EventProcess(const Event &event) { - if ( !m_object->RetEnable() ) return true; + if ( !m_object->GetEnable() ) return true; if ( m_brain != 0 ) { m_brain->EventProcess(event); } - if ( event.event == EVENT_FRAME ) + if ( event.type == EVENT_FRAME ) { return EventFrame(event); } @@ -792,7 +781,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) Math::Vector pos, motorSpeed; float energy, speed, factor, h; - type = m_object->RetType(); + type = m_object->GetType(); motorSpeed = m_motorSpeed; @@ -810,8 +799,8 @@ void CPhysics::MotorUpdate(float aTime, float rTime) type == OBJECT_TECH ) { power = 0; - if ( m_object->RetFret() != 0 && // carries something? - !m_object->RetCargo() ) + if ( m_object->GetFret() != 0 && // carries something? + !m_object->GetCargo() ) { motorSpeed.x *= 0.7f; // forward more slowly motorSpeed.z *= 0.5f; @@ -825,7 +814,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) motorSpeed.z *= 0.5f; motorSpeed.y *= 0.5f; - if ( m_object->RetFret() != 0 ) // carries something? + if ( m_object->GetFret() != 0 ) // carries something? { motorSpeed.x *= 0.2f; motorSpeed.z *= 0.9f; @@ -842,8 +831,8 @@ void CPhysics::MotorUpdate(float aTime, float rTime) } else { - power = m_object->RetPower(); // searches for the object battery uses - if ( power == 0 || power->RetEnergy() == 0.0f ) // no battery or flat? + power = m_object->GetPower(); // searches for the object battery uses + if ( power == 0 || power->GetEnergy() == 0.0f ) // no battery or flat? { motorSpeed.x = 0.0f; motorSpeed.z = 0.0f; @@ -859,11 +848,11 @@ void CPhysics::MotorUpdate(float aTime, float rTime) } } - if ( m_object->RetDead() ) // dead man? + if ( m_object->GetDead() ) // dead man? { motorSpeed.x = 0.0f; motorSpeed.z = 0.0f; - if ( m_motion->RetAction() == MHS_DEADw ) // drowned? + if ( m_motion->GetAction() == MHS_DEADw ) // drowned? { motorSpeed.y = 0.0f; // this is MHS_DEADw going back } @@ -876,9 +865,9 @@ void CPhysics::MotorUpdate(float aTime, float rTime) if ( m_type == TYPE_FLYING && !m_bLand && motorSpeed.y > 0.0f ) { - pos = m_object->RetPosition(0); - h = m_terrain->RetFlyingLimit(pos, type==OBJECT_BEE); - h += m_object->RetCharacter()->height; + pos = m_object->GetPosition(0); + h = m_terrain->GetFlyingLimit(pos, type==OBJECT_BEE); + h += m_object->GetCharacter()->height; if ( pos.y > h-40.0f ) // almost at the top? { factor = 1.0f-(pos.y-(h-40.0f))/40.0f; @@ -889,7 +878,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) } if ( type != OBJECT_BEE && - m_object->RetRange() > 0.0f ) // limited flight range? + m_object->GetRange() > 0.0f ) // limited flight range? { if ( m_bLand || m_bSwim || m_bObstacle ) // on the ground or in the water? { @@ -900,9 +889,9 @@ void CPhysics::MotorUpdate(float aTime, float rTime) if ( m_reactorRange > 1.0f ) { m_reactorRange = 1.0f; - if ( m_bLowLevel && m_object->RetSelect() ) // beep cool? + if ( m_bLowLevel && m_object->GetSelect() ) // beep cool? { - m_sound->Play(SOUND_INFO, m_object->RetPosition(0), 1.0f, 2.0f); + m_sound->Play(SOUND_INFO, m_object->GetPosition(0), 1.0f, 2.0f); m_bLowLevel = false; } } @@ -910,7 +899,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) } else // in flight? { - m_reactorRange -= rTime*(1.0f/m_object->RetRange()); + m_reactorRange -= rTime*(1.0f/m_object->GetRange()); if ( m_reactorRange < 0.0f ) m_reactorRange = 0.0f; if ( m_reactorRange < 0.5f ) m_bLowLevel = true; } @@ -921,7 +910,7 @@ void CPhysics::MotorUpdate(float aTime, float rTime) } } -//? MotorParticule(aTime); +//? MotorParticle(aTime); // Forward/backward. if ( motorSpeed.x > 0.0f ) @@ -991,9 +980,9 @@ void CPhysics::MotorUpdate(float aTime, float rTime) m_linMotion.motorAccel.x = m_linMotion.stopAccel.x*factor; m_cirMotion.motorAccel.y = m_cirMotion.stopAccel.y*factor; - pos = m_object->RetPosition(0); - h = m_terrain->RetFlyingLimit(pos, type==OBJECT_BEE); - h += m_object->RetCharacter()->height; + pos = m_object->GetPosition(0); + h = m_terrain->GetFlyingLimit(pos, type==OBJECT_BEE); + h += m_object->GetCharacter()->height; if ( motorSpeed.y > 0.0f && m_reactorRange > 0.1f && pos.y < h ) { m_bLand = false; // take off @@ -1024,9 +1013,9 @@ void CPhysics::MotorUpdate(float aTime, float rTime) type == OBJECT_MOBILEic || type == OBJECT_MOBILEii ) factor = 0.5f; - factor /= power->RetCapacity(); + factor /= power->GetCapacity(); - energy = power->RetEnergy(); + energy = power->GetEnergy(); energy -= fabs(motorSpeed.x)*rTime*factor*0.005f; energy -= fabs(motorSpeed.z)*rTime*factor*0.005f; @@ -1050,21 +1039,21 @@ void CPhysics::EffectUpdate(float aTime, float rTime) ObjectType type; bool bOnBoard; - if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return; + if ( !m_engine->IsVisiblePoint(m_object->GetPosition(0)) ) return; - type = m_object->RetType(); - character = m_object->RetCharacter(); + type = m_object->GetType(); + character = m_object->GetCharacter(); bOnBoard = false; - if ( m_object->RetSelect() && - m_camera->RetType() == CAMERA_ONBOARD ) + if ( m_object->GetSelect() && + m_camera->GetType() == Gfx::CAM_TYPE_ONBOARD ) { bOnBoard = true; } - vibLin = m_motion->RetLinVibration(); - vibCir = m_motion->RetCirVibration(); - incl = m_motion->RetInclinaison(); + vibLin = m_motion->GetLinVibration(); + vibCir = m_motion->GetCirVibration(); + incl = m_motion->GetInclinaison(); if ( type == OBJECT_HUMAN || // human? type == OBJECT_TECH ) @@ -1175,6 +1164,7 @@ void CPhysics::EffectUpdate(float aTime, float rTime) else { m_motion->SetLinVibration(Math::Vector(0.0f, 0.0f, 0.0f)); + //? m_motion->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f)); //? m_motion->SetInclinaison(Math::Vector(0.0f, 0.0f, 0.0f)); } @@ -1475,24 +1465,24 @@ bool CPhysics::EventFrame(const Event &event) float h, w; int i; - if ( m_engine->RetPause() ) return true; + if ( m_engine->GetPause() ) return true; m_time += event.rTime; m_timeUnderWater += event.rTime; m_soundTimeJostle += event.rTime; - type = m_object->RetType(); + type = m_object->GetType(); - FrameParticule(m_time, event.rTime); + FrameParticle(m_time, event.rTime); MotorUpdate(m_time, event.rTime); EffectUpdate(m_time, event.rTime); WaterFrame(m_time, event.rTime); - iPos = pos = m_object->RetPosition(0); - iAngle = angle = m_object->RetAngle(0); + iPos = pos = m_object->GetPosition(0); + iAngle = angle = m_object->GetAngle(0); // Accelerate is the descent, brake is the ascent. - if ( m_bFreeze || m_object->RetDead() ) + if ( m_bFreeze || m_object->GetDead() ) { m_linMotion.terrainSpeed.x = 0.0f; m_linMotion.terrainSpeed.z = 0.0f; @@ -1501,7 +1491,7 @@ bool CPhysics::EventFrame(const Event &event) else { tAngle = angle; - h = m_terrain->RetBuildingFactor(pos); + h = m_terrain->GetBuildingFactor(pos); if ( type == OBJECT_HUMAN || type == OBJECT_TECH ) { @@ -1512,7 +1502,7 @@ bool CPhysics::EventFrame(const Event &event) FloorAngle(pos, tAngle); // calculates the angle with the ground } #if 1 - if ( pos.y < m_water->RetLevel(m_object) ) // underwater? + if ( pos.y < m_water->GetLevel(m_object) ) // underwater? { h *= 0.5f; } @@ -1535,7 +1525,7 @@ bool CPhysics::EventFrame(const Event &event) if ( type == OBJECT_BEE && !m_bLand ) { h = m_floorLevel; // ground level - w = m_water->RetLevel(m_object); + w = m_water->GetLevel(m_object); if ( h < w ) h = w; h = pos.y-h-10.0f; // maximum height (*) if ( h < 0.0f ) h = 0.0f; @@ -1554,12 +1544,12 @@ bool CPhysics::EventFrame(const Event &event) newpos = Transform(matRotate, newpos); newpos += pos; - m_terrain->LimitPos(newpos); + m_terrain->AdjustToStandardBounds(newpos); if ( m_type == TYPE_FLYING && !m_bLand ) { - h = m_terrain->RetFlyingLimit(newpos, type==OBJECT_BEE); - h += m_object->RetCharacter()->height; + h = m_terrain->GetFlyingLimit(newpos, type==OBJECT_BEE); + h += m_object->GetCharacter()->height; if ( newpos.y > h ) newpos.y = h; } @@ -1604,7 +1594,7 @@ bool CPhysics::EventFrame(const Event &event) m_object->SetPosition(0, newpos); } - MotorParticule(m_time, event.rTime); + MotorParticle(m_time, event.rTime); SoundMotor(event.rTime); m_bForceUpdate = false; @@ -1621,33 +1611,33 @@ void CPhysics::SoundMotor(float rTime) float energy; m_lastSoundInsect -= rTime; - type = m_object->RetType(); + type = m_object->GetType(); if ( type == OBJECT_MOTHER ) { - if ( m_lastSoundInsect <= 0.0f && m_object->RetActif() ) + if ( m_lastSoundInsect <= 0.0f && m_object->GetActif() ) { - m_sound->Play(SOUND_INSECTm, m_object->RetPosition(0)); + m_sound->Play(SOUND_INSECTm, m_object->GetPosition(0)); if ( m_bMotor ) m_lastSoundInsect = 0.4f+Math::Rand()*2.5f; else m_lastSoundInsect = 1.5f+Math::Rand()*4.0f; } } else if ( type == OBJECT_ANT ) { - if ( m_object->RetBurn() || - m_object->RetFixed() ) + if ( m_object->GetBurn() || + m_object->GetFixed() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTa, m_object->RetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); + m_sound->Play(SOUND_INSECTa, m_object->GetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); m_lastSoundInsect = 0.4f+Math::Rand()*0.6f; } } - else if ( m_object->RetActif() ) + else if ( m_object->GetActif() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTa, m_object->RetPosition(0)); + m_sound->Play(SOUND_INSECTa, m_object->GetPosition(0)); if ( m_bMotor ) m_lastSoundInsect = 0.4f+Math::Rand()*2.5f; else m_lastSoundInsect = 1.5f+Math::Rand()*4.0f; } @@ -1655,60 +1645,60 @@ void CPhysics::SoundMotor(float rTime) } else if ( type == OBJECT_BEE ) { - if ( m_object->RetActif() ) + if ( m_object->GetActif() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTb, m_object->RetPosition(0)); + m_sound->Play(SOUND_INSECTb, m_object->GetPosition(0)); if ( m_bMotor ) m_lastSoundInsect = 0.4f+Math::Rand()*2.5f; else m_lastSoundInsect = 1.5f+Math::Rand()*4.0f; } } - else if ( m_object->RetBurn() ) + else if ( m_object->GetBurn() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTb, m_object->RetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); + m_sound->Play(SOUND_INSECTb, m_object->GetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); m_lastSoundInsect = 0.3f+Math::Rand()*0.5f; } } } else if ( type == OBJECT_WORM ) { - if ( m_object->RetActif() ) + if ( m_object->GetActif() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTw, m_object->RetPosition(0)); + m_sound->Play(SOUND_INSECTw, m_object->GetPosition(0)); if ( m_bMotor ) m_lastSoundInsect = 0.4f+Math::Rand()*2.5f; else m_lastSoundInsect = 1.5f+Math::Rand()*4.0f; } } - else if ( m_object->RetBurn() ) + else if ( m_object->GetBurn() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTw, m_object->RetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); + m_sound->Play(SOUND_INSECTw, m_object->GetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); m_lastSoundInsect = 0.2f+Math::Rand()*0.2f; } } } else if ( type == OBJECT_SPIDER ) { - if ( m_object->RetBurn() || - m_object->RetFixed() ) + if ( m_object->GetBurn() || + m_object->GetFixed() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTs, m_object->RetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); + m_sound->Play(SOUND_INSECTs, m_object->GetPosition(0), 1.0f, 1.5f+Math::Rand()*0.5f); m_lastSoundInsect = 0.4f+Math::Rand()*0.6f; } } - else if ( m_object->RetActif() ) + else if ( m_object->GetActif() ) { if ( m_lastSoundInsect <= 0.0f ) { - m_sound->Play(SOUND_INSECTs, m_object->RetPosition(0)); + m_sound->Play(SOUND_INSECTs, m_object->GetPosition(0)); if ( m_bMotor ) m_lastSoundInsect = 0.4f+Math::Rand()*2.5f; else m_lastSoundInsect = 1.5f+Math::Rand()*4.0f; } @@ -1718,20 +1708,20 @@ void CPhysics::SoundMotor(float rTime) { if ( m_type == TYPE_ROLLING ) { - if ( m_bMotor && m_object->RetActif() ) + if ( m_bMotor && m_object->GetActif() ) { SoundMotorFull(rTime, type); // full diet } else { energy = 0.0f; - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); } - if ( m_object->RetSelect() && + if ( m_object->GetSelect() && energy != 0.0f ) { SoundMotorSlow(rTime, type); // in slow motion @@ -1746,7 +1736,7 @@ void CPhysics::SoundMotor(float rTime) if ( m_type == TYPE_FLYING ) { if ( m_bMotor && !m_bSwim && - m_object->RetActif() && !m_object->RetDead() ) + m_object->GetActif() && !m_object->GetDead() ) { SoundReactorFull(rTime, type); // full diet } @@ -1767,20 +1757,20 @@ void CPhysics::WaterFrame(float aTime, float rTime) Math::Point dim; float level; - level = m_water->RetLevel(); + level = m_water->GetLevel(); if ( level == 0.0f ) return; // no water? - if ( m_object->RetTruck() != 0 ) return; // object transported? + if ( m_object->GetTruck() != 0 ) return; // object transported? // Management of flames into the lava. - pos = m_object->RetPosition(0); - if ( m_water->RetLava() && - pos.y-m_object->RetCharacter()->height <= level ) + pos = m_object->GetPosition(0); + if ( m_water->GetLava() && + pos.y-m_object->GetCharacter()->height <= level ) { - if ( m_lastFlameParticule+m_engine->ParticuleAdapt(0.05f) <= aTime ) + if ( m_lastFlameParticle+m_engine->ParticleAdapt(0.05f) <= aTime ) { - m_lastFlameParticule = aTime; + m_lastFlameParticle = aTime; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*3.0f; pos.z += (Math::Rand()-0.5f)*3.0f; speed.x = 0.0f; @@ -1788,9 +1778,9 @@ void CPhysics::WaterFrame(float aTime, float rTime) speed.y = Math::Rand()*5.0f+3.0f; dim.x = Math::Rand()*2.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLAME, 2.0f, 0.0f, 0.2f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFLAME, 2.0f, 0.0f, 0.2f); - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y -= 2.0f; pos.x += (Math::Rand()-0.5f)*5.0f; pos.z += (Math::Rand()-0.5f)*5.0f; @@ -1799,23 +1789,23 @@ void CPhysics::WaterFrame(float aTime, float rTime) speed.y = 6.0f+Math::Rand()*6.0f+6.0f; dim.x = Math::Rand()*1.5f+1.0f+3.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE3, 4.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f); } } - pos = m_object->RetPosition(0); - if ( pos.y >= m_water->RetLevel(m_object) ) return; // out of water? + pos = m_object->GetPosition(0); + if ( pos.y >= m_water->GetLevel(m_object) ) return; // out of water? - type = m_object->RetType(); + type = m_object->GetType(); if ( type == OBJECT_TOTO ) return; if ( type == OBJECT_NULL ) return; - if ( !m_object->RetActif() ) return; - if ( m_object->RetResetBusy() ) return; // reset in progress? + if ( !m_object->GetActif() ) return; + if ( m_object->GetResetBusy() ) return; // reset in progress? - if ( m_water->RetLava() || + if ( m_water->GetLava() || (type == OBJECT_HUMAN && - m_object->RetOption() != 0 ) || // human without a helmet? + m_object->GetOption() != 0 ) || // human without a helmet? type == OBJECT_MOBILEfa || type == OBJECT_MOBILEta || type == OBJECT_MOBILEwa || @@ -1861,13 +1851,13 @@ void CPhysics::SoundMotorFull(float rTime, ObjectType type) { if ( m_soundChannel == -1 ) { - m_soundChannel = m_sound->Play(SOUND_MOTORi, m_object->RetPosition(0), 0.0f, 1.0f, true); + m_soundChannel = m_sound->Play(SOUND_MOTORi, m_object->GetPosition(0), 0.0f, 1.0f, true); m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 0.2f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); } else { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + m_sound->Position(m_soundChannel, m_object->GetPosition(0)); } freq = 1.0f+m_linMotion.terrainSpeed.x/50.0f; @@ -1921,7 +1911,7 @@ void CPhysics::SoundMotorFull(float rTime, ObjectType type) time = 0.3f; } - if ( m_object->RetToy() ) + if ( m_object->GetToy() ) { sound = SOUND_MOTORd; amplitude = 1.0f; @@ -1930,17 +1920,17 @@ void CPhysics::SoundMotorFull(float rTime, ObjectType type) freq = 0.75f+(fabs(m_motorSpeed.x)+fabs(m_motorSpeed.z))*0.25f; if ( freq > 1.0f ) freq = 1.0f; - if ( m_object->RetToy() ) freq = 1.0f; + if ( m_object->GetToy() ) freq = 1.0f; if ( m_soundChannel == -1 ) { - m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 0.5f, true); + m_soundChannel = m_sound->Play(sound, m_object->GetPosition(0), 0.0f, 0.5f, true); m_sound->AddEnvelope(m_soundChannel, amplitude, freq, time, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, amplitude, freq, 1.0f, SOPER_LOOP); } else { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + m_sound->Position(m_soundChannel, m_object->GetPosition(0)); if ( m_bSoundSlow ) // in slow motion? { @@ -2020,7 +2010,7 @@ void CPhysics::SoundMotorSlow(float rTime, ObjectType type) amplitude = 0.3f; } - if ( m_object->RetToy() ) + if ( m_object->GetToy() ) { sound = SOUND_MOTORd; amplitude = 0.0f; @@ -2028,13 +2018,13 @@ void CPhysics::SoundMotorSlow(float rTime, ObjectType type) if ( m_soundChannel == -1 ) { - m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 0.25f, true); + m_soundChannel = m_sound->Play(sound, m_object->GetPosition(0), 0.0f, 0.25f, true); m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 0.2f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, amplitude, 0.5f, 1.0f, SOPER_LOOP); } else { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + m_sound->Position(m_soundChannel, m_object->GetPosition(0)); if ( !m_bSoundSlow ) // full power? { @@ -2056,12 +2046,12 @@ void CPhysics::SoundMotorSlow(float rTime, ObjectType type) { amplitude = 0.5f-m_soundTimePshhh*0.08f; if ( amplitude > 1.0f ) amplitude = 1.0f; -//? m_sound->Play(SOUND_PSHHH, m_object->RetPosition(0), amplitude); - m_sound->Play(SOUND_PSHHH, m_object->RetPosition(0), 1.0f); +//? m_sound->Play(SOUND_PSHHH, m_object->GetPosition(0), amplitude); + m_sound->Play(SOUND_PSHHH, m_object->GetPosition(0), 1.0f); m_soundTimePshhh = 4.0f+4.0f*Math::Rand(); - max = (int)(10.0f*m_engine->RetParticuleDensity()); + max = static_cast<int>(10.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { pos = Math::Vector(-5.0f, 2.0f, 0.0f); @@ -2073,14 +2063,14 @@ void CPhysics::SoundMotorSlow(float rTime, ObjectType type) speed.y -= Math::Rand()*3.0f; speed.z += (Math::Rand()-0.5f)*6.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed = Transform(*mat, speed)-pos; dim.x = Math::Rand()*1.0f+1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIMOTOR, 2.0f); } } } @@ -2146,13 +2136,13 @@ void CPhysics::SoundReactorFull(float rTime, ObjectType type) sound = SOUND_FLY; } - m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0), 0.0f, 1.0f, true); + m_soundChannel = m_sound->Play(sound, m_object->GetPosition(0), 0.0f, 1.0f, true); m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 0.6f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, 1.0f, SOPER_LOOP); } else { - m_sound->Position(m_soundChannel, m_object->RetPosition(0)); + m_sound->Position(m_soundChannel, m_object->GetPosition(0)); } freq = 1.0f + m_linMotion.realSpeed.y/100.0f; @@ -2171,13 +2161,13 @@ void CPhysics::SoundReactorFull(float rTime, ObjectType type) if ( m_timeReactorFail <= m_time ) { freq = 1.0f+Math::Rand()*0.5f; - m_sound->Play(SOUND_FLYf, m_object->RetPosition(0), 1.0f, freq); - m_camera->StartEffect(CE_PET, m_object->RetPosition(0), 1.0f); + m_sound->Play(SOUND_FLYf, m_object->GetPosition(0), 1.0f, freq); + m_camera->StartEffect(Gfx::CAM_EFFECT_PET, m_object->GetPosition(0), 1.0f); for ( i=0 ; i<5 ; i++ ) { - if ( m_object->RetType() == OBJECT_HUMAN || - m_object->RetType() == OBJECT_TECH ) + if ( m_object->GetType() == OBJECT_HUMAN || + m_object->GetType() == OBJECT_TECH ) { pos = Math::Vector(-1.6f, -0.5f, 0.0f); } @@ -2187,22 +2177,22 @@ void CPhysics::SoundReactorFull(float rTime, ObjectType type) } pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed.x = (Math::Rand()-0.5f)*5.0f; speed.z = (Math::Rand()-0.5f)*5.0f; speed.y = -(4.0f+Math::Rand()*4.0f); dim.x = (2.0f+Math::Rand()*1.0f); dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 2.0f, 0.0f, 0.1f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE1, 2.0f, 0.0f, 0.1f); } m_timeReactorFail = m_time+0.10f+Math::Rand()*0.30f; } else { - if ( m_object->RetType() == OBJECT_HUMAN || - m_object->RetType() == OBJECT_TECH ) + if ( m_object->GetType() == OBJECT_HUMAN || + m_object->GetType() == OBJECT_TECH ) { pos = Math::Vector(-1.6f, -0.5f, 0.0f); } @@ -2212,14 +2202,14 @@ void CPhysics::SoundReactorFull(float rTime, ObjectType type) } pos.x += (Math::Rand()-0.5f)*1.0f; pos.z += (Math::Rand()-0.5f)*1.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed.x = (Math::Rand()-0.5f)*2.0f; speed.z = (Math::Rand()-0.5f)*2.0f; speed.y = -(4.0f+Math::Rand()*4.0f); dim.x = (0.7f+Math::Rand()*0.4f); dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE1, 2.0f, 0.0f, 0.1f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE1, 2.0f, 0.0f, 0.1f); } } @@ -2233,10 +2223,10 @@ void CPhysics::SoundReactorStop(float rTime, ObjectType type) float energy; energy = 0.0f; - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); } if ( m_soundChannel != -1 ) // engine is running? @@ -2264,11 +2254,11 @@ void CPhysics::SoundReactorStop(float rTime, ObjectType type) { if ( m_soundChannelSlide == -1 ) { - m_soundChannelSlide = m_sound->Play(SOUND_SLIDE, m_object->RetPosition(0), 0.0f, 1.0f, true); + m_soundChannelSlide = m_sound->Play(SOUND_SLIDE, m_object->GetPosition(0), 0.0f, 1.0f, true); m_sound->AddEnvelope(m_soundChannelSlide, 0.5f, 1.0f, 0.3f, SOPER_CONTINUE); m_sound->AddEnvelope(m_soundChannelSlide, 0.5f, 1.0f, 1.0f, SOPER_LOOP); } - m_sound->Position(m_soundChannelSlide, m_object->RetPosition(0)); + m_sound->Position(m_soundChannelSlide, m_object->GetPosition(0)); } else { @@ -2293,21 +2283,20 @@ void CPhysics::FloorAdapt(float aTime, float rTime, Math::Vector norm; Math::Matrix matRotate; float level, h, f, a1, volume, freq, force; - bool bOldSwim, bSlopingTerrain; + bool bSlopingTerrain; - type = m_object->RetType(); - character = m_object->RetCharacter(); + type = m_object->GetType(); + character = m_object->GetCharacter(); - level = m_water->RetLevel(m_object); - bOldSwim = m_bSwim; + level = m_water->GetLevel(m_object); SetSwim( pos.y < level ); - m_floorLevel = m_terrain->RetFloorLevel(pos); // height above the ground + m_floorLevel = m_terrain->GetFloorLevel(pos); // height above the ground h = pos.y-m_floorLevel; h -= character->height; m_floorHeight = h; - WaterParticule(aTime, pos, type, m_floorLevel, + WaterParticle(aTime, pos, type, m_floorLevel, fabs(m_linMotion.realSpeed.x), fabs(m_cirMotion.realSpeed.y*15.0f)); @@ -2342,13 +2331,13 @@ void CPhysics::FloorAdapt(float aTime, float rTime, { volume = fabs(m_linMotion.realSpeed.x*0.02f)+ fabs(m_linMotion.realSpeed.y*0.02f); - freq = 0.5f+m_terrain->RetHardness(pos)*2.5f; + freq = 0.5f+m_terrain->GetHardness(pos)*2.5f; m_sound->Play(SOUND_BOUM, pos, volume, freq); m_soundTimeBoum = aTime; } -//? pos = m_object->RetPosition(0); // gives position before collision +//? pos = m_object->GetPosition(0); // gives position before collision } } } @@ -2358,7 +2347,7 @@ void CPhysics::FloorAdapt(float aTime, float rTime, if ( !m_bLand ) // in flight? { volume = fabs(m_linMotion.realSpeed.y*0.02f); - freq = 0.5f+m_terrain->RetHardness(pos)*2.5f; + freq = 0.5f+m_terrain->GetHardness(pos)*2.5f; m_sound->Play(SOUND_BOUM, pos, volume, freq); } @@ -2370,7 +2359,7 @@ void CPhysics::FloorAdapt(float aTime, float rTime, if ( h < 0.0f ) { f = fabs(m_linMotion.currentSpeed.y/m_linMotion.advanceSpeed.y); - CrashParticule(f); + CrashParticle(f); } m_linMotion.currentSpeed.y = 0.0f; m_inclinaisonFactor = 1.0f/LANDING_SPEED; // slips a little to the ground @@ -2422,13 +2411,13 @@ void CPhysics::FloorAdapt(float aTime, float rTime, if ( m_floorHeight == 0.0f ) // ground plate? { - if ( m_object->RetTraceDown() ) + if ( m_object->GetTraceDown() ) { - WheelParticule(m_object->RetTraceColor(), m_object->RetTraceWidth()*g_unit); + WheelParticle(m_object->GetTraceColor(), m_object->GetTraceWidth()*g_unit); } else { - WheelParticule(-1, 0.0f); + WheelParticle(-1, 0.0f); } } @@ -2463,29 +2452,29 @@ void CPhysics::FloorAngle(const Math::Vector &pos, Math::Vector &angle) Math::Vector pw, norm; float a1, a2; - character = m_object->RetCharacter(); + character = m_object->GetCharacter(); pw.x = pos.x+character->wheelFront*cosf(angle.y+Math::PI*0.0f); pw.y = pos.y; pw.z = pos.z-character->wheelFront*sinf(angle.y+Math::PI*0.0f); - a1 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelFront); + a1 = atanf(m_terrain->GetHeightToFloor(pw)/character->wheelFront); pw.x = pos.x+character->wheelBack*cosf(angle.y+Math::PI*1.0f); pw.y = pos.y; pw.z = pos.z-character->wheelBack*sinf(angle.y+Math::PI*1.0f); - a2 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelBack); + a2 = atanf(m_terrain->GetHeightToFloor(pw)/character->wheelBack); angle.z = (a2-a1)/2.0f; pw.x = pos.x+character->wheelLeft*cosf(angle.y+Math::PI*0.5f)*cosf(angle.z); pw.y = pos.y; pw.z = pos.z-character->wheelLeft*sinf(angle.y+Math::PI*0.5f)*cosf(angle.z); - a1 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelLeft); + a1 = atanf(m_terrain->GetHeightToFloor(pw)/character->wheelLeft); pw.x = pos.x+character->wheelRight*cosf(angle.y+Math::PI*1.5f)*cosf(angle.z); pw.y = pos.y; pw.z = pos.z-character->wheelRight*sinf(angle.y+Math::PI*1.5f)*cosf(angle.z); - a2 = atanf(m_terrain->RetFloorHeight(pw)/character->wheelRight); + a2 = atanf(m_terrain->GetHeightToFloor(pw)/character->wheelRight); angle.x = (a2-a1)/2.0f; } @@ -2498,37 +2487,37 @@ void CPhysics::FloorAngle(const Math::Vector &pos, Math::Vector &angle) int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) { - CObject* pObj; - CPyro* pyro; - CPhysics* ph; + CObject* pObj; + Gfx::CPyro* pyro; + CPhysics* ph; Math::Matrix matRotate; Math::Vector iPos, oPos, iiPos, oAngle, oSpeed; - Sound sound; - float iRad, oRad, distance, force, volume; - int i, j, colType; - ObjectType iType, oType; + Sound sound; + float iRad, oRad, distance, force, volume; + int i, j, colType; + ObjectType iType, oType; - if ( m_object->RetRuin() ) return 0; // is burning or exploding? - if ( !m_object->RetClip() ) return 0; + if ( m_object->GetRuin() ) return 0; // is burning or exploding? + if ( !m_object->GetClip() ) return 0; // iiPos = sphere center is the old position. // iPos = sphere center has the new position. m_object->GetCrashSphere(0, iiPos, iRad); - iPos = iiPos + (pos - m_object->RetPosition(0)); - iType = m_object->RetType(); + iPos = iiPos + (pos - m_object->GetPosition(0)); + iType = m_object->GetType(); for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; if ( pObj == m_object ) continue; // yourself? - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetEnable() ) continue; // inactive? - if ( pObj->RetRuin() ) continue; // is burning or exploding? - if ( pObj->RetDead() ) continue; // dead man? + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetEnable() ) continue; // inactive? + if ( pObj->GetRuin() ) continue; // is burning or exploding? + if ( pObj->GetDead() ) continue; // dead man? - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType == OBJECT_NULL ) continue; if ( oType == OBJECT_TOTO ) continue; //? if ( iType == OBJECT_BEE && oType == OBJECT_BEE ) continue; @@ -2571,34 +2560,34 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) #if _TEEN if ( oType == OBJECT_WAYPOINT && - pObj->RetEnable() && - !m_object->RetResetBusy() ) // driving vehicle? + pObj->GetEnable() && + !m_object->GetResetBusy() ) // driving vehicle? #else if ( oType == OBJECT_WAYPOINT && - pObj->RetEnable() && - !m_object->RetResetBusy() && - m_object->RetTrainer() ) // driving vehicle? + pObj->GetEnable() && + !m_object->GetResetBusy() && + m_object->GetTrainer() ) // driving vehicle? #endif { - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); distance = Math::DistanceProjected(oPos, iPos); if ( distance < 4.0f ) { - m_sound->Play(SOUND_WAYPOINT, m_object->RetPosition(0)); - pyro = new CPyro(m_iMan); - pyro->Create(PT_WPCHECK, pObj); + m_sound->Play(SOUND_WAYPOINT, m_object->GetPosition(0)); + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_WPCHECK, pObj); } } if ( oType == OBJECT_TARGET2 ) { - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); distance = Math::Distance(oPos, iPos); if ( distance < 10.0f*1.5f ) { - m_sound->Play(SOUND_WAYPOINT, m_object->RetPosition(0)); - pyro = new CPyro(m_iMan); - pyro->Create(PT_WPCHECK, pObj); + m_sound->Play(SOUND_WAYPOINT, m_object->GetPosition(0)); + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_WPCHECK, pObj); } } @@ -2620,11 +2609,11 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) m_bCollision = true; m_bObstacle = true; - sound = pObj->RetCrashSphereSound(j-1); + sound = pObj->GetCrashSphereSound(j-1); if ( sound != SOUND_CLICK ) { force = fabs(m_linMotion.realSpeed.x); - force *= pObj->RetCrashSphereHardness(j-1)*2.0f; + force *= pObj->GetCrashSphereHardness(j-1)*2.0f; if ( ExploOther(iType, pObj, oType, force) ) continue; colType = ExploHimself(iType, oType, force); if ( colType == 2 ) return 2; // destroyed? @@ -2632,16 +2621,16 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) } force = m_linMotion.realSpeed.Length(); - force *= pObj->RetCrashSphereHardness(j-1); + force *= pObj->GetCrashSphereHardness(j-1); volume = fabs(force*0.05f); if ( volume > 1.0f ) volume = 1.0f; if ( sound != SOUND_CLICK ) { - m_sound->Play(sound, m_object->RetPosition(0), volume); + m_sound->Play(sound, m_object->GetPosition(0), volume); } if ( iType == OBJECT_HUMAN && volume > 0.5f ) { - m_sound->Play(SOUND_AIE, m_object->RetPosition(0), volume); + m_sound->Play(SOUND_AIE, m_object->GetPosition(0), volume); } if ( m_repeatCollision > 0 ) @@ -2663,14 +2652,14 @@ int CPhysics::ObjectAdapt(const Math::Vector &pos, const Math::Vector &angle) m_linMotion.currentSpeed.y = 0.0f; } - ph = pObj->RetPhysics(); + ph = pObj->GetPhysics(); if ( ph != 0 ) { - oAngle = pObj->RetAngle(0); + oAngle = pObj->GetAngle(0); oSpeed = Normalize(oPos-iPos)*force; Math::LoadRotationXZYMatrix(matRotate, -oAngle); oSpeed = Transform(matRotate, oSpeed); - if ( ph->RetType() == TYPE_ROLLING ) + if ( ph->GetType() == TYPE_ROLLING ) { oSpeed.y = 0.0f; } @@ -2737,7 +2726,7 @@ bool CPhysics::JostleObject(CObject* pObj, float force) if ( m_soundTimeJostle >= 0.20f ) { m_soundTimeJostle = 0.0f; - m_sound->Play(SOUND_JOSTLE, pObj->RetPosition(0), force); + m_sound->Play(SOUND_JOSTLE, pObj->GetPosition(0), force); } return pObj->JostleObject(force); @@ -2749,9 +2738,9 @@ bool CPhysics::JostleObject(CObject* pObj, float force) bool CPhysics::ExploOther(ObjectType iType, CObject *pObj, ObjectType oType, float force) { - CPyro* pyro; + Gfx::CPyro* pyro; - if ( !pObj->RetEnable() ) return true; + if ( !pObj->GetEnable() ) return true; JostleObject(pObj, 1.0f); // shakes the object @@ -2759,24 +2748,24 @@ bool CPhysics::ExploOther(ObjectType iType, (oType == OBJECT_FRET || oType == OBJECT_METAL ) ) { - pyro = new CPyro(m_iMan); - pyro->Create(PT_EXPLOT, pObj); // total destruction + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_EXPLOT, pObj); // total destruction } if ( force > 50.0f && (oType == OBJECT_POWER || oType == OBJECT_ATOMIC ) ) { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_FRAGT, pObj); // total destruction } if ( force > 25.0f && (oType == OBJECT_STONE || oType == OBJECT_URANIUM ) ) { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_FRAGT, pObj); // total destruction } if ( force > 25.0f && @@ -2836,15 +2825,15 @@ bool CPhysics::ExploOther(ObjectType iType, (oType == OBJECT_MOBILEtg || oType == OBJECT_TNT ) ) { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_FRAGT, pObj); // total destruction } if ( force > 0.0f && oType == OBJECT_BOMB ) { - pyro = new CPyro(m_iMan); - pyro->Create(PT_FRAGT, pObj); // total destruction + pyro = new Gfx::CPyro(m_iMan); + pyro->Create(Gfx::PT_FRAGT, pObj); // total destruction } return false; @@ -2857,16 +2846,16 @@ bool CPhysics::ExploOther(ObjectType iType, int CPhysics::ExploHimself(ObjectType iType, ObjectType oType, float force) { - PyroType type; - CPyro* pyro; + Gfx::PyroType type; + Gfx::CPyro* pyro; if ( force > 10.0f && (oType == OBJECT_TNT || oType == OBJECT_MOBILEtg ) ) { - if ( iType == OBJECT_HUMAN ) type = PT_DEADG; - else type = PT_EXPLOT; - pyro = new CPyro(m_iMan); + if ( iType == OBJECT_HUMAN ) type = Gfx::PT_DEADG; + else type = Gfx::PT_EXPLOT; + pyro = new Gfx::CPyro(m_iMan); pyro->Create(type, m_object); // total destruction return 2; } @@ -2876,19 +2865,19 @@ int CPhysics::ExploHimself(ObjectType iType, ObjectType oType, float force) { if ( iType == OBJECT_HUMAN ) { - type = PT_DEADG; + type = Gfx::PT_DEADG; } else if ( iType == OBJECT_ANT || iType == OBJECT_SPIDER || iType == OBJECT_BEE ) { - type = PT_EXPLOO; + type = Gfx::PT_EXPLOO; } else { - type = PT_EXPLOT; + type = Gfx::PT_EXPLOT; } - pyro = new CPyro(m_iMan); + pyro = new Gfx::CPyro(m_iMan); pyro->Create(type, m_object); // total destruction return 2; } @@ -2980,7 +2969,7 @@ int CPhysics::ExploHimself(ObjectType iType, ObjectType oType, float force) // Makes the particles evolve. -void CPhysics::FrameParticule(float aTime, float rTime) +void CPhysics::FrameParticle(float aTime, float rTime) { Math::Vector pos; CObject* power; @@ -2988,61 +2977,61 @@ void CPhysics::FrameParticule(float aTime, float rTime) int effectLight; bool bFlash; - m_restBreakParticule -= rTime; - if ( aTime-m_lastPowerParticule < m_engine->ParticuleAdapt(0.05f) ) return; - m_lastPowerParticule = aTime; + m_restBreakParticle -= rTime; + if ( aTime-m_lastPowerParticle < m_engine->ParticleAdapt(0.05f) ) return; + m_lastPowerParticle = aTime; bFlash = false; energy = 0.0f; - power = m_object->RetPower(); + power = m_object->GetPower(); if ( power != 0 ) { - energy = power->RetEnergy(); + energy = power->GetEnergy(); } if ( energy != m_lastEnergy ) // change the energy level? { if ( energy > m_lastEnergy ) // recharge? { - PowerParticule(1.0f, false); + PowerParticle(1.0f, false); bFlash = true; } if ( energy == 0.0f || m_lastEnergy == 0.0f ) { - m_restBreakParticule = 2.5f; // particles for 2.5s + m_restBreakParticle = 2.5f; // particles for 2.5s } m_lastEnergy = energy; } - if ( m_restBreakParticule > 0.0f ) + if ( m_restBreakParticle > 0.0f ) { - PowerParticule(m_restBreakParticule/2.5f, (energy == 0)); + PowerParticle(m_restBreakParticle/2.5f, (energy == 0)); bFlash = true; } - effectLight = m_object->RetEffectLight(); + effectLight = m_object->GetEffectLight(); if ( effectLight != -1 ) { if ( bFlash ) { intensity = 0.0f; if ( Math::Rand() < 0.5f ) intensity = 1.0f; - m_light->SetLightIntensity(effectLight, intensity); - m_light->SetLightIntensitySpeed(effectLight, 10000.0f); + m_lightMan->SetLightIntensity(effectLight, intensity); + m_lightMan->SetLightIntensitySpeed(effectLight, 10000.0f); } else { - m_light->SetLightIntensity(effectLight, 0.0f); + m_lightMan->SetLightIntensity(effectLight, 0.0f); } } } // Generates some particles after a recharge. -void CPhysics::PowerParticule(float factor, bool bBreak) +void CPhysics::PowerParticle(float factor, bool bBreak) { Character* character; CObject* fret; @@ -3052,15 +3041,15 @@ void CPhysics::PowerParticule(float factor, bool bBreak) bool bCarryPower; bCarryPower = false; - fret = m_object->RetFret(); - if ( fret != 0 && fret->RetType() == OBJECT_POWER && - m_object->RetAngleZ(1) == ARM_STOCK_ANGLE1 ) + fret = m_object->GetFret(); + if ( fret != 0 && fret->GetType() == OBJECT_POWER && + m_object->GetAngleZ(1) == ARM_STOCK_ANGLE1 ) { bCarryPower = true; // carries a battery } - mat = m_object->RetWorldMatrix(0); - character = m_object->RetCharacter(); + mat = m_object->GetWorldMatrix(0); + character = m_object->GetCharacter(); pos = character->posPower; pos.x -= 0.3f; @@ -3078,7 +3067,7 @@ void CPhysics::PowerParticule(float factor, bool bBreak) dim.x = 1.0f*factor; dim.y = 1.0f*factor; - m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTIBLITZ, 0.5f, 0.0f, 0.0f); if ( bCarryPower ) // carry a battery? { @@ -3096,27 +3085,27 @@ void CPhysics::PowerParticule(float factor, bool bBreak) dim.x = 1.0f*factor; dim.y = 1.0f*factor; - m_particule->CreateParticule(ppos, speed, dim, PARTIBLITZ, 0.5f, 0.0f, 0.0f); + m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTIBLITZ, 0.5f, 0.0f, 0.0f); } } // Generates some particles after a fall. // crash: 0=super soft, 1=big crash -void CPhysics::CrashParticule(float crash) +void CPhysics::CrashParticle(float crash) { Math::Vector pos, ppos, speed; Math::Point dim; - float len; - int i, max; + float len; + int i, max; if ( crash < 0.2f ) return; - pos = m_object->RetPosition(0); - m_camera->StartEffect(CE_CRASH, pos, crash); + pos = m_object->GetPosition(0); + m_camera->StartEffect(Gfx::CAM_EFFECT_CRASH, pos, crash); //? max = (int)(crash*50.0f); - max = (int)(crash*10.0f*m_engine->RetParticuleDensity()); + max = static_cast<int>(crash*10.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<max ; i++ ) { @@ -3130,13 +3119,13 @@ void CPhysics::CrashParticule(float crash) speed.y = -2.0f; dim.x = 2.0f+crash*5.0f*len; dim.y = dim.x; - m_particule->CreateParticule(ppos, speed, dim, PARTICRASH, 2.0f); + m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTICRASH, 2.0f); } } // Generates some exhaust gas particle. -void CPhysics::MotorParticule(float aTime, float rTime) +void CPhysics::MotorParticle(float aTime, float rTime) { Math::Matrix* mat; Math::Vector pos, speed; @@ -3146,9 +3135,9 @@ void CPhysics::MotorParticule(float aTime, float rTime) float h, a, delay, level; int r, i, nb; - if ( m_object->RetToy() ) return; + if ( m_object->GetToy() ) return; - type = m_object->RetType(); + type = m_object->GetType(); if ( type == OBJECT_MOBILEia || type == OBJECT_MOBILEic || @@ -3166,14 +3155,14 @@ void CPhysics::MotorParticule(float aTime, float rTime) else delay = 8.0f; if ( m_bSwim && m_timeUnderWater < delay ) // bubbles when entering water? { - if ( aTime-m_lastUnderParticule >= m_engine->ParticuleAdapt(0.05f) ) + if ( aTime-m_lastUnderParticle >= m_engine->ParticleAdapt(0.05f) ) { - m_lastUnderParticule = aTime; + m_lastUnderParticle = aTime; - nb = (int)(20.0f-(20.0f/delay)*m_timeUnderWater); + nb = static_cast<int>(20.0f-(20.0f/delay)*m_timeUnderWater); for ( i=0 ; i<nb ; i++ ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.x += (Math::Rand()-0.5f)*4.0f; pos.y += (Math::Rand()-0.5f)*4.0f; pos.z += (Math::Rand()-0.5f)*4.0f; @@ -3182,13 +3171,13 @@ void CPhysics::MotorParticule(float aTime, float rTime) speed.z = (Math::Rand()-0.5f)*0.2f; dim.x = 0.06f+Math::Rand()*0.10f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBUBBLE, 3.0f, 0.0f, 0.0f); } } } - level = m_water->RetLevel(); - pos = m_object->RetPosition(0); + level = m_water->GetLevel(); + pos = m_object->GetPosition(0); if ( type == OBJECT_HUMAN ) pos.y -= 2.0f; if ( pos.y < level ) // underwater? { @@ -3203,16 +3192,16 @@ void CPhysics::MotorParticule(float aTime, float rTime) if ( pos.y >= level && m_absorbWater > 0.0f && - !m_water->RetLava() ) // drops on leaving the water? + !m_water->GetLava() ) // drops on leaving the water? { - if ( aTime-m_lastUnderParticule >= m_engine->ParticuleAdapt(0.05f) ) + if ( aTime-m_lastUnderParticle >= m_engine->ParticleAdapt(0.05f) ) { - m_lastUnderParticule = aTime; + m_lastUnderParticle = aTime; - nb = (int)(8.0f*m_absorbWater); + nb = static_cast<int>(8.0f*m_absorbWater); for ( i=0 ; i<nb ; i++ ) { - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); if ( type == OBJECT_HUMAN ) pos.y -= Math::Rand()*2.0f; else pos.y += Math::Rand()*2.0f; pos.x += (Math::Rand()-0.5f)*2.0f; @@ -3222,7 +3211,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) speed.z = 0.0f; dim.x = 0.2f; dim.y = 0.2f; - m_particule->CreateParticule(pos, speed, dim, PARTIWATER, 2.0f, 0.0f, 1.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIWATER, 2.0f, 0.0f, 1.0f); } } } @@ -3231,18 +3220,18 @@ void CPhysics::MotorParticule(float aTime, float rTime) type == OBJECT_TECH ) { if ( m_bLand && - aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) + aTime-m_lastSlideParticle >= m_engine->ParticleAdapt(0.05f) ) { h = Math::Max(fabs(m_linMotion.terrainSpeed.x), fabs(m_linMotion.terrainSpeed.z)); if ( h > m_linMotion.terrainSlide.x+0.5f && m_linMotion.motorSpeed.x == 0.0f ) // slides a stop? { - m_lastSlideParticule = aTime; + m_lastSlideParticle = aTime; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos.x = (Math::Rand()-0.5f)*1.0f; - pos.y = -m_object->RetCharacter()->height; + pos.y = -m_object->GetCharacter()->height; pos.z = Math::Rand()*0.4f+1.0f; if ( rand()%2 == 0 ) pos.z = -pos.z; pos = Transform(*mat, pos); @@ -3250,7 +3239,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = Math::Rand()*(h-5.0f)/2.0f+1.0f; if ( dim.x > 2.5f ) dim.x = 2.5f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 0.2f); } } } @@ -3260,14 +3249,14 @@ void CPhysics::MotorParticule(float aTime, float rTime) type == OBJECT_MOBILEti || type == OBJECT_MOBILEts ) // caterpillars? { - if ( aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) + if ( aTime-m_lastSlideParticle >= m_engine->ParticleAdapt(0.05f) ) { h = fabs(m_linMotion.motorSpeed.x-m_linMotion.realSpeed.x); if ( h > 5.0f ) { - m_lastSlideParticule = aTime; + m_lastSlideParticle = aTime; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos.x = (Math::Rand()-0.5f)*8.0f; pos.y = 0.0f; pos.z = Math::Rand()*2.0f+3.0f; @@ -3277,7 +3266,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = Math::Rand()*(h-5.0f)/2.0f+1.0f; if ( dim.x > 3.0f ) dim.x = 3.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 0.2f); } } } @@ -3287,14 +3276,14 @@ void CPhysics::MotorParticule(float aTime, float rTime) type == OBJECT_MOBILErr || type == OBJECT_MOBILErs ) // large caterpillars? { - if ( aTime-m_lastSlideParticule >= m_engine->ParticuleAdapt(0.05f) ) + if ( aTime-m_lastSlideParticle >= m_engine->ParticleAdapt(0.05f) ) { h = fabs(m_linMotion.motorSpeed.x-m_linMotion.realSpeed.x); if ( h > 5.0f ) { - m_lastSlideParticule = aTime; + m_lastSlideParticle = aTime; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos.x = (Math::Rand()-0.5f)*9.0f; pos.y = 0.0f; pos.z = Math::Rand()*3.0f+3.0f; @@ -3304,7 +3293,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = Math::Rand()*(h-5.0f)/2.0f+1.0f; if ( dim.x > 3.0f ) dim.x = 3.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.2f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 0.2f); } } } @@ -3323,11 +3312,11 @@ void CPhysics::MotorParticule(float aTime, float rTime) } if ( m_reactorTemperature == 0.0f || - aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.05f) ) return; - m_lastMotorParticule = aTime; + aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.05f) ) return; + m_lastMotorParticle = aTime; pos = Math::Vector(-1.6f, -0.5f, 0.0f); - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed.x = (Math::Rand()-0.5f)*0.6f; @@ -3337,7 +3326,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = (1.0f+Math::Rand()*0.5f)*(0.2f+m_reactorTemperature*0.8f); dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTISMOKE2, 3.0f, 0.0f, 0.1f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE2, 3.0f, 0.0f, 0.1f); } else // in flight? { @@ -3352,14 +3341,14 @@ void CPhysics::MotorParticule(float aTime, float rTime) } } - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.02f) ) return; + m_lastMotorParticle = aTime; pos = Math::Vector(-1.6f, -1.0f, 0.0f); pos.x += (Math::Rand()-0.5f)*3.0f; pos.y += (Math::Rand()-0.5f)*1.5f; pos.z += (Math::Rand()-0.5f)*3.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); h = m_floorHeight; @@ -3377,7 +3366,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = 0.12f; dim.y = 0.12f; - m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, 2.0f, 10.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISCRAPS, 2.0f, 10.0f); #if 1 pos = Math::Vector(-1.6f, -0.5f, 0.0f); @@ -3396,7 +3385,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) { speed.y += m_linMotion.realSpeed.y*1.2f; } - a = m_object->RetAngleY(0); + a = m_object->GetAngleY(0); p.x = speed.x; p.y = speed.z; p = Math::RotatePoint(-a, p); @@ -3406,7 +3395,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = 0.4f+Math::Rand()*0.2f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIEJECT, 0.3f, 10.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIEJECT, 0.3f, 10.0f); #endif } } @@ -3431,8 +3420,8 @@ void CPhysics::MotorParticule(float aTime, float rTime) if ( h < 3.0f ) return; - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.2f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.2f) ) return; + m_lastMotorParticle = aTime; r = rand()%3; if ( r == 0 ) pos = Math::Vector(-3.0f, 0.0f, -4.0f); @@ -3441,20 +3430,20 @@ void CPhysics::MotorParticule(float aTime, float rTime) pos.x += (Math::Rand()-0.5f)*2.0f; pos.z += (Math::Rand()-0.5f)*2.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = Math::Rand()*h/5.0f+2.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f); } else // glide with small reactors in skates? { if ( m_linMotion.realSpeed.x == 0.0f && m_cirMotion.realSpeed.y == 0.0f ) return; - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.02f) ) return; + m_lastMotorParticle = aTime; r = rand()%3; if ( r == 0 ) pos = Math::Vector(-3.0f, 0.0f, -4.0f); @@ -3463,26 +3452,26 @@ void CPhysics::MotorParticule(float aTime, float rTime) pos.x += (Math::Rand()-0.5f)*1.0f; pos.z += (Math::Rand()-0.5f)*1.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed = Math::Vector(0.0f, 0.0f, 0.0f); dim.x = 1.0f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIEJECT); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIEJECT); } } else // in flight? { if ( !m_bMotor || m_reactorRange == 0.0f ) return; - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.02f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.02f) ) return; + m_lastMotorParticle = aTime; pos = Math::Vector(0.0f, -1.0f, 0.0f); pos.x += (Math::Rand()-0.5f)*6.0f; pos.y += (Math::Rand()-0.5f)*3.0f; pos.z += (Math::Rand()-0.5f)*6.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); h = m_floorHeight; @@ -3500,7 +3489,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = 0.2f; dim.y = 0.2f; - m_particule->CreateParticule(pos, speed, dim, PARTISCRAPS, 2.0f, 10.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISCRAPS, 2.0f, 10.0f); #if 1 pos = Math::Vector(0.0f, 1.0f, 0.0f); @@ -3519,7 +3508,7 @@ void CPhysics::MotorParticule(float aTime, float rTime) { speed.y += m_linMotion.realSpeed.y*1.2f; } - a = m_object->RetAngleY(0); + a = m_object->GetAngleY(0); p.x = speed.x; p.y = speed.z; p = Math::RotatePoint(-a, p); @@ -3529,23 +3518,23 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = 0.7f+Math::Rand()*0.6f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIEJECT, 0.5f, 10.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIEJECT, 0.5f, 10.0f); #endif } } if ( (type == OBJECT_HUMAN || type == OBJECT_TECH) && m_bSwim ) { - if ( !m_object->RetDead() ) + if ( !m_object->GetDead() ) { h = Math::Mod(aTime, 5.0f); if ( h < 3.5f && ( h < 1.5f || h > 1.6f ) ) return; } - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.06f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.06f) ) return; + m_lastMotorParticle = aTime; pos = Math::Vector(0.0f, 3.0f, 0.0f); - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); pos.x += (Math::Rand()-0.5f)*1.0f; pos.z += (Math::Rand()-0.5f)*1.0f; @@ -3554,12 +3543,12 @@ void CPhysics::MotorParticule(float aTime, float rTime) speed.z = (Math::Rand()-0.5f)*0.2f; dim.x = 0.2f; dim.y = 0.2f; - m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBUBBLE, 3.0f, 0.0f, 0.0f); if ( aTime-m_lastSoundWater > 1.5f ) { m_lastSoundWater = aTime; - m_sound->Play(SOUND_BLUP, m_object->RetPosition(0), 0.5f+Math::Rand()*0.5f); + m_sound->Play(SOUND_BLUP, m_object->GetPosition(0), 0.5f+Math::Rand()*0.5f); } } @@ -3567,11 +3556,11 @@ void CPhysics::MotorParticule(float aTime, float rTime) { h = Math::Mod(aTime, 3.0f); if ( h < 1.5f && ( h < 0.5f || h > 0.9f ) ) return; - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.06f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.06f) ) return; + m_lastMotorParticle = aTime; pos = Math::Vector(0.0f, 3.0f, 0.0f); - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); pos.x += (Math::Rand()-0.5f)*1.0f; pos.z += (Math::Rand()-0.5f)*1.0f; @@ -3580,12 +3569,12 @@ void CPhysics::MotorParticule(float aTime, float rTime) speed.z = (Math::Rand()-0.5f)*0.2f; dim.x = 0.2f; dim.y = 0.2f; - m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBUBBLE, 3.0f, 0.0f, 0.0f); if ( aTime-m_lastSoundWater > 1.5f ) { m_lastSoundWater = aTime; - m_sound->Play(SOUND_BLUP, m_object->RetPosition(0), 0.5f+Math::Rand()*0.5f); + m_sound->Play(SOUND_BLUP, m_object->GetPosition(0), 0.5f+Math::Rand()*0.5f); } } @@ -3600,13 +3589,13 @@ void CPhysics::MotorParticule(float aTime, float rTime) { if ( !m_bMotor ) return; - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.1f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.1f) ) return; + m_lastMotorParticle = aTime; pos = Math::Vector(-2.5f, 10.3f, -1.3f); pos.x += (Math::Rand()-0.5f)*1.0f; pos.z += (Math::Rand()-0.5f)*1.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed.x = (Math::Rand()-0.5f)*2.0f; @@ -3616,14 +3605,14 @@ void CPhysics::MotorParticule(float aTime, float rTime) dim.x = Math::Rand()*0.6f+0.4f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIMOTOR, 2.0f); } else { if ( !m_bMotor ) return; - if ( aTime-m_lastMotorParticule < m_engine->ParticuleAdapt(0.05f) ) return; - m_lastMotorParticule = aTime; + if ( aTime-m_lastMotorParticle < m_engine->ParticleAdapt(0.05f) ) return; + m_lastMotorParticle = aTime; pos = Math::Vector(-3.4f, 1.8f, 0.5f); @@ -3643,21 +3632,21 @@ void CPhysics::MotorParticule(float aTime, float rTime) speed.y -= 0.5f+Math::Rand()*2.0f; speed.z += (Math::Rand()-0.5f)*3.0f; - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); pos = Transform(*mat, pos); speed = Transform(*mat, speed)-pos; dim.x = Math::Rand()*0.4f+0.3f; dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIMOTOR, 2.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIMOTOR, 2.0f); } } } // Generates some particles after falling into the water. -void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, +void CPhysics::WaterParticle(float aTime, Math::Vector pos, ObjectType type, float floor, float advance, float turn) { Math::Vector ppos, speed; @@ -3665,7 +3654,7 @@ void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, float delay, level, min, max, force, volume, diam; int i, nb; - level = m_water->RetLevel(); + level = m_water->GetLevel(); if ( floor >= level ) return; if ( type == OBJECT_HUMAN || @@ -3684,9 +3673,9 @@ void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, // Management of the particle "splash". if ( m_linMotion.realSpeed.y < -10.0f && - aTime-m_lastPloufParticule >= 1.0f ) + aTime-m_lastPloufParticle >= 1.0f ) { - m_lastPloufParticule = aTime; + m_lastPloufParticle = aTime; force = -m_linMotion.realSpeed.y/20.0f; // power according to speed drops if ( type == OBJECT_HUMAN || @@ -3700,14 +3689,14 @@ void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, force *= 1.3f; // a robot is heavier } - pos = m_object->RetPosition(0); - pos.y = m_water->RetLevel()-1.0f; + pos = m_object->GetPosition(0); + pos.y = m_water->GetLevel()-1.0f; dim.x = 2.0f*force; // height dim.y = diam; // diameter - m_particule->CreateParticule(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, PARTIPLOUF0, 1.4f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, Math::Vector(0.0f, 0.0f, 0.0f), dim, Gfx::PARTIPLOUF0, 1.4f, 0.0f, 0.0f); force = (0.5f+force*0.5f); - nb = (int)(force*50.0f*m_engine->RetParticuleDensity()); + nb = static_cast<int>(force*50.0f*m_engine->GetParticleDensity()); for ( i=0 ; i<nb ; i++ ) { ppos = pos; @@ -3719,7 +3708,7 @@ void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, speed.y = 6.0f+Math::Rand()*6.0f*force; dim.x = 0.5f; dim.y = dim.x; - m_particule->CreateParticule(ppos, speed, dim, PARTIDROP, 2.0f, 20.0f, 0.2f); + m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTIDROP, 2.0f, 20.0f, 0.2f); } volume = fabs(m_linMotion.realSpeed.y*0.02f); @@ -3728,7 +3717,7 @@ void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, } // Management particles "cop". - if ( m_water->RetLava() ) return; + if ( m_water->GetLava() ) return; if ( advance == 0.0f && turn == 0.0f ) { @@ -3743,15 +3732,15 @@ void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, { delay = 0.06f; } - m_engine->ParticuleAdapt(delay); + m_engine->ParticleAdapt(delay); - if ( aTime-m_lastWaterParticule < delay ) return; - m_lastWaterParticule = aTime; + if ( aTime-m_lastWaterParticle < delay ) return; + m_lastWaterParticle = aTime; force = (advance+turn)*0.16f; if ( force < 0.001f ) return; - pos = m_object->RetPosition(0); + pos = m_object->GetPosition(0); pos.y = level+0.1f; if ( advance == 0 ) { @@ -3768,29 +3757,27 @@ void CPhysics::WaterParticule(float aTime, Math::Vector pos, ObjectType type, speed.z = 0.0f; dim.x = Math::Min(Math::Rand()*force+force+1.0f, 10.0f); dim.y = dim.x; - m_particule->CreateParticule(pos, speed, dim, PARTIFLIC, 3.0f, 0.0f, 0.0f); + m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIFLIC, 3.0f, 0.0f, 0.0f); } // Creates the trace under the robot. -void CPhysics::WheelParticule(int color, float width) +void CPhysics::WheelParticle(int color, float width) { - Character* character; Math::Matrix* mat; Math::Vector goal1, goal2, wheel1, wheel2; - ParticuleType parti; - float dist1, dist2, step; + Gfx::ParticleType parti; + float dist1, dist2, step; - character = m_object->RetCharacter(); - mat = m_object->RetWorldMatrix(0); + mat = m_object->GetWorldMatrix(0); // Draw a trace on the ground. if ( color >= 0 && color <= 17 ) { - parti = (ParticuleType)(PARTITRACE0+color); + parti = static_cast<Gfx::ParticleType>(Gfx::PARTITRACE0+color); step = 2.0f; if ( color >= 16 ) step = 4.0f; // arrow? - step /= m_engine->RetTracePrecision(); + step /= m_engine->GetTracePrecision(); goal1.x = step/2.0f; goal1.y = 0.0f; @@ -3802,36 +3789,36 @@ void CPhysics::WheelParticule(int color, float width) goal2.z = width/2.0f; goal2 = Transform(*mat, goal2); - if ( !m_bWheelParticuleBrake ) + if ( !m_bWheelParticleBrake ) { - m_wheelParticulePos[0] = goal1; - m_wheelParticulePos[1] = goal2; + m_wheelParticlePos[0] = goal1; + m_wheelParticlePos[1] = goal2; } while ( true ) { - dist1 = Math::Distance(m_wheelParticulePos[0], goal1); + dist1 = Math::Distance(m_wheelParticlePos[0], goal1); if ( dist1 < step ) break; - dist2 = Math::Distance(m_wheelParticulePos[1], goal2); - wheel1 = Math::SegmentPoint(m_wheelParticulePos[0], goal1, step); - wheel2 = Math::SegmentPoint(m_wheelParticulePos[1], goal2, step*dist2/dist1); + dist2 = Math::Distance(m_wheelParticlePos[1], goal2); + wheel1 = Math::SegmentPoint(m_wheelParticlePos[0], goal1, step); + wheel2 = Math::SegmentPoint(m_wheelParticlePos[1], goal2, step*dist2/dist1); if ( m_linMotion.realSpeed.x >= 0.0f ) { - m_particule->CreateWheelTrace(m_wheelParticulePos[0], m_wheelParticulePos[1], wheel1, wheel2, parti); + m_particle->CreateWheelTrace(m_wheelParticlePos[0], m_wheelParticlePos[1], wheel1, wheel2, parti); } else { - m_particule->CreateWheelTrace(m_wheelParticulePos[1], m_wheelParticulePos[0], wheel2, wheel1, parti); + m_particle->CreateWheelTrace(m_wheelParticlePos[1], m_wheelParticlePos[0], wheel2, wheel1, parti); } - m_wheelParticulePos[0] = wheel1; - m_wheelParticulePos[1] = wheel2; + m_wheelParticlePos[0] = wheel1; + m_wheelParticlePos[1] = wheel2; } - m_bWheelParticuleBrake = true; + m_bWheelParticleBrake = true; } else { - m_bWheelParticuleBrake = false; + m_bWheelParticleBrake = false; } } @@ -3849,12 +3836,12 @@ void CPhysics::CreateInterface(bool bSelect) // Returns an error related to the general state. -Error CPhysics::RetError() +Error CPhysics::GetError() { ObjectType type; CObject* power; - type = m_object->RetType(); + type = m_object->GetType(); if ( type == OBJECT_HUMAN || type == OBJECT_TECH || type == OBJECT_MOTHER || @@ -3865,19 +3852,19 @@ Error CPhysics::RetError() type == OBJECT_APOLLO2 || type == OBJECT_MOBILEdr ) return ERR_OK; - if ( m_brain != 0 && m_brain->RetActiveVirus() ) + if ( m_brain != 0 && m_brain->GetActiveVirus() ) { return ERR_VEH_VIRUS; } - power = m_object->RetPower(); // searches for the object battery used + power = m_object->GetPower(); // searches for the object battery used if ( power == 0 ) { return ERR_VEH_POWER; } else { - if ( power->RetEnergy() == 0.0f ) return ERR_VEH_ENERGY; + if ( power->GetEnergy() == 0.0f ) return ERR_VEH_ENERGY; } return ERR_OK; diff --git a/src/physics/physics.h b/src/physics/physics.h index 2e1f5eb..79d28e4 100644 --- a/src/physics/physics.h +++ b/src/physics/physics.h @@ -1,5 +1,6 @@ // * This file is part of the COLOBOT source code // * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * Copyright (C) 2012, Polish Portal of Colobot (PPC) // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -14,10 +15,14 @@ // * You should have received a copy of the GNU General Public License // * along with this program. If not, see http://www.gnu.org/licenses/. -// physics.h - #pragma once +/** + * \file physics/physics.h + * \brief Responsible for physics "and more" in game + */ + + #include "common/misc.h" #include "object/object.h" @@ -25,17 +30,17 @@ class CInstanceManager; -class CCamera; class CObject; class CBrain; class CMotion; -class CSound; +class CSoundInterface; namespace Gfx { +class CCamera; class CEngine; class CLight; -class CParticule; +class CParticle; class CTerrain; class CWater; }; @@ -170,7 +175,7 @@ protected: void SoundMotorStop(float rTime, ObjectType type); void SoundReactorFull(float rTime, ObjectType type); void SoundReactorStop(float rTime, ObjectType type); - void FrameParticule(float aTime, float rTime); + void FrameParticle(float aTime, float rTime); void MotorUpdate(float aTime, float rTime); void EffectUpdate(float aTime, float rTime); void UpdateMotionStruct(float rTime, Motion &motion); @@ -182,24 +187,24 @@ protected: bool ExploOther(ObjectType iType, CObject *pObj, ObjectType oType, float force); int ExploHimself(ObjectType iType, ObjectType oType, float force); - void PowerParticule(float factor, bool bBreak); - void CrashParticule(float crash); - void MotorParticule(float aTime, float rTime); - void WaterParticule(float aTime, Math::Vector pos, ObjectType type, float floor, float advance, float turn); - void WheelParticule(int color, float width); + void PowerParticle(float factor, bool bBreak); + void CrashParticle(float crash); + void MotorParticle(float aTime, float rTime); + void WaterParticle(float aTime, Math::Vector pos, ObjectType type, float floor, float advance, float turn); + void WheelParticle(int color, float width); protected: - CInstanceManager* m_iMan; + CInstanceManager* m_iMan; Gfx::CEngine* m_engine; Gfx::CLightManager* m_lightMan; Gfx::CParticle* m_particle; Gfx::CTerrain* m_terrain; Gfx::CWater* m_water; Gfx::CCamera* m_camera; - CObject* m_object; - CBrain* m_brain; - CMotion* m_motion; - CSound* m_sound; + CObject* m_object; + CBrain* m_brain; + CMotion* m_motion; + CSoundInterface* m_sound; PhysicsType m_type; // TYPE_* float m_gravity; // force of gravity @@ -217,15 +222,15 @@ protected: float m_linVibrationFactor; float m_cirVibrationFactor; float m_inclinaisonFactor; - float m_lastPowerParticule; - float m_lastSlideParticule; - float m_lastMotorParticule; - float m_lastWaterParticule; - float m_lastUnderParticule; - float m_lastPloufParticule; - float m_lastFlameParticule; - bool m_bWheelParticuleBrake; - Math::Vector m_wheelParticulePos[2]; + float m_lastPowerParticle; + float m_lastSlideParticle; + float m_lastMotorParticle; + float m_lastWaterParticle; + float m_lastUnderParticle; + float m_lastPloufParticle; + float m_lastFlameParticle; + bool m_bWheelParticleBrake; + Math::Vector m_wheelParticlePos[2]; float m_absorbWater; float m_reactorTemperature; float m_reactorRange; @@ -234,7 +239,7 @@ protected: float m_lastEnergy; float m_lastSoundWater; float m_lastSoundInsect; - float m_restBreakParticule; + float m_restBreakParticle; float m_floorLevel; // ground level float m_floorHeight; // height above the ground int m_soundChannel; diff --git a/src/script/cbottoken.cpp b/src/script/cbottoken.cpp index 788dba2..4d33bca 100644 --- a/src/script/cbottoken.cpp +++ b/src/script/cbottoken.cpp @@ -15,18 +15,18 @@ // * along with this program. If not, see http://www.gnu.org/licenses/. -#include <windows.h> -#include <stdio.h> -#include <d3d.h> - -#include "common/struct.h" -#include "old/d3dengine.h" -#include "old/d3dmath.h" -#include "common/language.h" -#include "common/global.h" -#include "common/event.h" +// #include <windows.h> +// #include <stdio.h> +// #include <d3d.h> +// +// #include "common/struct.h" +// #include "old/d3dengine.h" +// #include "old/d3dmath.h" +// #include "common/language.h" +// #include "common/global.h" +// #include "common/event.h" #include "object/object.h" -#include "script/cbottoken.h" +// #include "script/cbottoken.h" diff --git a/src/script/cmdtoken.cpp b/src/script/cmdtoken.cpp index 256b580..0b441a4 100644 --- a/src/script/cmdtoken.cpp +++ b/src/script/cmdtoken.cpp @@ -15,20 +15,7 @@ // * along with this program. If not, see http://www.gnu.org/licenses/. -#include <windows.h> -#include <stdio.h> -#include <d3d.h> - -#include "common/struct.h" -#include "old/d3dengine.h" -#include "old/d3dmath.h" -#include "common/language.h" #include "common/global.h" -#include "common/event.h" -#include "old/water.h" -#include "old/pyro.h" -#include "old/camera.h" -#include "object/object.h" #include "script/cmdtoken.h" @@ -48,7 +35,7 @@ char* SkipSpace(char *line) // Checks if a line contains a command. -bool Cmd(char *line, char *token) +bool Cmd(char *line, const char *token) { char* p; @@ -59,7 +46,7 @@ bool Cmd(char *line, char *token) // Seeking an operator. -char* SearchOp(char *line, char *op) +char* SearchOp(char *line, const char *op) { char opeq[50]; char* p; @@ -418,7 +405,7 @@ ObjectType GetTypeObject(char *line, int rank, ObjectType def) // Returns the name of an object type. -char* GetTypeObject(ObjectType type) +const char* GetTypeObject(ObjectType type) { if ( type == OBJECT_PORTICO ) return "Portico"; if ( type == OBJECT_BASE ) return "SpaceShip"; @@ -663,35 +650,35 @@ char* GetTypeObject(ObjectType type) // Returns the type of water. -WaterType GetTypeWater(char *line, int rank, WaterType def) +Gfx::WaterType GetTypeWater(char *line, int rank, Gfx::WaterType def) { char* p; p = SearchArg(line, rank); if ( *p == 0 ) return def; - if ( Cmd(p, "NULL" ) ) return WATER_NULL; - if ( Cmd(p, "TT" ) ) return WATER_TT; - if ( Cmd(p, "TO" ) ) return WATER_TO; - if ( Cmd(p, "CT" ) ) return WATER_CT; - if ( Cmd(p, "CO" ) ) return WATER_CO; + if ( Cmd(p, "NULL" ) ) return Gfx::WATER_NULL; + if ( Cmd(p, "TT" ) ) return Gfx::WATER_TT; + if ( Cmd(p, "TO" ) ) return Gfx::WATER_TO; + if ( Cmd(p, "CT" ) ) return Gfx::WATER_CT; + if ( Cmd(p, "CO" ) ) return Gfx::WATER_CO; return def; } // Returns the type of terrain. -D3DTypeObj GetTypeTerrain(char *line, int rank, D3DTypeObj def) +Gfx::EngineObjectType GetTypeTerrain(char *line, int rank, Gfx::EngineObjectType def) { char* p; p = SearchArg(line, rank); if ( *p == 0 ) return def; - if ( Cmd(p, "Terrain" ) ) return TYPETERRAIN; - if ( Cmd(p, "Object" ) ) return TYPEFIX; - if ( Cmd(p, "Quartz" ) ) return TYPEQUARTZ; - if ( Cmd(p, "Metal" ) ) return TYPEMETAL; + if ( Cmd(p, "Terrain" ) ) return Gfx::ENG_OBJTYPE_TERRAIN; + if ( Cmd(p, "Object" ) ) return Gfx::ENG_OBJTYPE_FIX; + if ( Cmd(p, "Quartz" ) ) return Gfx::ENG_OBJTYPE_QUARTZ; + if ( Cmd(p, "Metal" ) ) return Gfx::ENG_OBJTYPE_METAL; return def; } @@ -753,64 +740,64 @@ int GetResearch(char *line, int rank) // Returns the type of pyrotechnic effect. -PyroType GetPyro(char *line, int rank) +Gfx::PyroType GetPyro(char *line, int rank) { char* p; p = SearchArg(line, rank); - if ( *p == 0 ) return PT_NULL; - - if ( Cmd(p, "FRAGt" ) ) return PT_FRAGT; - if ( Cmd(p, "FRAGo" ) ) return PT_FRAGO; - if ( Cmd(p, "FRAGw" ) ) return PT_FRAGW; - if ( Cmd(p, "EXPLOt" ) ) return PT_EXPLOT; - if ( Cmd(p, "EXPLOo" ) ) return PT_EXPLOO; - if ( Cmd(p, "EXPLOw" ) ) return PT_EXPLOW; - if ( Cmd(p, "SHOTt" ) ) return PT_SHOTT; - if ( Cmd(p, "SHOTh" ) ) return PT_SHOTH; - if ( Cmd(p, "SHOTm" ) ) return PT_SHOTM; - if ( Cmd(p, "SHOTw" ) ) return PT_SHOTW; - if ( Cmd(p, "EGG" ) ) return PT_EGG; - if ( Cmd(p, "BURNt" ) ) return PT_BURNT; - if ( Cmd(p, "BURNo" ) ) return PT_BURNO; - if ( Cmd(p, "SPIDER" ) ) return PT_SPIDER; - if ( Cmd(p, "FALL" ) ) return PT_FALL; - if ( Cmd(p, "RESET" ) ) return PT_RESET; - if ( Cmd(p, "WIN" ) ) return PT_WIN; - if ( Cmd(p, "LOST" ) ) return PT_LOST; - - return PT_NULL; + if ( *p == 0 ) return Gfx::PT_NULL; + + if ( Cmd(p, "FRAGt" ) ) return Gfx::PT_FRAGT; + if ( Cmd(p, "FRAGo" ) ) return Gfx::PT_FRAGO; + if ( Cmd(p, "FRAGw" ) ) return Gfx::PT_FRAGW; + if ( Cmd(p, "EXPLOt" ) ) return Gfx::PT_EXPLOT; + if ( Cmd(p, "EXPLOo" ) ) return Gfx::PT_EXPLOO; + if ( Cmd(p, "EXPLOw" ) ) return Gfx::PT_EXPLOW; + if ( Cmd(p, "SHOTt" ) ) return Gfx::PT_SHOTT; + if ( Cmd(p, "SHOTh" ) ) return Gfx::PT_SHOTH; + if ( Cmd(p, "SHOTm" ) ) return Gfx::PT_SHOTM; + if ( Cmd(p, "SHOTw" ) ) return Gfx::PT_SHOTW; + if ( Cmd(p, "EGG" ) ) return Gfx::PT_EGG; + if ( Cmd(p, "BURNt" ) ) return Gfx::PT_BURNT; + if ( Cmd(p, "BURNo" ) ) return Gfx::PT_BURNO; + if ( Cmd(p, "SPIDER" ) ) return Gfx::PT_SPIDER; + if ( Cmd(p, "FALL" ) ) return Gfx::PT_FALL; + if ( Cmd(p, "RESET" ) ) return Gfx::PT_RESET; + if ( Cmd(p, "WIN" ) ) return Gfx::PT_WIN; + if ( Cmd(p, "LOST" ) ) return Gfx::PT_LOST; + + return Gfx::PT_NULL; } // Returns the type of camera. -CameraType GetCamera(char *line, int rank) +Gfx::CameraType GetCamera(char *line, int rank) { char* p; p = SearchArg(line, rank); - if ( *p == 0 ) return CAMERA_NULL; + if ( *p == 0 ) return Gfx::CAM_TYPE_NULL; - if ( Cmd(p, "BACK" ) ) return CAMERA_BACK; - if ( Cmd(p, "PLANE" ) ) return CAMERA_PLANE; - if ( Cmd(p, "ONBOARD" ) ) return CAMERA_ONBOARD; - if ( Cmd(p, "FIX" ) ) return CAMERA_FIX; + if ( Cmd(p, "BACK" ) ) return Gfx::CAM_TYPE_BACK; + if ( Cmd(p, "PLANE" ) ) return Gfx::CAM_TYPE_PLANE; + if ( Cmd(p, "ONBOARD" ) ) return Gfx::CAM_TYPE_ONBOARD; + if ( Cmd(p, "FIX" ) ) return Gfx::CAM_TYPE_FIX; - return CAMERA_NULL; + return Gfx::CAM_TYPE_NULL; } // Returns the name of a camera. -char* GetCamera(CameraType type) +const char* GetCamera(Gfx::CameraType type) { - if ( type == CAMERA_ONBOARD ) return "ONBOARD"; - if ( type == CAMERA_FIX ) return "FIX"; + if ( type == Gfx::CAM_TYPE_ONBOARD ) return "ONBOARD"; + if ( type == Gfx::CAM_TYPE_FIX ) return "FIX"; return "BACK"; } // Returns an integer. -int OpInt(char *line, char *op, int def) +int OpInt(char *line, const char *op, int def) { line = SearchOp(line, op); if ( *line == 0 ) return def; @@ -819,7 +806,7 @@ int OpInt(char *line, char *op, int def) // Returns a float number. -float OpFloat(char *line, char *op, float def) +float OpFloat(char *line, const char *op, float def) { line = SearchOp(line, op); if ( *line == 0 ) return def; @@ -852,7 +839,7 @@ ObjectType OpTypeObject(char *line, char *op, ObjectType def) // Returns the type of a water. -WaterType OpTypeWater(char *line, char *op, WaterType def) +Gfx::WaterType OpTypeWater(char *line, char *op, Gfx::WaterType def) { line = SearchOp(line, op); if ( *line == 0 ) return def; @@ -861,7 +848,7 @@ WaterType OpTypeWater(char *line, char *op, WaterType def) // Returns the type of a terrain. -D3DTypeObj OpTypeTerrain(char *line, char *op, D3DTypeObj def) +Gfx::EngineObjectType OpTypeTerrain(char *line, char *op, Gfx::EngineObjectType def) { line = SearchOp(line, op); if ( *line == 0 ) return def; @@ -879,19 +866,19 @@ int OpResearch(char *line, char *op) // Returns the type of pyrotechnic effect. -PyroType OpPyro(char *line, char *op) +Gfx::PyroType OpPyro(char *line, char *op) { line = SearchOp(line, op); - if ( *line == 0 ) return PT_NULL; + if ( *line == 0 ) return Gfx::PT_NULL; return GetPyro(line, 0); } // Returns the type of camera. -CameraType OpCamera(char *line, char *op) +Gfx::CameraType OpCamera(char *line, const char *op) { line = SearchOp(line, op); - if ( *line == 0 ) return CAMERA_NULL; + if ( *line == 0 ) return Gfx::CAM_TYPE_NULL; return GetCamera(line, 0); } @@ -924,7 +911,7 @@ Math::Vector OpPos(char *line, char *op) // Returns a direction. -Math::Vector OpDir(char *line, char *op) +Math::Vector OpDir(char *line, const char *op) { Math::Vector dir; @@ -940,28 +927,10 @@ Math::Vector OpDir(char *line, char *op) return dir; } -// Reads a color (0 .. 255). - -D3DCOLOR OpColor(char *line, char *op, D3DCOLOR def) -{ - D3DCOLOR color; - - line = SearchOp(line, op); - if ( *line == 0 ) return def; - - color = 0; - color |= (GetInt(line, 0, 0)&0xff)<<16; // r - color |= (GetInt(line, 1, 0)&0xff)<<8; // g - color |= (GetInt(line, 2, 0)&0xff)<<0; // b - color |= (GetInt(line, 3, 0)&0xff)<<24; // a - return color; -} - // Reads a color (-1 .. 1). - -D3DCOLORVALUE OpColorValue(char *line, char *op, D3DCOLORVALUE def) +Gfx::Color OpColor(char *line, char *op, Gfx::Color def) { - D3DCOLORVALUE color; + Gfx::Color color; line = SearchOp(line, op); if ( *line == 0 ) return def; diff --git a/src/script/cmdtoken.h b/src/script/cmdtoken.h index 05ff758..911bd55 100644 --- a/src/script/cmdtoken.h +++ b/src/script/cmdtoken.h @@ -19,46 +19,44 @@ #pragma once -#include "old/d3denum.h" -#include "old/d3dengine.h" -#include "object/object.h" -#include "old/water.h" -#include "old/pyro.h" -#include "old/camera.h" +// #include "old/d3denum.h" +// #include "old/d3dengine.h" +// #include "object/object.h" +#include "graphics/engine/water.h" +#include "graphics/engine/engine.h" +#include "graphics/engine/pyro.h" // Procedures. -extern bool Cmd(char *line, char *token); -extern char* SearchOp(char *line, char *op); +extern bool Cmd(char *line, const char *token); +extern char* SearchOp(char *line, const char *op); extern int GetInt(char *line, int rank, int def); extern float GetFloat(char *line, int rank, float def); extern void GetString(char *line, int rank, char *buffer); extern ObjectType GetTypeObject(char *line, int rank, ObjectType def); -extern char* GetTypeObject(ObjectType type); -extern WaterType GetTypeWater(char *line, int rank, WaterType def); -extern D3DTypeObj GetTypeTerrain(char *line, int rank, D3DTypeObj def); +extern const char* GetTypeObject(ObjectType type); +extern Gfx::WaterType GetTypeWater(char *line, int rank, Gfx::WaterType def); +extern Gfx::EngineObjectType GetTypeTerrain(char *line, int rank, Gfx::EngineObjectType def); extern int GetBuild(char *line, int rank); extern int GetResearch(char *line, int rank); -extern PyroType GetPyro(char *line, int rank); -extern CameraType GetCamera(char *line, int rank); -extern char* GetCamera(CameraType type); +extern Gfx::PyroType GetPyro(char *line, int rank); +extern Gfx::CameraType GetCamera(char *line, int rank); +extern const char* GetCamera(Gfx::CameraType type); -extern int OpInt(char *line, char *op, int def); -extern float OpFloat(char *line, char *op, float def); +extern int OpInt(char *line, const char *op, int def); +extern float OpFloat(char *line, const char *op, float def); extern void OpString(char *line, char *op, char *buffer); extern ObjectType OpTypeObject(char *line, char *op, ObjectType def); -extern WaterType OpTypeWater(char *line, char *op, WaterType def); -extern D3DTypeObj OpTypeTerrain(char *line, char *op, D3DTypeObj def); +extern Gfx::WaterType OpTypeWater(char *line, char *op, Gfx::WaterType def); +extern Gfx::EngineObjectType OpTypeTerrain(char *line, char *op, Gfx::EngineObjectType def); extern int OpResearch(char *line, char *op); -extern PyroType OpPyro(char *line, char *op); -extern CameraType OpCamera(char *line, char *op); +extern Gfx::PyroType OpPyro(char *line, char *op); +extern Gfx::CameraType OpCamera(char *line, const char *op); extern int OpBuild(char *line, char *op); extern Math::Vector OpPos(char *line, char *op); -extern Math::Vector OpDir(char *line, char *op); -extern D3DCOLOR OpColor(char *line, char *op, D3DCOLOR def); -extern D3DCOLORVALUE OpColorValue(char *line, char *op, D3DCOLORVALUE def); - +extern Math::Vector OpDir(char *line, const char *op); +extern Gfx::Color OpColor(char *line, char *op, Gfx::Color def); diff --git a/src/script/script.cpp b/src/script/script.cpp index d9d6444..cbdbbf4 100644 --- a/src/script/script.cpp +++ b/src/script/script.cpp @@ -17,38 +17,38 @@ // script.cpp -#include <windows.h> +#include "script/script.h" +// #include <windows.h> #include <stdio.h> -#include <d3d.h> - -#include "CBot/CBotDll.h" -#include "common/struct.h" +// #include <d3d.h> +// +#include "math/vector.h" +// #include "common/struct.h" #include "math/geometry.h" -#include "old/d3dengine.h" -#include "old/d3dmath.h" +// #include "old/d3dengine.h" +// #include "old/d3dmath.h" #include "common/global.h" -#include "common/event.h" -#include "common/misc.h" +// #include "common/event.h" +// #include "common/misc.h" #include "common/iman.h" #include "common/restext.h" -#include "old/math3d.h" +// #include "old/math3d.h" #include "object/robotmain.h" -#include "old/terrain.h" -#include "old/water.h" +#include "graphics/engine/terrain.h" +#include "graphics/engine/water.h" +#include "graphics/engine/text.h" #include "object/object.h" #include "physics/physics.h" #include "ui/interface.h" #include "ui/edit.h" #include "ui/list.h" -#include "old/text.h" #include "ui/displaytext.h" #include "object/task/taskmanager.h" -#include "object/task/task.h" -#include "object/task/taskmanip.h" -#include "object/task/taskgoto.h" -#include "object/task/taskshield.h" +// #include "object/task/task.h" +// #include "object/task/taskmanip.h" +// #include "object/task/taskgoto.h" +// #include "object/task/taskshield.h" #include "script/cbottoken.h" -#include "script/script.h" @@ -62,7 +62,7 @@ const int ERM_STOP = 1; // if error -> stop // Compiling a procedure without any parameters. -CBotTypResult cNull(CBotVar* &var, void* user) +CBotTypResult CScript::cNull(CBotVar* &var, void* user) { if ( var != 0 ) return CBotErrOverParam; return CBotTypResult(CBotTypFloat); @@ -70,26 +70,26 @@ CBotTypResult cNull(CBotVar* &var, void* user) // Compiling a procedure with a single real number. -CBotTypResult cOneFloat(CBotVar* &var, void* user) +CBotTypResult CScript::cOneFloat(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); } // Compiling a procedure with two real numbers. -CBotTypResult cTwoFloat(CBotVar* &var, void* user) +CBotTypResult CScript::cTwoFloat(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); @@ -97,26 +97,26 @@ CBotTypResult cTwoFloat(CBotVar* &var, void* user) // Compiling a procedure with a "dot". -CBotTypResult cPoint(CBotVar* &var, void* user) +CBotTypResult CScript::cPoint(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() <= CBotTypDouble ) + if ( var->GetType() <= CBotTypDouble ) { - var = var->GivNext(); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); //? if ( var == 0 ) return CBotTypResult(CBotErrLowParam); -//? if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); -//? var = var->GivNext(); +//? if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); +//? var = var->GetNext(); return CBotTypResult(0); } - if ( var->GivType() == CBotTypClass ) + if ( var->GetType() == CBotTypClass ) { if ( !var->IsElemOfClass("point") ) return CBotTypResult(CBotErrBadParam); - var = var->GivNext(); + var = var->GetNext(); return CBotTypResult(0); } @@ -125,12 +125,12 @@ CBotTypResult cPoint(CBotVar* &var, void* user) // Compiling a procedure with a single "point". -CBotTypResult cOnePoint(CBotVar* &var, void* user) +CBotTypResult CScript::cOnePoint(CBotVar* &var, void* user) { CBotTypResult ret; ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); @@ -138,12 +138,12 @@ CBotTypResult cOnePoint(CBotVar* &var, void* user) // Compiling a procedure with a single string. -CBotTypResult cString(CBotVar* &var, void* user) +CBotTypResult CScript::cString(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString && - var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() != CBotTypString && + var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); } @@ -155,8 +155,8 @@ bool FindList(CBotVar* array, int type) { while ( array != 0 ) { - if ( type == array->GivValInt() ) return true; - array = array->GivNext(); + if ( type == array->GetValInt() ) return true; + array = array->GetNext(); } return false; } @@ -168,40 +168,40 @@ bool GetPoint(CBotVar* &var, int& exception, Math::Vector& pos) { CBotVar *pX, *pY, *pZ; - if ( var->GivType() <= CBotTypDouble ) + if ( var->GetType() <= CBotTypDouble ) { - pos.x = var->GivValFloat()*g_unit; - var = var->GivNext(); + pos.x = var->GetValFloat()*g_unit; + var = var->GetNext(); - pos.z = var->GivValFloat()*g_unit; - var = var->GivNext(); + pos.z = var->GetValFloat()*g_unit; + var = var->GetNext(); pos.y = 0.0f; } else { - pX = var->GivItem("x"); + pX = var->GetItem("x"); if ( pX == NULL ) { exception = CBotErrUndefItem; return true; } - pos.x = pX->GivValFloat()*g_unit; + pos.x = pX->GetValFloat()*g_unit; - pY = var->GivItem("y"); + pY = var->GetItem("y"); if ( pY == NULL ) { exception = CBotErrUndefItem; return true; } - pos.z = pY->GivValFloat()*g_unit; // attention y -> z ! + pos.z = pY->GetValFloat()*g_unit; // attention y -> z ! - pZ = var->GivItem("z"); + pZ = var->GetItem("z"); if ( pZ == NULL ) { exception = CBotErrUndefItem; return true; } - pos.y = pZ->GivValFloat()*g_unit; // attention z -> y ! + pos.y = pZ->GetValFloat()*g_unit; // attention z -> y ! - var = var->GivNext(); + var = var->GetNext(); } return true; } @@ -209,33 +209,33 @@ bool GetPoint(CBotVar* &var, int& exception, Math::Vector& pos) // Instruction "sin(degrees)". -bool rSin(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rSin(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(sinf(value*Math::PI/180.0f)); return true; } // Instruction "cos(degrees)". -bool rCos(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rCos(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(cosf(value*Math::PI/180.0f)); return true; } // Instruction "tan(degrees)". -bool rTan(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rTan(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(tanf(value*Math::PI/180.0f)); return true; } @@ -246,7 +246,7 @@ bool raSin(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(asinf(value)*180.0f/Math::PI); return true; } @@ -257,7 +257,7 @@ bool raCos(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(acosf(value)*180.0f/Math::PI); return true; } @@ -268,38 +268,38 @@ bool raTan(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(atanf(value)*180.0f/Math::PI); return true; } // Instruction "sqrt(value)". -bool rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(sqrtf(value)); return true; } // Instruction "pow(x, y)". -bool rPow(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rPow(CBotVar* var, CBotVar* result, int& exception, void* user) { float x, y; - x = var->GivValFloat(); - var = var->GivNext(); - y = var->GivValFloat(); + x = var->GetValFloat(); + var = var->GetNext(); + y = var->GetValFloat(); result->SetValFloat(powf(x, y)); return true; } // Instruction "rand()". -bool rRand(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rRand(CBotVar* var, CBotVar* result, int& exception, void* user) { result->SetValFloat(Math::Rand()); return true; @@ -307,11 +307,11 @@ bool rRand(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "abs()". -bool rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) { float value; - value = var->GivValFloat(); + value = var->GetValFloat(); result->SetValFloat(fabs(value)); return true; } @@ -319,11 +319,11 @@ bool rAbs(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "retobject(rank)". -CBotTypResult cRetObject(CBotVar* &var, void* user) +CBotTypResult CScript::cGetObject(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypPointer, "object"); @@ -331,22 +331,22 @@ CBotTypResult cRetObject(CBotVar* &var, void* user) // Instruction "retobject(rank)". -bool rRetObject(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rGetObject(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject*>(user))->GetRunScript(); CObject* pObj; int rank; - rank = var->GivValInt(); + rank = var->GetValInt(); - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, rank); + pObj = static_cast<CObject*>(script->m_iMan->SearchInstance(CLASS_OBJECT, rank)); if ( pObj == 0 ) { result->SetPointer(0); } else { - result->SetPointer(pObj->RetBotVar()); + result->SetPointer(pObj->GetBotVar()); } return true; } @@ -354,24 +354,24 @@ bool rRetObject(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "search(type, pos)". -CBotTypResult cSearch(CBotVar* &var, void* user) +CBotTypResult CScript::cSearch(CBotVar* &var, void* user) { CBotVar* array; CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() == CBotTypArrayPointer ) + if ( var->GetType() == CBotTypArrayPointer ) { - array = var->GivItemList(); + array = var->GetItemList(); if ( array == 0 ) return CBotTypResult(CBotTypPointer); - if ( array->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); } - else if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) { ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var != 0 ) return CBotTypResult(CBotErrOverParam); } @@ -380,9 +380,9 @@ CBotTypResult cSearch(CBotVar* &var, void* user) // Instruction "search(type, pos)". -bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); CObject *pObj, *pBest; CBotVar* array; Math::Vector pos, oPos; @@ -391,17 +391,17 @@ bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) float min, dist; int type, oType, i; - if ( var->GivType() == CBotTypArrayPointer ) + if ( var->GetType() == CBotTypArrayPointer ) { - array = var->GivItemList(); + array = var->GetItemList(); bArray = true; } else { - type = var->GivValInt(); + type = var->GetValInt(); bArray = false; } - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { if ( !GetPoint(var, exception, pos) ) return true; @@ -412,13 +412,13 @@ bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) pBest = 0; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(script->m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetActif() ) continue; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType == OBJECT_TOTO ) continue; if ( oType == OBJECT_RUINmobilew2 || @@ -455,7 +455,7 @@ bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) if ( bNearest ) { - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::DistanceProjected(pos, oPos); if ( dist < min ) { @@ -476,7 +476,7 @@ bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) } else { - result->SetPointer(pBest->RetBotVar()); + result->SetPointer(pBest->GetBotVar()); } return true; } @@ -484,47 +484,47 @@ bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of instruction "radar(type, angle, focus, min, max, sens)". -CBotTypResult cRadar(CBotVar* &var, void* user) +CBotTypResult CScript::cRadar(CBotVar* &var, void* user) { CBotVar* array; if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() == CBotTypArrayPointer ) + if ( var->GetType() == CBotTypArrayPointer ) { - array = var->GivItemList(); + array = var->GetItemList(); if ( array == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( array->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type + if ( array->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type } - else if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type - var = var->GivNext(); + else if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // type + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // angle - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // angle + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // focus - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // focus + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // min + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // max + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // sense + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); // filter + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypPointer, "object"); return CBotTypResult(CBotErrOverParam); } // Instruction "radar(type, angle, focus, min, max, sens, filter)". -bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); CObject *pObj, *pBest; CPhysics* physics; CBotVar* array; @@ -544,46 +544,46 @@ bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) if ( var != 0 ) { - if ( var->GivType() == CBotTypArrayPointer ) + if ( var->GetType() == CBotTypArrayPointer ) { - array = var->GivItemList(); + array = var->GetItemList(); bArray = true; } else { - type = var->GivValInt(); + type = var->GetValInt(); bArray = false; } - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - angle = -var->GivValFloat()*Math::PI/180.0f; + angle = -var->GetValFloat()*Math::PI/180.0f; - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - focus = var->GivValFloat()*Math::PI/180.0f; + focus = var->GetValFloat()*Math::PI/180.0f; - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - minDist = var->GivValFloat()*g_unit; + minDist = var->GetValFloat()*g_unit; - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - maxDist = var->GivValFloat()*g_unit; + maxDist = var->GetValFloat()*g_unit; - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - sens = var->GivValFloat(); + sens = var->GetValFloat(); - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - filter = (RadarFilter)var->GivValInt(); + filter = static_cast<RadarFilter>(var->GetValInt()); } } } @@ -592,8 +592,8 @@ bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) } } - iPos = pThis->RetPosition(0); - iAngle = pThis->RetAngleY(0)+angle; + iPos = pThis->GetPosition(0); + iAngle = pThis->GetAngleY(0)+angle; iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI if ( sens >= 0.0f ) best = 100000.0f; @@ -601,15 +601,15 @@ bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) pBest = 0; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(script->m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; if ( pObj == pThis ) continue; - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetActif() ) continue; + if ( pObj->GetProxyActivate() ) continue; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType == OBJECT_TOTO ) continue; if ( oType == OBJECT_RUINmobilew2 || @@ -637,13 +637,13 @@ bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) if ( filter == FILTER_ONLYLANDING ) { - physics = pObj->RetPhysics(); - if ( physics != 0 && !physics->RetLand() ) continue; + physics = pObj->GetPhysics(); + if ( physics != 0 && !physics->GetLand() ) continue; } if ( filter == FILTER_ONLYFLYING ) { - physics = pObj->RetPhysics(); - if ( physics != 0 && physics->RetLand() ) continue; + physics = pObj->GetPhysics(); + if ( physics != 0 && physics->GetLand() ) continue; } if ( bArray ) @@ -655,7 +655,7 @@ bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) if ( type != oType && type != OBJECT_NULL ) continue; } - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); d = Math::DistanceProjected(iPos, oPos); if ( d < minDist || d > maxDist ) continue; // too close or too far? @@ -688,7 +688,7 @@ bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) } else { - result->SetPointer(pBest->RetBotVar()); + result->SetPointer(pBest->GetBotVar()); } return true; } @@ -696,7 +696,7 @@ bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user) // Monitoring a task. -bool Process(CScript* script, CBotVar* result, int &exception) +bool CScript::Process(CScript* script, CBotVar* result, int &exception) { Error err; @@ -726,21 +726,21 @@ bool Process(CScript* script, CBotVar* result, int &exception) // Compilation of the instruction "detect(type)". -CBotTypResult cDetect(CBotVar* &var, void* user) +CBotTypResult CScript::cDetect(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypBoolean); } // Instruction "detect(type)". -bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); CObject *pObj, *pGoal, *pBest; CPhysics* physics; CBotVar* array; @@ -765,20 +765,20 @@ bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) if ( var != 0 ) { - if ( var->GivType() == CBotTypArrayPointer ) + if ( var->GetType() == CBotTypArrayPointer ) { - array = var->GivItemList(); + array = var->GetItemList(); bArray = true; } else { - type = var->GivValInt(); + type = var->GetValInt(); bArray = false; } } - iPos = pThis->RetPosition(0); - iAngle = pThis->RetAngleY(0)+angle; + iPos = pThis->GetPosition(0); + iAngle = pThis->GetAngleY(0)+angle; iAngle = Math::NormAngle(iAngle); // 0..2*Math::PI bGoal = 100000.0f; @@ -788,15 +788,15 @@ bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) pBest = 0; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(script->m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; if ( pObj == pThis ) continue; - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetActif() ) continue; + if ( pObj->GetProxyActivate() ) continue; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType == OBJECT_TOTO ) continue; if ( oType == OBJECT_RUINmobilew2 || @@ -824,13 +824,13 @@ bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) if ( filter == FILTER_ONLYLANDING ) { - physics = pObj->RetPhysics(); - if ( physics != 0 && !physics->RetLand() ) continue; + physics = pObj->GetPhysics(); + if ( physics != 0 && !physics->GetLand() ) continue; } if ( filter == FILTER_ONLYFLYING ) { - physics = pObj->RetPhysics(); - if ( physics != 0 && physics->RetLand() ) continue; + physics = pObj->GetPhysics(); + if ( physics != 0 && physics->GetLand() ) continue; } if ( bArray ) @@ -842,7 +842,7 @@ bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) if ( type != oType && type != OBJECT_NULL ) continue; } - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); d = Math::DistanceProjected(iPos, oPos); a = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! @@ -911,13 +911,13 @@ bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "direction(pos)". -CBotTypResult cDirection(CBotVar* &var, void* user) +CBotTypResult CScript::cDirection(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); @@ -925,18 +925,17 @@ CBotTypResult cDirection(CBotVar* &var, void* user) // Instruction "direction(pos)". -bool rDirection(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rDirection(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CObject* pThis = static_cast<CObject *>(user); Math::Vector iPos, oPos; - float a, g; + float a, g; if ( !GetPoint(var, exception, oPos) ) return true; - iPos = pThis->RetPosition(0); + iPos = pThis->GetPosition(0); - a = pThis->RetAngleY(0); + a = pThis->GetAngleY(0); g = Math::RotateAngle(oPos.x-iPos.x, iPos.z-oPos.z); // CW ! result->SetValFloat(-Math::Direction(a, g)*180.0f/Math::PI); @@ -946,25 +945,25 @@ bool rDirection(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "produce(pos, angle, type, scriptName)". -CBotTypResult cProduce(CBotVar* &var, void* user) +CBotTypResult CScript::cProduce(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); @@ -973,9 +972,9 @@ CBotTypResult cProduce(CBotVar* &var, void* user) // Instruction "produce(pos, angle, type, scriptName)". -bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); CObject* object; CBotString cbs; const char* name; @@ -985,13 +984,13 @@ bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) if ( !GetPoint(var, exception, pos) ) return true; - angle = var->GivValFloat()*Math::PI/180.0f; - var = var->GivNext(); + angle = var->GetValFloat()*Math::PI/180.0f; + var = var->GetNext(); - type = (ObjectType)var->GivValInt(); - var = var->GivNext(); + type = static_cast<ObjectType>(var->GetValInt()); + var = var->GetNext(); - cbs = var->GivValString(); + cbs = var->GetValString(); name = cbs; if ( type == OBJECT_FRET || @@ -1054,7 +1053,7 @@ bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) return true; } object->SetActivity(false); - object->ReadProgram(0, (char*)name); + object->ReadProgram(0, static_cast<const char*>(name)); object->RunProgram(0); result->SetValInt(0); // no error @@ -1064,17 +1063,17 @@ bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "distance(p1, p2)". -CBotTypResult cDistance(CBotVar* &var, void* user) +CBotTypResult CScript::cDistance(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var != 0 ) return CBotTypResult(CBotErrOverParam); @@ -1083,7 +1082,7 @@ CBotTypResult cDistance(CBotVar* &var, void* user) // Instruction "distance(p1, p2)". -bool rDistance(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rDistance(CBotVar* var, CBotVar* result, int& exception, void* user) { Math::Vector p1, p2; float value; @@ -1098,7 +1097,7 @@ bool rDistance(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "distance2d(p1, p2)". -bool rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user) { Math::Vector p1, p2; float value; @@ -1114,25 +1113,25 @@ bool rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "space(center, rMin, rMax, dist)". -CBotTypResult cSpace(CBotVar* &var, void* user) +CBotTypResult CScript::cSpace(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypIntrinsic, "point"); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypIntrinsic, "point"); @@ -1140,10 +1139,10 @@ CBotTypResult cSpace(CBotVar* &var, void* user) // Instruction "space(center, rMin, rMax, dist)". -bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); CBotVar* pSub; Math::Vector center; float rMin, rMax, dist; @@ -1154,7 +1153,7 @@ bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) if ( var == 0 ) { - center = pThis->RetPosition(0); + center = pThis->GetPosition(0); } else { @@ -1162,18 +1161,18 @@ bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) if ( var != 0 ) { - rMin = var->GivValFloat()*g_unit; - var = var->GivNext(); + rMin = var->GetValFloat()*g_unit; + var = var->GetNext(); if ( var != 0 ) { - rMax = var->GivValFloat()*g_unit; - var = var->GivNext(); + rMax = var->GetValFloat()*g_unit; + var = var->GetNext(); if ( var != 0 ) { - dist = var->GivValFloat()*g_unit; - var = var->GivNext(); + dist = var->GetValFloat()*g_unit; + var = var->GetNext(); } } } @@ -1182,13 +1181,13 @@ bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) if ( result != 0 ) { - pSub = result->GivItemList(); + pSub = result->GetItemList(); if ( pSub != 0 ) { pSub->SetValFloat(center.x/g_unit); - pSub = pSub->GivNext(); // "y" + pSub = pSub->GetNext(); // "y" pSub->SetValFloat(center.z/g_unit); - pSub = pSub->GivNext(); // "z" + pSub = pSub->GetNext(); // "z" pSub->SetValFloat(center.y/g_unit); } } @@ -1198,17 +1197,17 @@ bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "flatground(center, rMax)". -CBotTypResult cFlatGround(CBotVar* &var, void* user) +CBotTypResult CScript::cFlatGround(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); @@ -1217,18 +1216,18 @@ CBotTypResult cFlatGround(CBotVar* &var, void* user) // Instruction "flatground(center, rMax)". -bool rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); Math::Vector center; float rMax, dist; if ( !GetPoint(var, exception, center) ) return true; - rMax = var->GivValFloat()*g_unit; - var = var->GivNext(); + rMax = var->GetValFloat()*g_unit; + var = var->GetNext(); - dist = script->m_main->RetFlatZoneRadius(center, rMax, pThis); + dist = script->m_main->GetFlatZoneRadius(center, rMax, pThis); result->SetValFloat(dist/g_unit); return true; @@ -1237,9 +1236,9 @@ bool rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "wait(t)". -bool rWait(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rWait(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); float value; Error err; @@ -1248,7 +1247,7 @@ bool rWait(CBotVar* var, CBotVar* result, int& exception, void* user) if ( script->m_primaryTask == 0 ) // no task in progress? { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); + value = var->GetValFloat(); err = script->m_primaryTask->StartTaskWait(value); if ( err != ERR_OK ) { @@ -1268,9 +1267,9 @@ bool rWait(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "move(dist)". -bool rMove(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rMove(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); float value; Error err; @@ -1279,7 +1278,7 @@ bool rMove(CBotVar* var, CBotVar* result, int& exception, void* user) if ( script->m_primaryTask == 0 ) // no task in progress? { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); + value = var->GetValFloat(); err = script->m_primaryTask->StartTaskAdvance(value*g_unit); if ( err != ERR_OK ) { @@ -1299,9 +1298,9 @@ bool rMove(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "turn(angle)". -bool rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); float value; Error err; @@ -1310,7 +1309,7 @@ bool rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) if ( script->m_primaryTask == 0 ) // no task in progress? { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); + value = var->GetValFloat(); err = script->m_primaryTask->StartTaskTurn(-value*Math::PI/180.0f); if ( err != ERR_OK ) { @@ -1330,25 +1329,25 @@ bool rTurn(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "goto(pos, altitude, crash, goal)". -CBotTypResult cGoto(CBotVar* &var, void* user) +CBotTypResult CScript::cGoto(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + if ( ret.GetType() != 0 ) return ret; if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); return CBotTypResult(CBotErrOverParam); @@ -1356,9 +1355,9 @@ CBotTypResult cGoto(CBotVar* &var, void* user) // Instruction "goto(pos, altitude, mode)". -bool rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); Math::Vector pos; TaskGotoGoal goal; TaskGotoCrash crash; @@ -1378,17 +1377,17 @@ bool rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) if ( var != 0 ) { - altitude = var->GivValFloat()*g_unit; + altitude = var->GetValFloat()*g_unit; - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - goal = (TaskGotoGoal)var->GivValInt(); + goal = static_cast<TaskGotoGoal>(var->GetValInt()); - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - crash = (TaskGotoCrash)var->GivValInt(); + crash = static_cast<TaskGotoCrash>(var->GetValInt()); } } } @@ -1412,19 +1411,19 @@ bool rGoto(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "find(type)". -bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rFind(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); Math::Vector pos; TaskGotoGoal goal; TaskGotoCrash crash; float altitude; Error err; - CObject* pThis = (CObject*)user; + CObject* pThis = static_cast<CObject *>(user); CObject *pObj, *pBest; CBotVar* array; Math::Vector iPos, oPos; - float best, minDist, maxDist, sens, iAngle, angle, focus, d, a; + float best, minDist, maxDist, iAngle, focus, d, a; int type, oType, i; bool bArray; @@ -1433,20 +1432,18 @@ bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user) if ( script->m_primaryTask == 0 ) // no task in progress? { type = OBJECT_NULL; - angle = 0.0f; focus = Math::PI*2.0f; minDist = 0.0f*g_unit; maxDist = 1000.0f*g_unit; - sens = 1.0f; - if ( var->GivType() == CBotTypArrayPointer ) + if ( var->GetType() == CBotTypArrayPointer ) { - array = var->GivItemList(); + array = var->GetItemList(); bArray = true; } else { - type = var->GivValInt(); + type = var->GetValInt(); bArray = false; } @@ -1454,15 +1451,15 @@ bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user) pBest = 0; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(script->m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; if ( pObj == pThis ) continue; - if ( pObj->RetTruck() != 0 ) continue; // object transported? - if ( !pObj->RetActif() ) continue; - if ( pObj->RetProxyActivate() ) continue; + if ( pObj->GetTruck() != 0 ) continue; // object transported? + if ( !pObj->GetActif() ) continue; + if ( pObj->GetProxyActivate() ) continue; - oType = pObj->RetType(); + oType = pObj->GetType(); if ( oType == OBJECT_TOTO ) continue; if ( oType == OBJECT_RUINmobilew2 || @@ -1497,7 +1494,7 @@ bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user) if ( type != oType && type != OBJECT_NULL ) continue; } - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); d = Math::DistanceProjected(iPos, oPos); if ( d < minDist || d > maxDist ) continue; // too close or too far? @@ -1528,7 +1525,7 @@ bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user) return false; } - pos = pBest->RetPosition(0); + pos = pBest->GetPosition(0); goal = TGG_DEFAULT; crash = TGC_DEFAULT; altitude = 0.0f*g_unit; @@ -1553,21 +1550,21 @@ bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation "grab/drop(oper)". -CBotTypResult cGrabDrop(CBotVar* &var, void* user) +CBotTypResult CScript::cGrabDrop(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); } // Instruction "grab(oper)". -bool rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); ObjectType oType; TaskManipArm type; Error err; @@ -1577,10 +1574,16 @@ bool rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) if ( script->m_primaryTask == 0 ) // no task in progress? { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - if ( var == 0 ) type = TMA_FFRONT; - else type = (TaskManipArm)var->GivValInt(); + if ( var == 0 ) + { + type = TMA_FFRONT; + } + else + { + type = static_cast<TaskManipArm>(var->GetValInt()); + } - oType = pThis->RetType(); + oType = pThis->GetType(); if ( oType == OBJECT_HUMAN || oType == OBJECT_TECH ) { @@ -1609,10 +1612,10 @@ bool rGrab(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "drop(oper)". -bool rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); ObjectType oType; TaskManipArm type; Error err; @@ -1623,9 +1626,9 @@ bool rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); if ( var == 0 ) type = TMA_FFRONT; - else type = (TaskManipArm)var->GivValInt(); + else type = static_cast<TaskManipArm>(var->GetValInt()); - oType = pThis->RetType(); + oType = pThis->GetType(); if ( oType == OBJECT_HUMAN || oType == OBJECT_TECH ) { @@ -1654,9 +1657,9 @@ bool rDrop(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "sniff()". -bool rSniff(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rSniff(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); Error err; exception = 0; @@ -1683,15 +1686,15 @@ bool rSniff(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "receive(nom, power)". -CBotTypResult cReceive(CBotVar* &var, void* user) +CBotTypResult CScript::cReceive(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); @@ -1699,10 +1702,10 @@ CBotTypResult cReceive(CBotVar* &var, void* user) // Instruction "receive(nom, power)". -bool rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); CBotString cbs; Error err; const char* p; @@ -1714,18 +1717,18 @@ bool rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - cbs = var->GivValString(); + cbs = var->GetValString(); p = cbs; - var = var->GivNext(); + var = var->GetNext(); power = 10.0f*g_unit; if ( var != 0 ) { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); + power = var->GetValFloat()*g_unit; + var = var->GetNext(); } - err = script->m_primaryTask->StartTaskInfo((char*)p, 0.0f, power, false); + err = script->m_primaryTask->StartTaskInfo(static_cast<const char*>(p), 0.0f, power, false); if ( err != ERR_OK ) { delete script->m_primaryTask; @@ -1736,7 +1739,7 @@ bool rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) } if ( !Process(script, result, exception) ) return false; // not finished - value = pThis->RetInfoReturn(); + value = pThis->GetInfoReturn(); if ( value == NAN ) { result->SetInit(IS_NAN); @@ -1750,19 +1753,19 @@ bool rReceive(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "send(nom, value, power)". -CBotTypResult cSend(CBotVar* &var, void* user) +CBotTypResult CScript::cSend(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); @@ -1770,10 +1773,9 @@ CBotTypResult cSend(CBotVar* &var, void* user) // Instruction "send(nom, value, power)". -bool rSend(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rSend(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); CBotString cbs; Error err; const char* p; @@ -1785,21 +1787,21 @@ bool rSend(CBotVar* var, CBotVar* result, int& exception, void* user) { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - cbs = var->GivValString(); + cbs = var->GetValString(); p = cbs; - var = var->GivNext(); + var = var->GetNext(); - value = var->GivValFloat(); - var = var->GivNext(); + value = var->GetValFloat(); + var = var->GetNext(); power = 10.0f*g_unit; if ( var != 0 ) { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); + power = var->GetValFloat()*g_unit; + var = var->GetNext(); } - err = script->m_primaryTask->StartTaskInfo((char*)p, value, power, true); + err = script->m_primaryTask->StartTaskInfo(static_cast<const char*>(p), value, power, true); if ( err != ERR_OK ) { delete script->m_primaryTask; @@ -1818,7 +1820,7 @@ bool rSend(CBotVar* var, CBotVar* result, int& exception, void* user) // Seeks the nearest information terminal. -CObject* SearchInfo(CScript* script, CObject* object, float power) +CObject* CScript::SearchInfo(CScript* script, CObject* object, float power) { CObject *pObj, *pBest; Math::Vector iPos, oPos; @@ -1826,21 +1828,21 @@ CObject* SearchInfo(CScript* script, CObject* object, float power) float dist, min; int i; - iPos = object->RetPosition(0); + iPos = object->GetPosition(0); min = 100000.0f; pBest = 0; for ( i=0 ; i<1000000 ; i++ ) { - pObj = (CObject*)script->m_iMan->SearchInstance(CLASS_OBJECT, i); + pObj = static_cast<CObject*>(script->m_iMan->SearchInstance(CLASS_OBJECT, i)); if ( pObj == 0 ) break; - type = pObj->RetType(); + type = pObj->GetType(); if ( type != OBJECT_INFO ) continue; - if ( !pObj->RetActif() ) continue; + if ( !pObj->GetActif() ) continue; - oPos = pObj->RetPosition(0); + oPos = pObj->GetPosition(0); dist = Math::Distance(oPos, iPos); if ( dist > power ) continue; // too far? if ( dist < min ) @@ -1855,15 +1857,15 @@ CObject* SearchInfo(CScript* script, CObject* object, float power) // Compilation of the instruction "deleteinfo(nom, power)". -CBotTypResult cDeleteInfo(CBotVar* &var, void* user) +CBotTypResult CScript::cDeleteInfo(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); @@ -1871,10 +1873,10 @@ CBotTypResult cDeleteInfo(CBotVar* &var, void* user) // Instruction "deleteinfo(nom, power)". -bool rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); CObject* pInfo; CBotString cbs; Info info; @@ -1884,15 +1886,15 @@ bool rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) exception = 0; - cbs = var->GivValString(); + cbs = var->GetValString(); p = cbs; - var = var->GivNext(); + var = var->GetNext(); power = 10.0f*g_unit; if ( var != 0 ) { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); + power = var->GetValFloat()*g_unit; + var = var->GetNext(); } pInfo = SearchInfo(script, pThis, power); @@ -1902,10 +1904,10 @@ bool rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) return true; } - total = pInfo->RetInfoTotal(); + total = pInfo->GetInfoTotal(); for ( i=0 ; i<total ; i++ ) { - info = pInfo->RetInfo(i); + info = pInfo->GetInfo(i); if ( strcmp(info.name, p) == 0 ) { pInfo->DeleteInfo(i); @@ -1919,15 +1921,15 @@ bool rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "testinfo(nom, power)". -CBotTypResult cTestInfo(CBotVar* &var, void* user) +CBotTypResult CScript::cTestInfo(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString ) return CBotTypResult(CBotErrBadString); - var = var->GivNext(); + if ( var->GetType() != CBotTypString ) return CBotTypResult(CBotErrBadString); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypBoolean); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypBoolean); @@ -1935,10 +1937,10 @@ CBotTypResult cTestInfo(CBotVar* &var, void* user) // Instruction "testinfo(nom, power)". -bool rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); CObject* pInfo; CBotString cbs; Info info; @@ -1948,15 +1950,15 @@ bool rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) exception = 0; - cbs = var->GivValString(); + cbs = var->GetValString(); p = cbs; - var = var->GivNext(); + var = var->GetNext(); power = 10.0f*g_unit; if ( var != 0 ) { - power = var->GivValFloat()*g_unit; - var = var->GivNext(); + power = var->GetValFloat()*g_unit; + var = var->GetNext(); } pInfo = SearchInfo(script, pThis, power); @@ -1966,10 +1968,10 @@ bool rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) return true; } - total = pInfo->RetInfoTotal(); + total = pInfo->GetInfoTotal(); for ( i=0 ; i<total ; i++ ) { - info = pInfo->RetInfo(i); + info = pInfo->GetInfo(i); if ( strcmp(info.name, p) == 0 ) { result->SetValInt(true); @@ -1982,9 +1984,9 @@ bool rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "thump()". -bool rThump(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rThump(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); Error err; exception = 0; @@ -2011,9 +2013,9 @@ bool rThump(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "recycle()". -bool rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); Error err; exception = 0; @@ -2040,15 +2042,15 @@ bool rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation "shield(oper, radius)". -CBotTypResult cShield(CBotVar* &var, void* user) +CBotTypResult CScript::cShield(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); @@ -2057,17 +2059,17 @@ CBotTypResult cShield(CBotVar* &var, void* user) // Instruction "shield(oper, radius)". -bool rShield(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rShield(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); float oper, radius; Error err; - oper = var->GivValFloat(); // 0=down, 1=up - var = var->GivNext(); + oper = var->GetValFloat(); // 0=down, 1=up + var = var->GetNext(); - radius = var->GivValFloat(); + radius = var->GetValFloat(); if ( radius < 10.0f ) radius = 10.0f; if ( radius > 25.0f ) radius = 25.0f; radius = (radius-10.0f)/15.0f; @@ -2111,13 +2113,13 @@ bool rShield(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation "fire(delay)". -CBotTypResult cFire(CBotVar* &var, void* user) +CBotTypResult CScript::cFire(CBotVar* &var, void* user) { #if 0 - CObject* pThis = (CObject*)user; + CObject* pThis = static_cast<CObject *>(user); ObjectType type; - type = pThis->RetType(); + type = pThis->GetType(); if ( type == OBJECT_ANT ) { @@ -2130,8 +2132,8 @@ CBotTypResult cFire(CBotVar* &var, void* user) else { if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); return CBotTypResult(CBotTypFloat); } @@ -2142,10 +2144,10 @@ CBotTypResult cFire(CBotVar* &var, void* user) // Instruction "fire(delay)". -bool rFire(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rFire(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); float delay; Math::Vector impact; Error err; @@ -2157,12 +2159,12 @@ bool rFire(CBotVar* var, CBotVar* result, int& exception, void* user) { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - type = pThis->RetType(); + type = pThis->GetType(); if ( type == OBJECT_ANT ) { if ( !GetPoint(var, exception, impact) ) return true; - impact.y += pThis->RetWaterLevel(); + impact.y += pThis->GetWaterLevel(); err = script->m_primaryTask->StartTaskFireAnt(impact); } else if ( type == OBJECT_SPIDER ) @@ -2172,7 +2174,7 @@ bool rFire(CBotVar* var, CBotVar* result, int& exception, void* user) else { if ( var == 0 ) delay = 0.0f; - else delay = var->GivValFloat(); + else delay = var->GetValFloat(); err = script->m_primaryTask->StartTaskFire(delay); } @@ -2189,9 +2191,9 @@ bool rFire(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "aim(dir)". -bool rAim(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rAim(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); float value; Error err; @@ -2200,7 +2202,7 @@ bool rAim(CBotVar* var, CBotVar* result, int& exception, void* user) if ( script->m_primaryTask == 0 ) // no task in progress? { script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - value = var->GivValFloat(); + value = var->GetValFloat(); err = script->m_primaryTask->StartTaskGunGoal(value*Math::PI/180.0f, 0.0f); if ( err != ERR_OK ) { @@ -2215,15 +2217,15 @@ bool rAim(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "motor(left, right)". -CBotTypResult cMotor(CBotVar* &var, void* user) +CBotTypResult CScript::cMotor(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var != 0 ) return CBotTypResult(CBotErrOverParam); @@ -2232,15 +2234,15 @@ CBotTypResult cMotor(CBotVar* &var, void* user) // Instruction "motor(left, right)". -bool rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) { - CObject* pThis = (CObject*)user; - CPhysics* physics = ((CObject*)user)->RetPhysics(); + CObject* pThis = static_cast<CObject *>(user); + CPhysics* physics = (static_cast<CObject *>(user))->GetPhysics(); float left, right, speed, turn; - left = var->GivValFloat(); - var = var->GivNext(); - right = var->GivValFloat(); + left = var->GetValFloat(); + var = var->GetNext(); + right = var->GetValFloat(); speed = (left+right)/2.0f; if ( speed < -1.0f ) speed = -1.0f; @@ -2250,7 +2252,7 @@ bool rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) if ( turn < -1.0f ) turn = -1.0f; if ( turn > 1.0f ) turn = 1.0f; - if ( pThis->RetFixed() ) // ant on the back? + if ( pThis->GetFixed() ) // ant on the back? { speed = 0.0f; turn = 0.0f; @@ -2264,12 +2266,12 @@ bool rMotor(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "jet(power)". -bool rJet(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rJet(CBotVar* var, CBotVar* result, int& exception, void* user) { - CPhysics* physics = ((CObject*)user)->RetPhysics(); + CPhysics* physics = (static_cast<CObject *>(user))->GetPhysics(); float value; - value = var->GivValFloat(); + value = var->GetValFloat(); physics->SetMotorSpeedY(value); return true; @@ -2277,13 +2279,13 @@ bool rJet(CBotVar* var, CBotVar* result, int& exception, void* user) // Compilation of the instruction "topo(pos)". -CBotTypResult cTopo(CBotVar* &var, void* user) +CBotTypResult CScript::cTopo(CBotVar* &var, void* user) { CBotTypResult ret; if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - ret = cPoint(var, user); - if ( ret.GivType() != 0 ) return ret; + ret = CScript::cPoint(var, user); + if ( ret.GetType() != 0 ) return ret; if ( var == 0 ) return CBotTypResult(CBotTypFloat); return CBotTypResult(CBotErrOverParam); @@ -2291,9 +2293,9 @@ CBotTypResult cTopo(CBotVar* &var, void* user) // Instruction "topo(pos)". -bool rTopo(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rTopo(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); Math::Vector pos; float level; @@ -2301,24 +2303,24 @@ bool rTopo(CBotVar* var, CBotVar* result, int& exception, void* user) if ( !GetPoint(var, exception, pos) ) return true; - level = script->m_terrain->RetFloorLevel(pos); - level -= script->m_water->RetLevel(); + level = script->m_terrain->GetFloorLevel(pos); + level -= script->m_water->GetLevel(); result->SetValFloat(level/g_unit); return true; } // Compilation of the instruction "message(string, type)". -CBotTypResult cMessage(CBotVar* &var, void* user) +CBotTypResult CScript::cMessage(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotErrLowParam); - if ( var->GivType() != CBotTypString && - var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() != CBotTypString && + var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); return CBotTypResult(CBotErrOverParam); @@ -2326,40 +2328,39 @@ CBotTypResult cMessage(CBotVar* &var, void* user) // Instruction "message(string, type)". -bool rMessage(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rMessage(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); CBotString cbs; const char* p; - TextType type; + Ui::TextType type; - cbs = var->GivValString(); + cbs = var->GetValString(); p = cbs; - type = TT_MESSAGE; - var = var->GivNext(); + type = Ui::TT_MESSAGE; + var = var->GetNext(); if ( var != 0 ) { - type = (TextType)var->GivValInt(); + type = static_cast<Ui::TextType>(var->GetValInt()); } - script->m_displayText->DisplayText((char*)p, script->m_object, 10.0f, type); - script->m_main->CheckEndMessage((char*)p); + script->m_displayText->DisplayText(p, script->m_object, 10.0f, type); + script->m_main->CheckEndMessage(p); return true; } // Instruction "cmdline(rank)". -bool rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CObject* pThis = static_cast<CObject *>(user); float value; int rank; - rank = var->GivValInt(); - value = pThis->RetCmdLine(rank); + rank = var->GetValInt(); + value = pThis->GetCmdLine(rank); result->SetValFloat(value); return true; @@ -2367,12 +2368,12 @@ bool rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "ismovie()". -bool rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); float value; - value = script->m_main->RetMovieLock()?1.0f:0.0f; + value = script->m_main->GetMovieLock()?1.0f:0.0f; result->SetValFloat(value); return true; @@ -2380,12 +2381,12 @@ bool rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "errmode(mode)". -bool rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); int value; - value = var->GivValInt(); + value = var->GetValInt(); if ( value < 0 ) value = 0; if ( value > 1 ) value = 1; script->m_errMode = value; @@ -2395,12 +2396,12 @@ bool rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "ipf(num)". -bool rIPF(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rIPF(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); int value; - value = var->GivValInt(); + value = var->GetValInt(); if ( value < 1 ) value = 1; if ( value > 10000 ) value = 10000; script->m_ipf = value; @@ -2410,12 +2411,12 @@ bool rIPF(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "abstime()". -bool rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); float value; - value = script->m_main->RetGameTime(); + value = script->m_main->GetGameTime(); result->SetValFloat(value); return true; } @@ -2450,33 +2451,32 @@ void PrepareFilename(CBotString &filename, char *dir) // Instruction "deletefile(filename)". -bool rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); CBotString cbs; - const char* p; + const char* filename; char* dir; - cbs = var->GivValString(); - dir = script->m_main->RetFilesDir(); + cbs = var->GetValString(); + dir = script->m_main->GetFilesDir(); PrepareFilename(cbs, dir); - p = cbs; - DeleteFile(p); - - return true; + filename = cbs; + //std function that removes file. + return (!remove(filename)); } // Compilation of the instruction "pendown(color, width)". -CBotTypResult cPenDown(CBotVar* &var, void* user) +CBotTypResult CScript::cPenDown(CBotVar* &var, void* user) { if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); - if ( var->GivType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); - var = var->GivNext(); + if ( var->GetType() > CBotTypDouble ) return CBotTypResult(CBotErrBadNum); + var = var->GetNext(); if ( var == 0 ) return CBotTypResult(CBotTypFloat); return CBotTypResult(CBotErrOverParam); @@ -2484,15 +2484,15 @@ CBotTypResult cPenDown(CBotVar* &var, void* user) // Instruction "pendown(color, width)". -bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); int color; float width; Error err; - if ( pThis->RetType() == OBJECT_MOBILEdr ) + if ( pThis->GetType() == OBJECT_MOBILEdr ) { exception = 0; @@ -2500,15 +2500,15 @@ bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) { if ( var != 0 ) { - color = var->GivValInt(); + color = var->GetValInt(); if ( color < 0 ) color = 0; if ( color > 17 ) color = 17; pThis->SetTraceColor(color); - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - width = var->GivValFloat(); + width = var->GetValFloat(); if ( width < 0.1f ) width = 0.1f; if ( width > 1.0f ) width = 1.0f; pThis->SetTraceWidth(width); @@ -2517,7 +2517,7 @@ bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) pThis->SetTraceDown(true); script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); + err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); if ( err != ERR_OK ) { delete script->m_primaryTask; @@ -2537,15 +2537,15 @@ bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) { if ( var != 0 ) { - color = var->GivValInt(); + color = var->GetValInt(); if ( color < 0 ) color = 0; if ( color > 17 ) color = 17; pThis->SetTraceColor(color); - var = var->GivNext(); + var = var->GetNext(); if ( var != 0 ) { - width = var->GivValFloat(); + width = var->GetValFloat(); if ( width < 0.1f ) width = 0.1f; if ( width > 1.0f ) width = 1.0f; pThis->SetTraceWidth(width); @@ -2559,13 +2559,13 @@ bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "penup()". -bool rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); Error err; - if ( pThis->RetType() == OBJECT_MOBILEdr ) + if ( pThis->GetType() == OBJECT_MOBILEdr ) { exception = 0; @@ -2574,7 +2574,7 @@ bool rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) pThis->SetTraceDown(false); script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); + err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); if ( err != ERR_OK ) { delete script->m_primaryTask; @@ -2599,27 +2599,26 @@ bool rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "pencolor()". -bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) { - CScript* script = ((CObject*)user)->RetRunScript(); - CPhysics* physics = ((CObject*)user)->RetPhysics(); - CObject* pThis = (CObject*)user; + CScript* script = (static_cast<CObject *>(user))->GetRunScript(); + CObject* pThis = static_cast<CObject *>(user); int color; Error err; - if ( pThis->RetType() == OBJECT_MOBILEdr ) + if ( pThis->GetType() == OBJECT_MOBILEdr ) { exception = 0; if ( script->m_primaryTask == 0 ) // no task in progress? { - color = var->GivValInt(); + color = var->GetValInt(); if ( color < 0 ) color = 0; if ( color > 17 ) color = 17; pThis->SetTraceColor(color); script->m_primaryTask = new CTaskManager(script->m_iMan, script->m_object); - err = script->m_primaryTask->StartTaskPen(pThis->RetTraceDown(), pThis->RetTraceColor()); + err = script->m_primaryTask->StartTaskPen(pThis->GetTraceDown(), pThis->GetTraceColor()); if ( err != ERR_OK ) { delete script->m_primaryTask; @@ -2637,7 +2636,7 @@ bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) } else { - color = var->GivValInt(); + color = var->GetValInt(); if ( color < 0 ) color = 0; if ( color > 17 ) color = 17; pThis->SetTraceColor(color); @@ -2648,12 +2647,12 @@ bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user) // Instruction "penwidth()". -bool rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user) +bool CScript::rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user) { - CObject* pThis = (CObject*)user; + CObject* pThis = static_cast<CObject *>(user); float width; - width = var->GivValFloat(); + width = var->GetValFloat(); if ( width < 0.1f ) width = 0.1f; if ( width > 1.0f ) width = 1.0f; pThis->SetTraceWidth(width); @@ -2669,15 +2668,13 @@ CScript::CScript(CInstanceManager* iMan, CObject* object, CTaskManager** seconda m_iMan = iMan; m_iMan->AddInstance(CLASS_SCRIPT, this, 100); - m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); - m_interface = (CInterface*)m_iMan->SearchInstance(CLASS_INTERFACE); - m_displayText = (CDisplayText*)m_iMan->SearchInstance(CLASS_DISPLAYTEXT); - m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); - m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); - m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); - m_botProg = 0; - m_object = object; - m_primaryTask = 0; + m_engine = static_cast<Gfx::CEngine*>(m_iMan->SearchInstance(CLASS_ENGINE)); + m_main = static_cast<CRobotMain*>(m_iMan->SearchInstance(CLASS_MAIN)); + m_terrain = static_cast<Gfx::CTerrain*>(m_iMan->SearchInstance(CLASS_TERRAIN)); + m_water = static_cast<Gfx::CWater*>(m_iMan->SearchInstance(CLASS_WATER)); + m_botProg = 0; + m_object = object; + m_primaryTask = 0; m_secondaryTask = secondaryTask; m_ipf = CBOT_IPF; @@ -2697,58 +2694,58 @@ CScript::CScript(CInstanceManager* iMan, CObject* object, CTaskManager** seconda void CScript::InitFonctions() { - CBotProgram::AddFunction("sin", rSin, cOneFloat); - CBotProgram::AddFunction("cos", rCos, cOneFloat); - CBotProgram::AddFunction("tan", rTan, cOneFloat); - CBotProgram::AddFunction("asin", raSin, cOneFloat); - CBotProgram::AddFunction("acos", raCos, cOneFloat); - CBotProgram::AddFunction("atan", raTan, cOneFloat); - CBotProgram::AddFunction("sqrt", rSqrt, cOneFloat); - CBotProgram::AddFunction("pow", rPow, cTwoFloat); - CBotProgram::AddFunction("rand", rRand, cNull); - CBotProgram::AddFunction("abs", rAbs, cOneFloat); - - CBotProgram::AddFunction("retobject", rRetObject, cRetObject); - CBotProgram::AddFunction("search", rSearch, cSearch); - CBotProgram::AddFunction("radar", rRadar, cRadar); - CBotProgram::AddFunction("detect", rDetect, cDetect); - CBotProgram::AddFunction("direction", rDirection, cDirection); - CBotProgram::AddFunction("produce", rProduce, cProduce); - CBotProgram::AddFunction("distance", rDistance, cDistance); - CBotProgram::AddFunction("distance2d",rDistance2d,cDistance); - CBotProgram::AddFunction("space", rSpace, cSpace); - CBotProgram::AddFunction("flatground",rFlatGround,cFlatGround); - CBotProgram::AddFunction("wait", rWait, cOneFloat); - CBotProgram::AddFunction("move", rMove, cOneFloat); - CBotProgram::AddFunction("turn", rTurn, cOneFloat); - CBotProgram::AddFunction("goto", rGoto, cGoto); - CBotProgram::AddFunction("find", rFind, cOneFloat); - CBotProgram::AddFunction("grab", rGrab, cGrabDrop); - CBotProgram::AddFunction("drop", rDrop, cGrabDrop); - CBotProgram::AddFunction("sniff", rSniff, cNull); - CBotProgram::AddFunction("receive", rReceive, cReceive); - CBotProgram::AddFunction("send", rSend, cSend); - CBotProgram::AddFunction("deleteinfo",rDeleteInfo,cDeleteInfo); - CBotProgram::AddFunction("testinfo", rTestInfo, cTestInfo); - CBotProgram::AddFunction("thump", rThump, cNull); - CBotProgram::AddFunction("recycle", rRecycle, cNull); - CBotProgram::AddFunction("shield", rShield, cShield); - CBotProgram::AddFunction("fire", rFire, cFire); - CBotProgram::AddFunction("aim", rAim, cOneFloat); - CBotProgram::AddFunction("motor", rMotor, cMotor); - CBotProgram::AddFunction("jet", rJet, cOneFloat); - CBotProgram::AddFunction("topo", rTopo, cTopo); - CBotProgram::AddFunction("message", rMessage, cMessage); - CBotProgram::AddFunction("cmdline", rCmdline, cOneFloat); - CBotProgram::AddFunction("ismovie", rIsMovie, cNull); - CBotProgram::AddFunction("errmode", rErrMode, cOneFloat); - CBotProgram::AddFunction("ipf", rIPF, cOneFloat); - CBotProgram::AddFunction("abstime", rAbsTime, cNull); - CBotProgram::AddFunction("deletefile",rDeleteFile,cString); - CBotProgram::AddFunction("pendown", rPenDown, cPenDown); - CBotProgram::AddFunction("penup", rPenUp, cNull); - CBotProgram::AddFunction("pencolor", rPenColor, cOneFloat); - CBotProgram::AddFunction("penwidth", rPenWidth, cOneFloat); + CBotProgram::AddFunction("sin", rSin, CScript::cOneFloat); + CBotProgram::AddFunction("cos", rCos, CScript::cOneFloat); + CBotProgram::AddFunction("tan", rTan, CScript::cOneFloat); + CBotProgram::AddFunction("asin", raSin, CScript::cOneFloat); + CBotProgram::AddFunction("acos", raCos, CScript::cOneFloat); + CBotProgram::AddFunction("atan", raTan, CScript::cOneFloat); + CBotProgram::AddFunction("sqrt", rSqrt, CScript::cOneFloat); + CBotProgram::AddFunction("pow", rPow, CScript::cTwoFloat); + CBotProgram::AddFunction("rand", rRand, CScript::cNull); + CBotProgram::AddFunction("abs", rAbs, CScript::cOneFloat); + + CBotProgram::AddFunction("retobject", rGetObject, CScript::cGetObject); + CBotProgram::AddFunction("search", rSearch, CScript::cSearch); + CBotProgram::AddFunction("radar", rRadar, CScript::cRadar); + CBotProgram::AddFunction("detect", rDetect, CScript::cDetect); + CBotProgram::AddFunction("direction", rDirection, CScript::cDirection); + CBotProgram::AddFunction("produce", rProduce, CScript::cProduce); + CBotProgram::AddFunction("distance", rDistance, CScript::cDistance); + CBotProgram::AddFunction("distance2d",rDistance2d,CScript::cDistance); + CBotProgram::AddFunction("space", rSpace, CScript::cSpace); + CBotProgram::AddFunction("flatground",rFlatGround,CScript::cFlatGround); + CBotProgram::AddFunction("wait", rWait, CScript::cOneFloat); + CBotProgram::AddFunction("move", rMove, CScript::cOneFloat); + CBotProgram::AddFunction("turn", rTurn, CScript::cOneFloat); + CBotProgram::AddFunction("goto", rGoto, CScript::cGoto); + CBotProgram::AddFunction("find", rFind, CScript::cOneFloat); + CBotProgram::AddFunction("grab", rGrab, CScript::cGrabDrop); + CBotProgram::AddFunction("drop", rDrop, CScript::cGrabDrop); + CBotProgram::AddFunction("sniff", rSniff, CScript::cNull); + CBotProgram::AddFunction("receive", rReceive, CScript::cReceive); + CBotProgram::AddFunction("send", rSend, CScript::cSend); + CBotProgram::AddFunction("deleteinfo",rDeleteInfo,CScript::cDeleteInfo); + CBotProgram::AddFunction("testinfo", rTestInfo, CScript::cTestInfo); + CBotProgram::AddFunction("thump", rThump, CScript::cNull); + CBotProgram::AddFunction("recycle", rRecycle, CScript::cNull); + CBotProgram::AddFunction("shield", rShield, CScript::cShield); + CBotProgram::AddFunction("fire", rFire, CScript::cFire); + CBotProgram::AddFunction("aim", rAim, CScript::cOneFloat); + CBotProgram::AddFunction("motor", rMotor, CScript::cMotor); + CBotProgram::AddFunction("jet", rJet, CScript::cOneFloat); + CBotProgram::AddFunction("topo", rTopo, CScript::cTopo); + CBotProgram::AddFunction("message", rMessage, CScript::cMessage); + CBotProgram::AddFunction("cmdline", rCmdline, CScript::cOneFloat); + CBotProgram::AddFunction("ismovie", rIsMovie, CScript::cNull); + CBotProgram::AddFunction("errmode", rErrMode, CScript::cOneFloat); + CBotProgram::AddFunction("ipf", rIPF, CScript::cOneFloat); + CBotProgram::AddFunction("abstime", rAbsTime, CScript::cNull); + CBotProgram::AddFunction("deletefile",rDeleteFile,CScript::cString); + CBotProgram::AddFunction("pendown", rPenDown, CScript::cPenDown); + CBotProgram::AddFunction("penup", rPenUp, CScript::cNull); + CBotProgram::AddFunction("pencolor", rPenColor, CScript::cOneFloat); + CBotProgram::AddFunction("penwidth", rPenWidth, CScript::cOneFloat); } // Object's destructor. @@ -2767,7 +2764,7 @@ CScript::~CScript() // Gives the script editable block of text. -void CScript::PutScript(CEdit* edit, char* name) +void CScript::PutScript(Ui::CEdit* edit, char* name) { if ( m_script == 0 ) { @@ -2784,15 +2781,15 @@ void CScript::PutScript(CEdit* edit, char* name) // The script takes a paved text. -bool CScript::GetScript(CEdit* edit) +bool CScript::GetScript(Ui::CEdit* edit) { int len; delete m_script; m_script = 0; - len = edit->RetTextLength(); - m_script = (char*)malloc(sizeof(char)*(len+1)); + len = edit->GetTextLength(); + m_script = static_cast<char*>(malloc(sizeof(char)*(len+1))); edit->GetText(m_script, len+1); edit->GetCursor(m_cursor2, m_cursor1); @@ -2819,7 +2816,7 @@ bool CScript::GetScript(CEdit* edit) // Indicates whether a program is compiled correctly. -bool CScript::RetCompile() +bool CScript::GetCompile() { return m_bCompile; } @@ -2846,17 +2843,17 @@ bool CScript::CheckToken() CBotToken* bt; CBotString bs; const char* token; - int error, type, cursor1, cursor2, i; + int error, cursor1, cursor2, i; char used[100]; - if ( !m_object->RetCheckToken() ) return true; + if ( !m_object->GetCheckToken() ) return true; m_error = 0; m_title[0] = 0; m_token[0] = 0; m_bCompile = false; - for ( i=0 ; i<m_main->RetObligatoryToken() ; i++ ) + for ( i=0 ; i<m_main->GetObligatoryToken() ; i++ ) { used[i] = 0; // token not used } @@ -2864,20 +2861,19 @@ bool CScript::CheckToken() bt = CBotToken::CompileTokens(m_script, error); while ( bt != 0 ) { - bs = bt->GivString(); + bs = bt->GetString(); token = bs; - type = bt->GivType(); - cursor1 = bt->GivStart(); - cursor2 = bt->GivEnd(); + cursor1 = bt->GetStart(); + cursor2 = bt->GetEnd(); - i = m_main->IsObligatoryToken((char*)token); + i = m_main->IsObligatoryToken(token); if ( i != -1 ) { used[i] = 1; // token used } - if ( !m_main->IsProhibitedToken((char*)token) ) + if ( !m_main->IsProhibitedToken(token) ) { m_error = ERR_PROHIBITEDTOKEN; m_cursor1 = cursor1; @@ -2887,15 +2883,15 @@ bool CScript::CheckToken() return false; } - bt = bt->GivNext(); + bt = bt->GetNext(); } // At least once every obligatory instruction? - for ( i=0 ; i<m_main->RetObligatoryToken() ; i++ ) + for ( i=0 ; i<m_main->GetObligatoryToken() ; i++ ) { if ( used[i] == 0 ) // token not used? { - strcpy(m_token, m_main->RetObligatoryToken(i)); + strcpy(m_token, m_main->GetObligatoryToken(i)); m_error = ERR_OBLIGATORYTOKEN; strcpy(m_title, "<erreur>"); CBotToken::Delete(bt); @@ -2930,12 +2926,12 @@ bool CScript::Compile() if ( m_botProg == 0 ) { - m_botProg = new CBotProgram(m_object->RetBotVar()); + m_botProg = new CBotProgram(m_object->GetBotVar()); } if ( m_botProg->Compile(m_script, liste, this) ) { - if ( liste.GivSize() == 0 ) + if ( liste.GetSize() == 0 ) { strcpy(m_title, "<sans nom>"); } @@ -3014,7 +3010,7 @@ bool CScript::Run() if ( m_bStepMode ) // step by step mode? { Event newEvent; - ZeroMemory(&newEvent, sizeof(Event)); + memset(&newEvent, 0, sizeof(Event)); Step(newEvent); } @@ -3054,7 +3050,7 @@ bool CScript::Continue(const Event &event) { char s[100]; GetError(s); - m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); + m_displayText->DisplayText(s, m_object, 10.0f, Ui::TT_ERROR); } m_engine->SetPause(true); // gives pause return true; @@ -3087,7 +3083,7 @@ bool CScript::Continue(const Event &event) { char s[100]; GetError(s); - m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); + m_displayText->DisplayText(s, m_object, 10.0f, Ui::TT_ERROR); } return true; } @@ -3105,7 +3101,7 @@ bool CScript::Step(const Event &event) if ( !m_bStepMode ) return false; m_engine->SetPause(false); - m_engine->StepSimul(0.01f); // advance of 10ms + m_engine->StepSimulation(0.01f); // advance of 10ms m_engine->SetPause(true); m_event = event; @@ -3129,7 +3125,7 @@ bool CScript::Step(const Event &event) { char s[100]; GetError(s); - m_displayText->DisplayText(s, m_object, 10.0f, TT_ERROR); + m_displayText->DisplayText(s, m_object, 10.0f, Ui::TT_ERROR); } return true; } @@ -3201,7 +3197,7 @@ bool CScript::GetCursor(int &cursor1, int &cursor2) // Put of the variables in a list. -void PutList(char *baseName, bool bArray, CBotVar *var, CList *list, int &rankList) +void PutList(const char *baseName, bool bArray, CBotVar *var, Ui::CList *list, int &rankList) { CBotString bs; CBotVar *svar, *pStatic; @@ -3221,13 +3217,13 @@ void PutList(char *baseName, bool bArray, CBotVar *var, CList *list, int &rankLi while ( var != 0 ) { var->Maj(NULL, false); - pStatic = var->GivStaticVar(); // finds the static element + pStatic = var->GetStaticVar(); // finds the static element - bs = pStatic->GivName(); // variable name + bs = pStatic->GetName(); // variable name p = bs; //? if ( strcmp(p, "this") == 0 ) //? { -//? var = var->GivNext(); +//? var = var->GetNext(); //? continue; //? } @@ -3247,12 +3243,12 @@ void PutList(char *baseName, bool bArray, CBotVar *var, CList *list, int &rankLi } } - type = pStatic->GivType(); + type = pStatic->GetType(); if ( type < CBotTypBoolean ) { CBotString value; - value = pStatic->GivValString(); + value = pStatic->GetValString(); p = value; sprintf(buffer, "%s = %s;", varName, p); list->SetName(rankList++, buffer); @@ -3260,20 +3256,20 @@ void PutList(char *baseName, bool bArray, CBotVar *var, CList *list, int &rankLi else if ( type == CBotTypString ) { CBotString value; - value = pStatic->GivValString(); + value = pStatic->GetValString(); p = value; sprintf(buffer, "%s = \"%s\";", varName, p); list->SetName(rankList++, buffer); } else if ( type == CBotTypArrayPointer ) { - svar = pStatic->GivItemList(); + svar = pStatic->GetItemList(); PutList(varName, true, svar, list, rankList); } else if ( type == CBotTypClass || type == CBotTypPointer ) { - svar = pStatic->GivItemList(); + svar = pStatic->GetItemList(); PutList(varName, false, svar, list, rankList); } else @@ -3283,13 +3279,13 @@ void PutList(char *baseName, bool bArray, CBotVar *var, CList *list, int &rankLi } index ++; - var = var->GivNext(); + var = var->GetNext(); } } // Fills a list with variables. -void CScript::UpdateList(CList* list) +void CScript::UpdateList(Ui::CList* list) { CBotVar *var; const char *progName, *funcName; @@ -3297,8 +3293,8 @@ void CScript::UpdateList(CList* list) if( m_botProg == 0 ) return; - total = list->RetTotal(); - select = list->RetSelect(); + total = list->GetTotal(); + select = list->GetSelect(); list->Flush(); // empty list m_botProg->GetRunPos(progName, cursor1, cursor2); @@ -3308,70 +3304,71 @@ void CScript::UpdateList(CList* list) rank = 0; while ( true ) { - var = m_botProg->GivStackVars(funcName, level--); + var = m_botProg->GetStackVars(funcName, level--); if ( funcName != progName ) break; PutList("", false, var, list, rank); } - if ( total == list->RetTotal() ) // same total? + if ( total == list->GetTotal() ) // same total? { list->SetSelect(select); } list->SetTooltip(""); - list->SetState(STATE_ENABLE); + list->SetState(Ui::STATE_ENABLE); } // Colorize the text according to syntax. -void CScript::ColorizeScript(CEdit* edit) +void CScript::ColorizeScript(Ui::CEdit* edit) { CBotToken* bt; CBotString bs; const char* token; - int error, type, cursor1, cursor2, color; + int error, type, cursor1, cursor2; + Gfx::FontHighlight color; edit->ClearFormat(); - bt = CBotToken::CompileTokens(edit->RetText(), error); + bt = CBotToken::CompileTokens(edit->GetText(), error); while ( bt != 0 ) { - bs = bt->GivString(); + bs = bt->GetString(); token = bs; - type = bt->GivType(); + type = bt->GetType(); - cursor1 = bt->GivStart(); - cursor2 = bt->GivEnd(); + cursor1 = bt->GetStart(); + cursor2 = bt->GetEnd(); - color = 0; + color = Gfx::FONT_HIGHLIGHT_NONE; if ( type >= TokenKeyWord && type < TokenKeyWord+100 ) { - color = COLOR_TOKEN; + color = Gfx::FONT_HIGHLIGHT_TOKEN; } if ( type >= TokenKeyDeclare && type < TokenKeyDeclare+100 ) { - color = COLOR_TYPE; + color = Gfx::FONT_HIGHLIGHT_TYPE; } if ( type >= TokenKeyVal && type < TokenKeyVal+100 ) { - color = COLOR_CONST; + color = Gfx::FONT_HIGHLIGHT_CONST; } if ( type == TokenTypVar ) { if ( IsType(token) ) { - color = COLOR_TYPE; + color = Gfx::FONT_HIGHLIGHT_TYPE; } else if ( IsFunction(token) ) { - color = COLOR_TOKEN; + color = Gfx::FONT_HIGHLIGHT_TOKEN; } } if ( type == TokenTypDef ) { - color = COLOR_CONST; + color =Gfx::FONT_HIGHLIGHT_CONST; } if ( cursor1 < cursor2 && color != 0 ) @@ -3379,7 +3376,7 @@ void CScript::ColorizeScript(CEdit* edit) edit->SetFormat(cursor1, cursor2, color); } - bt = bt->GivNext(); + bt = bt->GetNext(); } CBotToken::Delete(bt); @@ -3389,7 +3386,8 @@ void CScript::ColorizeScript(CEdit* edit) // Seeks a token at random in a script. // Returns the index of the start of the token found, or -1. -int SearchToken(char* script, char* token) + +int SearchToken(char* script, const char* token) { int lScript, lToken, i, iFound; int found[100]; @@ -3425,7 +3423,7 @@ void DeleteToken(char* script, int pos, int len) // Inserts a token in a script. -void InsertToken(char* script, int pos, char* token) +void InsertToken(char* script, int pos, const char* token) { int lScript, lToken, i; @@ -3446,7 +3444,7 @@ bool CScript::IntroduceVirus() int found[11*2]; char* newScript; - char* names[11*2] = + const char* names[11*2] = { "==", "!=", "!=", "==", @@ -3477,7 +3475,7 @@ bool CScript::IntroduceVirus() start = found[i+1]; i = found[i+0]; - newScript = (char*)malloc(sizeof(char)*(m_len+strlen(names[i+1])+1)); + newScript = static_cast<char*>(malloc(sizeof(char)*(m_len+strlen(names[i+1])+1))); strcpy(newScript, m_script); delete m_script; m_script = newScript; @@ -3493,7 +3491,7 @@ bool CScript::IntroduceVirus() // Returns the number of the error. -int CScript::RetError() +int CScript::GetError() { return m_error; } @@ -3528,7 +3526,7 @@ void CScript::GetError(char* buffer) // New program. -void CScript::New(CEdit* edit, char* name) +void CScript::New(Ui::CEdit* edit, char* name) { FILE *file = NULL; char res[100]; @@ -3553,7 +3551,7 @@ void CScript::New(CEdit* edit, char* name) } else { - if ( edit->RetAutoIndent() ) + if ( edit->GetAutoIndent() ) { cursor1 = 20+strlen(text)+6; cursor2 = cursor1; // cursor in { } @@ -3569,7 +3567,7 @@ void CScript::New(CEdit* edit, char* name) edit->ShowSelect(); edit->SetFocus(true); - sf = m_main->RetScriptFile(); + sf = m_main->GetScriptFile(); if ( sf[0] != 0 ) // Load an empty program specific? { strcpy(filename, "script\\"); @@ -3599,7 +3597,7 @@ void CScript::New(CEdit* edit, char* name) continue; } - if ( buffer[i] == '\t' && edit->RetAutoIndent() ) + if ( buffer[i] == '\t' && edit->GetAutoIndent() ) { i ++; continue; @@ -3642,7 +3640,7 @@ void CScript::New(CEdit* edit, char* name) bool CScript::SendScript(char* text) { m_len = strlen(text); - m_script = (char*)malloc(sizeof(char)*(m_len+1)); + m_script = static_cast<char*>(malloc(sizeof(char)*(m_len+1))); strcpy(m_script, text); if ( !CheckToken() ) return false; if ( !Compile() ) return false; @@ -3655,7 +3653,7 @@ bool CScript::SendScript(char* text) bool CScript::ReadScript(char* filename) { FILE* file; - CEdit* edit; + Ui::CEdit* edit; char name[100]; if ( strchr(filename, '\\') == 0 ) @@ -3677,8 +3675,8 @@ bool CScript::ReadScript(char* filename) m_script = 0; edit = m_interface->CreateEdit(Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f), 0, EVENT_EDIT9); - edit->SetMaxChar(EDITSTUDIOMAX); - edit->SetAutoIndent(m_engine->RetEditIndentMode()); + edit->SetMaxChar(Ui::EDITSTUDIOMAX); + edit->SetAutoIndent(m_engine->GetEditIndentMode()); edit->ReadText(name); GetScript(edit); m_interface->DeleteControl(EVENT_EDIT9); @@ -3689,7 +3687,7 @@ bool CScript::ReadScript(char* filename) bool CScript::WriteScript(char* filename) { - CEdit* edit; + Ui::CEdit* edit; char name[100]; if ( strchr(filename, '\\') == 0 ) @@ -3709,8 +3707,8 @@ bool CScript::WriteScript(char* filename) } edit = m_interface->CreateEdit(Math::Point(0.0f, 0.0f), Math::Point(0.0f, 0.0f), 0, EVENT_EDIT9); - edit->SetMaxChar(EDITSTUDIOMAX); - edit->SetAutoIndent(m_engine->RetEditIndentMode()); + edit->SetMaxChar(Ui::EDITSTUDIOMAX); + edit->SetAutoIndent(m_engine->GetEditIndentMode()); edit->SetText(m_script); edit->WriteText(name); m_interface->DeleteControl(EVENT_EDIT9); @@ -3769,7 +3767,7 @@ void CScript::SetFilename(char *filename) strcpy(m_filename, filename); } -char* CScript::RetFilename() +char* CScript::GetFilename() { return m_filename; } diff --git a/src/script/script.h b/src/script/script.h index 8b2ae0b..3cb1a85 100644 --- a/src/script/script.h +++ b/src/script/script.h @@ -22,20 +22,26 @@ #include <stdio.h> #include "common/event.h" +#include "CBot/CBotDll.h" class CInstanceManager; -class CD3DEngine; -class CInterface; -class CDisplayText; -class CEdit; -class CList; class CObject; class CTaskManager; -class CBotProgram; class CRobotMain; + +namespace Ui{ +class CDisplayText; +class CEdit; +class CInterface; +class CList; +} /* Ui */ + +namespace Gfx { +class CEngine; class CTerrain; class CWater; +} /* Gfx */ @@ -47,9 +53,9 @@ public: static void InitFonctions(); - void PutScript(CEdit* edit, char* name); - bool GetScript(CEdit* edit); - bool RetCompile(); + void PutScript(Ui::CEdit* edit, char* name); + bool GetScript(Ui::CEdit* edit); + bool GetCompile(); void GetTitle(char* buffer); @@ -61,14 +67,14 @@ public: bool IsRunning(); bool IsContinue(); bool GetCursor(int &cursor1, int &cursor2); - void UpdateList(CList* list); - void ColorizeScript(CEdit* edit); + void UpdateList(Ui::CList* list); + void ColorizeScript(Ui::CEdit* edit); bool IntroduceVirus(); - int RetError(); + int GetError(); void GetError(char* buffer); - void New(CEdit* edit, char* name); + void New(Ui::CEdit* edit, char* name); bool SendScript(char* text); bool ReadScript(char* filename); bool WriteScript(char* filename); @@ -77,42 +83,124 @@ public: bool Compare(CScript* other); void SetFilename(char *filename); - char* RetFilename(); + char* GetFilename(); protected: bool IsEmpty(); bool CheckToken(); bool Compile(); -public: - CInstanceManager* m_iMan; - CD3DEngine* m_engine; - CInterface* m_interface; - CDisplayText* m_displayText; - CBotProgram* m_botProg; - CRobotMain* m_main; - CTerrain* m_terrain; - CWater* m_water; - CTaskManager* m_primaryTask; - CTaskManager** m_secondaryTask; - CObject* m_object; - - int m_ipf; // number of instructions/second - int m_errMode; // what to do in case of error - int m_len; // length of the script (without <0>) - char* m_script; // script ends with <0> - bool m_bRun; // program during execution? - bool m_bStepMode; // step by step - bool m_bContinue; // external function to continue - bool m_bCompile; // compilation ok? - char m_title[50]; // script title - char m_filename[50]; // file name - char m_token[50]; // missing instruction - int m_error; // error (0=ok) - int m_cursor1; - int m_cursor2; - Event m_event; - float m_returnValue; +private: + + static CBotTypResult cNull(CBotVar* &var, void* user); + static CBotTypResult cOneFloat(CBotVar* &var, void* user); + static CBotTypResult cTwoFloat(CBotVar* &var, void* user); + static CBotTypResult cString(CBotVar* &var, void* user); + static CBotTypResult cGetObject(CBotVar* &var, void* user); + static CBotTypResult cSearch(CBotVar* &var, void* user); + static CBotTypResult cRadar(CBotVar* &var, void* user); + static CBotTypResult cDetect(CBotVar* &var, void* user); + static CBotTypResult cDirection(CBotVar* &var, void* user); + static CBotTypResult cProduce(CBotVar* &var, void* user); + static CBotTypResult cDistance(CBotVar* &var, void* user); + static CBotTypResult cSpace(CBotVar* &var, void* user); + static CBotTypResult cFlatGround(CBotVar* &var, void* user); + static CBotTypResult cGoto(CBotVar* &var, void* user); + static CBotTypResult cGrabDrop(CBotVar* &var, void* user); + static CBotTypResult cReceive(CBotVar* &var, void* user); + static CBotTypResult cSend(CBotVar* &var, void* user); + static CBotTypResult cDeleteInfo(CBotVar* &var, void* user); + static CBotTypResult cTestInfo(CBotVar* &var, void* user); + static CBotTypResult cShield(CBotVar* &var, void* user); + static CBotTypResult cFire(CBotVar* &var, void* user); + static CBotTypResult cMotor(CBotVar* &var, void* user); + static CBotTypResult cTopo(CBotVar* &var, void* user); + static CBotTypResult cMessage(CBotVar* &var, void* user); + static CBotTypResult cPenDown(CBotVar* &var, void* user); + static CBotTypResult cOnePoint(CBotVar* &var, void* user); + static CBotTypResult cPoint(CBotVar* &var, void* user); + + + static bool rSin(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rCos(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTan(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSqrt(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPow(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rRand(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rAbs(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGetObject(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSearch(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rRadar(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDetect(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDirection(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rProduce(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDistance(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDistance2d(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSpace(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rFlatGround(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rWait(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rMove(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTurn(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGoto(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rFind(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rGrab(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDrop(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSniff(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rReceive(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rSend(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDeleteInfo(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTestInfo(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rThump(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rRecycle(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rShield(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rFire(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rAim(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rMotor(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rJet(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rTopo(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rMessage(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rCmdline(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rIsMovie(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rErrMode(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rIPF(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rAbsTime(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rDeleteFile(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenDown(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenUp(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenColor(CBotVar* var, CBotVar* result, int& exception, void* user); + static bool rPenWidth(CBotVar* var, CBotVar* result, int& exception, void* user); + + static bool Process(CScript* script, CBotVar* result, int &exception); + static CObject* SearchInfo(CScript* script, CObject* object, float power); + + CInstanceManager* m_iMan; + Gfx::CEngine* m_engine; + Ui::CInterface* m_interface; + Ui::CDisplayText* m_displayText; + CBotProgram* m_botProg; + CRobotMain* m_main; + Gfx::CTerrain* m_terrain; + Gfx::CWater* m_water; + CTaskManager* m_primaryTask; + CTaskManager** m_secondaryTask; + CObject* m_object; + + int m_ipf; // number of instructions/second + int m_errMode; // what to do in case of error + int m_len; // length of the script (without <0>) + char* m_script; // script ends with <0> + bool m_bRun; // program during execution? + bool m_bStepMode; // step by step + bool m_bContinue; // external function to continue + bool m_bCompile; // compilation ok? + char m_title[50]; // script title + char m_filename[50]; // file name + char m_token[50]; // missing instruction + int m_error; // error (0=ok) + int m_cursor1; + int m_cursor2; + Event m_event; + float m_returnValue; }; diff --git a/src/tools/CMakeLists.txt b/src/tools/CMakeLists.txt new file mode 100644 index 0000000..f6c6112 --- /dev/null +++ b/src/tools/CMakeLists.txt @@ -0,0 +1,13 @@ +set(CONVERT_MODEL_SOURCES +../common/iman.cpp +../common/logger.cpp +../common/stringutils.cpp +../graphics/engine/modelfile.cpp +convert_model.cpp +) + +include_directories(. ..) + +add_definitions(-DMODELFILE_NO_ENGINE) + +add_executable(convert_model ${CONVERT_MODEL_SOURCES}) diff --git a/src/tools/README.txt b/src/tools/README.txt new file mode 100644 index 0000000..de2f087 --- /dev/null +++ b/src/tools/README.txt @@ -0,0 +1,4 @@ +/** + * \dir tools + * \brief Various tools (separate programs) + */ diff --git a/src/tools/convert_model.cpp b/src/tools/convert_model.cpp new file mode 100644 index 0000000..a2f2b7a --- /dev/null +++ b/src/tools/convert_model.cpp @@ -0,0 +1,286 @@ +#include "common/iman.h"
+#include "common/logger.h"
+#include "graphics/engine/modelfile.h"
+
+#include <iostream>
+#include <map>
+
+
+bool EndsWith(std::string const &fullString, std::string const &ending)
+{
+ if (fullString.length() >= ending.length()) {
+ return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending));
+ } else {
+ return false;
+ }
+}
+
+
+struct Args
+{
+ bool usage;
+ bool dumpInfo;
+ bool mirror;
+ std::string inputFile;
+ std::string outputFile;
+ std::string inputFormat;
+ std::string outputFormat;
+
+ Args()
+ {
+ usage = false;
+ dumpInfo = false;
+ mirror = false;
+ }
+};
+
+Args ARGS;
+
+void PrintUsage(const std::string& program)
+{
+ std::cerr << "Colobot model converter" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "Usage:" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << " Convert files:" << std::endl;
+ std::cerr << " " << program << " -i input_file -if input_format -o output_file -of output_format [-m]" << std::endl;
+ std::cerr << " -m => mirror" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << " Dump info:" << std::endl;
+ std::cerr << " " << program << " -d -i input_file -if input_format" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << " Help:" << std::endl;
+ std::cerr << " " << program << " -h" << std::endl;
+ std::cerr << std::endl;
+
+ std::cerr << "Model formats:" << std::endl;
+ std::cerr << " old => old binary format" << std::endl;
+ std::cerr << " new_bin => new binary format" << std::endl;
+ std::cerr << " new_txt => new text format" << std::endl;
+}
+
+bool ParseArgs(int argc, char *argv[])
+{
+ bool waitI = false, waitO = false;
+ bool waitIf = false, waitOf = false;
+ for (int i = 1; i < argc; ++i)
+ {
+ std::string arg = std::string(argv[i]);
+
+ if (arg == "-i")
+ {
+ waitI = true;
+ continue;
+ }
+ if (arg == "-o")
+ {
+ waitO = true;
+ continue;
+ }
+ if (arg == "-if")
+ {
+ waitIf = true;
+ continue;
+ }
+ if (arg == "-of")
+ {
+ waitOf = true;
+ continue;
+ }
+
+ if (waitI)
+ {
+ waitI = false;
+ ARGS.inputFile = arg;
+ }
+ else if (waitO)
+ {
+ waitO = false;
+ ARGS.outputFile = arg;
+ }
+ else if (waitIf)
+ {
+ waitIf = false;
+ ARGS.inputFormat = arg;
+ }
+ else if (waitOf)
+ {
+ waitOf = false;
+ ARGS.outputFormat = arg;
+ }
+ else if (arg == "-h")
+ {
+ PrintUsage(argv[0]);
+ ARGS.usage = true;
+ }
+ else if (arg == "-d")
+ {
+ ARGS.dumpInfo = true;
+ }
+ else if (arg == "-m")
+ {
+ ARGS.mirror = true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ if (waitI || waitO || waitIf || waitOf)
+ return false;
+
+ if (ARGS.usage)
+ return true;
+
+ if (ARGS.inputFile.empty() || (!ARGS.dumpInfo && ARGS.outputFile.empty() ))
+ return false;
+
+ if (ARGS.inputFormat.empty() || (!ARGS.dumpInfo && ARGS.outputFormat.empty() ))
+ return false;
+
+ return true;
+}
+
+template<typename T>
+void PrintStats(const std::map<T, int>& stats, int total)
+{
+ for (auto it = stats.begin(); it != stats.end(); ++it)
+ {
+ std::cerr << " " << (*it).first << " : " << (*it).second << " / " << total << std::endl;
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ CLogger logger;
+ logger.SetLogLevel(LOG_ERROR);
+
+ if (!ParseArgs(argc, argv))
+ {
+ std::cerr << "Invalid arguments! Run with -h for usage info." << std::endl;
+ return 1;
+ }
+
+ if (ARGS.usage)
+ return 0;
+
+ CInstanceManager iMan;
+ Gfx::CModelFile model(&iMan);
+
+ bool ok = true;
+
+ if (ARGS.inputFormat == "old")
+ {
+ ok = model.ReadModel(ARGS.inputFile);
+ }
+ else if (ARGS.inputFormat == "new_bin")
+ {
+ ok = model.ReadBinaryModel(ARGS.inputFile);
+ }
+ else if (ARGS.inputFormat == "new_txt")
+ {
+ ok = model.ReadTextModel(ARGS.inputFile);
+ }
+ else
+ {
+ std::cerr << "Invalid input format" << std::endl;
+ return 1;
+ }
+
+ if (!ok)
+ {
+ std::cerr << "Reading input model failed" << std::endl;
+ return 1;
+ }
+
+ if (ARGS.dumpInfo)
+ {
+ const std::vector<Gfx::ModelTriangle>& triangles = model.GetTriangles();
+
+ Math::Vector min( Math::HUGE_NUM, Math::HUGE_NUM, Math::HUGE_NUM);
+ Math::Vector max(-Math::HUGE_NUM, -Math::HUGE_NUM, -Math::HUGE_NUM);
+
+ std::map<std::string, int> texs1, texs2;
+ std::map<int, int> states;
+ std::map<float, int> mins, maxs;
+ int variableTexs2 = 0;
+
+ for (int i = 0; i < static_cast<int>( triangles.size() ); ++i)
+ {
+ const Gfx::ModelTriangle& t = triangles[i];
+
+ min.x = Math::Min(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, min.x);
+ min.y = Math::Min(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, min.y);
+ min.z = Math::Min(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, min.z);
+
+ max.x = Math::Max(t.p1.coord.x, t.p2.coord.x, t.p3.coord.x, max.x);
+ max.y = Math::Max(t.p1.coord.y, t.p2.coord.y, t.p3.coord.y, max.y);
+ max.z = Math::Max(t.p1.coord.z, t.p2.coord.z, t.p3.coord.z, max.z);
+
+ texs1[t.tex1Name] += 1;
+ if (! t.tex2Name.empty())
+ texs2[t.tex2Name] += 1;
+ if (t.variableTex2)
+ variableTexs2 += 1;
+ states[t.state] += 1;
+
+ mins[t.min] += 1;
+ maxs[t.max] += 1;
+ }
+
+ std::cerr << "---- Info ----" << std::endl;
+ std::cerr << "Total triangles: " << triangles.size();
+ std::cerr << std::endl;
+ std::cerr << "Bounding box:" << std::endl;
+ std::cerr << " min: [" << min.x << ", " << min.y << ", " << min.z << "]" << std::endl;
+ std::cerr << " max: [" << max.x << ", " << max.y << ", " << max.z << "]" << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "Textures:" << std::endl;
+ std::cerr << " tex1:" << std::endl;
+ PrintStats(texs1, triangles.size());
+ std::cerr << " tex2:" << std::endl;
+ PrintStats(texs2, triangles.size());
+ std::cerr << " variable tex2: " << variableTexs2 << " / " << triangles.size() << std::endl;
+ std::cerr << std::endl;
+ std::cerr << "States:" << std::endl;
+ PrintStats(states, triangles.size());
+ std::cerr << std::endl;
+ std::cerr << "LOD:" << std::endl;
+ std::cerr << " min:" << std::endl;
+ PrintStats(mins, triangles.size());
+ std::cerr << " max:" << std::endl;
+ PrintStats(maxs, triangles.size());
+
+ return 0;
+ }
+
+ if (ARGS.mirror)
+ model.Mirror();
+
+ if (ARGS.outputFormat == "old")
+ {
+ ok = model.WriteModel(ARGS.outputFile);
+ }
+ else if (ARGS.outputFormat == "new_bin")
+ {
+ ok = model.WriteBinaryModel(ARGS.outputFile);
+ }
+ else if (ARGS.outputFormat == "new_txt")
+ {
+ ok = model.WriteTextModel(ARGS.outputFile);
+ }
+ else
+ {
+ std::cerr << "Invalid output format" << std::endl;
+ return 1;
+ }
+
+ if (!ok)
+ {
+ std::cerr << "Writing output model failed" << std::endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/tools/blender-scripts.py b/tools/blender-scripts.py new file mode 100644 index 0000000..6591393 --- /dev/null +++ b/tools/blender-scripts.py @@ -0,0 +1,542 @@ +# +# Script for exporting Blender models (meshes) to Colobot model files +# (text format) +# +# Copyright (C) 2012, PPC (Polish Portal of Colobot) +# + +import bpy +import struct +import array +import os +import copy + +FUZZY_TOLERANCE = 1e-5 + +class ColobotError(Exception): + """Exception in I/O operations""" + def __init__(self, value): + self.value = value + def __str__(self): + return repr(self.value) + +def fuzzy_equal_v(v1, v2): + for i in range(len(v1)): + if abs(v1[i] - v2[i]) > FUZZY_TOLERANCE: + return False + return True + +class ColobotVertex: + """Vertex as saved in Colobot model file""" + def __init__(self): + self.coord = array.array('f', [0.0, 0.0, 0.0]) + self.normal = array.array('f', [0.0, 0.0, 0.0]) + self.t1 = array.array('f', [0.0, 0.0]) + self.t2 = array.array('f', [0.0, 0.0]) + + def __hash__(self): + return 1 + + def __eq__(self, other): + return fuzzy_equal_v(self.coord, other.coord) and + fuzzy_equal_v(self.normal, other.normal) and + fuzzy_equal_v(self.t1, other.t1) and + fuzzy_equal_v(self.t2, other.t2) + +class ColobotMaterial: + """Material as saved in Colobot model file""" + def __init__(self): + self.diffuse = array.array('f', [0.0, 0.0, 0.0, 0.0]) + self.ambient = array.array('f', [0.0, 0.0, 0.0, 0.0]) + self.specular = array.array('f', [0.0, 0.0, 0.0, 0.0]) + self.tex1 = '' + self.tex2 = '' + + def __hash__(self): + return 1 + + def __eq__(self, other): + return fuzzy_equal_v(self.diffuse, other.diffuse) and + fuzzy_equal_v(self.ambient, other.ambient) and + fuzzy_equal_v(self.specular, other.specular) and + self.tex1 == other.tex1 and + self.tex2 == other.tex2 + +class ColobotTriangle: + """Triangle as saved in Colobot model file""" + def __init__(self): + self.p = [ColobotVertex(), ColobotVertex(), ColobotVertex()] + self.mat = ColobotMaterial() + self.tex1 = '' + self.tex2 = '' + self.var_tex2 = False + self.state = 0 + self.min = 0.0 + self.max = 0.0 + +class ColobotModel: + """Colobot model (content of model file)""" + def __init__(self): + self.version = 1 + self.triangles = [] + + def append(self, model): + self.triangles.extend(model.triangles) + +def v3to4(vec): + return array.array('f', [vec[0], vec[1], vec[2], 0.0]) + +def v4to3(vec): + return array.array('f', [vec[0], vec[1], vec[2]]) + +def write_colobot_model(filename, model): + file = open(filename, 'w') + + file.write('# Colobot text model\n') + file.write('\n') + + file.write('### HEAD\n') + file.write('version ' + str(model.version) + '\n') + file.write('total_triangles ' + str(len(model.triangles)) + '\n') + file.write('\n') + file.write('### TRIANGLES\n') + + for t in model.triangles: + for i in range(0, 3): + p = t.p[i] + file.write('p' + str(i+1)) + file.write(' c ' + ' '.join(map(str, p.coord ))) + file.write(' n ' + ' '.join(map(str, p.normal))) + file.write(' t1 ' + ' '.join(map(str, p.t1))) + file.write(' t2 ' + ' '.join(map(str, p.t2))) + file.write('\n') + + file.write('mat') + file.write(' dif ' + ' '.join(map(str, t.mat.diffuse))) + file.write(' amb ' + ' '.join(map(str, t.mat.ambient))) + file.write(' spc ' + ' '.join(map(str, t.mat.specular))) + file.write('\n') + + file.write('tex1 ' + t.tex1 + '\n') + file.write('tex2 ' + t.tex2 + '\n') + file.write('var_tex2 ' + ( 'Y' if t.var_tex2 else 'N' + '\n' ) ) + file.write('min ' + str(t.min) + '\n') + file.write('max ' + str(t.max) + '\n') + file.write('state ' + str(t.state) + '\n') + file.write('\n') + + file.close() + +def token_next_line(lines, index): + while (index < len(lines)): + line = lines[index] + index = index + 1 + if (not (len(line) == 0 or line[0] == '#' or line[0] == '\n') ): + return ( line.split(), index) + + raise ColobotError('Unexpected EOF') + +def read_colobot_vertex(tokens): + vertex = ColobotVertex() + + if (tokens[1] != 'c'): + raise ColobotError('Invalid vertex') + vertex.coord[0] = float(tokens[2]) + vertex.coord[1] = float(tokens[3]) + vertex.coord[2] = float(tokens[4]) + + if (tokens[5] != 'n'): + raise ColobotError('Invalid vertex') + vertex.normal[0] = float(tokens[6]) + vertex.normal[1] = float(tokens[7]) + vertex.normal[2] = float(tokens[8]) + + if (tokens[9] != 't1'): + raise ColobotError('Invalid vertex') + vertex.t1[0] = float(tokens[10]) + vertex.t1[1] = float(tokens[11]) + + if (tokens[12] != 't2'): + raise ColobotError('Invalid vertex') + vertex.t2[0] = float(tokens[13]) + vertex.t2[1] = float(tokens[14]) + + return vertex + +def read_colobot_material(tokens): + material = ColobotMaterial() + + if (tokens[1] != 'dif'): + raise ColobotError('Invalid material') + material.diffuse[0] = float(tokens[2]) + material.diffuse[1] = float(tokens[3]) + material.diffuse[2] = float(tokens[4]) + material.diffuse[3] = float(tokens[5]) + + if (tokens[6] != 'amb'): + raise ColobotError('Invalid material') + material.ambient[0] = float(tokens[7]) + material.ambient[1] = float(tokens[8]) + material.ambient[2] = float(tokens[9]) + material.ambient[3] = float(tokens[10]) + + if (tokens[11] != 'spc'): + raise ColobotError('Invalid material') + material.specular[0] = float(tokens[12]) + material.specular[1] = float(tokens[13]) + material.specular[2] = float(tokens[14]) + material.specular[3] = float(tokens[15]) + + return material + +def read_colobot_model(filename): + model = ColobotModel() + + file = open(filename, 'r') + lines = file.readlines() + file.close() + + index = 0 + numTriangles = 0 + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'version'): + raise ColobotError('Invalid header') + model.version = int(tokens[1]) + if (model.version != 1): + raise ColobotError('Unknown model file version') + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'total_triangles'): + raise ColobotError('Invalid header') + numTriangles = int(tokens[1]) + + for i in range(0, numTriangles): + t = ColobotTriangle() + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'p1'): + raise ColobotError('Invalid triangle') + t.p[0] = read_colobot_vertex(tokens) + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'p2'): + raise ColobotError('Invalid triangle') + t.p[1] = read_colobot_vertex(tokens) + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'p3'): + raise ColobotError('Invalid triangle') + t.p[2] = read_colobot_vertex(tokens) + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'mat'): + raise ColobotError('Invalid triangle') + t.mat = read_colobot_material(tokens) + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'tex1'): + raise ColobotError('Invalid triangle') + if (len(tokens) > 1): + t.tex1 = tokens[1] + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'tex2'): + raise ColobotError('Invalid triangle') + if (len(tokens) > 1): + t.tex2 = tokens[1] + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'var_tex2'): + raise ColobotError('Invalid triangle') + t.var_tex2 = tokens[1] == 'Y' + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'min'): + raise ColobotError('Invalid triangle') + t.min = float(tokens[1]) + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'max'): + raise ColobotError('Invalid triangle') + t.max = float(tokens[1]) + + tokens, index = token_next_line(lines, index) + if (tokens[0] != 'state'): + raise ColobotError('Invalid triangle') + t.state = int(tokens[1]) + + model.triangles.append(t) + + return model + +def mesh_to_colobot_model(mesh, scene, defaults): + model = ColobotModel() + + if (mesh.type != 'MESH'): + raise ColobotError('Only mesh meshs can be exported') + + for poly in mesh.data.polygons: + if (poly.loop_total > 3): + raise ColobotError('Cannot export polygons with > 3 vertices!') + + for i, poly in enumerate(mesh.data.polygons): + t = ColobotTriangle() + j = 0 + for loop_index in poly.loop_indices: + v = mesh.data.vertices[mesh.data.loops[loop_index].vertex_index] + + t.p[j].coord = copy.copy(v.co) + t.p[j].normal = copy.copy(v.normal) + + if (len(mesh.data.uv_layers) >= 1): + t.p[j].t1 = copy.copy(mesh.data.uv_layers[0].data[loop_index].uv) + t.p[j].t1[1] = 1.0 - t.p[j].t1[1] + if (len(mesh.data.uv_layers) >= 2): + t.p[j].t2 = copy.copy(mesh.data.uv_layers[1].data[loop_index].uv) + t.p[j].t2[1] = 1.0 - t.p[j].t2[1] + + j = j + 1 + + mat = mesh.data.materials[poly.material_index] + t.mat.diffuse = v3to4(mat.diffuse_color) + t.mat.diffuse[3] = mat.alpha + t.mat.ambient = v3to4(scene.world.ambient_color * mat.ambient) + t.mat.ambient[3] = mat.alpha + t.mat.specular = v3to4(mat.specular_color) + t.mat.specular[3] = mat.specular_alpha + + if (mat.texture_slots[0] != None): + t.tex1 = bpy.path.basename(mat.texture_slots[0].texture.image.filepath) + if (mat.texture_slots[1] != None): + t.tex2 = bpy.path.basename(mat.texture_slots[1].texture.image.filepath) + + t.var_tex2 = mesh.get('var_tex2', defaults['var_tex2']) + t.state = mesh.get('state', defaults['state']) + t.min = mesh.get('min', defaults['min']) + t.max = mesh.get('max', defaults['max']) + + model.triangles.append(t) + + return model + + +def colobot_model_to_mesh(model, mesh_name, texture_dir): + mesh = bpy.data.meshes.new(name=mesh_name) + + vertex_set = set() + + for t in model.triangles: + for i in range(0, 3): + vertex_set.add(t.p[i]) + + vertex_list = list(vertex_set) + + mat_set = set() + + for t in model.triangles: + mat = t.mat + mat.tex1 = t.tex1 + mat.tex2 = t.tex2 + mat_set.add(mat) + + mat_list = list(mat_set) + + uv1map = False + uv2map = False + + zero_t = array.array('f', [0.0, 0.0]) + + for v in vertex_list: + if ((not uv1map) and (v.t1 != zero_t)): + uv1map = True + if ((not uv2map) and (v.t2 != zero_t)): + uv2map = True + + mesh.vertices.add(len(vertex_list)) + + for i, v in enumerate(mesh.vertices): + v.co = copy.copy(vertex_list[i].coord) + v.normal = copy.copy(vertex_list[i].normal) + + for i, m in enumerate(mat_list): + material = bpy.data.materials.new(name=mesh_name + '_mat_' + str(i+1)) + material.diffuse_color = v4to3(m.diffuse) + material.ambient = (m.ambient[0] + m.ambient[1] + m.ambient[2]) / 3.0 + material.alpha = (m.diffuse[3] + m.ambient[3]) / 2.0 + material.specular_color = v4to3(m.specular) + material.specular_alpha = m.specular[3] + + mesh.materials.append(material) + + mesh.tessfaces.add(len(model.triangles)) + + for i, f in enumerate(mesh.tessfaces): + t = model.triangles[i] + mat = t.mat + mat.tex1 = t.tex1 + mat.tex2 = t.tex2 + f.material_index = mat_list.index(mat) + for i in range(0, 3): + f.vertices[i] = vertex_list.index(t.p[i]) + + if uv1map: + uvlay1 = mesh.tessface_uv_textures.new(name='UV_1') + for i, f in enumerate(uvlay1.data): + f.uv1[0] = model.triangles[i].p[0].t1[0] + f.uv1[1] = 1.0 - model.triangles[i].p[0].t1[1] + f.uv2[0] = model.triangles[i].p[1].t1[0] + f.uv2[1] = 1.0 - model.triangles[i].p[1].t1[1] + f.uv3[0] = model.triangles[i].p[2].t1[0] + f.uv3[1] = 1.0 - model.triangles[i].p[2].t1[1] + + if uv2map: + uvlay2 = mesh.tessface_uv_textures.new(name='UV_2') + for i, f in enumerate(uvlay2.data): + f.uv1[0] = model.triangles[i].p[0].t2[0] + f.uv1[1] = 1.0 - model.triangles[i].p[0].t2[1] + f.uv2[0] = model.triangles[i].p[1].t2[0] + f.uv2[1] = 1.0 - model.triangles[i].p[1].t2[1] + f.uv3[0] = model.triangles[i].p[2].t2[0] + f.uv3[1] = 1.0 - model.triangles[i].p[2].t2[1] + + def load_tex(name): + import os + import sys + from bpy_extras.image_utils import load_image + + if (name == ''): + return None, None + + encoding = sys.getfilesystemencoding() + image = load_image(name, texture_dir, recursive=True, place_holder=True) + texture = None + if image: + name = bpy.path.display_name_from_filepath(name) + texture = bpy.data.textures.new(name=name, type='IMAGE') + texture.image = image + return image, texture + + for i, m in enumerate(mat_list): + + image1, tex1 = load_tex(m.tex1) + if image1: + mtex = mesh.materials[i].texture_slots.add() + mtex.texture = tex1 + mtex.texture_coords = 'UV' + mtex.uv_layer = 'UV_1' + mtex.use_map_color_diffuse = True + + for j, face in enumerate(mesh.uv_textures[0].data): + if (model.triangles[j].tex1 == m.tex1): + face.image = image1 + + image2, tex2 = load_tex(m.tex2) + if image2: + mtex = mesh.materials[i].texture_slots.add() + mtex.texture = tex2 + mtex.texture_coords = 'UV' + mtex.uv_layer = 'UV_2' + mtex.use_map_color_diffuse = True + + for face in mesh.uv_textures[1].data: + if (model.triangles[j].tex2 == m.tex2): + face.image = image2 + + mesh.validate() + mesh.update() + + return mesh + +class ExportColobot(bpy.types.Operator): + """Exporter to Colobot text format""" + bl_idname = "export.colobot" + bl_label = "Export to Colobot" + + # TODO: set the following in a UI dialog or panel + + # Variable tex2 + DEFAULT_VAR_TEX2 = False + # Min & max LOD + DEFAULT_MIN = 0.0 + DEFAULT_MAX = 0.0 + # Render state + DEFAULT_STATE = 0 + + filepath = bpy.props.StringProperty(subtype="FILE_PATH") + + @classmethod + def poll(cls, context): + return context.object is not None + + def execute(self, context): + defaults = { + 'var_tex2': self.DEFAULT_VAR_TEX2, + 'min': self.DEFAULT_MIN, + 'max': self.DEFAULT_MAX, + 'state': self.DEFAULT_STATE } + try: + model = mesh_to_colobot_model(context.object, context.scene, defaults) + write_colobot_model(self.filepath, model) + except ColobotError as e: + self.report({'ERROR'}, e.args[0]) + return {'FINISHED'} + + self.report({'INFO'}, 'Export OK') + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + + +# For menu item +def export_menu_func(self, context): + self.layout.operator_context = 'INVOKE_DEFAULT' + self.layout.operator(ExportColobot.bl_idname, text="Colobot (Text Format)") + +# Register and add to the file selector +bpy.utils.register_class(ExportColobot) +bpy.types.INFO_MT_file_export.append(export_menu_func) + + + +class ImportColobot(bpy.types.Operator): + """Importer from Colobot text format""" + bl_idname = "import.colobot" + bl_label = "Import from Colobot" + + filepath = bpy.props.StringProperty(subtype="FILE_PATH") + + @classmethod + def poll(cls, context): + return True + + def execute(self, context): + try: + model = read_colobot_model(self.filepath) + mesh = colobot_model_to_mesh(model, 'ColobotMesh', os.path.dirname(self.filepath)) + obj = bpy.data.objects.new('ColobotMesh', mesh) + bpy.context.scene.objects.link(obj) + bpy.context.scene.objects.active = obj + obj.select = True + except ColobotError as e: + self.report({'ERROR'}, e.args[0]) + return {'FINISHED'} + + self.report({'INFO'}, 'Import OK') + return {'FINISHED'} + + def invoke(self, context, event): + context.window_manager.fileselect_add(self) + return {'RUNNING_MODAL'} + + +# For menu item +def import_menu_func(self, context): + self.layout.operator_context = 'INVOKE_DEFAULT' + self.layout.operator(ImportColobot.bl_idname, text="Colobot (Text Format)") + +# Register and add to the file selector +bpy.utils.register_class(ImportColobot) +bpy.types.INFO_MT_file_import.append(import_menu_func) |