diff --git a/AndroidSetup.md b/AndroidSetup.md new file mode 100644 index 0000000000..5dfa85d5a9 --- /dev/null +++ b/AndroidSetup.md @@ -0,0 +1,68 @@ +# How to Set Up an Android Development Environment + +If you'd like to contribute to the Android project, but do not currently have a development environment setup, follow the instructions in this guide. + +## Prerequisites + +* A Linux VM or host, or a Mac. +* JDK 7 for your platform. +* CMake +* [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html) +* [Android Studio](http://developer.android.com/tools/studio/index.html) **OR** +* [Android SDK Tools](http://developer.android.com/sdk/index.html#Other) (for command-line usage) + +If you downloaded Android Studio, extract it and then see [Setting up Android Studio](#setting-up-android-studio). + +If you instead chose to download the commoand-line SDK tools, see [Setting up the SDK Tools](#setting-up-the-sdk-tools). + +## Setting up Android Studio + +1. Launch Android Studio, which will start a first-launch wizard. +2. Choose a custom installation. +3. If offered a choice of themes, select your preference. +4. When offered a choice of components, uncheck the "Android Virtual Device" option. ![Android Studio Components][components] +5. Accept all licenses, and click Finish. Android Studio will download the SDK Tools package automatically. (Ubuntu users, if you get an error running the `mksdcard` tool, make sure the `lib32stdc++6` package is installed.) +6. At the Android Studio welcome screen, click "Configure", then "SDK Manager". +7. Use the SDK Manager to get necessary dependencies, as described in [Getting Dependencies](#getting-dependencies). +8. When done, follow the steps in [Readme.md](Readme.md#installation-on-android) to compile and deploy the application. + +## Setting up the SDK Tools + +1. In `Source/Android`, create a file called `local.properties`. +2. Add a single line: `sdk.dir=`, where `` is the path where you extracted the SDK Tools package. +3. Follow the steps in [Readme.md](Readme.md#installation-on-android) to compile and deploy the application. + +## Executing Gradle Tasks + +In Android Studio, you can find a list of possible Gradle tasks in a tray at the top right of the screen: + +![Gradle Tasks][gradle] + +Double clicking any of these tasks will execute it, and also add it to a short list in the main toolbar: + +![Gradle Task Shortcuts][shortcut] + +Clicking the green triangle next to this list will execute the currently selected task. + +For command-line users, any task may be executed with `Source/Android/gradlew `. + +## Getting Dependencies + +Most dependencies for the Android project are supplied by Gradle automatically. However, Android platform libraries (and a few Google-supplied supplementary libraries) must be downloaded through the Android package manager. + +1. Launch the Android SDK Manager from the commandline by executing `/tools/android`, or by clicking on its icon in Android Studio's main toolbar: +![Android Studio Package Icon][package-icon] +2. At the bottom of the window, click "Deselect All", and then "Updates". +3. Install or update the following packages: + +* SDK Platform, under "Android 5.0.1 (API 21)". This will allow compiling apps that target Lollipop. +* Android Support Repository +* Android Support Library +* Google Repository + +In the future, if the project targets a newer version of Android, or use newer versions of the tools/build-tools packages, it will be necessary to use this tool to download updates. + +[components]: http://i.imgur.com/Oo1Fs93.png +[package-icon]: http://i.imgur.com/NUpkAH8.png +[gradle]: http://i.imgur.com/dXIH6o3.png +[shortcut]: http://i.imgur.com/eCWP4Yy.png \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f7afb60cee..291efeed84 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,18 @@ option(ENABLE_QT "Enable Qt (use the experimental Qt interface)" OFF) option(ENABLE_PCH "Use PCH to speed up compilation" ON) option(ENABLE_LTO "Enables Link Time Optimization" OFF) option(ENABLE_GENERIC "Enables generic build that should run on any little-endian host" OFF) + +# Enable SDL for default on operating systems that aren't OSX, Android, Linux or Windows. +if(NOT APPLE AND NOT ANDROID AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT MSVC) + option(ENABLE_SDL "Enables SDL as a generic controller backend" ON) +else() + option(ENABLE_SDL "Enables SDL as a generic controller backend" OFF) +endif() + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux" AND NOT ANDROID) + option(ENABLE_EVDEV "Enables the evdev controller backend" ON) +endif() + if(APPLE) option(OSX_USE_DEFAULT_SEARCH_PATH "Don't prioritize system library paths" OFF) endif() @@ -300,6 +312,14 @@ if(WIN32) add_definitions(-D_CRT_SECURE_NO_DEPRECATE) endif(WIN32) +# Dolphin requires threads. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, we will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type (Release/Debug/RelWithDebInfo/MinSizeRe)" FORCE) @@ -508,6 +528,19 @@ if(USE_EGL) add_definitions(-DUSE_EGL=1) endif() +if(ENABLE_EVDEV) + include(FindLibudev REQUIRED) + include(FindLibevdev REQUIRED) + if(LIBUDEV_FOUND AND LIBEVDEV_FOUND) + message("libevdev/libudev found, enabling evdev controller backend") + add_definitions(-DHAVE_LIBUDEV=1) + add_definitions(-DHAVE_LIBEVDEV=1) + include_directories(${LIBUDEV_INCLUDE_DIR} ${LIBEVDEV_INCLUDE_DIR}) + else() + message(FATAL_ERROR "Couldn't find libevdev and/or libudev. Can't build evdev controller backend.\nDisable ENABLE_EVDEV if you wish to build without controller support") + endif() +endif() + ######################################## # Setup include directories (and make sure they are preferred over the Externals) # @@ -614,26 +647,21 @@ if(OPENAL_FOUND) endif() endif() -if(NOT ANDROID) - if(NOT APPLE) - include(FindSDL2 OPTIONAL) - endif() +if(ENABLE_SDL) + include(FindSDL2 OPTIONAL) if(SDL2_FOUND) message("Using shared SDL2") add_definitions(-DHAVE_SDL=1) include_directories(${SDL2_INCLUDE_DIR}) else(SDL2_FOUND) # SDL2 not found, try SDL - if(NOT APPLE) - include(FindSDL OPTIONAL) - endif() + include(FindSDL OPTIONAL) if(SDL_FOUND) message("Using shared SDL") add_definitions(-DHAVE_SDL=1) include_directories(${SDL_INCLUDE_DIR}) else(SDL_FOUND) message("SDL NOT found, disabling SDL input") - add_definitions(-DHAVE_SDL=0) endif(SDL_FOUND) endif(SDL2_FOUND) endif() @@ -839,7 +867,7 @@ add_custom_command(TARGET unittests POST_BUILD COMMAND ${CMAKE_CTEST_COMMAND}) ######################################## # Start compiling our code # -add_definitions(-std=gnu++0x) +add_definitions(-std=c++1y) # These aren't actually needed for C11/C++11 # but some dependencies require them (LLVM, libav). diff --git a/CMakeTests/FindLLVM.cmake b/CMakeTests/FindLLVM.cmake index 7fe664f6ef..cfcfaedb92 100644 --- a/CMakeTests/FindLLVM.cmake +++ b/CMakeTests/FindLLVM.cmake @@ -1,6 +1,9 @@ # This file only exists because LLVM's cmake files are broken. # This affects both LLVM 3.4 and 3.5. # Hopefully when they fix their cmake system we don't need this garbage. + +include(CheckLibraryExists) + list(APPEND LLVM_CONFIG_EXECUTABLES "llvm-config") list(APPEND LLVM_CONFIG_EXECUTABLES "llvm-config-3.5") list(APPEND LLVM_CONFIG_EXECUTABLES "llvm-config-3.4") @@ -11,13 +14,16 @@ foreach(LLVM_CONFIG_NAME ${LLVM_CONFIG_EXECUTABLES}) execute_process(COMMAND ${LLVM_CONFIG_EXE} --version OUTPUT_VARIABLE LLVM_PACKAGE_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE ) if (${LLVM_PACKAGE_VERSION} VERSION_GREATER "3.3") - set(LLVM_FOUND 1) execute_process(COMMAND ${LLVM_CONFIG_EXE} --includedir OUTPUT_VARIABLE LLVM_INCLUDE_DIRS OUTPUT_STRIP_TRAILING_WHITESPACE ) execute_process(COMMAND ${LLVM_CONFIG_EXE} --ldflags OUTPUT_VARIABLE LLVM_LDFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE ) - set(LLVM_LIBRARIES "${LLVM_LDFLAGS} -lLLVM-${LLVM_PACKAGE_VERSION}") - break() + check_library_exists(LLVM-${LLVM_PACKAGE_VERSION} LLVMVerifyFunction "${LLVM_LDFLAGS}" HAVE_DYNAMIC_LLVM_${LLVM_PACKAGE_VERSION}) + if (HAVE_DYNAMIC_LLVM_${LLVM_PACKAGE_VERSION}) + set(LLVM_LIBRARIES "${LLVM_LDFLAGS} -lLLVM-${LLVM_PACKAGE_VERSION}") + set(LLVM_FOUND 1) + break() + endif() endif() endif() endforeach() diff --git a/CMakeTests/FindLibevdev.cmake b/CMakeTests/FindLibevdev.cmake new file mode 100644 index 0000000000..e89a5f229d --- /dev/null +++ b/CMakeTests/FindLibevdev.cmake @@ -0,0 +1,33 @@ +# - Try to find libevdev +# Once done this will define +# LIBEVDEV_FOUND - System has libevdev +# LIBEVDEV_INCLUDE_DIRS - The libevdev include directories +# LIBEVDEV_LIBRARIES - The libraries needed to use libevdev + +find_package(PkgConfig) +pkg_check_modules(PC_LIBEVDEV QUIET libevdev) + +FIND_PATH( + LIBEVDEV_INCLUDE_DIR libevdev/libevdev.h + HINTS ${PC_LIBEVDEV_INCLUDEDIR} ${PC_LIBEVDEV_INCLUDE_DIRS} + /usr/include + /usr/local/include + ${LIBEVDEV_PATH_INCLUDES} +) + +FIND_LIBRARY( + LIBEVDEV_LIBRARY + NAMES evdev libevdev + HINTS ${PC_LIBEVDEV_LIBDIR} ${PC_LIBEVDEV_LIBRARY_DIRS} + PATHS ${ADDITIONAL_LIBRARY_PATHS} + ${LIBEVDEV_PATH_LIB} +) + +set(LIBEVDEV_LIBRARIES ${LIBEVDEV_LIBRARY} ) +set(LIBEVDEV_INCLUDE_DIRS ${LIBEVDEV_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(libevdev DEFAULT_MSG + LIBEVDEV_LIBRARY LIBEVDEV_INCLUDE_DIR) + +mark_as_advanced(LIBEVDEV_INCLUDE_DIR LIBEVDEV_LIBRARY ) diff --git a/CMakeTests/FindLibudev.cmake b/CMakeTests/FindLibudev.cmake new file mode 100644 index 0000000000..2b71e4e605 --- /dev/null +++ b/CMakeTests/FindLibudev.cmake @@ -0,0 +1,28 @@ +# - Try to find LIBUDEV +# Once done this will define +# LIBUDEV_FOUND - System has LIBUDEV +# LIBUDEV_INCLUDE_DIRS - The LIBUDEV include directories +# LIBUDEV_LIBRARIES - The libraries needed to use LIBUDEV + +FIND_PATH( + LIBUDEV_INCLUDE_DIR libudev.h + /usr/include + /usr/local/include + ${LIBUDEV_PATH_INCLUDES} +) + +FIND_LIBRARY( + LIBUDEV_LIBRARY + NAMES udev libudev + PATHS ${ADDITIONAL_LIBRARY_PATHS} + ${LIBUDEV_PATH_LIB} +) + +set(LIBUDEV_LIBRARIES ${LIBUDEV_LIBRARY} ) +set(LIBUDEV_INCLUDE_DIRS ${LIBUDEV_INCLUDE_DIR} ) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(LIBUDEV DEFAULT_MSG + LIBUDEV_LIBRARY LIBUDEV_INCLUDE_DIR) + +mark_as_advanced(LIBUDEV_INCLUDE_DIR LIBUDEV_LIBRARY ) diff --git a/CMakeTests/FindPolarSSL.cmake b/CMakeTests/FindPolarSSL.cmake index 32302a9780..a209f2f2a1 100644 --- a/CMakeTests/FindPolarSSL.cmake +++ b/CMakeTests/FindPolarSSL.cmake @@ -34,6 +34,7 @@ if (POLARSSL_FOUND) set(CMAKE_REQUIRED_LIBRARIES ${POLARSSL_LIBRARY}) unset(POLARSSL_WORKS CACHE) check_cxx_source_compiles(" + #include #include #include #include diff --git a/CMakeTests/FindSDL2.cmake b/CMakeTests/FindSDL2.cmake index 614426cccf..aef817ec6a 100644 --- a/CMakeTests/FindSDL2.cmake +++ b/CMakeTests/FindSDL2.cmake @@ -172,9 +172,22 @@ IF(SDL2_LIBRARY_TEMP) SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") SET(SDL2_FOUND "YES") + + # extract the major and minor version numbers from SDL2/SDL_version.h + # we have to handle framework a little bit differently : + if("${SDL2_INCLUDE_DIR}" MATCHES ".framework") + set(SDL2_VERSION_H_INPUT "${SDL2_INCLUDE_DIR}/Headers/SDL_version.h") + else() + set(SDL2_VERSION_H_INPUT "${SDL2_INCLUDE_DIR}/SDL_version.h") + endif() + FILE(READ "${SDL2_VERSION_H_INPUT}" SDL2_VERSION_H_CONTENTS) + STRING(REGEX REPLACE ".*#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+).*#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+).*#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+).*" + "\\1.\\2.\\3" SDL2_VERSION "${SDL2_VERSION_H_CONTENTS}") +#MESSAGE("SDL2 Version is ${SDL2_VERSION}") + ENDIF(SDL2_LIBRARY_TEMP) INCLUDE(FindPackageHandleStandardArgs) FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 - REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) + REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR VERSION_VAR SDL2_VERSION) diff --git a/Data/Sys/GC/dsp_coef.bin b/Data/Sys/GC/dsp_coef.bin index a276f2cede..1137fd741e 100644 Binary files a/Data/Sys/GC/dsp_coef.bin and b/Data/Sys/GC/dsp_coef.bin differ diff --git a/Data/Sys/GameSettings/FB2.ini b/Data/Sys/GameSettings/FB2.ini new file mode 100644 index 0000000000..ee42a85e06 --- /dev/null +++ b/Data/Sys/GameSettings/FB2.ini @@ -0,0 +1,29 @@ +# FB2E01, FB2P01 - Super Mario Bros. The Lost Levels + +[Core] +# Values set here will override the main Dolphin settings. + +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationStateId = 4 +EmulationIssues = Texture filtering will cause glitches. + +[OnLoad] +# Add memory patches to be loaded once on boot here. + +[OnFrame] +# Add memory patches to be applied every frame here. + +[ActionReplay] +# Add action replay cheats here. + +[Video_Settings] +SafeTextureCacheColorSamples = 0 +EFBScale = 2 + +[Video_Hacks] +EFBToTextureEnable = False + +[Video_Enhancements] +MaxAnisotropy = 0 +ForceFiltering = False diff --git a/Data/Sys/GameSettings/FFY.ini b/Data/Sys/GameSettings/FFY.ini new file mode 100644 index 0000000000..12c0b16789 --- /dev/null +++ b/Data/Sys/GameSettings/FFY.ini @@ -0,0 +1,29 @@ +# FFYE01, FFYJ01, FFYP01 - Mega Man 5 + +[Core] +# Values set here will override the main Dolphin settings. + +[EmuState] +# The Emulation State. 1 is worst, 5 is best, 0 is not set. +EmulationIssues = Texture filtering will cause glitches. +EmulationStateId = 4 + +[OnLoad] +# Add memory patches to be loaded once on boot here. + +[OnFrame] +# Add memory patches to be applied every frame here. + +[ActionReplay] +# Add action replay cheats here. + +[Video_Settings] +SafeTextureCacheColorSamples = 0 +EFBScale = 2 + +[Video_Hacks] +EFBToTextureEnable = False + +[Video_Enhancements] +MaxAnisotropy = 0 +ForceFiltering = False diff --git a/Data/Sys/GameSettings/G2R.ini b/Data/Sys/GameSettings/G2R.ini index 62d18fb189..c51e5f9e70 100644 --- a/Data/Sys/GameSettings/G2R.ini +++ b/Data/Sys/GameSettings/G2R.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,8 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[Video] - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GAC.ini b/Data/Sys/GameSettings/GAC.ini index 8d8f467164..71d035b6d1 100644 --- a/Data/Sys/GameSettings/GAC.ini +++ b/Data/Sys/GameSettings/GAC.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,6 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GAFE01.ini b/Data/Sys/GameSettings/GAFE01.ini index 069b9b3e83..4a89878d74 100644 --- a/Data/Sys/GameSettings/GAFE01.ini +++ b/Data/Sys/GameSettings/GAFE01.ini @@ -167,7 +167,7 @@ $NES Balloon Fight - P2 Infinite Lives (donny2112) $NES Clu Clu Land - P1 Infinite Lives (donny2112) 01527EEE 08000000 01659020 00000009 -$NES Clu Clu Land - Max out Clock (C-stick Right) (donny2112) +$NES Clu Clu Land - Max out Clock (C Stick Right) (donny2112) 01523F59 08000000 BD2F5408 00010000 03658FCE 00000999 @@ -175,7 +175,7 @@ BD2F5408 00010000 $NES Clu Clu Land D - P1 Infinite Lives (donny2112) 01527EEE 08000000 01659020 00000009 -$NES Clu Clu Land D - Max out Clock (C-stick Right) (donny2112) +$NES Clu Clu Land D - Max out Clock (C Stick Right) (donny2112) 01526C12 08000000 BD2F5408 00010000 03658FC6 00000999 @@ -183,7 +183,7 @@ BD2F5408 00010000 $NES Donkey Kong - P1 Infinite Lives (donny2112) 01523F81 08000000 01658FF5 00000009 -$NES Donkey Kong - Jump to get Hammer (Hold A+C-stick Right) (donny2112) +$NES Donkey Kong - Jump to get Hammer (Hold A + C Stick Right) (donny2112) 015246D9 08000000 BD2F5408 00810000 01659040 00000001 @@ -237,7 +237,7 @@ $NES Legend of Zelda - Have Magical Shield (donny2112) $NES Legend of Zelda - Max Hearts/Invincibility (donny2112) 01521605 08000000 0165960F 000000FF -$NES Legend of Zelda - Freeze Enemies (C-stick Left) (donny2112) +$NES Legend of Zelda - Freeze Enemies (C Stick Left) (donny2112) 01527C62 08000000 BD2F5408 00020000 0165960C 00000001 diff --git a/Data/Sys/GameSettings/GALE01r0.ini b/Data/Sys/GameSettings/GALE01r0.ini index 68c453a52e..154cbe80a3 100644 --- a/Data/Sys/GameSettings/GALE01r0.ini +++ b/Data/Sys/GameSettings/GALE01r0.ini @@ -319,10 +319,10 @@ C225910C 00000025 C022C9E8 00000000 # Gameplay Codes -$Normal C-Stick Functionality in Singleplayer Modes [Zauron] +$Normal C Stick Functionality in Singleplayer Modes [Zauron] 0416AB64 60000000 -$Normal C-Stick Functionality in Develop Mode [Magus, Achilles] +$Normal C Stick Functionality in Develop Mode [Magus, Achilles] *Does not work with Nana 0406AD38 38000000 04030024 38000000 diff --git a/Data/Sys/GameSettings/GALE01r1.ini b/Data/Sys/GameSettings/GALE01r1.ini index 723d0eaed3..356d94b040 100644 --- a/Data/Sys/GameSettings/GALE01r1.ini +++ b/Data/Sys/GameSettings/GALE01r1.ini @@ -40,10 +40,10 @@ $Spoof Controller Plugins (P4) [Achilles] 04375F24 38000001 # Gameplay Codes -$Normal C-Stick Functionality in Singleplayer Modes [Zauron, Standardtoaster] +$Normal C Stick Functionality in Singleplayer Modes [Zauron, Standardtoaster] 0416B18C 60000000 -$Normal C-Stick Functionality in Develop Mode [Magus, Achilles] +$Normal C Stick Functionality in Develop Mode [Magus, Achilles] *Does not work with Nana 0406AE48 38000000 040300A4 38000000 diff --git a/Data/Sys/GameSettings/GALE01r2.ini b/Data/Sys/GameSettings/GALE01r2.ini index 1aaa9c3ce2..f2ea4743e3 100644 --- a/Data/Sys/GameSettings/GALE01r2.ini +++ b/Data/Sys/GameSettings/GALE01r2.ini @@ -1,28 +1,6 @@ # GALE01 - Super Smash Bros. Melee [ActionReplay] -$Global Melee Netplay Settings -0445BF28 FFFFFFFF -0445BF2C FFFFFFFF -0045C370 000000FF -0045BF12 00000001 -0045BF18 00000008 -0045BF14 00000004 -0045BF18 00000008 -041A45A0 3C000202 -041A45A4 901E0000 -0422D638 38000006 -0416B480 60000000 -0445C388 470000B0 -0445C20C 39400000 -0245C390 00030000 -0445C0D4 01010100 -0045C110 00000001 -0445C230 10000000 -0045C114 00000027 -0445C228 80000000 -0045C22C 00001111 - $Items Off 0045C370 000000FF @@ -42,7 +20,7 @@ $Boot to Character Select [Dan Salvato] $Debug Menu 0422D638 38000006 -$C-Stick in Single Player [Zauron] +$C Stick in Single Player [Zauron] 0416B480 60000000 $Disable Peach's Castle Bullets [Zauron] @@ -147,9 +125,6 @@ $Input Delay Tester [Dan Salvato] $Widescreen Support v1.2 [Dan Salvato] 04BDC5E4 3FCFC217 -$Netplay Safe Kill Music [JMC47] -024D3886 00000000 - $Tournament Stages Only for Random 0445C388 47000090 @@ -168,6 +143,221 @@ $True Special Message Delete [JMC47] [Gecko] # General Codes +$Netplay Community Settings +*Boot to CSS, unlock everything, 4 stock 8 minute friendly fire on, trophy messages off, +*L+R+A+Start during stage load returns to CSS, name tags don't reset on close or exit, +*L-cancel % on results screen, normal C Stick functionality in 1P modes, +*Stage striking, A+B salty runback, unrestricted pause camera, C Stick pause camera translation, +*Normal C Stick functionality in develop mode, debug menu access and set to English, +*Universal debug menu control, leaving debug menu loads CSS, 20XXTE neutral spawns +0445BF28 FFFFFFFF +0445BF2C FFFFFFFF +0415d94c 4e800020 +041a45a0 3c000202 +041a45a4 901e0000 +C21BFA20 00000003 +3DE08017 61EF2898 +7DE903A6 4E800421 +38600002 00000000 +0424cec4 48000058 +04162ee8 60000000 +0245C390 00000125 +0245C395 01266363 +041644E8 38600001 +041648F4 38600001 +04164F34 38600001 +043D4A48 00340102 +043D4A4C 04000A00 +043D4A50 08010100 +043D4A60 FF000000 +043D4A70 00000000 +043D4A78 E70000B0 +0415d984 4e800020 +0425b8bc 38600002 +04261B1C 60000000 +04261B30 60000000 +041A55EC 4E800020 +C208D600 00000009 +8A830678 3DC08000 +61CE45D4 1EB40008 +7DCEAA14 81EE0000 +39EF0001 91EE0000 +3A0EFFFC 82300000 +7E717BD6 3E408045 +62523DA4 1EB40E90 +7E52AA14 92720000 +3880FFFF 00000000 +C208D6A4 00000009 +8A830678 3DC08000 +61CE45D4 1EB40008 +7DCEAA14 81EE0000 +3A0EFFFC 82300000 +3A310064 92300000 +7E717BD6 3E408045 +62523DA4 1EB40E90 +7E52AA14 92720000 +EC010024 00000000 +04040BBC 60000000 +20C61DB8 16200D20 +06C61DB8 00000014 +1620151A 200C2024 +20312026 2028202F +1A210300 00000000 +020045D0 000F0000 +E2000001 00000000 +C225A3BC 00000025 +39E00001 3E008046 +6210B0FC 1E2F000C +7E31802E 5630014B +4182000C 3A200001 +48000020 56300109 +4182000C 3A200002 +48000010 563002D7 +418200DC 3A200003 +3EA0803F 62B506D0 +3EC0804D 62D66CAE +3A800000 3A600000 +3A400000 2C110001 +40820014 8A560000 +2C12001C 418100A8 +48000050 2C110003 +40820010 3A80003F +3A600002 4800003C +1E12001C 7E10AA14 +8AF0000A 3E008045 +6210C388 82100000 +7E10BC30 561007FF +41820010 3A600002 +3A80003F 4800000C +3A600000 3A800000 +1E12001C 7E10A82E +2C120016 41800008 +82100010 82100018 +82100004 82100008 +8210001C 82100008 +9A900000 1E12001C +3A100008 7E70A9AE +3A00001E 9A160000 +2C110001 41820010 +3A520001 2C12001D +41A0FF4C 39EF0001 +2C0F0005 41A0FEE8 +C022C9E8 00000000 +C216E2DC 00000017 +3C608000 60633300 +3C80804D 88846CAE +38C00000 7CA6182E +7C052000 41820014 +2C05FFFF 4182000C +38C6000C 4BFFFFE8 +38C60004 3CE08048 +88E707C8 2C070000 +41820008 38C60004 +7CA6182E 90A3FFFC +4182005C 39000000 +3C80803F 60840E06 +80E40000 39080001 +2C080004 40800040 +1D280024 7CC9202E +7C063800 4082FFE8 +3863FFFC 7D064378 +38C6FFFF 2C060000 +4081001C 7C8618AE +7CA818AE 7CA619AE +7C8819AE 3908FFFF +4BFFFFE0 881F0007 +60000000 00000000 +C216E48C 00000004 +3CA08000 60A532FC +8085FFFC 7C6428AE +38840001 9085FFFC +60000000 00000000 +C216DF54 00000004 +3CA08000 60A532FC +8085FFFC 7C6428AE +38840001 9085FFFC +60000000 00000000 +C216DF30 00000003 +3C808000 608432F8 +38A00000 90A40000 +3B9A0000 00000000 +C216E468 00000003 +3C808000 608432F8 +38A00000 90A40000 +3F600004 00000000 +06003300 00000060 +00000019 00010203 +00020103 00000008 +00010203 02000301 +00000006 00010302 +03000201 0000001a +01030002 00010203 +00000018 02030001 +00020103 00000012 +03020001 03000201 +0000001c 00030102 +00010302 ffffffff +00010203 00010203 +0416B480 60000000 +C21A4160 00000008 +39C00000 3DE08046 +61EFB108 820F0000 +5611018D 41820010 +561101CF 41820008 +38000002 39CE0001 +2C0E0004 4080000C +39EF000C 4BFFFFD8 +981F0003 00000000 +04452F54 42000000 +04452F58 42000000 +04452F5C 42000000 +04452F60 40200000 +04452F64 47000000 +C202CB34 0000000C +7C040774 3E00804C +62101FD4 1DE00044 +7E107A14 C022C3D8 +FE200850 C1F00000 +FC0F0840 4081000C +FC0F8840 41800010 +C21F0314 FE0F802A +D21F0314 C1F00004 +FC0F0840 4081000C +FC0F8840 41800010 +C21F0318 FE0F802A +D21F0318 00000000 +0406AE90 38000000 +040300A4 38000000 +0422D638 38000006 +043FA25B 01000000 +C23039A4 00000016 +39400000 39000000 +38E00008 3C80804C +608420BC 1CAA0044 +7D242A14 80690008 +70631F10 7D081B78 +80690000 70600020 +41820008 38E00000 +5460C8C6 5060D884 +5060F002 7D080378 +54606006 7D080378 +54604007 4182000C +38E00000 7D080378 +394A0001 2C0A0004 +4180FFA4 7500F000 +41820028 886DB7AC +2C030000 41820014 +3863FFFF 986DB7AC +5508013E 48000014 +98EDB7AC 4800000C +38600000 986DB7AC +7D034378 4E800020 +60000000 00000000 +041b0a14 38600002 + +$Netplay Safe Kill Music [JMC47] +024D3886 00000000 + $Unlock All Characters and Stages [Datel] *Also Unlocks All Star Mode, Sound Test, and Vs. Mode Additions 0445BF28 FFFFFFFF @@ -353,10 +543,10 @@ C223C5A0 0000000F 60000000 00000000 # Gameplay Codes -$Normal C-Stick Functionality in Singleplayer Modes [Zauron] +$Normal C Stick Functionality in Singleplayer Modes [Zauron] 0416B480 60000000 -$Normal C-Stick Functionality in Develop Mode [Magus, Achilles] +$Normal C Stick Functionality in Develop Mode [Magus, Achilles] *Does not work with Nana 0406AE90 38000000 040300A4 38000000 @@ -873,21 +1063,8 @@ C2021ABC 00000002 60000000 00000000 C236A4A8 00000007 C03F0034 2C0E0001 -41820024 3C004260 -90010030 3C00421C -90010034 C0010030 -EC210032 C0010034 -EC210024 39C00000 -281E0000 00000000 - -$Properly Display in 4:3 [Dan Salvato, mirrorbender] -C2021ABC 00000002 -39C00001 38600006 -60000000 00000000 -C236A4A8 00000007 -C03F0034 2C0E0001 -41820024 3C004160 -90010030 3C004150 +41820024 3C004080 +90010030 3C004040 90010034 C0010030 EC210032 C0010034 EC210024 39C00000 diff --git a/Data/Sys/GameSettings/GALP01.ini b/Data/Sys/GameSettings/GALP01.ini index 2a877ee231..d0116b449a 100644 --- a/Data/Sys/GameSettings/GALP01.ini +++ b/Data/Sys/GameSettings/GALP01.ini @@ -222,7 +222,7 @@ C225AEF4 00000025 C022CA40 00000000 # Gameplay Codes -$Normal C-Stick Functionality in Singleplayer Modes [Zauron] +$Normal C Stick Functionality in Singleplayer Modes [Zauron] 0416BE50 60000000 $Skip Result Screen & KO Star Count Equals Placement [Sham Rock] diff --git a/Data/Sys/GameSettings/GAUE08.ini b/Data/Sys/GameSettings/GAUE08.ini index 4e0bed3aad..caaf608444 100644 --- a/Data/Sys/GameSettings/GAUE08.ini +++ b/Data/Sys/GameSettings/GAUE08.ini @@ -31,28 +31,28 @@ $No 4th+ Places $No Top Speed/No Shifting Needed 3A1EA826 00000020 04205CC0 00000000 -$C-Stick Sends Car 1 Back To Start +$C Stick Sends Car 1 Back To Start 3A1EA826 00000080 00206704 00000000 -$C-Stick Sends Car 2 Back To Start +$C Stick Sends Car 2 Back To Start 3A1EA826 00000080 00207264 00000000 -$C-Stick Sends Car 3 Back To Start +$C Stick Sends Car 3 Back To Start 3A1EA826 00000080 00207DC4 00000000 -$C-Stick Sends Car 4 Back To Start +$C Stick Sends Car 4 Back To Start 3A1EA826 00000080 00208924 00000000 -$C-Stick Sends Car 5 Back To Start +$C Stick Sends Car 5 Back To Start 3A1EA826 00000080 00209484 00000000 -$C-Stick Sends Car 6 Back To Start +$C Stick Sends Car 6 Back To Start 3A1EA826 00000080 00209FE4 00000000 -$C-Stick Sends Car 7 Back To Start +$C Stick Sends Car 7 Back To Start 3A1EA826 00000080 0020AB44 00000000 -$C-Stick Sends All Car Back To Start +$C Stick Sends All Cars Back To Start 7A1EA826 00000080 00000000 80206704 00000000 00070B60 diff --git a/Data/Sys/GameSettings/GB3.ini b/Data/Sys/GameSettings/GB3.ini index 8336dfd953..936341400c 100644 --- a/Data/Sys/GameSettings/GB3.ini +++ b/Data/Sys/GameSettings/GB3.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,6 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GBV.ini b/Data/Sys/GameSettings/GBV.ini index 24a840e071..0b99af1684 100644 --- a/Data/Sys/GameSettings/GBV.ini +++ b/Data/Sys/GameSettings/GBV.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 3 -EmulationIssues = Needs Real xfb for videos to display. Slow audio with HLE. +EmulationIssues = Needs Real xfb for videos to display. [OnLoad] # Add memory patches to be loaded once on boot here. @@ -21,7 +20,3 @@ EmulationIssues = Needs Real xfb for videos to display. Slow audio with HLE. [Video_Settings] UseXFB = True UseRealXFB = True - -[DSP] -EnableJIT = True - diff --git a/Data/Sys/GameSettings/GBX.ini b/Data/Sys/GameSettings/GBX.ini index 468af38620..6830160bae 100644 --- a/Data/Sys/GameSettings/GBX.ini +++ b/Data/Sys/GameSettings/GBX.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,7 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[DSP] -EnableJIT = True - diff --git a/Data/Sys/GameSettings/GDD.ini b/Data/Sys/GameSettings/GDD.ini index 7c2ff71444..b14da616cc 100644 --- a/Data/Sys/GameSettings/GDD.ini +++ b/Data/Sys/GameSettings/GDD.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. Needs real xfb for the videos to display. +EmulationIssues = Needs real xfb for the videos to display. [OnLoad] # Add memory patches to be loaded once on boot here. @@ -18,11 +17,6 @@ EmulationIssues = Slow audio with HLE. Needs real xfb for the videos to display. [ActionReplay] # Add action replay cheats here. -[Video] - -[DSP] -EnableJIT = True - [Video_Settings] UseXFB = True UseRealXFB = True diff --git a/Data/Sys/GameSettings/GE5.ini b/Data/Sys/GameSettings/GE5.ini index 0777586fdb..22e4998f85 100644 --- a/Data/Sys/GameSettings/GE5.ini +++ b/Data/Sys/GameSettings/GE5.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,6 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GFG.ini b/Data/Sys/GameSettings/GFG.ini index 0f8a20c08d..7e3d551cb4 100644 --- a/Data/Sys/GameSettings/GFG.ini +++ b/Data/Sys/GameSettings/GFG.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Needs real xfb for the videos to display. Slow audio with HLE. +EmulationIssues = Needs real xfb for the videos to display. [OnLoad] # Add memory patches to be loaded once on boot here. @@ -18,9 +17,6 @@ EmulationIssues = Needs real xfb for the videos to display. Slow audio with HLE. [ActionReplay] # Add action replay cheats here. -[DSP] -EnableJIT = True - [Video_Settings] UseXFB = True UseRealXFB = True diff --git a/Data/Sys/GameSettings/GFO.ini b/Data/Sys/GameSettings/GFO.ini index a079bdc637..8f7d5dc444 100644 --- a/Data/Sys/GameSettings/GFO.ini +++ b/Data/Sys/GameSettings/GFO.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,8 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[Video] - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GIL.ini b/Data/Sys/GameSettings/GIL.ini index cb324b63bb..4e40e56094 100644 --- a/Data/Sys/GameSettings/GIL.ini +++ b/Data/Sys/GameSettings/GIL.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 5 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -20,6 +19,3 @@ EmulationIssues = Slow audio with HLE. [Video_Settings] SafeTextureCacheColorSamples = 512 - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GLC.ini b/Data/Sys/GameSettings/GLC.ini index 7f9bb188df..b496c70c5c 100644 --- a/Data/Sys/GameSettings/GLC.ini +++ b/Data/Sys/GameSettings/GLC.ini @@ -21,7 +21,6 @@ EmulationStateId = 4 [Video_Settings] SafeTextureCacheColorSamples = 512 -DstAlphaPass = True [Video_Hacks] EFBToTextureEnable = True diff --git a/Data/Sys/GameSettings/GM8.ini b/Data/Sys/GameSettings/GM8.ini index 9e0ad74502..c4ca582289 100644 --- a/Data/Sys/GameSettings/GM8.ini +++ b/Data/Sys/GameSettings/GM8.ini @@ -21,4 +21,3 @@ EmulationIssues = SafeTextureCacheColorSamples = 512 [Video_Hacks] -EFBToTextureEnable = False diff --git a/Data/Sys/GameSettings/GMN.ini b/Data/Sys/GameSettings/GMN.ini index 636a2126d2..847e98d75b 100644 --- a/Data/Sys/GameSettings/GMN.ini +++ b/Data/Sys/GameSettings/GMN.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Videos require real XFB, slow audio with HLE. +EmulationIssues = Videos require real XFB. [OnLoad] # Add memory patches to be loaded once on boot here. @@ -21,6 +20,3 @@ EmulationIssues = Videos require real XFB, slow audio with HLE. [Video_Settings] UseXFB = True UseRealXFB = True - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GNH.ini b/Data/Sys/GameSettings/GNH.ini index 33f5151d3b..a6cd582b85 100644 --- a/Data/Sys/GameSettings/GNH.ini +++ b/Data/Sys/GameSettings/GNH.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,6 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GOB.ini b/Data/Sys/GameSettings/GOB.ini index 884d708529..eabb4f5eff 100644 --- a/Data/Sys/GameSettings/GOB.ini +++ b/Data/Sys/GameSettings/GOB.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,6 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GP8.ini b/Data/Sys/GameSettings/GP8.ini index e22fa5c61f..8a0ec4bf27 100644 --- a/Data/Sys/GameSettings/GP8.ini +++ b/Data/Sys/GameSettings/GP8.ini @@ -2,12 +2,11 @@ [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Slow audio with HLE. +EmulationIssues = [OnLoad] # Add memory patches to be loaded once on boot here. @@ -17,6 +16,3 @@ EmulationIssues = Slow audio with HLE. [ActionReplay] # Add action replay cheats here. - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/GZ2J01.ini b/Data/Sys/GameSettings/GZ2J01.ini new file mode 100644 index 0000000000..fd5dd774ac --- /dev/null +++ b/Data/Sys/GameSettings/GZ2J01.ini @@ -0,0 +1,40 @@ +# GZ2J01 - The Legend of Zelda: Twilight Princess [GC] + +[EmuState] +EmulationIssues = Enable the "Hyrule Field Speed Hack" patch in game properties for a speed boost. + +[OnLoad] +# Add memory patches to be loaded once on boot here. + +[OnFrame] +$Hyrule Field Speed Hack +0x8003D50C:dword:0x60000000 +0x8003D528:dword:0x60000000 +0x8003D540:dword:0x60000000 +0x8003D55C:dword:0x60000000 +0x8003D55C:dword:0x60000000 +0x8003D560:dword:0x60000000 +0x8003D564:dword:0x60000000 +0x8003D568:dword:0x60000000 +0x8003D56C:dword:0x60000000 +0x8003D570:dword:0x60000000 +0x8003D574:dword:0x60000000 +0x8003D578:dword:0x60000000 +0x8003D57C:dword:0x60000000 +0x8003D580:dword:0x60000000 +0x8003D584:dword:0x60000000 +0x8003D588:dword:0x60000000 +0x8003D58C:dword:0x60000000 +0x8003D590:dword:0x60000000 +0x8003D594:dword:0x60000000 +0x8003D598:dword:0x60000000 +0x8003D59C:dword:0x60000000 +0x8003D5A0:dword:0x60000000 +0x8003D5A4:dword:0x60000000 +0x8003D5A8:dword:0x60000000 +0x8003D5AC:dword:0x60000000 +0x8003D5B0:dword:0x60000000 +0x8003D5B8:dword:0x60000000 +0x8003D5D4:dword:0x60000000 +0x8003D5EC:dword:0x60000000 +0x8003D608:dword:0x60000000 diff --git a/Data/Sys/GameSettings/GZP.ini b/Data/Sys/GameSettings/GZP.ini index 209b040234..e64360681e 100644 --- a/Data/Sys/GameSettings/GZP.ini +++ b/Data/Sys/GameSettings/GZP.ini @@ -1,13 +1,12 @@ -# GZPE70, GZPP70- Zapper +# GZPE70, GZPP70 - Zapper [Core] # Values set here will override the main Dolphin settings. -DSPHLE = False [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. EmulationStateId = 4 -EmulationIssues = Needs real xfb for the videos to display. Slow audio with HLE. +EmulationIssues = Needs real xfb for the videos to display. [OnLoad] # Add memory patches to be loaded once on boot here. @@ -21,6 +20,3 @@ EmulationIssues = Needs real xfb for the videos to display. Slow audio with HLE. [Video_Settings] UseXFB = True UseRealXFB = True - -[DSP] -EnableJIT = True diff --git a/Data/Sys/GameSettings/RSB.ini b/Data/Sys/GameSettings/RSB.ini index be0a7d8d02..aa966b28ce 100644 --- a/Data/Sys/GameSettings/RSB.ini +++ b/Data/Sys/GameSettings/RSB.ini @@ -16,3 +16,6 @@ EmulationIssues = Classic mode score report needs real xfb. Nes masterpieces and [ActionReplay] # Add action replay cheats here. + +[Video_Stereoscopy] +StereoConvergenceMinimum = 136 diff --git a/Data/Sys/GameSettings/SF8.ini b/Data/Sys/GameSettings/SF8.ini index 3757b78967..b924e1d2e1 100644 --- a/Data/Sys/GameSettings/SF8.ini +++ b/Data/Sys/GameSettings/SF8.ini @@ -20,3 +20,5 @@ EmulationIssues = Sound crackling can be fixed by lle audio. [Video_Settings] SafeTextureCacheColorSamples = 512 +[Video_Stereoscopy] +StereoConvergenceMinimum = 26 diff --git a/Data/Sys/GameSettings/SMN.ini b/Data/Sys/GameSettings/SMN.ini index 70e3592672..204d8a32df 100644 --- a/Data/Sys/GameSettings/SMN.ini +++ b/Data/Sys/GameSettings/SMN.ini @@ -5,7 +5,6 @@ [EmuState] # The Emulation State. 1 is worst, 5 is best, 0 is not set. -EmulationIssues = If "Store EFB Copies to Texture Only" is enabled, "Scaled EFB Copy" needs to be disabled for the coins to spin. EmulationStateId = 4 [OnLoad] @@ -20,5 +19,4 @@ EmulationStateId = 4 [Video_Settings] SafeTextureCacheColorSamples = 512 -[Video_Hacks] -EFBScaledCopy = False +[Video_Hacks] \ No newline at end of file diff --git a/Data/Sys/Resources/Flag_Europe.png b/Data/Sys/Resources/Flag_Europe.png index e1b4dbba5a..34282db4af 100644 Binary files a/Data/Sys/Resources/Flag_Europe.png and b/Data/Sys/Resources/Flag_Europe.png differ diff --git a/Data/Sys/Resources/Flag_Europe@2x.png b/Data/Sys/Resources/Flag_Europe@2x.png new file mode 100644 index 0000000000..cc50dcabd7 Binary files /dev/null and b/Data/Sys/Resources/Flag_Europe@2x.png differ diff --git a/Data/Sys/Resources/Flag_Europe@4x.png b/Data/Sys/Resources/Flag_Europe@4x.png new file mode 100644 index 0000000000..e9e8d7c893 Binary files /dev/null and b/Data/Sys/Resources/Flag_Europe@4x.png differ diff --git a/Data/Sys/Resources/Flag_France.png b/Data/Sys/Resources/Flag_France.png index e04c5d2114..6b6b907f38 100644 Binary files a/Data/Sys/Resources/Flag_France.png and b/Data/Sys/Resources/Flag_France.png differ diff --git a/Data/Sys/Resources/Flag_France@2x.png b/Data/Sys/Resources/Flag_France@2x.png new file mode 100644 index 0000000000..a5f2d4d6a3 Binary files /dev/null and b/Data/Sys/Resources/Flag_France@2x.png differ diff --git a/Data/Sys/Resources/Flag_France@4x.png b/Data/Sys/Resources/Flag_France@4x.png new file mode 100644 index 0000000000..4f66b5db26 Binary files /dev/null and b/Data/Sys/Resources/Flag_France@4x.png differ diff --git a/Data/Sys/Resources/Flag_Germany.png b/Data/Sys/Resources/Flag_Germany.png index 7ae9671399..28470211b4 100644 Binary files a/Data/Sys/Resources/Flag_Germany.png and b/Data/Sys/Resources/Flag_Germany.png differ diff --git a/Data/Sys/Resources/Flag_Germany@2x.png b/Data/Sys/Resources/Flag_Germany@2x.png new file mode 100644 index 0000000000..cc4aa1714d Binary files /dev/null and b/Data/Sys/Resources/Flag_Germany@2x.png differ diff --git a/Data/Sys/Resources/Flag_Germany@4x.png b/Data/Sys/Resources/Flag_Germany@4x.png new file mode 100644 index 0000000000..ccb67794aa Binary files /dev/null and b/Data/Sys/Resources/Flag_Germany@4x.png differ diff --git a/Data/Sys/Resources/Flag_International.png b/Data/Sys/Resources/Flag_International.png new file mode 100644 index 0000000000..10ab085f53 Binary files /dev/null and b/Data/Sys/Resources/Flag_International.png differ diff --git a/Data/Sys/Resources/Flag_International@2x.png b/Data/Sys/Resources/Flag_International@2x.png new file mode 100644 index 0000000000..ab6ce847c8 Binary files /dev/null and b/Data/Sys/Resources/Flag_International@2x.png differ diff --git a/Data/Sys/Resources/Flag_International@4x.png b/Data/Sys/Resources/Flag_International@4x.png new file mode 100644 index 0000000000..0bc6e4e884 Binary files /dev/null and b/Data/Sys/Resources/Flag_International@4x.png differ diff --git a/Data/Sys/Resources/Flag_Italy.png b/Data/Sys/Resources/Flag_Italy.png index 9e87c615bf..5840f9fb36 100644 Binary files a/Data/Sys/Resources/Flag_Italy.png and b/Data/Sys/Resources/Flag_Italy.png differ diff --git a/Data/Sys/Resources/Flag_Italy@2x.png b/Data/Sys/Resources/Flag_Italy@2x.png new file mode 100644 index 0000000000..39e18d95e8 Binary files /dev/null and b/Data/Sys/Resources/Flag_Italy@2x.png differ diff --git a/Data/Sys/Resources/Flag_Italy@4x.png b/Data/Sys/Resources/Flag_Italy@4x.png new file mode 100644 index 0000000000..69253dd59c Binary files /dev/null and b/Data/Sys/Resources/Flag_Italy@4x.png differ diff --git a/Data/Sys/Resources/Flag_Japan.png b/Data/Sys/Resources/Flag_Japan.png index e25cd10948..da4c134f26 100644 Binary files a/Data/Sys/Resources/Flag_Japan.png and b/Data/Sys/Resources/Flag_Japan.png differ diff --git a/Data/Sys/Resources/Flag_Japan@2x.png b/Data/Sys/Resources/Flag_Japan@2x.png new file mode 100644 index 0000000000..1c386afb55 Binary files /dev/null and b/Data/Sys/Resources/Flag_Japan@2x.png differ diff --git a/Data/Sys/Resources/Flag_Japan@4x.png b/Data/Sys/Resources/Flag_Japan@4x.png new file mode 100644 index 0000000000..b8664e957b Binary files /dev/null and b/Data/Sys/Resources/Flag_Japan@4x.png differ diff --git a/Data/Sys/Resources/Flag_Korea.png b/Data/Sys/Resources/Flag_Korea.png index d1ae515358..cef3f57180 100644 Binary files a/Data/Sys/Resources/Flag_Korea.png and b/Data/Sys/Resources/Flag_Korea.png differ diff --git a/Data/Sys/Resources/Flag_Korea@2x.png b/Data/Sys/Resources/Flag_Korea@2x.png new file mode 100644 index 0000000000..f72545a9b8 Binary files /dev/null and b/Data/Sys/Resources/Flag_Korea@2x.png differ diff --git a/Data/Sys/Resources/Flag_Korea@4x.png b/Data/Sys/Resources/Flag_Korea@4x.png new file mode 100644 index 0000000000..fe79f85f89 Binary files /dev/null and b/Data/Sys/Resources/Flag_Korea@4x.png differ diff --git a/Data/Sys/Resources/Flag_Netherlands.png b/Data/Sys/Resources/Flag_Netherlands.png index 4f5cd1ab16..7c4719d566 100644 Binary files a/Data/Sys/Resources/Flag_Netherlands.png and b/Data/Sys/Resources/Flag_Netherlands.png differ diff --git a/Data/Sys/Resources/Flag_Netherlands@2x.png b/Data/Sys/Resources/Flag_Netherlands@2x.png new file mode 100644 index 0000000000..e96bd15fe6 Binary files /dev/null and b/Data/Sys/Resources/Flag_Netherlands@2x.png differ diff --git a/Data/Sys/Resources/Flag_Netherlands@4x.png b/Data/Sys/Resources/Flag_Netherlands@4x.png new file mode 100644 index 0000000000..e808f7e693 Binary files /dev/null and b/Data/Sys/Resources/Flag_Netherlands@4x.png differ diff --git a/Data/Sys/Resources/Flag_Russia.png b/Data/Sys/Resources/Flag_Russia.png index b6e926a982..1c1b1985ab 100644 Binary files a/Data/Sys/Resources/Flag_Russia.png and b/Data/Sys/Resources/Flag_Russia.png differ diff --git a/Data/Sys/Resources/Flag_Russia@2x.png b/Data/Sys/Resources/Flag_Russia@2x.png new file mode 100644 index 0000000000..00c07d7cd4 Binary files /dev/null and b/Data/Sys/Resources/Flag_Russia@2x.png differ diff --git a/Data/Sys/Resources/Flag_Russia@4x.png b/Data/Sys/Resources/Flag_Russia@4x.png new file mode 100644 index 0000000000..f462e3e001 Binary files /dev/null and b/Data/Sys/Resources/Flag_Russia@4x.png differ diff --git a/Data/Sys/Resources/Flag_Spain.png b/Data/Sys/Resources/Flag_Spain.png index 1a89e7a198..47b4d4250d 100644 Binary files a/Data/Sys/Resources/Flag_Spain.png and b/Data/Sys/Resources/Flag_Spain.png differ diff --git a/Data/Sys/Resources/Flag_Spain@2x.png b/Data/Sys/Resources/Flag_Spain@2x.png new file mode 100644 index 0000000000..ebb37e2704 Binary files /dev/null and b/Data/Sys/Resources/Flag_Spain@2x.png differ diff --git a/Data/Sys/Resources/Flag_Spain@4x.png b/Data/Sys/Resources/Flag_Spain@4x.png new file mode 100644 index 0000000000..0858130572 Binary files /dev/null and b/Data/Sys/Resources/Flag_Spain@4x.png differ diff --git a/Data/Sys/Resources/Flag_Taiwan.png b/Data/Sys/Resources/Flag_Taiwan.png index f9a5dffa28..d6f83c85f1 100644 Binary files a/Data/Sys/Resources/Flag_Taiwan.png and b/Data/Sys/Resources/Flag_Taiwan.png differ diff --git a/Data/Sys/Resources/Flag_Taiwan@2x.png b/Data/Sys/Resources/Flag_Taiwan@2x.png new file mode 100644 index 0000000000..c426a29332 Binary files /dev/null and b/Data/Sys/Resources/Flag_Taiwan@2x.png differ diff --git a/Data/Sys/Resources/Flag_Taiwan@4x.png b/Data/Sys/Resources/Flag_Taiwan@4x.png new file mode 100644 index 0000000000..54ea7d555b Binary files /dev/null and b/Data/Sys/Resources/Flag_Taiwan@4x.png differ diff --git a/Data/Sys/Resources/Flag_USA.png b/Data/Sys/Resources/Flag_USA.png index 6e438c4b02..a5fa17ad07 100644 Binary files a/Data/Sys/Resources/Flag_USA.png and b/Data/Sys/Resources/Flag_USA.png differ diff --git a/Data/Sys/Resources/Flag_USA@2x.png b/Data/Sys/Resources/Flag_USA@2x.png new file mode 100644 index 0000000000..57d26f17f0 Binary files /dev/null and b/Data/Sys/Resources/Flag_USA@2x.png differ diff --git a/Data/Sys/Resources/Flag_USA@4x.png b/Data/Sys/Resources/Flag_USA@4x.png new file mode 100644 index 0000000000..e8a658877f Binary files /dev/null and b/Data/Sys/Resources/Flag_USA@4x.png differ diff --git a/Data/Sys/Resources/Flag_Unknown.png b/Data/Sys/Resources/Flag_Unknown.png index 9177a7416c..77f5a6556f 100644 Binary files a/Data/Sys/Resources/Flag_Unknown.png and b/Data/Sys/Resources/Flag_Unknown.png differ diff --git a/Data/Sys/Resources/Flag_Unknown@2x.png b/Data/Sys/Resources/Flag_Unknown@2x.png new file mode 100644 index 0000000000..a450f2a4a9 Binary files /dev/null and b/Data/Sys/Resources/Flag_Unknown@2x.png differ diff --git a/Data/Sys/Resources/Flag_Unknown@4x.png b/Data/Sys/Resources/Flag_Unknown@4x.png new file mode 100644 index 0000000000..acd99ae374 Binary files /dev/null and b/Data/Sys/Resources/Flag_Unknown@4x.png differ diff --git a/Data/Sys/Themes/Boomy/audio.png b/Data/Sys/Themes/Boomy/audio.png deleted file mode 100644 index 22752cdf74..0000000000 Binary files a/Data/Sys/Themes/Boomy/audio.png and /dev/null differ diff --git a/Data/Sys/Themes/Boomy/fileplatform.png b/Data/Sys/Themes/Boomy/fileplatform.png new file mode 100644 index 0000000000..0e6a236729 Binary files /dev/null and b/Data/Sys/Themes/Boomy/fileplatform.png differ diff --git a/Data/Sys/Themes/Clean Blue/README.txt b/Data/Sys/Themes/Clean Blue/README.txt deleted file mode 100644 index a878862e20..0000000000 --- a/Data/Sys/Themes/Clean Blue/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -By Michael "MaJoR" Roesch of the Dolphin team - -dolphin-emu.org \ No newline at end of file diff --git a/Data/Sys/Themes/Clean Blue/audio.png b/Data/Sys/Themes/Clean Blue/audio.png deleted file mode 100644 index 91ef63ccc0..0000000000 Binary files a/Data/Sys/Themes/Clean Blue/audio.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean Blue/audio@2x.png b/Data/Sys/Themes/Clean Blue/audio@2x.png deleted file mode 100644 index 0da09dba1c..0000000000 Binary files a/Data/Sys/Themes/Clean Blue/audio@2x.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean Blue/fileplatform.png b/Data/Sys/Themes/Clean Blue/fileplatform.png new file mode 100644 index 0000000000..0e6a236729 Binary files /dev/null and b/Data/Sys/Themes/Clean Blue/fileplatform.png differ diff --git a/Data/Sys/Themes/Clean Lite/README.txt b/Data/Sys/Themes/Clean Lite/README.txt deleted file mode 100644 index a878862e20..0000000000 --- a/Data/Sys/Themes/Clean Lite/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -By Michael "MaJoR" Roesch of the Dolphin team - -dolphin-emu.org \ No newline at end of file diff --git a/Data/Sys/Themes/Clean Lite/audio.png b/Data/Sys/Themes/Clean Lite/audio.png deleted file mode 100644 index b961039ba4..0000000000 Binary files a/Data/Sys/Themes/Clean Lite/audio.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean Lite/audio@2x.png b/Data/Sys/Themes/Clean Lite/audio@2x.png deleted file mode 100644 index 8bd6acf759..0000000000 Binary files a/Data/Sys/Themes/Clean Lite/audio@2x.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean Lite/fileplatform.png b/Data/Sys/Themes/Clean Lite/fileplatform.png new file mode 100644 index 0000000000..0e6a236729 Binary files /dev/null and b/Data/Sys/Themes/Clean Lite/fileplatform.png differ diff --git a/Data/Sys/Themes/Clean Pink/README.txt b/Data/Sys/Themes/Clean Pink/README.txt deleted file mode 100644 index a878862e20..0000000000 --- a/Data/Sys/Themes/Clean Pink/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -By Michael "MaJoR" Roesch of the Dolphin team - -dolphin-emu.org \ No newline at end of file diff --git a/Data/Sys/Themes/Clean Pink/audio.png b/Data/Sys/Themes/Clean Pink/audio.png deleted file mode 100644 index ad669c8c71..0000000000 Binary files a/Data/Sys/Themes/Clean Pink/audio.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean Pink/audio@2x.png b/Data/Sys/Themes/Clean Pink/audio@2x.png deleted file mode 100644 index 3daee4b555..0000000000 Binary files a/Data/Sys/Themes/Clean Pink/audio@2x.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean Pink/fileplatform.png b/Data/Sys/Themes/Clean Pink/fileplatform.png new file mode 100644 index 0000000000..0e6a236729 Binary files /dev/null and b/Data/Sys/Themes/Clean Pink/fileplatform.png differ diff --git a/Data/Sys/Themes/Clean/README.txt b/Data/Sys/Themes/Clean/README.txt deleted file mode 100644 index a878862e20..0000000000 --- a/Data/Sys/Themes/Clean/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -By Michael "MaJoR" Roesch of the Dolphin team - -dolphin-emu.org \ No newline at end of file diff --git a/Data/Sys/Themes/Clean/audio.png b/Data/Sys/Themes/Clean/audio.png deleted file mode 100644 index 53d4413cb8..0000000000 Binary files a/Data/Sys/Themes/Clean/audio.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean/audio@2x.png b/Data/Sys/Themes/Clean/audio@2x.png deleted file mode 100644 index f83e43ff80..0000000000 Binary files a/Data/Sys/Themes/Clean/audio@2x.png and /dev/null differ diff --git a/Data/Sys/Themes/Clean/fileplatform.png b/Data/Sys/Themes/Clean/fileplatform.png new file mode 100644 index 0000000000..0e6a236729 Binary files /dev/null and b/Data/Sys/Themes/Clean/fileplatform.png differ diff --git a/Externals/Bochs_disasm/Bochs_disasm.vcxproj b/Externals/Bochs_disasm/Bochs_disasm.vcxproj index e1eb8d1949..b6d1cfa333 100644 --- a/Externals/Bochs_disasm/Bochs_disasm.vcxproj +++ b/Externals/Bochs_disasm/Bochs_disasm.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/LZO/LZO.vcxproj b/Externals/LZO/LZO.vcxproj index e89fde653c..97118d532c 100644 --- a/Externals/LZO/LZO.vcxproj +++ b/Externals/LZO/LZO.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/SFML/build/vc2010/SFML_Network.vcxproj b/Externals/SFML/build/vc2010/SFML_Network.vcxproj index d1382d30bc..efc40da491 100644 --- a/Externals/SFML/build/vc2010/SFML_Network.vcxproj +++ b/Externals/SFML/build/vc2010/SFML_Network.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode @@ -80,4 +80,4 @@ - + \ No newline at end of file diff --git a/Externals/SOIL/SOIL.vcxproj b/Externals/SOIL/SOIL.vcxproj index 77b61ff418..65a6d4f4f9 100644 --- a/Externals/SOIL/SOIL.vcxproj +++ b/Externals/SOIL/SOIL.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/enet/enet.vcxproj b/Externals/enet/enet.vcxproj index 74a77d3a91..f402fbfec5 100644 --- a/Externals/enet/enet.vcxproj +++ b/Externals/enet/enet.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -45,7 +45,7 @@ StaticLibrary - v120 + v140 Unicode @@ -66,4 +66,4 @@ - + \ No newline at end of file diff --git a/Externals/gtest/LICENSE b/Externals/gtest/LICENSE new file mode 100644 index 0000000000..1941a11f8c --- /dev/null +++ b/Externals/gtest/LICENSE @@ -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/Externals/gtest/include/gtest/gtest-param-test.h b/Externals/gtest/include/gtest/gtest-param-test.h index d6702c8f16..9a1d8a62e0 100644 --- a/Externals/gtest/include/gtest/gtest-param-test.h +++ b/Externals/gtest/include/gtest/gtest-param-test.h @@ -1387,14 +1387,17 @@ internal::CartesianProductHolder10parameterized_test_registry(). \ GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ - #test_case_name, \ - #test_name, \ - new ::testing::internal::TestMetaFactory< \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + #test_case_name, \ + ::testing::internal::CodeLocation(\ + __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_; \ + static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ @@ -1406,13 +1409,15 @@ internal::CartesianProductHolder10 \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ - int gtest_##prefix##test_case_name##_dummy_ = \ + int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ - #prefix, \ - >est_##prefix##test_case_name##_EvalGenerator_, \ - __FILE__, __LINE__) + #test_case_name, \ + ::testing::internal::CodeLocation(\ + __FILE__, __LINE__))->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) } // namespace testing diff --git a/Externals/gtest/include/gtest/gtest-param-test.h.pump b/Externals/gtest/include/gtest/gtest-param-test.h.pump index 2dc9303b5e..45896502a1 100644 --- a/Externals/gtest/include/gtest/gtest-param-test.h.pump +++ b/Externals/gtest/include/gtest/gtest-param-test.h.pump @@ -453,14 +453,17 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( static int AddToRegistry() { \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ - #test_case_name, \ - #test_name, \ - new ::testing::internal::TestMetaFactory< \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + #test_case_name, \ + ::testing::internal::CodeLocation(\ + __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_; \ + static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ GTEST_DISALLOW_COPY_AND_ASSIGN_(\ GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ }; \ @@ -472,13 +475,15 @@ internal::CartesianProductHolder$i<$for j, [[Generator$j]]> Combine( # define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ ::testing::internal::ParamGenerator \ gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ - int gtest_##prefix##test_case_name##_dummy_ = \ + int gtest_##prefix##test_case_name##_dummy_ GTEST_ATTRIBUTE_UNUSED_ = \ ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ - #prefix, \ - >est_##prefix##test_case_name##_EvalGenerator_, \ - __FILE__, __LINE__) + #test_case_name, \ + ::testing::internal::CodeLocation(\ + __FILE__, __LINE__))->AddTestCaseInstantiation(\ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) } // namespace testing diff --git a/Externals/gtest/include/gtest/gtest-printers.h b/Externals/gtest/include/gtest/gtest-printers.h index 852d44a701..e4df7823b4 100644 --- a/Externals/gtest/include/gtest/gtest-printers.h +++ b/Externals/gtest/include/gtest/gtest-printers.h @@ -593,10 +593,7 @@ 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 + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) // Note: we deliberately don't call this PrintTo(), as that name // conflicts with ::testing::internal::PrintTo in the body of the @@ -613,9 +610,7 @@ class UniversalPrinter { PrintTo(value, os); } -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() }; // UniversalPrintArray(begin, len, os) prints an array of 'len' @@ -667,10 +662,7 @@ 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 + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4180) static void Print(const T& value, ::std::ostream* os) { // Prints the address of the value. We use reinterpret_cast here @@ -681,9 +673,7 @@ class UniversalPrinter { UniversalPrint(value, os); } -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() }; // Prints a value tersely: for a reference type, the referenced value @@ -835,9 +825,9 @@ struct TuplePrefixPrinter { template static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { TuplePrefixPrinter::PrintPrefixTo(t, os); - GTEST_INTENTIONAL_CONST_COND_PUSH_ + GTEST_INTENTIONAL_CONST_COND_PUSH_() if (N > 1) { - GTEST_INTENTIONAL_CONST_COND_POP_ + GTEST_INTENTIONAL_CONST_COND_POP_() *os << ", "; } UniversalPrinter< @@ -898,4 +888,9 @@ template } // namespace testing +// Include any custom printer added by the local installation. +// We must include this header at the end to make sure it can use the +// declarations from this file. +#include "gtest/internal/custom/gtest-printers.h" + #endif // GTEST_INCLUDE_GTEST_GTEST_PRINTERS_H_ diff --git a/Externals/gtest/include/gtest/gtest-typed-test.h b/Externals/gtest/include/gtest/gtest-typed-test.h index fe1e83b274..5f69d5678e 100644 --- a/Externals/gtest/include/gtest/gtest-typed-test.h +++ b/Externals/gtest/include/gtest/gtest-typed-test.h @@ -181,7 +181,8 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); ::testing::internal::TemplateSel< \ GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ GTEST_TYPE_PARAMS_(CaseName)>::Register(\ - "", #CaseName, #TestName, 0); \ + "", ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + #CaseName, #TestName, 0); \ template \ void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() @@ -252,7 +253,10 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); ::testing::internal::TypeParameterizedTestCase::type>::Register(\ - #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) + #Prefix, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ + >EST_TYPED_TEST_CASE_P_STATE_(CaseName), \ + #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P diff --git a/Externals/gtest/include/gtest/gtest.h b/Externals/gtest/include/gtest/gtest.h index 6fa0a3925e..3f080b84a2 100644 --- a/Externals/gtest/include/gtest/gtest.h +++ b/Externals/gtest/include/gtest/gtest.h @@ -70,14 +70,14 @@ // 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 +// You 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 ::std::string and ::string are the same class on your platform +// due to aliasing, you should define GTEST_HAS_GLOBAL_STRING to 0. // -// If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined +// If you do not define GTEST_HAS_GLOBAL_STRING, it is defined // heuristically. namespace testing { @@ -258,8 +258,31 @@ class GTEST_API_ AssertionResult { // Copy constructor. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult(const AssertionResult& other); + + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 /* forcing value to bool */) + // Used in the EXPECT_TRUE/FALSE(bool_expression). - explicit AssertionResult(bool success) : success_(success) {} + // + // T must be contextually convertible to bool. + // + // The second parameter prevents this overload from being considered if + // the argument is implicitly convertible to AssertionResult. In that case + // we want AssertionResult's copy constructor to be used. + template + explicit AssertionResult( + const T& success, + typename internal::EnableIf< + !internal::ImplicitlyConvertible::value>::type* + /*enabler*/ = NULL) + : success_(success) {} + + GTEST_DISABLE_MSC_WARNINGS_POP_() + + // Assignment operator. + AssertionResult& operator=(AssertionResult other) { + swap(other); + return *this; + } // Returns true iff the assertion succeeded. operator bool() const { return success_; } // NOLINT @@ -300,6 +323,9 @@ class GTEST_API_ AssertionResult { message_->append(a_message.GetString().c_str()); } + // Swap the contents of this AssertionResult with other. + void swap(AssertionResult& other); + // Stores result of the assertion predicate. bool success_; // Stores the message describing the condition in case the expectation @@ -307,8 +333,6 @@ class GTEST_API_ AssertionResult { // 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. @@ -335,8 +359,8 @@ GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // // class FooTest : public testing::Test { // protected: -// virtual void SetUp() { ... } -// virtual void TearDown() { ... } +// void SetUp() override { ... } +// void TearDown() override { ... } // ... // }; // @@ -428,20 +452,19 @@ class GTEST_API_ Test { // 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_; + const internal::scoped_ptr< GTEST_FLAG_SAVER_ > gtest_flag_saver_; - // Often a user mis-spells SetUp() as Setup() and spends a long time + // Often a user misspells 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. + // will be a conflict if void Setup() is declared in the user's + // test fixture. // // - This method is private, so it will be another compiler error - // if a user calls it from his test fixture. + // if the method is called from the user's test fixture. // // DO NOT OVERRIDE THIS FUNCTION. // @@ -646,6 +669,12 @@ class GTEST_API_ TestInfo { return NULL; } + // Returns the file name where this test is defined. + const char* file() const { return location_.file.c_str(); } + + // Returns the line where this test is defined. + int line() const { return location_.line; } + // 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. @@ -688,6 +717,7 @@ class GTEST_API_ TestInfo { const char* name, const char* type_param, const char* value_param, + internal::CodeLocation code_location, internal::TypeId fixture_class_id, Test::SetUpTestCaseFunc set_up_tc, Test::TearDownTestCaseFunc tear_down_tc, @@ -699,6 +729,7 @@ class GTEST_API_ TestInfo { const std::string& name, const char* a_type_param, // NULL if not a type-parameterized test const char* a_value_param, // NULL if not a value-parameterized test + internal::CodeLocation a_code_location, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory); @@ -725,6 +756,7 @@ class GTEST_API_ TestInfo { // Text representation of the value parameter, or NULL if this is not a // value-parameterized test. const internal::scoped_ptr value_param_; + internal::CodeLocation location_; 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 @@ -924,7 +956,7 @@ class GTEST_API_ TestCase { }; // An Environment object is capable of setting up and tearing down an -// environment. The user should subclass this to define his own +// environment. You should subclass this to define your own // environment(s). // // An Environment object does the set-up and tear-down in virtual @@ -1433,31 +1465,34 @@ std::string FormatForComparisonFailureMessage( return FormatForComparison::Format(value); } +// Separate the error generating code from the code path to reduce the stack +// frame size of CmpHelperEQ. This helps reduce the overhead of some sanitizers +// when calling EXPECT_* in a tight loop. +template +AssertionResult CmpHelperEQFailure(const char* expected_expression, + const char* actual_expression, + const T1& expected, const T2& actual) { + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); +} + // The helper function for {ASSERT|EXPECT}_EQ. template 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 - +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4389 /* signed/unsigned mismatch */) if (expected == actual) { return AssertionSuccess(); } +GTEST_DISABLE_MSC_WARNINGS_POP_() -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif - - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); + return CmpHelperEQFailure(expected_expression, actual_expression, expected, + actual); } // With this overloaded version, we allow anonymous enums to be used @@ -1545,6 +1580,19 @@ class EqHelper { } }; +// Separate the error generating code from the code path to reduce the stack +// frame size of CmpHelperOP. This helps reduce the overhead of some sanitizers +// when calling EXPECT_OP in a tight loop. +template +AssertionResult CmpHelperOpFailure(const char* expr1, const char* expr2, + const T1& val1, const T2& val2, + const char* op) { + return AssertionFailure() + << "Expected: (" << expr1 << ") " << op << " (" << expr2 + << "), actual: " << FormatForComparisonFailureMessage(val1, val2) + << " vs " << FormatForComparisonFailureMessage(val2, val1); +} + // 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. @@ -1555,6 +1603,7 @@ class EqHelper { // with gcc 4. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + #define GTEST_IMPL_CMP_HELPER_(op_name, op)\ template \ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ @@ -1562,10 +1611,7 @@ AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ if (val1 op val2) {\ return AssertionSuccess();\ } else {\ - return AssertionFailure() \ - << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ + return CmpHelperOpFailure(expr1, expr2, val1, val2, #op);\ }\ }\ GTEST_API_ AssertionResult CmpHelper##op_name(\ @@ -2215,8 +2261,8 @@ bool StaticAssertTypeEq() { // 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 code should appear between braces after an invocation of +// this macro. Example: // // TEST(FooTest, InitializesCorrectly) { // Foo foo; diff --git a/Externals/gtest/include/gtest/internal/custom/gtest-port.h b/Externals/gtest/include/gtest/internal/custom/gtest-port.h new file mode 100644 index 0000000000..7e744bd3bb --- /dev/null +++ b/Externals/gtest/include/gtest/internal/custom/gtest-port.h @@ -0,0 +1,69 @@ +// Copyright 2015, 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. +// +// Injection point for custom user configurations. +// The following macros can be defined: +// +// Flag related macros: +// GTEST_FLAG(flag_name) +// GTEST_USE_OWN_FLAGFILE_FLAG_ - Define to 0 when the system provides its +// own flagfile flag parsing. +// GTEST_DECLARE_bool_(name) +// GTEST_DECLARE_int32_(name) +// GTEST_DECLARE_string_(name) +// GTEST_DEFINE_bool_(name, default_val, doc) +// GTEST_DEFINE_int32_(name, default_val, doc) +// GTEST_DEFINE_string_(name, default_val, doc) +// +// Test filtering: +// GTEST_TEST_FILTER_ENV_VAR_ - The name of an environment variable that +// will be used if --GTEST_FLAG(test_filter) +// is not provided. +// +// Logging: +// GTEST_LOG_(severity) +// GTEST_CHECK_(condition) +// Functions LogToStderr() and FlushInfoLog() have to be provided too. +// +// Threading: +// GTEST_HAS_NOTIFICATION_ - Enabled if Notification is already provided. +// GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ - Enabled if Mutex and ThreadLocal are +// already provided. +// Must also provide GTEST_DECLARE_STATIC_MUTEX_(mutex) and +// GTEST_DEFINE_STATIC_MUTEX_(mutex) +// +// GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +// GTEST_LOCK_EXCLUDED_(locks) +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PORT_H_ diff --git a/Externals/gtest/include/gtest/internal/custom/gtest-printers.h b/Externals/gtest/include/gtest/internal/custom/gtest-printers.h new file mode 100644 index 0000000000..60c1ea050b --- /dev/null +++ b/Externals/gtest/include/gtest/internal/custom/gtest-printers.h @@ -0,0 +1,42 @@ +// Copyright 2015, 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 provides an injection point for custom printers in a local +// installation of gTest. +// It will be included from gtest-printers.h and the overrides in this file +// will be visible to everyone. +// See documentation at gtest/gtest-printers.h for details on how to define a +// custom printer. +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_PRINTERS_H_ diff --git a/Externals/gtest/include/gtest/internal/custom/gtest.h b/Externals/gtest/include/gtest/internal/custom/gtest.h new file mode 100644 index 0000000000..c27412a898 --- /dev/null +++ b/Externals/gtest/include/gtest/internal/custom/gtest.h @@ -0,0 +1,41 @@ +// Copyright 2015, 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. +// +// Injection point for custom user configurations. +// The following macros can be defined: +// +// GTEST_OS_STACK_TRACE_GETTER_ - The name of an implementation of +// OsStackTraceGetterInterface. +// +// ** Custom implementation starts here ** + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_CUSTOM_GTEST_H_ diff --git a/Externals/gtest/include/gtest/internal/gtest-internal.h b/Externals/gtest/include/gtest/internal/gtest-internal.h index f58f65f620..ee2dc4a121 100644 --- a/Externals/gtest/include/gtest/internal/gtest-internal.h +++ b/Externals/gtest/include/gtest/internal/gtest-internal.h @@ -55,7 +55,10 @@ #include #include #include +#include #include +#include +#include #include "gtest/gtest-message.h" #include "gtest/internal/gtest-string.h" @@ -171,6 +174,36 @@ class GTEST_API_ ScopedTrace { // c'tor and d'tor. Therefore it doesn't // need to be used otherwise. +namespace edit_distance { +// Returns the optimal edits to go from 'left' to 'right'. +// All edits cost the same, with replace having lower priority than +// add/remove. +// Simple implementation of the Wagner–Fischer algorithm. +// See http://en.wikipedia.org/wiki/Wagner-Fischer_algorithm +enum EditType { kMatch, kAdd, kRemove, kReplace }; +GTEST_API_ std::vector CalculateOptimalEdits( + const std::vector& left, const std::vector& right); + +// Same as above, but the input is represented as strings. +GTEST_API_ std::vector CalculateOptimalEdits( + const std::vector& left, + const std::vector& right); + +// Create a diff of the input strings in Unified diff format. +GTEST_API_ std::string CreateUnifiedDiff(const std::vector& left, + const std::vector& right, + size_t context = 2); + +} // namespace edit_distance + +// Calculate the diff between 'left' and 'right' and return it in unified diff +// format. +// If not null, stores in 'total_line_count' the total number of lines found +// in left + right. +GTEST_API_ std::string DiffStrings(const std::string& left, + const std::string& right, + size_t* total_line_count); + // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // @@ -471,6 +504,13 @@ GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); +struct CodeLocation { + CodeLocation(const string& a_file, int a_line) : file(a_file), line(a_line) {} + + string file; + int line; +}; + // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // @@ -482,6 +522,7 @@ typedef void (*TearDownTestCaseFunc)(); // 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. +// code_location: code location where the test is defined // 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 @@ -493,6 +534,7 @@ GTEST_API_ TestInfo* MakeAndRegisterTestInfo( const char* name, const char* type_param, const char* value_param, + CodeLocation code_location, TypeId fixture_class_id, SetUpTestCaseFunc set_up_tc, TearDownTestCaseFunc tear_down_tc, @@ -522,10 +564,21 @@ class GTEST_API_ TypedTestCasePState { fflush(stderr); posix::Abort(); } - defined_test_names_.insert(test_name); + registered_tests_.insert( + ::std::make_pair(test_name, CodeLocation(file, line))); return true; } + bool TestExists(const std::string& test_name) const { + return registered_tests_.count(test_name) > 0; + } + + const CodeLocation& GetCodeLocation(const std::string& test_name) const { + RegisteredTestsMap::const_iterator it = registered_tests_.find(test_name); + GTEST_CHECK_(it != registered_tests_.end()); + return it->second; + } + // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. @@ -533,8 +586,10 @@ class GTEST_API_ TypedTestCasePState { const char* file, int line, const char* registered_tests); private: + typedef ::std::map RegisteredTestsMap; + bool registered_; - ::std::set defined_test_names_; + RegisteredTestsMap registered_tests_; }; // Skips to the first non-space char after the first comma in 'str'; @@ -555,6 +610,11 @@ inline std::string GetPrefixUntilComma(const char* str) { return comma == NULL ? str : std::string(str, comma); } +// Splits a given string on a given delimiter, populating a given +// vector with the fields. +void SplitString(const ::std::string& str, char delimiter, + ::std::vector< ::std::string>* dest); + // TypeParameterizedTest::Register() // registers a list of type-parameterized tests with Google Test. The // return value is insignificant - we just need to return something @@ -569,8 +629,10 @@ class TypeParameterizedTest { // 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) { + static bool Register(const char* prefix, + CodeLocation code_location, + const char* case_name, const char* test_names, + int index) { typedef typename Types::Head Type; typedef Fixture FixtureClass; typedef typename GTEST_BIND_(TestSel, Type) TestClass; @@ -580,9 +642,10 @@ class TypeParameterizedTest { MakeAndRegisterTestInfo( (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + StreamableToString(index)).c_str(), - GetPrefixUntilComma(test_names).c_str(), + StripTrailingSpaces(GetPrefixUntilComma(test_names)).c_str(), GetTypeName().c_str(), NULL, // No value parameter. + code_location, GetTypeId(), TestClass::SetUpTestCase, TestClass::TearDownTestCase, @@ -590,7 +653,7 @@ class TypeParameterizedTest { // Next, recurses (at compile time) with the tail of the type list. return TypeParameterizedTest - ::Register(prefix, case_name, test_names, index + 1); + ::Register(prefix, code_location, case_name, test_names, index + 1); } }; @@ -598,8 +661,9 @@ class TypeParameterizedTest { template class TypeParameterizedTest { public: - static bool Register(const char* /*prefix*/, const char* /*case_name*/, - const char* /*test_names*/, int /*index*/) { + static bool Register(const char* /*prefix*/, CodeLocation, + const char* /*case_name*/, const char* /*test_names*/, + int /*index*/) { return true; } }; @@ -611,17 +675,31 @@ class TypeParameterizedTest { template class TypeParameterizedTestCase { public: - static bool Register(const char* prefix, const char* case_name, - const char* test_names) { + static bool Register(const char* prefix, CodeLocation code_location, + const TypedTestCasePState* state, + const char* case_name, const char* test_names) { + std::string test_name = StripTrailingSpaces( + GetPrefixUntilComma(test_names)); + if (!state->TestExists(test_name)) { + fprintf(stderr, "Failed to get code location for test %s.%s at %s.", + case_name, test_name.c_str(), + FormatFileLocation(code_location.file.c_str(), + code_location.line).c_str()); + fflush(stderr); + posix::Abort(); + } + const CodeLocation& test_location = state->GetCodeLocation(test_name); + typedef typename Tests::Head Head; // First, register the first test in 'Test' for each type in 'Types'. TypeParameterizedTest::Register( - prefix, case_name, test_names, 0); + prefix, test_location, case_name, test_names, 0); // Next, recurses (at compile time) with the tail of the test list. return TypeParameterizedTestCase - ::Register(prefix, case_name, SkipComma(test_names)); + ::Register(prefix, code_location, state, + case_name, SkipComma(test_names)); } }; @@ -629,8 +707,9 @@ class TypeParameterizedTestCase { template class TypeParameterizedTestCase { public: - static bool Register(const char* /*prefix*/, const char* /*case_name*/, - const char* /*test_names*/) { + static bool Register(const char* /*prefix*/, CodeLocation, + const TypedTestCasePState* /*state*/, + const char* /*case_name*/, const char* /*test_names*/) { return true; } }; @@ -802,25 +881,20 @@ class ImplicitlyConvertible { // 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__) +#if 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 + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4244) static const bool value = sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; -#endif // _MSV_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif // __BORLANDC__ }; template const bool ImplicitlyConvertible::value; @@ -946,11 +1020,10 @@ void CopyArray(const T* from, size_t size, U* to) { // 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. -}; +// We use 2 different structs to allow non-copyable types to be used, as long +// as RelationToSourceReference() is passed. +struct RelationToSourceReference {}; +struct RelationToSourceCopy {}; // Adapts a native array to a read-only STL-style container. Instead // of the complete STL container concept, this adaptor only implements @@ -968,22 +1041,23 @@ class NativeArray { 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); + // Constructs from a native array. References the source. + NativeArray(const Element* array, size_t count, RelationToSourceReference) { + InitRef(array, count); + } + + // Constructs from a native array. Copies the source. + NativeArray(const Element* array, size_t count, RelationToSourceCopy) { + InitCopy(array, count); } // Copy constructor. NativeArray(const NativeArray& rhs) { - Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + (this->*rhs.clone_)(rhs.array_, rhs.size_); } ~NativeArray() { - // Ensures that the user doesn't instantiate NativeArray with a - // const or reference type. - static_cast(StaticAssertTypeEqHelper()); - if (relation_to_source_ == kCopy) + if (clone_ != &NativeArray::InitRef) delete[] array_; } @@ -997,23 +1071,30 @@ class NativeArray { } 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; - } + enum { + kCheckTypeIsNotConstOrAReference = StaticAssertTypeEqHelper< + Element, GTEST_REMOVE_REFERENCE_AND_CONST_(Element)>::value, + }; + + // Initializes this object with a copy of the input. + void InitCopy(const Element* array, size_t a_size) { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; size_ = a_size; - relation_to_source_ = relation; + clone_ = &NativeArray::InitCopy; + } + + // Initializes this object with a reference of the input. + void InitRef(const Element* array, size_t a_size) { + array_ = array; + size_ = a_size; + clone_ = &NativeArray::InitRef; } const Element* array_; size_t size_; - RelationToSource relation_to_source_; + void (NativeArray::*clone_)(const Element*, size_t); GTEST_DISALLOW_ASSIGN_(NativeArray); }; @@ -1148,6 +1229,7 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ ::test_info_ =\ ::testing::internal::MakeAndRegisterTestInfo(\ #test_case_name, #test_name, NULL, NULL, \ + ::testing::internal::CodeLocation(__FILE__, __LINE__), \ (parent_id), \ parent_class::SetUpTestCase, \ parent_class::TearDownTestCase, \ @@ -1156,3 +1238,4 @@ class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ + diff --git a/Externals/gtest/include/gtest/internal/gtest-linked_ptr.h b/Externals/gtest/include/gtest/internal/gtest-linked_ptr.h index b1362cd002..3602942217 100644 --- a/Externals/gtest/include/gtest/internal/gtest-linked_ptr.h +++ b/Externals/gtest/include/gtest/internal/gtest-linked_ptr.h @@ -110,7 +110,12 @@ class linked_ptr_internal { MutexLock lock(&g_linked_ptr_mutex); linked_ptr_internal const* p = ptr; - while (p->next_ != ptr) p = p->next_; + while (p->next_ != ptr) { + assert(p->next_ != this && + "Trying to join() a linked ring we are already in. " + "Is GMock thread safety enabled?"); + p = p->next_; + } p->next_ = this; next_ = ptr; } @@ -123,7 +128,12 @@ class linked_ptr_internal { if (next_ == this) return true; linked_ptr_internal const* p = next_; - while (p->next_ != this) p = p->next_; + while (p->next_ != this) { + assert(p->next_ != next_ && + "Trying to depart() a linked ring we are not in. " + "Is GMock thread safety enabled?"); + p = p->next_; + } p->next_ = next_; return false; } diff --git a/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h b/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h index e80548592c..4d1d81d20f 100644 --- a/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h +++ b/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h @@ -40,7 +40,7 @@ // 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 +// by the maximum arity of the implementation of tuple which is // currently set at 10. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ @@ -79,7 +79,10 @@ class ValueArray1 { explicit ValueArray1(T1 v1) : v1_(v1) {} template - operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + operator ParamGenerator() const { + const T array[] = {static_cast(v1_)}; + return ValuesIn(array); + } private: // No implementation - assignment is unsupported. @@ -3157,9 +3160,9 @@ class ValueArray50 { // template class CartesianProductGenerator2 - : public ParamGeneratorInterface< ::std::tr1::tuple > { + : public ParamGeneratorInterface< ::testing::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator2(const ParamGenerator& g1, const ParamGenerator& g2) @@ -3272,9 +3275,9 @@ class CartesianProductGenerator2 template class CartesianProductGenerator3 - : public ParamGeneratorInterface< ::std::tr1::tuple > { + : public ParamGeneratorInterface< ::testing::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator3(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3) @@ -3404,9 +3407,9 @@ class CartesianProductGenerator3 template class CartesianProductGenerator4 - : public ParamGeneratorInterface< ::std::tr1::tuple > { + : public ParamGeneratorInterface< ::testing::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator4(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, @@ -3555,9 +3558,9 @@ class CartesianProductGenerator4 template class CartesianProductGenerator5 - : public ParamGeneratorInterface< ::std::tr1::tuple > { + : public ParamGeneratorInterface< ::testing::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator5(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, @@ -3723,10 +3726,10 @@ class CartesianProductGenerator5 template class CartesianProductGenerator6 - : public ParamGeneratorInterface< ::std::tr1::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator6(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, @@ -3909,10 +3912,10 @@ class CartesianProductGenerator6 template class CartesianProductGenerator7 - : public ParamGeneratorInterface< ::std::tr1::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator7(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, @@ -4112,10 +4115,10 @@ class CartesianProductGenerator7 template class CartesianProductGenerator8 - : public ParamGeneratorInterface< ::std::tr1::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator8(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, @@ -4334,10 +4337,10 @@ class CartesianProductGenerator8 template class CartesianProductGenerator9 - : public ParamGeneratorInterface< ::std::tr1::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator9(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, @@ -4573,10 +4576,10 @@ class CartesianProductGenerator9 template class CartesianProductGenerator10 - : public ParamGeneratorInterface< ::std::tr1::tuple > { public: - typedef ::std::tr1::tuple ParamType; + typedef ::testing::tuple ParamType; CartesianProductGenerator10(const ParamGenerator& g1, const ParamGenerator& g2, const ParamGenerator& g3, @@ -4838,8 +4841,8 @@ class CartesianProductHolder2 { CartesianProductHolder2(const Generator1& g1, const Generator2& g2) : g1_(g1), g2_(g2) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator2( static_cast >(g1_), static_cast >(g2_))); @@ -4860,8 +4863,8 @@ CartesianProductHolder3(const Generator1& g1, const Generator2& g2, const Generator3& g3) : g1_(g1), g2_(g2), g3_(g3) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator3( static_cast >(g1_), static_cast >(g2_), @@ -4885,8 +4888,8 @@ CartesianProductHolder4(const Generator1& g1, const Generator2& g2, const Generator3& g3, const Generator4& g4) : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator4( static_cast >(g1_), static_cast >(g2_), @@ -4912,8 +4915,8 @@ 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 - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator5( static_cast >(g1_), static_cast >(g2_), @@ -4943,8 +4946,8 @@ CartesianProductHolder6(const Generator1& g1, const Generator2& g2, : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator6( static_cast >(g1_), static_cast >(g2_), @@ -4976,9 +4979,9 @@ CartesianProductHolder7(const Generator1& g1, const Generator2& g2, : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator7( static_cast >(g1_), static_cast >(g2_), @@ -5014,9 +5017,9 @@ CartesianProductHolder8(const Generator1& g1, const Generator2& g2, g8_(g8) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator8( static_cast >(g1_), static_cast >(g2_), @@ -5055,9 +5058,9 @@ CartesianProductHolder9(const Generator1& g1, const Generator2& g2, g9_(g9) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( new CartesianProductGenerator9( static_cast >(g1_), @@ -5099,10 +5102,10 @@ CartesianProductHolder10(const Generator1& g1, const Generator2& g2, g9_(g9), g10_(g10) {} template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( + operator ParamGenerator< ::testing::tuple >() const { + return ParamGenerator< ::testing::tuple >( new CartesianProductGenerator10( static_cast >(g1_), diff --git a/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h.pump b/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h.pump index 009206fd31..5c7c47af0b 100644 --- a/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h.pump +++ b/Externals/gtest/include/gtest/internal/gtest-param-util-generated.h.pump @@ -39,7 +39,7 @@ $var maxtuple = 10 $$ Maximum number of Combine arguments we want to support. // 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 +// by the maximum arity of the implementation of tuple which is // currently set at $maxtuple. #ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PARAM_UTIL_GENERATED_H_ @@ -72,29 +72,14 @@ internal::ParamGenerator ValuesIn( namespace internal { // Used in the Values() function to provide polymorphic capabilities. -template -class ValueArray1 { - public: - explicit ValueArray1(T1 v1) : v1_(v1) {} - - template - operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } - - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray1& other); - - const T1 v1_; -}; - -$range i 2..n +$range i 1..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)]] {} + $if i==1 [[explicit ]]ValueArray$i($for j, [[T$j v$j]]) : $for j, [[v$(j)_(v$j)]] {} template operator ParamGenerator() const { @@ -128,9 +113,9 @@ $range k 2..i template <$for j, [[typename T$j]]> class CartesianProductGenerator$i - : public ParamGeneratorInterface< ::std::tr1::tuple<$for j, [[T$j]]> > { + : public ParamGeneratorInterface< ::testing::tuple<$for j, [[T$j]]> > { public: - typedef ::std::tr1::tuple<$for j, [[T$j]]> ParamType; + typedef ::testing::tuple<$for j, [[T$j]]> ParamType; CartesianProductGenerator$i($for j, [[const ParamGenerator& g$j]]) : $for j, [[g$(j)_(g$j)]] {} @@ -269,8 +254,8 @@ class CartesianProductHolder$i { 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]]> >( + operator ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >() const { + return ParamGenerator< ::testing::tuple<$for j, [[T$j]]> >( new CartesianProductGenerator$i<$for j, [[T$j]]>( $for j,[[ diff --git a/Externals/gtest/include/gtest/internal/gtest-param-util.h b/Externals/gtest/include/gtest/internal/gtest-param-util.h index d5e1028b0c..efb2b94535 100644 --- a/Externals/gtest/include/gtest/internal/gtest-param-util.h +++ b/Externals/gtest/include/gtest/internal/gtest-param-util.h @@ -58,7 +58,7 @@ namespace internal { // 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); + CodeLocation code_location); template class ParamGeneratorInterface; template class ParamGenerator; @@ -450,8 +450,9 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { // A function that returns an instance of appropriate generator type. typedef ParamGenerator(GeneratorCreationFunc)(); - explicit ParameterizedTestCaseInfo(const char* name) - : test_case_name_(name) {} + explicit ParameterizedTestCaseInfo( + const char* name, CodeLocation code_location) + : test_case_name_(name), code_location_(code_location) {} // Test case base name for display purposes. virtual const string& GetTestCaseName() const { return test_case_name_; } @@ -510,6 +511,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { test_name_stream.GetString().c_str(), NULL, // No type parameter. PrintToString(*param_it).c_str(), + code_location_, GetTestCaseTypeId(), TestCase::SetUpTestCase, TestCase::TearDownTestCase, @@ -541,6 +543,7 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { InstantiationContainer; const string test_case_name_; + CodeLocation code_location_; TestInfoContainer tests_; InstantiationContainer instantiations_; @@ -568,8 +571,7 @@ class ParameterizedTestCaseRegistry { template ParameterizedTestCaseInfo* GetTestCasePatternHolder( const char* test_case_name, - const char* file, - int line) { + CodeLocation code_location) { ParameterizedTestCaseInfo* typed_test_info = NULL; for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); it != test_case_infos_.end(); ++it) { @@ -578,7 +580,7 @@ class ParameterizedTestCaseRegistry { // 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); + ReportInvalidTestCaseType(test_case_name, code_location); posix::Abort(); } else { // At this point we are sure that the object we found is of the same @@ -591,7 +593,8 @@ class ParameterizedTestCaseRegistry { } } if (typed_test_info == NULL) { - typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + typed_test_info = new ParameterizedTestCaseInfo( + test_case_name, code_location); test_case_infos_.push_back(typed_test_info); } return typed_test_info; diff --git a/Externals/gtest/include/gtest/internal/gtest-port-arch.h b/Externals/gtest/include/gtest/internal/gtest-port-arch.h new file mode 100644 index 0000000000..74ab949057 --- /dev/null +++ b/Externals/gtest/include/gtest/internal/gtest-port-arch.h @@ -0,0 +1,93 @@ +// Copyright 2015, 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. +// +// The Google C++ Testing Framework (Google Test) +// +// This header file defines the GTEST_OS_* macro. +// It is separate from gtest-port.h so that custom/gtest-port.h can include it. + +#ifndef GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ +#define GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ + +// 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 +# elif defined(WINAPI_FAMILY) +# include +# if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) +# define GTEST_OS_WINDOWS_DESKTOP 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP) +# define GTEST_OS_WINDOWS_PHONE 1 +# elif WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +# define GTEST_OS_WINDOWS_RT 1 +# else + // WINAPI_FAMILY defined but no known partition matched. + // Default to desktop. +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif +# else +# define GTEST_OS_WINDOWS_DESKTOP 1 +# endif // _WIN32_WCE +#elif defined __APPLE__ +# define GTEST_OS_MAC 1 +# if TARGET_OS_IPHONE +# define GTEST_OS_IOS 1 +# endif +#elif defined __FreeBSD__ +# define GTEST_OS_FREEBSD 1 +#elif defined __linux__ +# define GTEST_OS_LINUX 1 +# if defined __ANDROID__ +# define GTEST_OS_LINUX_ANDROID 1 +# endif +#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 +#elif defined __OpenBSD__ +# define GTEST_OS_OPENBSD 1 +#elif defined __QNX__ +# define GTEST_OS_QNX 1 +#endif // __CYGWIN__ + +#endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ diff --git a/Externals/gtest/include/gtest/internal/gtest-port.h b/Externals/gtest/include/gtest/internal/gtest-port.h index a1176760c3..936dfd509a 100644 --- a/Externals/gtest/include/gtest/internal/gtest-port.h +++ b/Externals/gtest/include/gtest/internal/gtest-port.h @@ -121,12 +121,12 @@ // // GTEST_OS_AIX - IBM AIX // GTEST_OS_CYGWIN - Cygwin +// GTEST_OS_FREEBSD - FreeBSD // GTEST_OS_HPUX - HP-UX // GTEST_OS_LINUX - Linux // GTEST_OS_LINUX_ANDROID - Google Android // GTEST_OS_MAC - Mac OS X // GTEST_OS_IOS - iOS -// GTEST_OS_IOS_SIMULATOR - iOS simulator // GTEST_OS_NACL - Google Native Client (NaCl) // GTEST_OS_OPENBSD - OpenBSD // GTEST_OS_QNX - QNX @@ -136,6 +136,8 @@ // GTEST_OS_WINDOWS_DESKTOP - Windows Desktop // GTEST_OS_WINDOWS_MINGW - MinGW // GTEST_OS_WINDOWS_MOBILE - Windows Mobile +// GTEST_OS_WINDOWS_PHONE - Windows Phone +// GTEST_OS_WINDOWS_RT - Windows Store App/WinRT // GTEST_OS_ZOS - z/OS // // Among the platforms, Cygwin, Linux, Max OS X, and Windows have the @@ -204,7 +206,7 @@ // // C++11 feature wrappers: // -// GTEST_MOVE_ - portability wrapper for std::move. +// testing::internal::move - portability wrapper for std::move. // // Synchronization: // Mutex, MutexLock, ThreadLocal, GetThreadCount() @@ -269,17 +271,23 @@ # include #endif +#include // NOLINT #include // NOLINT #include // NOLINT #include // NOLINT #include -#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/" +#include "gtest/internal/gtest-port-arch.h" +#include "gtest/internal/custom/gtest-port.h" + +#if !defined(GTEST_DEV_EMAIL_) +# 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/" +#endif // !defined(GTEST_DEV_EMAIL_) // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ @@ -288,48 +296,22 @@ (__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 -# if TARGET_OS_IPHONE -# define GTEST_OS_IOS 1 -# if TARGET_IPHONE_SIMULATOR -# define GTEST_OS_IOS_SIMULATOR 1 -# endif -# endif -#elif defined __linux__ -# define GTEST_OS_LINUX 1 -# if defined __ANDROID__ -# define GTEST_OS_LINUX_ANDROID 1 -# endif -#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 -#elif defined __OpenBSD__ -# define GTEST_OS_OPENBSD 1 -#elif defined __QNX__ -# define GTEST_OS_QNX 1 -#endif // __CYGWIN__ +// Macros for disabling Microsoft Visual C++ warnings. +// +// GTEST_DISABLE_MSC_WARNINGS_PUSH_(4800 4385) +// /* code that triggers warnings C4800 and C4385 */ +// GTEST_DISABLE_MSC_WARNINGS_POP_() +#if _MSC_VER >= 1500 +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) \ + __pragma(warning(push)) \ + __pragma(warning(disable: warnings)) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() \ + __pragma(warning(pop)) +#else +// Older versions of MSVC don't have __pragma. +# define GTEST_DISABLE_MSC_WARNINGS_PUSH_(warnings) +# define GTEST_DISABLE_MSC_WARNINGS_POP_() +#endif #ifndef GTEST_LANG_CXX11 // gcc and clang define __GXX_EXPERIMENTAL_CXX0X__ when @@ -344,12 +326,34 @@ # endif #endif -// C++11 specifies that provides std::initializer_list. Use -// that if gtest is used in C++11 mode and libstdc++ isn't very old (binaries -// targeting OS X 10.6 can build with clang but need to use gcc4.2's -// libstdc++). -#if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +// Distinct from C++11 language support, some environments don't provide +// proper C++11 library support. Notably, it's possible to build in +// C++11 mode when targeting Mac OS X 10.6, which has an old libstdc++ +// with no C++11 support. +// +// libstdc++ has sufficient C++11 support as of GCC 4.6.0, __GLIBCXX__ +// 20110325, but maintenance releases in the 4.4 and 4.5 series followed +// this date, so check for those versions by their date stamps. +// https://gcc.gnu.org/onlinedocs/libstdc++/manual/abi.html#abi.versioning +#if GTEST_LANG_CXX11 && \ + (!defined(__GLIBCXX__) || ( \ + __GLIBCXX__ >= 20110325ul && /* GCC >= 4.6.0 */ \ + /* Blacklist of patch releases of older branches: */ \ + __GLIBCXX__ != 20110416ul && /* GCC 4.4.6 */ \ + __GLIBCXX__ != 20120313ul && /* GCC 4.4.7 */ \ + __GLIBCXX__ != 20110428ul && /* GCC 4.5.3 */ \ + __GLIBCXX__ != 20120702ul)) /* GCC 4.5.4 */ +# define GTEST_STDLIB_CXX11 1 +#endif + +// Only use C++11 library features if the library provides them. +#if GTEST_STDLIB_CXX11 +# define GTEST_HAS_STD_BEGIN_AND_END_ 1 +# define GTEST_HAS_STD_FORWARD_LIST_ 1 +# define GTEST_HAS_STD_FUNCTION_ 1 # define GTEST_HAS_STD_INITIALIZER_LIST_ 1 +# define GTEST_HAS_STD_MOVE_ 1 +# define GTEST_HAS_STD_UNIQUE_PTR_ 1 #endif // C++11 specifies that provides std::tuple. @@ -379,16 +383,23 @@ // 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 +#if GTEST_OS_WINDOWS +# if !GTEST_OS_WINDOWS_MOBILE +# include +# include +# endif +// In order to avoid having to include , use forward declaration +// assuming CRITICAL_SECTION is a typedef of _RTL_CRITICAL_SECTION. +// This assumption is verified by +// WindowsTypesTest.CRITICAL_SECTIONIs_RTL_CRITICAL_SECTION. +struct _RTL_CRITICAL_SECTION; +#else // 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 # include -#elif !GTEST_OS_WINDOWS_MOBILE -# include -# include -#endif +#endif // GTEST_OS_WINDOWS #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. @@ -405,7 +416,10 @@ # endif #endif -#if GTEST_HAS_POSIX_RE +#if GTEST_USES_PCRE +// The appropriate headers have already been included. + +#elif GTEST_HAS_POSIX_RE // On some platforms, needs someone to define size_t, and // won't compile otherwise. We can #include it here as we already @@ -427,7 +441,7 @@ // simple regex implementation instead. # define GTEST_USES_SIMPLE_RE 1 -#endif // GTEST_HAS_POSIX_RE +#endif // GTEST_USES_PCRE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need @@ -440,6 +454,15 @@ # define _HAS_EXCEPTIONS 1 # endif // _HAS_EXCEPTIONS # define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +# elif defined(__clang__) +// clang defines __EXCEPTIONS iff exceptions are enabled before clang 220714, +// but iff cleanups are enabled after that. In Obj-C++ files, there can be +// cleanups for ObjC exceptions which also need cleanups, even if C++ exceptions +// are disabled. clang has __has_feature(cxx_exceptions) which checks for C++ +// exceptions starting at clang r206352, but which checked for cleanups prior to +// that. To reliably check for C++ exception availability with clang, check for +// __EXCEPTIONS && __has_feature(cxx_exceptions). +# define GTEST_HAS_EXCEPTIONS (__EXCEPTIONS && __has_feature(cxx_exceptions)) # elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. # define GTEST_HAS_EXCEPTIONS 1 @@ -565,13 +588,13 @@ // 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. +// The user didn't tell us explicitly, so we make reasonable assumptions about +// which platforms have pthreads support. // // 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 \ - || GTEST_OS_QNX) + || GTEST_OS_QNX || GTEST_OS_FREEBSD || GTEST_OS_NACL) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD @@ -583,6 +606,15 @@ # include // NOLINT #endif +// Determines if hash_map/hash_set are available. +// Only used for testing against those containers. +#if !defined(GTEST_HAS_HASH_MAP_) +# if _MSC_VER +# define GTEST_HAS_HASH_MAP_ 1 // Indicates that hash_map is available. +# define GTEST_HAS_HASH_SET_ 1 // Indicates that hash_set is available. +# endif // _MSC_VER +#endif // !defined(GTEST_HAS_HASH_MAP_) + // 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). @@ -633,11 +665,21 @@ // To avoid conditional compilation everywhere, we make it // gtest-port.h's responsibility to #include the header implementing -// tr1/tuple. +// tuple. +#if GTEST_HAS_STD_TUPLE_ +# include // IWYU pragma: export +# define GTEST_TUPLE_NAMESPACE_ ::std +#endif // GTEST_HAS_STD_TUPLE_ + +// We include tr1::tuple even if std::tuple is available to define printers for +// them. #if GTEST_HAS_TR1_TUPLE +# ifndef GTEST_TUPLE_NAMESPACE_ +# define GTEST_TUPLE_NAMESPACE_ ::std::tr1 +# endif // GTEST_TUPLE_NAMESPACE_ # if GTEST_USE_OWN_TR1_TUPLE -# include "gtest/internal/gtest-tuple.h" +# include "gtest/internal/gtest-tuple.h" // IWYU pragma: export // NOLINT # elif GTEST_ENV_HAS_STD_TUPLE_ # include // C++11 puts its tuple into the ::std namespace rather than @@ -668,7 +710,7 @@ using ::std::tuple_size; // This prevents , which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's . # define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED -# include +# include // IWYU pragma: export // NOLINT # elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the header. This does @@ -691,7 +733,7 @@ using ::std::tuple_size; # else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. -# include // NOLINT +# include // IWYU pragma: export // NOLINT # endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE @@ -725,7 +767,8 @@ using ::std::tuple_size; #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 +# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || \ + GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT # define GTEST_HAS_STREAM_REDIRECTION 0 # else # define GTEST_HAS_STREAM_REDIRECTION 1 @@ -737,10 +780,10 @@ using ::std::tuple_size; // 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_CYGWIN || GTEST_OS_SOLARIS || \ - (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || \ (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ - GTEST_OS_OPENBSD || GTEST_OS_QNX) + GTEST_OS_OPENBSD || GTEST_OS_QNX || GTEST_OS_FREEBSD) # define GTEST_HAS_DEATH_TEST 1 # include // NOLINT #endif @@ -806,7 +849,12 @@ using ::std::tuple_size; // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) # define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) -#else +#elif defined(__clang__) +# if __has_attribute(unused) +# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +# endif +#endif +#ifndef GTEST_ATTRIBUTE_UNUSED_ # define GTEST_ATTRIBUTE_UNUSED_ #endif @@ -832,30 +880,18 @@ using ::std::tuple_size; # define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC -#if GTEST_LANG_CXX11 -# define GTEST_MOVE_(x) ::std::move(x) // NOLINT -#else -# define GTEST_MOVE_(x) x -#endif - // MS C++ compiler emits warning when a conditional expression is compile time // constant. In some contexts this warning is false positive and needs to be // suppressed. Use the following two macros in such cases: // -// GTEST_INTENTIONAL_CONST_COND_PUSH_ +// GTEST_INTENTIONAL_CONST_COND_PUSH_() // while (true) { -// GTEST_INTENTIONAL_CONST_COND_POP_ +// GTEST_INTENTIONAL_CONST_COND_POP_() // } -#if defined(_MSC_VER) -# define GTEST_INTENTIONAL_CONST_COND_PUSH_ \ - __pragma(warning(push)) \ - __pragma(warning(disable: 4127)) -# define GTEST_INTENTIONAL_CONST_COND_POP_ \ - __pragma(warning(pop)) -#else -# define GTEST_INTENTIONAL_CONST_COND_PUSH_ -# define GTEST_INTENTIONAL_CONST_COND_POP_ -#endif +# define GTEST_INTENTIONAL_CONST_COND_PUSH_() \ + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4127) +# define GTEST_INTENTIONAL_CONST_COND_POP_() \ + GTEST_DISABLE_MSC_WARNINGS_POP_() // Determine whether the compiler supports Microsoft's Structured Exception // Handling. This is supported by several Windows compilers but generally @@ -871,6 +907,11 @@ using ::std::tuple_size; # define GTEST_HAS_SEH 0 # endif +#define GTEST_IS_THREADSAFE \ + (GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ \ + || (GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT) \ + || GTEST_HAS_PTHREAD) + #endif // GTEST_HAS_SEH #ifdef _MSC_VER @@ -926,10 +967,33 @@ using ::std::tuple_size; # define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ #endif // __clang__ +// A function level attribute to disable ThreadSanitizer instrumentation. +#if defined(__clang__) +# if __has_feature(thread_sanitizer) +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ \ + __attribute__((no_sanitize_thread)) +# else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +# endif // __has_feature(thread_sanitizer) +#else +# define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ +#endif // __clang__ + namespace testing { class Message; +#if defined(GTEST_TUPLE_NAMESPACE_) +// Import tuple and friends into the ::testing namespace. +// It is part of our interface, having them in ::testing allows us to change +// their types as needed. +using GTEST_TUPLE_NAMESPACE_::get; +using GTEST_TUPLE_NAMESPACE_::make_tuple; +using GTEST_TUPLE_NAMESPACE_::tuple; +using GTEST_TUPLE_NAMESPACE_::tuple_size; +using GTEST_TUPLE_NAMESPACE_::tuple_element; +#endif // defined(GTEST_TUPLE_NAMESPACE_) + namespace internal { // A secret type that Google Test users don't know about. It has no @@ -952,16 +1016,22 @@ class Secret; // the expression is false, most compilers will issue a warning/error // containing the name of the variable. +#if GTEST_LANG_CXX11 +# define GTEST_COMPILE_ASSERT_(expr, msg) static_assert(expr, #msg) +#else // !GTEST_LANG_CXX11 template -struct CompileAssert { + struct CompileAssert { }; -#define GTEST_COMPILE_ASSERT_(expr, msg) \ +# define GTEST_COMPILE_ASSERT_(expr, msg) \ typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ +#endif // !GTEST_LANG_CXX11 // Implementation details of GTEST_COMPILE_ASSERT_: // +// (In C++11, we simply use static_assert instead of the following) +// // - GTEST_COMPILE_ASSERT_ works by defining an array type that has -1 // elements (and thus is invalid) when the expression is false. // @@ -1008,7 +1078,9 @@ template struct StaticAssertTypeEqHelper; template -struct StaticAssertTypeEqHelper {}; +struct StaticAssertTypeEqHelper { + enum { value = true }; +}; // Evaluates to the number of elements in 'array'. #define GTEST_ARRAY_SIZE_(array) (sizeof(array) / sizeof(array[0])) @@ -1060,6 +1132,11 @@ class scoped_ptr { } } + friend void swap(scoped_ptr& a, scoped_ptr& b) { + using std::swap; + swap(a.ptr_, b.ptr_); + } + private: T* ptr_; @@ -1183,13 +1260,18 @@ class GTEST_API_ GTestLog { GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); }; -#define GTEST_LOG_(severity) \ +#if !defined(GTEST_LOG_) + +# define GTEST_LOG_(severity) \ ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ __FILE__, __LINE__).GetStream() inline void LogToStderr() {} inline void FlushInfoLog() { fflush(NULL); } +#endif // !defined(GTEST_LOG_) + +#if !defined(GTEST_CHECK_) // INTERNAL IMPLEMENTATION - DO NOT USE. // // GTEST_CHECK_ is an all-mode assert. It aborts the program if the condition @@ -1204,12 +1286,13 @@ inline void FlushInfoLog() { fflush(NULL); } // 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) \ +# define GTEST_CHECK_(condition) \ GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ if (::testing::internal::IsTrue(condition)) \ ; \ else \ GTEST_LOG_(FATAL) << "Condition " #condition " failed. " +#endif // !defined(GTEST_CHECK_) // An all-mode assert to verify that the given POSIX-style function // call returns 0 (indicating success). Known limitation: this @@ -1221,6 +1304,15 @@ inline void FlushInfoLog() { fflush(NULL); } GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ << gtest_error +#if GTEST_HAS_STD_MOVE_ +using std::move; +#else // GTEST_HAS_STD_MOVE_ +template +const T& move(const T& t) { + return t; +} +#endif // GTEST_HAS_STD_MOVE_ + // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Use ImplicitCast_ as a safe version of static_cast for upcasting in @@ -1242,7 +1334,7 @@ inline void FlushInfoLog() { fflush(NULL); } // 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 -inline To ImplicitCast_(To x) { return x; } +inline To ImplicitCast_(To x) { return ::testing::internal::move(x); } // When you upcast (that is, cast a pointer from type Foo to type // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts @@ -1271,9 +1363,9 @@ inline To DownCast_(From* f) { // so we only accept pointers // for compile-time type checking, and has no overhead in an // optimized build at run-time, as it will be optimized away // completely. - GTEST_INTENTIONAL_CONST_COND_PUSH_ + GTEST_INTENTIONAL_CONST_COND_PUSH_() if (false) { - GTEST_INTENTIONAL_CONST_COND_POP_ + GTEST_INTENTIONAL_CONST_COND_POP_() const To to = NULL; ::testing::internal::ImplicitCast_(to); } @@ -1294,6 +1386,11 @@ template Derived* CheckedDowncastToActualType(Base* base) { #if GTEST_HAS_RTTI GTEST_CHECK_(typeid(*base) == typeid(Derived)); +#endif + +#if GTEST_HAS_DOWNCAST_ + return ::down_cast(base); +#elif GTEST_HAS_RTTI return dynamic_cast(base); // NOLINT #else return static_cast(base); // Poor man's downcast. @@ -1315,6 +1412,14 @@ GTEST_API_ std::string GetCapturedStderr(); #endif // GTEST_HAS_STREAM_REDIRECTION +// Returns a path to temporary directory. +GTEST_API_ std::string TempDir(); + +// Returns the size (in bytes) of a file. +GTEST_API_ size_t GetFileSize(FILE* file); + +// Reads the entire content of a file as a string. +GTEST_API_ std::string ReadEntireFile(FILE* file); #if GTEST_HAS_DEATH_TEST @@ -1322,18 +1427,17 @@ const ::std::vector& GetInjectableArgvs(); void SetInjectableArgvs(const ::std::vector* new_argvs); -// A copy of all command line arguments. Set by InitGoogleTest(). +// A copy of all command line arguments. Set by ParseGTestFlags(). extern ::std::vector g_argvs; #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. +#if GTEST_IS_THREADSAFE +# if GTEST_HAS_PTHREAD +// Sleeps for (roughly) n milliseconds. 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. @@ -1341,7 +1445,13 @@ inline void SleepMilliseconds(int n) { }; nanosleep(&time, NULL); } +# endif // GTEST_HAS_PTHREAD +# if GTEST_HAS_NOTIFICATION_ +// Notification has already been imported into the namespace. +// Nothing to do here. + +# elif GTEST_HAS_PTHREAD // 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. @@ -1385,6 +1495,62 @@ class Notification { GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +GTEST_API_ void SleepMilliseconds(int n); + +// Provides leak-safe Windows kernel handle ownership. +// Used in death tests and in threading support. +class GTEST_API_ AutoHandle { + public: + // Assume that Win32 HANDLE type is equivalent to void*. Doing so allows us to + // avoid including in this header file. Including is + // undesirable because it defines a lot of symbols and macros that tend to + // conflict with client code. This assumption is verified by + // WindowsTypesTest.HANDLEIsVoidStar. + typedef void* Handle; + AutoHandle(); + explicit AutoHandle(Handle handle); + + ~AutoHandle(); + + Handle Get() const; + void Reset(); + void Reset(Handle handle); + + private: + // Returns true iff the handle is a valid handle object that can be closed. + bool IsCloseable() const; + + Handle handle_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); +}; + +// 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 GTEST_API_ Notification { + public: + Notification(); + void Notify(); + void WaitForNotification(); + + private: + AutoHandle event_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); +}; +# endif // GTEST_HAS_NOTIFICATION_ + +// On MinGW, we can have both GTEST_OS_WINDOWS and GTEST_HAS_PTHREAD +// defined, but we don't want to use MinGW's pthreads implementation, which +// has conformance problems with some versions of the POSIX standard. +# if GTEST_HAS_PTHREAD && !GTEST_OS_WINDOWS_MINGW + // 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 @@ -1422,10 +1588,9 @@ extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { template class ThreadWithParam : public ThreadWithParamBase { public: - typedef void (*UserThreadFunc)(T); + typedef void UserThreadFunc(T); - ThreadWithParam( - UserThreadFunc func, T param, Notification* thread_can_start) + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) : func_(func), param_(param), thread_can_start_(thread_can_start), @@ -1452,7 +1617,7 @@ class ThreadWithParam : public ThreadWithParamBase { } private: - const UserThreadFunc func_; // User-supplied thread function. + UserThreadFunc* const 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. @@ -1462,26 +1627,293 @@ class ThreadWithParam : public ThreadWithParamBase { GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; +# endif // !GTEST_OS_WINDOWS && GTEST_HAS_PTHREAD || + // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ -// MutexBase and Mutex implement mutex on pthreads-based platforms. They -// are used in conjunction with class MutexLock: +# if GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ +// Mutex and ThreadLocal have already been imported into the namespace. +// Nothing to do here. + +# elif GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT + +// Mutex implements mutex on Windows platforms. It is 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: +// MutexLock lock(&mutex); // Acquires the mutex and releases it at the +// // end of the current scope. // +// A static Mutex *must* be defined or declared using one of the following +// macros: // 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. +// (A non-static Mutex is defined/declared in the usual way). +class GTEST_API_ Mutex { + public: + enum MutexType { kStatic = 0, kDynamic = 1 }; + // We rely on kStaticMutex being 0 as it is to what the linker initializes + // type_ in static mutexes. critical_section_ will be initialized lazily + // in ThreadSafeLazyInit(). + enum StaticConstructorSelector { kStaticMutex = 0 }; + + // This constructor intentionally does nothing. It relies on type_ being + // statically initialized to 0 (effectively setting it to kStatic) and on + // ThreadSafeLazyInit() to lazily initialize the rest of the members. + explicit Mutex(StaticConstructorSelector /*dummy*/) {} + + Mutex(); + ~Mutex(); + + void Lock(); + + void Unlock(); + + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld(); + + private: + // Initializes owner_thread_id_ and critical_section_ in static mutexes. + void ThreadSafeLazyInit(); + + // Per http://blogs.msdn.com/b/oldnewthing/archive/2004/02/23/78395.aspx, + // we assume that 0 is an invalid value for thread IDs. + unsigned int owner_thread_id_; + + // For static mutexes, we rely on these members being initialized to zeros + // by the linker. + MutexType type_; + long critical_section_init_phase_; // NOLINT + _RTL_CRITICAL_SECTION* critical_section_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +}; + +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex + +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::Mutex mutex(::testing::internal::Mutex::kStaticMutex) + +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. +class GTestMutexLock { + public: + explicit GTestMutexLock(Mutex* mutex) + : mutex_(mutex) { mutex_->Lock(); } + + ~GTestMutexLock() { mutex_->Unlock(); } + + private: + Mutex* const mutex_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); +}; + +typedef GTestMutexLock MutexLock; + +// Base class for ValueHolder. Allows a caller to hold and delete a value +// without knowing its type. +class ThreadLocalValueHolderBase { + public: + virtual ~ThreadLocalValueHolderBase() {} +}; + +// Provides a way for a thread to send notifications to a ThreadLocal +// regardless of its parameter type. +class ThreadLocalBase { + public: + // Creates a new ValueHolder object holding a default value passed to + // this ThreadLocal's constructor and returns it. It is the caller's + // responsibility not to call this when the ThreadLocal instance already + // has a value on the current thread. + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const = 0; + + protected: + ThreadLocalBase() {} + virtual ~ThreadLocalBase() {} + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocalBase); +}; + +// Maps a thread to a set of ThreadLocals that have values instantiated on that +// thread and notifies them when the thread exits. A ThreadLocal instance is +// expected to persist until all threads it has values on have terminated. +class GTEST_API_ ThreadLocalRegistry { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance); + + // Invoked when a ThreadLocal instance is destroyed. + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance); +}; + +class GTEST_API_ ThreadWithParamBase { + public: + void Join(); + + protected: + class Runnable { + public: + virtual ~Runnable() {} + virtual void Run() = 0; + }; + + ThreadWithParamBase(Runnable *runnable, Notification* thread_can_start); + virtual ~ThreadWithParamBase(); + + private: + AutoHandle thread_; +}; + +// Helper class for testing Google Test's multi-threading constructs. +template +class ThreadWithParam : public ThreadWithParamBase { + public: + typedef void UserThreadFunc(T); + + ThreadWithParam(UserThreadFunc* func, T param, Notification* thread_can_start) + : ThreadWithParamBase(new RunnableImpl(func, param), thread_can_start) { + } + virtual ~ThreadWithParam() {} + + private: + class RunnableImpl : public Runnable { + public: + RunnableImpl(UserThreadFunc* func, T param) + : func_(func), + param_(param) { + } + virtual ~RunnableImpl() {} + virtual void Run() { + func_(param_); + } + + private: + UserThreadFunc* const func_; + const T param_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(RunnableImpl); + }; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); +}; + +// Implements thread-local storage on Windows systems. +// +// // Thread 1 +// ThreadLocal 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. +// +// The users of a TheadLocal instance have to make sure that all but one +// threads (including the main one) using that instance have exited before +// destroying it. Otherwise, the per-thread objects managed for them by the +// ThreadLocal instance are not guaranteed to be destroyed on all platforms. +// +// 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 +class ThreadLocal : public ThreadLocalBase { + public: + ThreadLocal() : default_factory_(new DefaultValueHolderFactory()) {} + explicit ThreadLocal(const T& value) + : default_factory_(new InstanceValueHolderFactory(value)) {} + + ~ThreadLocal() { ThreadLocalRegistry::OnThreadLocalDestroyed(this); } + + 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 T. Can be deleted via its base class without the caller + // knowing the type of T. + class ValueHolder : public ThreadLocalValueHolderBase { + public: + ValueHolder() : value_() {} + explicit ValueHolder(const T& value) : value_(value) {} + + T* pointer() { return &value_; } + + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; + + + T* GetOrCreateValue() const { + return static_cast( + ThreadLocalRegistry::GetValueOnCurrentThread(this))->pointer(); + } + + virtual ThreadLocalValueHolderBase* NewValueForCurrentThread() const { + return default_factory_->MakeNewHolder(); + } + + class ValueHolderFactory { + public: + ValueHolderFactory() {} + virtual ~ValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + }; + + class DefaultValueHolderFactory : public ValueHolderFactory { + public: + DefaultValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + }; + + class InstanceValueHolderFactory : public ValueHolderFactory { + public: + explicit InstanceValueHolderFactory(const T& value) : value_(value) {} + virtual ValueHolder* MakeNewHolder() const { + return new ValueHolder(value_); + } + + private: + const T value_; // The value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + }; + + scoped_ptr default_factory_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); +}; + +# elif GTEST_HAS_PTHREAD + +// MutexBase and Mutex implement mutex on pthreads-based platforms. class MutexBase { public: // Acquires this mutex. @@ -1526,8 +1958,8 @@ class MutexBase { }; // Forward-declares a static mutex. -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::MutexBase mutex +# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, @@ -1535,8 +1967,8 @@ class MutexBase { // particular, the owner_ field (a pthread_t) is not explicitly initialized. // This allows initialization to work whether pthread_t is a scalar or struct. // The flag -Wmissing-field-initializers must not be specified for this to work. -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ - ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } +# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } // The Mutex class can only be used for mutexes created at runtime. It // shares its API with MutexBase otherwise. @@ -1554,9 +1986,11 @@ class Mutex : public MutexBase { GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; -// We cannot name this class MutexLock as the ctor declaration would +// We cannot name this class MutexLock because the ctor declaration would // conflict with a macro named MutexLock, which is defined on some -// platforms. Hence the typedef trick below. +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(MutexBase* mutex) @@ -1590,41 +2024,14 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) { } // Implements thread-local storage on pthreads-based systems. -// -// // Thread 1 -// ThreadLocal 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 class ThreadLocal { public: - ThreadLocal() : key_(CreateKey()), - default_() {} - explicit ThreadLocal(const T& value) : key_(CreateKey()), - default_(value) {} + ThreadLocal() + : key_(CreateKey()), default_factory_(new DefaultValueHolderFactory()) {} + explicit ThreadLocal(const T& value) + : key_(CreateKey()), + default_factory_(new InstanceValueHolderFactory(value)) {} ~ThreadLocal() { // Destroys the managed object for the current thread, if any. @@ -1644,6 +2051,7 @@ class ThreadLocal { // Holds a value of type T. class ValueHolder : public ThreadLocalValueHolderBase { public: + ValueHolder() : value_() {} explicit ValueHolder(const T& value) : value_(value) {} T* pointer() { return &value_; } @@ -1669,22 +2077,54 @@ class ThreadLocal { return CheckedDowncastToActualType(holder)->pointer(); } - ValueHolder* const new_holder = new ValueHolder(default_); + ValueHolder* const new_holder = default_factory_->MakeNewHolder(); ThreadLocalValueHolderBase* const holder_base = new_holder; GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); return new_holder->pointer(); } + class ValueHolderFactory { + public: + ValueHolderFactory() {} + virtual ~ValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const = 0; + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolderFactory); + }; + + class DefaultValueHolderFactory : public ValueHolderFactory { + public: + DefaultValueHolderFactory() {} + virtual ValueHolder* MakeNewHolder() const { return new ValueHolder(); } + + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultValueHolderFactory); + }; + + class InstanceValueHolderFactory : public ValueHolderFactory { + public: + explicit InstanceValueHolderFactory(const T& value) : value_(value) {} + virtual ValueHolder* MakeNewHolder() const { + return new ValueHolder(value_); + } + + private: + const T value_; // The value for each thread. + + GTEST_DISALLOW_COPY_AND_ASSIGN_(InstanceValueHolderFactory); + }; + // A key pthreads uses for looking up per-thread values. const pthread_key_t key_; - const T default_; // The default value for each thread. + scoped_ptr default_factory_; GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; -# define GTEST_IS_THREADSAFE 1 +# endif // GTEST_HAS_MUTEX_AND_THREAD_LOCAL_ -#else // GTEST_HAS_PTHREAD +#else // GTEST_IS_THREADSAFE // A dummy implementation of synchronization primitives (mutex, lock, // and thread-local variable). Necessary for compiling Google Test where @@ -1704,6 +2144,11 @@ class Mutex { # define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex +// We cannot name this class MutexLock because the ctor declaration would +// conflict with a macro named MutexLock, which is defined on some +// platforms. That macro is used as a defensive measure to prevent against +// inadvertent misuses of MutexLock like "MutexLock(&mu)" rather than +// "MutexLock l(&mu)". Hence the typedef trick below. class GTestMutexLock { public: explicit GTestMutexLock(Mutex*) {} // NOLINT @@ -1724,11 +2169,7 @@ class ThreadLocal { 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 +#endif // GTEST_IS_THREADSAFE // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. @@ -1838,6 +2279,13 @@ inline char ToUpper(char ch) { return static_cast(toupper(static_cast(ch))); } +inline std::string StripTrailingSpaces(std::string str) { + std::string::iterator it = str.end(); + while (it != str.begin() && IsSpace(*--it)) + it = str.erase(it); + return str; +} + // 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 @@ -1901,11 +2349,7 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } // Functions deprecated by MSVC 8.0. -#ifdef _MSC_VER -// Temporarily disable warning 4996 (deprecated function). -# pragma warning(push) -# pragma warning(disable:4996) -#endif +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996 /* deprecated function */) inline const char* StrNCpy(char* dest, const char* src, size_t n) { return strncpy(dest, src, n); @@ -1915,7 +2359,7 @@ inline const char* StrNCpy(char* dest, const char* src, size_t n) { // StrError() aren't needed on Windows CE at this time and thus not // defined there. -#if !GTEST_OS_WINDOWS_MOBILE +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { @@ -1939,8 +2383,9 @@ 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 +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE | GTEST_OS_WINDOWS_RT // We are on Windows CE, which has no environment variables. + static_cast(name); // To prevent 'unused argument' warning. return NULL; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) // Environment variables which we programmatically clear will be set to the @@ -1952,9 +2397,7 @@ inline const char* GetEnv(const char* name) { #endif } -#ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif +GTEST_DISABLE_MSC_WARNINGS_POP_() #if GTEST_OS_WINDOWS_MOBILE // Windows CE has no C library. The abort() function is used in @@ -2055,11 +2498,20 @@ 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 +#if !defined(GTEST_FLAG) +# define GTEST_FLAG(name) FLAGS_gtest_##name +#endif // !defined(GTEST_FLAG) + +#if !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) +# define GTEST_USE_OWN_FLAGFILE_FLAG_ 1 +#endif // !defined(GTEST_USE_OWN_FLAGFILE_FLAG_) + +#if !defined(GTEST_DECLARE_bool_) +# define GTEST_FLAG_SAVER_ ::testing::internal::GTestFlagSaver // Macros for declaring flags. -#define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) -#define GTEST_DECLARE_int32_(name) \ +# 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 ::std::string GTEST_FLAG(name) @@ -2072,9 +2524,13 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. #define GTEST_DEFINE_string_(name, default_val, doc) \ GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) +#endif // !defined(GTEST_DECLARE_bool_) + // Thread annotations -#define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) -#define GTEST_LOCK_EXCLUDED_(locks) +#if !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) +# define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) +# define GTEST_LOCK_EXCLUDED_(locks) +#endif // !defined(GTEST_EXCLUSIVE_LOCK_REQUIRED_) // Parses 'str' for a 32-bit signed integer. If successful, writes the result // to *value and returns true; otherwise leaves *value unchanged and returns @@ -2094,3 +2550,4 @@ const char* StringFromGTestEnv(const char* flag, const char* default_val); } // namespace testing #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_H_ + diff --git a/Externals/gtest/src/gtest-death-test.cc b/Externals/gtest/src/gtest-death-test.cc index a6023fce4f..a61440743e 100644 --- a/Externals/gtest/src/gtest-death-test.cc +++ b/Externals/gtest/src/gtest-death-test.cc @@ -68,9 +68,9 @@ // 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. +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ @@ -169,6 +169,14 @@ KilledBySignal::KilledBySignal(int signum) : signum_(signum) { // KilledBySignal function-call operator. bool KilledBySignal::operator()(int exit_status) const { +# if defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) + { + bool result; + if (GTEST_KILLED_BY_SIGNAL_OVERRIDE_(signum_, exit_status, &result)) { + return result; + } + } +# endif // defined(GTEST_KILLED_BY_SIGNAL_OVERRIDE_) return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } # endif // !GTEST_OS_WINDOWS @@ -985,6 +993,8 @@ void StackLowerThanAddress(const void* ptr, bool* result) { *result = (&dummy < ptr); } +// Make sure AddressSanitizer does not tamper with the stack here. +GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ bool StackGrowsDown() { int dummy; bool result; @@ -1202,26 +1212,6 @@ bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, 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 diff --git a/Externals/gtest/src/gtest-filepath.cc b/Externals/gtest/src/gtest-filepath.cc index d221cfdec1..0292dc1195 100644 --- a/Externals/gtest/src/gtest-filepath.cc +++ b/Externals/gtest/src/gtest-filepath.cc @@ -97,7 +97,7 @@ static bool IsPathSeparator(char c) { // Returns the current working directory, or "" if unsuccessful. FilePath FilePath::GetCurrentDir() { -#if GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT // Windows CE doesn't have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); @@ -106,7 +106,14 @@ FilePath FilePath::GetCurrentDir() { return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; - return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); + char* result = getcwd(cwd, sizeof(cwd)); +# if GTEST_OS_NACL + // getcwd will likely fail in NaCl due to the sandbox, so return something + // reasonable. The user may have provided a shim implementation for getcwd, + // however, so fallback only when failure is detected. + return FilePath(result == NULL ? kCurrentDirectoryString : cwd); +# endif // GTEST_OS_NACL + return FilePath(result == NULL ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } diff --git a/Externals/gtest/src/gtest-internal-inl.h b/Externals/gtest/src/gtest-internal-inl.h index 35df303cca..56c8a20c65 100644 --- a/Externals/gtest/src/gtest-internal-inl.h +++ b/Externals/gtest/src/gtest-internal-inl.h @@ -40,7 +40,7 @@ // 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. +// If this file is included from the user's 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_ @@ -100,6 +100,7 @@ const char kShuffleFlag[] = "shuffle"; const char kStackTraceDepthFlag[] = "stack_trace_depth"; const char kStreamResultToFlag[] = "stream_result_to"; const char kThrowOnFailureFlag[] = "throw_on_failure"; +const char kFlagfileFlag[] = "flagfile"; // A valid random seed must be in [1, kMaxRandomSeed]. const int kMaxRandomSeed = 99999; @@ -432,6 +433,10 @@ class OsStackTraceGetterInterface { // CurrentStackTrace() will use to find and hide Google Test stack frames. virtual void UponLeavingGTest() = 0; + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; + private: GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; @@ -439,26 +444,12 @@ class OsStackTraceGetterInterface { // A working implementation of the OsStackTraceGetterInterface interface. class OsStackTraceGetter : public OsStackTraceGetterInterface { public: - OsStackTraceGetter() : caller_frame_(NULL) {} + OsStackTraceGetter() {} - virtual string CurrentStackTrace(int max_depth, int skip_count) - GTEST_LOCK_EXCLUDED_(mutex_); - - virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); - - // This string is inserted in place of stack frames that are part of - // Google Test's implementation. - static const char* const kElidedFramesMarker; + virtual string CurrentStackTrace(int max_depth, int skip_count); + virtual void UponLeavingGTest(); 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); }; @@ -968,32 +959,6 @@ GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); // platform. GTEST_API_ std::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 diff --git a/Externals/gtest/src/gtest-port.cc b/Externals/gtest/src/gtest-port.cc index 0c4df5f29a..cd3ac9a58c 100644 --- a/Externals/gtest/src/gtest-port.cc +++ b/Externals/gtest/src/gtest-port.cc @@ -35,15 +35,16 @@ #include #include #include +#include -#if GTEST_OS_WINDOWS_MOBILE -# include // For TerminateProcess() -#elif GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS +# include # include # include +# include // Used in ThreadLocal. #else # include -#endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS #if GTEST_OS_MAC # include @@ -53,6 +54,7 @@ #if GTEST_OS_QNX # include +# include # include #endif // GTEST_OS_QNX @@ -63,9 +65,9 @@ // 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. +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ @@ -82,10 +84,31 @@ const int kStdOutFileno = STDOUT_FILENO; const int kStdErrFileno = STDERR_FILENO; #endif // _MSC_VER -#if GTEST_OS_MAC +#if GTEST_OS_LINUX + +namespace { +template +T ReadProcFileField(const string& filename, int field) { + std::string dummy; + std::ifstream file(filename.c_str()); + while (field-- > 0) { + file >> dummy; + } + T output = 0; + file >> output; + return output; +} +} // namespace + +// Returns the number of active threads, or 0 when there is an error. +size_t GetThreadCount() { + const string filename = + (Message() << "/proc/" << getpid() << "/stat").GetString(); + return ReadProcFileField(filename, 19); +} + +#elif 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; @@ -131,7 +154,390 @@ size_t GetThreadCount() { return 0; } -#endif // GTEST_OS_MAC +#endif // GTEST_OS_LINUX + +#if GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS + +void SleepMilliseconds(int n) { + ::Sleep(n); +} + +AutoHandle::AutoHandle() + : handle_(INVALID_HANDLE_VALUE) {} + +AutoHandle::AutoHandle(Handle handle) + : handle_(handle) {} + +AutoHandle::~AutoHandle() { + Reset(); +} + +AutoHandle::Handle AutoHandle::Get() const { + return handle_; +} + +void AutoHandle::Reset() { + Reset(INVALID_HANDLE_VALUE); +} + +void AutoHandle::Reset(HANDLE handle) { + // Resetting with the same handle we already own is invalid. + if (handle_ != handle) { + if (IsCloseable()) { + ::CloseHandle(handle_); + } + handle_ = handle; + } else { + GTEST_CHECK_(!IsCloseable()) + << "Resetting a valid handle to itself is likely a programmer error " + "and thus not allowed."; + } +} + +bool AutoHandle::IsCloseable() const { + // Different Windows APIs may use either of these values to represent an + // invalid handle. + return handle_ != NULL && handle_ != INVALID_HANDLE_VALUE; +} + +Notification::Notification() + : event_(::CreateEvent(NULL, // Default security attributes. + TRUE, // Do not reset automatically. + FALSE, // Initially unset. + NULL)) { // Anonymous event. + GTEST_CHECK_(event_.Get() != NULL); +} + +void Notification::Notify() { + GTEST_CHECK_(::SetEvent(event_.Get()) != FALSE); +} + +void Notification::WaitForNotification() { + GTEST_CHECK_( + ::WaitForSingleObject(event_.Get(), INFINITE) == WAIT_OBJECT_0); +} + +Mutex::Mutex() + : type_(kDynamic), + owner_thread_id_(0), + critical_section_init_phase_(0), + critical_section_(new CRITICAL_SECTION) { + ::InitializeCriticalSection(critical_section_); +} + +Mutex::~Mutex() { + // Static mutexes are leaked intentionally. It is not thread-safe to try + // to clean them up. + // TODO(yukawa): Switch to Slim Reader/Writer (SRW) Locks, which requires + // nothing to clean it up but is available only on Vista and later. + // http://msdn.microsoft.com/en-us/library/windows/desktop/aa904937.aspx + if (type_ == kDynamic) { + ::DeleteCriticalSection(critical_section_); + delete critical_section_; + critical_section_ = NULL; + } +} + +void Mutex::Lock() { + ThreadSafeLazyInit(); + ::EnterCriticalSection(critical_section_); + owner_thread_id_ = ::GetCurrentThreadId(); +} + +void Mutex::Unlock() { + ThreadSafeLazyInit(); + // We don't protect writing to owner_thread_id_ here, as it's the + // caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + owner_thread_id_ = 0; + ::LeaveCriticalSection(critical_section_); +} + +// Does nothing if the current thread holds the mutex. Otherwise, crashes +// with high probability. +void Mutex::AssertHeld() { + ThreadSafeLazyInit(); + GTEST_CHECK_(owner_thread_id_ == ::GetCurrentThreadId()) + << "The current thread is not holding the mutex @" << this; +} + +// Initializes owner_thread_id_ and critical_section_ in static mutexes. +void Mutex::ThreadSafeLazyInit() { + // Dynamic mutexes are initialized in the constructor. + if (type_ == kStatic) { + switch ( + ::InterlockedCompareExchange(&critical_section_init_phase_, 1L, 0L)) { + case 0: + // If critical_section_init_phase_ was 0 before the exchange, we + // are the first to test it and need to perform the initialization. + owner_thread_id_ = 0; + critical_section_ = new CRITICAL_SECTION; + ::InitializeCriticalSection(critical_section_); + // Updates the critical_section_init_phase_ to 2 to signal + // initialization complete. + GTEST_CHECK_(::InterlockedCompareExchange( + &critical_section_init_phase_, 2L, 1L) == + 1L); + break; + case 1: + // Somebody else is already initializing the mutex; spin until they + // are done. + while (::InterlockedCompareExchange(&critical_section_init_phase_, + 2L, + 2L) != 2L) { + // Possibly yields the rest of the thread's time slice to other + // threads. + ::Sleep(0); + } + break; + + case 2: + break; // The mutex is already initialized and ready for use. + + default: + GTEST_CHECK_(false) + << "Unexpected value of critical_section_init_phase_ " + << "while initializing a static mutex."; + } + } +} + +namespace { + +class ThreadWithParamSupport : public ThreadWithParamBase { + public: + static HANDLE CreateThread(Runnable* runnable, + Notification* thread_can_start) { + ThreadMainParam* param = new ThreadMainParam(runnable, thread_can_start); + DWORD thread_id; + // TODO(yukawa): Consider to use _beginthreadex instead. + HANDLE thread_handle = ::CreateThread( + NULL, // Default security. + 0, // Default stack size. + &ThreadWithParamSupport::ThreadMain, + param, // Parameter to ThreadMainStatic + 0x0, // Default creation flags. + &thread_id); // Need a valid pointer for the call to work under Win98. + GTEST_CHECK_(thread_handle != NULL) << "CreateThread failed with error " + << ::GetLastError() << "."; + if (thread_handle == NULL) { + delete param; + } + return thread_handle; + } + + private: + struct ThreadMainParam { + ThreadMainParam(Runnable* runnable, Notification* thread_can_start) + : runnable_(runnable), + thread_can_start_(thread_can_start) { + } + scoped_ptr runnable_; + // Does not own. + Notification* thread_can_start_; + }; + + static DWORD WINAPI ThreadMain(void* ptr) { + // Transfers ownership. + scoped_ptr param(static_cast(ptr)); + if (param->thread_can_start_ != NULL) + param->thread_can_start_->WaitForNotification(); + param->runnable_->Run(); + return 0; + } + + // Prohibit instantiation. + ThreadWithParamSupport(); + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParamSupport); +}; + +} // namespace + +ThreadWithParamBase::ThreadWithParamBase(Runnable *runnable, + Notification* thread_can_start) + : thread_(ThreadWithParamSupport::CreateThread(runnable, + thread_can_start)) { +} + +ThreadWithParamBase::~ThreadWithParamBase() { + Join(); +} + +void ThreadWithParamBase::Join() { + GTEST_CHECK_(::WaitForSingleObject(thread_.Get(), INFINITE) == WAIT_OBJECT_0) + << "Failed to join the thread with error " << ::GetLastError() << "."; +} + +// Maps a thread to a set of ThreadIdToThreadLocals that have values +// instantiated on that thread and notifies them when the thread exits. A +// ThreadLocal instance is expected to persist until all threads it has +// values on have terminated. +class ThreadLocalRegistryImpl { + public: + // Registers thread_local_instance as having value on the current thread. + // Returns a value that can be used to identify the thread from other threads. + static ThreadLocalValueHolderBase* GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + DWORD current_thread = ::GetCurrentThreadId(); + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(current_thread); + if (thread_local_pos == thread_to_thread_locals->end()) { + thread_local_pos = thread_to_thread_locals->insert( + std::make_pair(current_thread, ThreadLocalValues())).first; + StartWatcherThreadFor(current_thread); + } + ThreadLocalValues& thread_local_values = thread_local_pos->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos == thread_local_values.end()) { + value_pos = + thread_local_values + .insert(std::make_pair( + thread_local_instance, + linked_ptr( + thread_local_instance->NewValueForCurrentThread()))) + .first; + } + return value_pos->second.get(); + } + + static void OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + std::vector > value_holders; + // Clean up the ThreadLocalValues data structure while holding the lock, but + // defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + for (ThreadIdToThreadLocals::iterator it = + thread_to_thread_locals->begin(); + it != thread_to_thread_locals->end(); + ++it) { + ThreadLocalValues& thread_local_values = it->second; + ThreadLocalValues::iterator value_pos = + thread_local_values.find(thread_local_instance); + if (value_pos != thread_local_values.end()) { + value_holders.push_back(value_pos->second); + thread_local_values.erase(value_pos); + // This 'if' can only be successful at most once, so theoretically we + // could break out of the loop here, but we don't bother doing so. + } + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + static void OnThreadExit(DWORD thread_id) { + GTEST_CHECK_(thread_id != 0) << ::GetLastError(); + std::vector > value_holders; + // Clean up the ThreadIdToThreadLocals data structure while holding the + // lock, but defer the destruction of the ThreadLocalValueHolderBases. + { + MutexLock lock(&mutex_); + ThreadIdToThreadLocals* const thread_to_thread_locals = + GetThreadLocalsMapLocked(); + ThreadIdToThreadLocals::iterator thread_local_pos = + thread_to_thread_locals->find(thread_id); + if (thread_local_pos != thread_to_thread_locals->end()) { + ThreadLocalValues& thread_local_values = thread_local_pos->second; + for (ThreadLocalValues::iterator value_pos = + thread_local_values.begin(); + value_pos != thread_local_values.end(); + ++value_pos) { + value_holders.push_back(value_pos->second); + } + thread_to_thread_locals->erase(thread_local_pos); + } + } + // Outside the lock, let the destructor for 'value_holders' deallocate the + // ThreadLocalValueHolderBases. + } + + private: + // In a particular thread, maps a ThreadLocal object to its value. + typedef std::map > ThreadLocalValues; + // Stores all ThreadIdToThreadLocals having values in a thread, indexed by + // thread's ID. + typedef std::map ThreadIdToThreadLocals; + + // Holds the thread id and thread handle that we pass from + // StartWatcherThreadFor to WatcherThreadFunc. + typedef std::pair ThreadIdAndHandle; + + static void StartWatcherThreadFor(DWORD thread_id) { + // The returned handle will be kept in thread_map and closed by + // watcher_thread in WatcherThreadFunc. + HANDLE thread = ::OpenThread(SYNCHRONIZE | THREAD_QUERY_INFORMATION, + FALSE, + thread_id); + GTEST_CHECK_(thread != NULL); + // We need to to pass a valid thread ID pointer into CreateThread for it + // to work correctly under Win98. + DWORD watcher_thread_id; + HANDLE watcher_thread = ::CreateThread( + NULL, // Default security. + 0, // Default stack size + &ThreadLocalRegistryImpl::WatcherThreadFunc, + reinterpret_cast(new ThreadIdAndHandle(thread_id, thread)), + CREATE_SUSPENDED, + &watcher_thread_id); + GTEST_CHECK_(watcher_thread != NULL); + // Give the watcher thread the same priority as ours to avoid being + // blocked by it. + ::SetThreadPriority(watcher_thread, + ::GetThreadPriority(::GetCurrentThread())); + ::ResumeThread(watcher_thread); + ::CloseHandle(watcher_thread); + } + + // Monitors exit from a given thread and notifies those + // ThreadIdToThreadLocals about thread termination. + static DWORD WINAPI WatcherThreadFunc(LPVOID param) { + const ThreadIdAndHandle* tah = + reinterpret_cast(param); + GTEST_CHECK_( + ::WaitForSingleObject(tah->second, INFINITE) == WAIT_OBJECT_0); + OnThreadExit(tah->first); + ::CloseHandle(tah->second); + delete tah; + return 0; + } + + // Returns map of thread local instances. + static ThreadIdToThreadLocals* GetThreadLocalsMapLocked() { + mutex_.AssertHeld(); + static ThreadIdToThreadLocals* map = new ThreadIdToThreadLocals; + return map; + } + + // Protects access to GetThreadLocalsMapLocked() and its return value. + static Mutex mutex_; + // Protects access to GetThreadMapLocked() and its return value. + static Mutex thread_map_mutex_; +}; + +Mutex ThreadLocalRegistryImpl::mutex_(Mutex::kStaticMutex); +Mutex ThreadLocalRegistryImpl::thread_map_mutex_(Mutex::kStaticMutex); + +ThreadLocalValueHolderBase* ThreadLocalRegistry::GetValueOnCurrentThread( + const ThreadLocalBase* thread_local_instance) { + return ThreadLocalRegistryImpl::GetValueOnCurrentThread( + thread_local_instance); +} + +void ThreadLocalRegistry::OnThreadLocalDestroyed( + const ThreadLocalBase* thread_local_instance) { + ThreadLocalRegistryImpl::OnThreadLocalDestroyed(thread_local_instance); +} + +#endif // GTEST_IS_THREADSAFE && GTEST_OS_WINDOWS #if GTEST_USES_POSIX_RE @@ -481,7 +887,6 @@ GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( return file_name + ":" + StreamableToString(line); } - GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { const char* const marker = @@ -502,10 +907,7 @@ GTestLog::~GTestLog() { } // 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 +GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) #if GTEST_HAS_STREAM_REDIRECTION @@ -581,12 +983,6 @@ class CapturedStream { } private: - // Reads the entire content of a file as an std::string. - static std::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. @@ -595,38 +991,7 @@ class CapturedStream { 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(ftell(file)); -} - -// Reads the entire content of a file as a string. -std::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 std::string content(buffer, bytes_read); - delete[] buffer; - - return content; -} - -# ifdef _MSC_VER -# pragma warning(pop) -# endif // _MSC_VER +GTEST_DISABLE_MSC_WARNINGS_POP_() static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; @@ -672,6 +1037,51 @@ std::string GetCapturedStderr() { #endif // GTEST_HAS_STREAM_REDIRECTION +std::string TempDir() { +#if GTEST_OS_WINDOWS_MOBILE + return "\\temp\\"; +#elif GTEST_OS_WINDOWS + const char* temp_dir = posix::GetEnv("TEMP"); + if (temp_dir == NULL || temp_dir[0] == '\0') + return "\\temp\\"; + else if (temp_dir[strlen(temp_dir) - 1] == '\\') + return temp_dir; + else + return std::string(temp_dir) + "\\"; +#elif GTEST_OS_LINUX_ANDROID + return "/sdcard/"; +#else + return "/tmp/"; +#endif // GTEST_OS_WINDOWS_MOBILE +} + +size_t GetFileSize(FILE* file) { + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); +} + +std::string 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 std::string content(buffer, bytes_read); + delete[] buffer; + + return content; +} + #if GTEST_HAS_DEATH_TEST // A copy of all command line arguments. Set by InitGoogleTest(). diff --git a/Externals/gtest/src/gtest-printers.cc b/Externals/gtest/src/gtest-printers.cc index 29c799a59a..a2df412f8a 100644 --- a/Externals/gtest/src/gtest-printers.cc +++ b/Externals/gtest/src/gtest-printers.cc @@ -45,6 +45,7 @@ #include "gtest/gtest-printers.h" #include #include +#include #include // NOLINT #include #include "gtest/internal/gtest-port.h" @@ -58,6 +59,7 @@ using ::std::ostream; // Prints a segment of bytes in the given object. GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, size_t count, ostream* os) { char text[5] = ""; @@ -256,6 +258,7 @@ void PrintTo(wchar_t wc, ostream* os) { template GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void PrintCharsAsStringTo( const CharType* begin, size_t len, ostream* os) { const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; @@ -279,6 +282,7 @@ static void PrintCharsAsStringTo( template GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ +GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ static void UniversalPrintCharArray( const CharType* begin, size_t len, ostream* os) { // The code @@ -335,7 +339,7 @@ void PrintTo(const wchar_t* s, ostream* os) { *os << "NULL"; } else { *os << ImplicitCast_(s) << " pointing to "; - PrintCharsAsStringTo(s, wcslen(s), os); + PrintCharsAsStringTo(s, std::wcslen(s), os); } } #endif // wchar_t is native diff --git a/Externals/gtest/src/gtest-test-part.cc b/Externals/gtest/src/gtest-test-part.cc index c60eef3ab3..fb0e35425e 100644 --- a/Externals/gtest/src/gtest-test-part.cc +++ b/Externals/gtest/src/gtest-test-part.cc @@ -35,9 +35,9 @@ // 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. +// included, or there will be a compiler error. This trick exists to +// prevent the accidental inclusion of gtest-internal-inl.h in the +// user's code. #define GTEST_IMPLEMENTATION_ 1 #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ diff --git a/Externals/gtest/src/gtest-typed-test.cc b/Externals/gtest/src/gtest-typed-test.cc index f0079f407c..df1eef4754 100644 --- a/Externals/gtest/src/gtest-typed-test.cc +++ b/Externals/gtest/src/gtest-typed-test.cc @@ -45,33 +45,41 @@ static const char* SkipSpaces(const char* str) { return str; } +static std::vector SplitIntoTestNames(const char* src) { + std::vector name_vec; + src = SkipSpaces(src); + for (; src != NULL; src = SkipComma(src)) { + name_vec.push_back(StripTrailingSpaces(GetPrefixUntilComma(src))); + } + return name_vec; +} + // Verifies that registered_tests match the test names in -// defined_test_names_; returns registered_tests if successful, or +// registered_tests_; 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_iterator DefinedTestIter; + typedef RegisteredTestsMap::const_iterator RegisteredTestIter; registered_ = true; - // Skip initial whitespace in registered_tests since some - // preprocessors prefix stringizied literals with whitespace. - registered_tests = SkipSpaces(registered_tests); + std::vector name_vec = SplitIntoTestNames(registered_tests); Message errors; - ::std::set tests; - for (const char* names = registered_tests; names != NULL; - names = SkipComma(names)) { - const std::string name = GetPrefixUntilComma(names); + + std::set tests; + for (std::vector::const_iterator name_it = name_vec.begin(); + name_it != name_vec.end(); ++name_it) { + const std::string& name = *name_it; 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(); + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); ++it) { - if (name == *it) { + if (name == it->first) { found = true; break; } @@ -85,11 +93,11 @@ const char* TypedTestCasePState::VerifyRegisteredTestNames( } } - for (DefinedTestIter it = defined_test_names_.begin(); - it != defined_test_names_.end(); + for (RegisteredTestIter it = registered_tests_.begin(); + it != registered_tests_.end(); ++it) { - if (tests.count(*it) == 0) { - errors << "You forgot to list test " << *it << ".\n"; + if (tests.count(it->first) == 0) { + errors << "You forgot to list test " << it->first << ".\n"; } } diff --git a/Externals/gtest/src/gtest.cc b/Externals/gtest/src/gtest.cc index 6de53dd019..0839389775 100644 --- a/Externals/gtest/src/gtest.cc +++ b/Externals/gtest/src/gtest.cc @@ -32,6 +32,7 @@ // The Google C++ Testing Framework (Google Test) #include "gtest/gtest.h" +#include "gtest/internal/custom/gtest.h" #include "gtest/gtest-spi.h" #include @@ -46,6 +47,8 @@ #include #include #include +#include +#include #include // NOLINT #include #include @@ -80,6 +83,7 @@ #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. # include // NOLINT +# undef min #elif GTEST_OS_WINDOWS // We are on Windows proper. @@ -102,6 +106,7 @@ // cpplint thinks that the header is already included, so we want to // silence it. # include // NOLINT +# undef min #else @@ -124,6 +129,8 @@ #if GTEST_CAN_STREAM_RESULTS_ # include // NOLINT # include // NOLINT +# include // NOLINT +# include // NOLINT #endif // Indicates that this translation unit is part of Google Test's @@ -183,6 +190,12 @@ bool g_help_flag = false; } // namespace internal static const char* GetDefaultFilter() { +#ifdef GTEST_TEST_FILTER_ENV_VAR_ + const char* const testbridge_test_only = getenv(GTEST_TEST_FILTER_ENV_VAR_); + if (testbridge_test_only != NULL) { + return testbridge_test_only; + } +#endif // GTEST_TEST_FILTER_ENV_VAR_ return kUniversalFilter; } @@ -283,6 +296,13 @@ GTEST_DEFINE_bool_( "if exceptions are enabled or exit the program with a non-zero code " "otherwise."); +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +GTEST_DEFINE_string_( + flagfile, + internal::StringFromGTestEnv("flagfile", ""), + "This flag specifies the flagfile to read command-line flags from."); +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + namespace internal { // Generates a random number from [0, range), using a Linear @@ -772,8 +792,12 @@ int UnitTestImpl::test_to_run_count() const { // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { - (void)skip_count; - return ""; + return os_stack_trace_getter()->CurrentStackTrace( + static_cast(GTEST_FLAG(stack_trace_depth)), + skip_count + 1 + // Skips the user-specified number of frames plus this function + // itself. + ); // NOLINT } // Returns the current time in milliseconds. @@ -802,21 +826,13 @@ TimeInMillis GetTimeInMillis() { #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. + GTEST_DISABLE_MSC_WARNINGS_PUSH_(4996) _ftime64(&now); -# pragma warning(pop) // Restores the warning state. -# else - - _ftime64(&now); - -# endif // _MSC_VER + GTEST_DISABLE_MSC_WARNINGS_POP_() return static_cast(now.time) * 1000 + now.millitm; #elif GTEST_HAS_GETTIMEOFDAY_ @@ -901,6 +917,23 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, #endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING +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); +} + } // namespace internal // Constructs an empty Message. @@ -956,6 +989,13 @@ AssertionResult::AssertionResult(const AssertionResult& other) static_cast< ::std::string*>(NULL)) { } +// Swaps two AssertionResults. +void AssertionResult::swap(AssertionResult& other) { + using std::swap; + swap(success_, other.success_); + swap(message_, other.message_); +} + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. AssertionResult AssertionResult::operator!() const { AssertionResult negation(!success_); @@ -982,6 +1022,276 @@ AssertionResult AssertionFailure(const Message& message) { namespace internal { +namespace edit_distance { +std::vector CalculateOptimalEdits(const std::vector& left, + const std::vector& right) { + std::vector > costs( + left.size() + 1, std::vector(right.size() + 1)); + std::vector > best_move( + left.size() + 1, std::vector(right.size() + 1)); + + // Populate for empty right. + for (size_t l_i = 0; l_i < costs.size(); ++l_i) { + costs[l_i][0] = static_cast(l_i); + best_move[l_i][0] = kRemove; + } + // Populate for empty left. + for (size_t r_i = 1; r_i < costs[0].size(); ++r_i) { + costs[0][r_i] = static_cast(r_i); + best_move[0][r_i] = kAdd; + } + + for (size_t l_i = 0; l_i < left.size(); ++l_i) { + for (size_t r_i = 0; r_i < right.size(); ++r_i) { + if (left[l_i] == right[r_i]) { + // Found a match. Consume it. + costs[l_i + 1][r_i + 1] = costs[l_i][r_i]; + best_move[l_i + 1][r_i + 1] = kMatch; + continue; + } + + const double add = costs[l_i + 1][r_i]; + const double remove = costs[l_i][r_i + 1]; + const double replace = costs[l_i][r_i]; + if (add < remove && add < replace) { + costs[l_i + 1][r_i + 1] = add + 1; + best_move[l_i + 1][r_i + 1] = kAdd; + } else if (remove < add && remove < replace) { + costs[l_i + 1][r_i + 1] = remove + 1; + best_move[l_i + 1][r_i + 1] = kRemove; + } else { + // We make replace a little more expensive than add/remove to lower + // their priority. + costs[l_i + 1][r_i + 1] = replace + 1.00001; + best_move[l_i + 1][r_i + 1] = kReplace; + } + } + } + + // Reconstruct the best path. We do it in reverse order. + std::vector best_path; + for (size_t l_i = left.size(), r_i = right.size(); l_i > 0 || r_i > 0;) { + EditType move = best_move[l_i][r_i]; + best_path.push_back(move); + l_i -= move != kAdd; + r_i -= move != kRemove; + } + std::reverse(best_path.begin(), best_path.end()); + return best_path; +} + +namespace { + +// Helper class to convert string into ids with deduplication. +class InternalStrings { + public: + size_t GetId(const std::string& str) { + IdMap::iterator it = ids_.find(str); + if (it != ids_.end()) return it->second; + size_t id = ids_.size(); + return ids_[str] = id; + } + + private: + typedef std::map IdMap; + IdMap ids_; +}; + +} // namespace + +std::vector CalculateOptimalEdits( + const std::vector& left, + const std::vector& right) { + std::vector left_ids, right_ids; + { + InternalStrings intern_table; + for (size_t i = 0; i < left.size(); ++i) { + left_ids.push_back(intern_table.GetId(left[i])); + } + for (size_t i = 0; i < right.size(); ++i) { + right_ids.push_back(intern_table.GetId(right[i])); + } + } + return CalculateOptimalEdits(left_ids, right_ids); +} + +namespace { + +// Helper class that holds the state for one hunk and prints it out to the +// stream. +// It reorders adds/removes when possible to group all removes before all +// adds. It also adds the hunk header before printint into the stream. +class Hunk { + public: + Hunk(size_t left_start, size_t right_start) + : left_start_(left_start), + right_start_(right_start), + adds_(), + removes_(), + common_() {} + + void PushLine(char edit, const char* line) { + switch (edit) { + case ' ': + ++common_; + FlushEdits(); + hunk_.push_back(std::make_pair(' ', line)); + break; + case '-': + ++removes_; + hunk_removes_.push_back(std::make_pair('-', line)); + break; + case '+': + ++adds_; + hunk_adds_.push_back(std::make_pair('+', line)); + break; + } + } + + void PrintTo(std::ostream* os) { + PrintHeader(os); + FlushEdits(); + for (std::list >::const_iterator it = + hunk_.begin(); + it != hunk_.end(); ++it) { + *os << it->first << it->second << "\n"; + } + } + + bool has_edits() const { return adds_ || removes_; } + + private: + void FlushEdits() { + hunk_.splice(hunk_.end(), hunk_removes_); + hunk_.splice(hunk_.end(), hunk_adds_); + } + + // Print a unified diff header for one hunk. + // The format is + // "@@ -, +, @@" + // where the left/right parts are ommitted if unnecessary. + void PrintHeader(std::ostream* ss) const { + *ss << "@@ "; + if (removes_) { + *ss << "-" << left_start_ << "," << (removes_ + common_); + } + if (removes_ && adds_) { + *ss << " "; + } + if (adds_) { + *ss << "+" << right_start_ << "," << (adds_ + common_); + } + *ss << " @@\n"; + } + + size_t left_start_, right_start_; + size_t adds_, removes_, common_; + std::list > hunk_, hunk_adds_, hunk_removes_; +}; + +} // namespace + +// Create a list of diff hunks in Unified diff format. +// Each hunk has a header generated by PrintHeader above plus a body with +// lines prefixed with ' ' for no change, '-' for deletion and '+' for +// addition. +// 'context' represents the desired unchanged prefix/suffix around the diff. +// If two hunks are close enough that their contexts overlap, then they are +// joined into one hunk. +std::string CreateUnifiedDiff(const std::vector& left, + const std::vector& right, + size_t context) { + const std::vector edits = CalculateOptimalEdits(left, right); + + size_t l_i = 0, r_i = 0, edit_i = 0; + std::stringstream ss; + while (edit_i < edits.size()) { + // Find first edit. + while (edit_i < edits.size() && edits[edit_i] == kMatch) { + ++l_i; + ++r_i; + ++edit_i; + } + + // Find the first line to include in the hunk. + const size_t prefix_context = std::min(l_i, context); + Hunk hunk(l_i - prefix_context + 1, r_i - prefix_context + 1); + for (size_t i = prefix_context; i > 0; --i) { + hunk.PushLine(' ', left[l_i - i].c_str()); + } + + // Iterate the edits until we found enough suffix for the hunk or the input + // is over. + size_t n_suffix = 0; + for (; edit_i < edits.size(); ++edit_i) { + if (n_suffix >= context) { + // Continue only if the next hunk is very close. + std::vector::const_iterator it = edits.begin() + edit_i; + while (it != edits.end() && *it == kMatch) ++it; + if (it == edits.end() || (it - edits.begin()) - edit_i >= context) { + // There is no next edit or it is too far away. + break; + } + } + + EditType edit = edits[edit_i]; + // Reset count when a non match is found. + n_suffix = edit == kMatch ? n_suffix + 1 : 0; + + if (edit == kMatch || edit == kRemove || edit == kReplace) { + hunk.PushLine(edit == kMatch ? ' ' : '-', left[l_i].c_str()); + } + if (edit == kAdd || edit == kReplace) { + hunk.PushLine('+', right[r_i].c_str()); + } + + // Advance indices, depending on edit type. + l_i += edit != kAdd; + r_i += edit != kRemove; + } + + if (!hunk.has_edits()) { + // We are done. We don't want this hunk. + break; + } + + hunk.PrintTo(&ss); + } + return ss.str(); +} + +} // namespace edit_distance + +namespace { + +// The string representation of the values received in EqFailure() are already +// escaped. Split them on escaped '\n' boundaries. Leave all other escaped +// characters the same. +std::vector SplitEscapedString(const std::string& str) { + std::vector lines; + size_t start = 0, end = str.size(); + if (end > 2 && str[0] == '"' && str[end - 1] == '"') { + ++start; + --end; + } + bool escaped = false; + for (size_t i = start; i + 1 < end; ++i) { + if (escaped) { + escaped = false; + if (str[i] == 'n') { + lines.push_back(str.substr(start, i - start - 1)); + start = i + 1; + } + } else { + escaped = str[i] == '\\'; + } + } + lines.push_back(str.substr(start, end - start)); + return lines; +} + +} // namespace + // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // @@ -1016,6 +1326,17 @@ AssertionResult EqFailure(const char* expected_expression, msg << "\nWhich is: " << expected_value; } + if (!expected_value.empty() && !actual_value.empty()) { + const std::vector expected_lines = + SplitEscapedString(expected_value); + const std::vector actual_lines = + SplitEscapedString(actual_value); + if (expected_lines.size() > 1 || actual_lines.size() > 1) { + msg << "\nWith diff:\n" + << edit_distance::CreateUnifiedDiff(expected_lines, actual_lines); + } + } + return AssertionFailure() << msg; } @@ -1887,14 +2208,15 @@ int TestResult::test_property_count() const { // Creates a Test object. -// The c'tor saves the values of all Google Test flags. +// The c'tor saves the states of all flags. Test::Test() - : gtest_flag_saver_(new internal::GTestFlagSaver) { + : gtest_flag_saver_(new GTEST_FLAG_SAVER_) { } -// The d'tor restores the values of all Google Test flags. +// The d'tor restores the states of all flags. The actual work is +// done by the d'tor of the gtest_flag_saver_ field, and thus not +// visible here. Test::~Test() { - delete gtest_flag_saver_; } // Sets up the test fixture. @@ -1963,8 +2285,8 @@ bool Test::HasSameFixtureClass() { 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. + // Both TEST and TEST_F appear in same test case, which is incorrect. + // Tell the user how to fix this. // 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 @@ -1984,8 +2306,8 @@ bool Test::HasSameFixtureClass() { << "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. + // Two fixture classes with the same name appear in two different + // namespaces, which is not allowed. Tell the user how to fix this. ADD_FAILURE() << "All tests in the same test case must use the same test fixture\n" << "class. However, in test case " @@ -2178,12 +2500,14 @@ TestInfo::TestInfo(const std::string& a_test_case_name, const std::string& a_name, const char* a_type_param, const char* a_value_param, + internal::CodeLocation a_code_location, 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), + location_(a_code_location), fixture_class_id_(fixture_class_id), should_run_(false), is_disabled_(false), @@ -2207,6 +2531,7 @@ namespace internal { // 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. +// code_location: code location where the test is defined // 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 @@ -2218,20 +2543,21 @@ TestInfo* MakeAndRegisterTestInfo( const char* name, const char* type_param, const char* value_param, + CodeLocation code_location, 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); + code_location, 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) { + CodeLocation code_location) { Message errors; errors << "Attempted redefinition of test case " << test_case_name << ".\n" @@ -2243,7 +2569,9 @@ void ReportInvalidTestCaseType(const char* test_case_name, << "probably rename one of the classes to put the tests into different\n" << "test cases."; - fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + fprintf(stderr, "%s %s", + FormatFileLocation(code_location.file.c_str(), + code_location.line).c_str(), errors.GetString().c_str()); } #endif // GTEST_HAS_PARAM_TEST @@ -2554,7 +2882,8 @@ enum GTestColor { COLOR_YELLOW }; -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // Returns the character attribute for the given color. WORD GetColorAttribute(GTestColor color) { @@ -2599,6 +2928,8 @@ bool ShouldUseColor(bool stdout_is_tty) { String::CStringEquals(term, "xterm-256color") || String::CStringEquals(term, "screen") || String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "rxvt-unicode") || + String::CStringEquals(term, "rxvt-unicode-256color") || String::CStringEquals(term, "linux") || String::CStringEquals(term, "cygwin"); return stdout_is_tty && term_supports_color; @@ -2622,8 +2953,9 @@ 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 || GTEST_OS_IOS - const bool use_color = false; +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || \ + GTEST_OS_IOS || GTEST_OS_WINDOWS_PHONE || GTEST_OS_WINDOWS_RT + const bool use_color = AlwaysFalse(); #else static const bool in_color_mode = ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); @@ -2637,7 +2969,8 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { return; } -#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE && \ + !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); // Gets the current text color. @@ -3212,34 +3545,39 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( // Formats the given time in milliseconds as seconds. std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { ::std::stringstream ss; - ss << ms/1000.0; + ss << (static_cast(ms) * 1e-3); return ss.str(); } +static bool PortableLocaltime(time_t seconds, struct tm* out) { +#if defined(_MSC_VER) + return localtime_s(out, &seconds) == 0; +#elif defined(__MINGW32__) || defined(__MINGW64__) + // MINGW provides neither localtime_r nor localtime_s, but uses + // Windows' localtime(), which has a thread-local tm buffer. + struct tm* tm_ptr = localtime(&seconds); // NOLINT + if (tm_ptr == NULL) + return false; + *out = *tm_ptr; + return true; +#else + return localtime_r(&seconds, out) != NULL; +#endif +} + // Converts the given epoch time in milliseconds to a date string in the ISO // 8601 format, without the timezone information. std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { - // Using non-reentrant version as localtime_r is not portable. - time_t seconds = static_cast(ms / 1000); -#ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996 - // (function or variable may be unsafe). - const struct tm* const time_struct = localtime(&seconds); // NOLINT -# pragma warning(pop) // Restores the warning state again. -#else - const struct tm* const time_struct = localtime(&seconds); // NOLINT -#endif - if (time_struct == NULL) - return ""; // Invalid ms value - + struct tm time_struct; + if (!PortableLocaltime(static_cast(ms / 1000), &time_struct)) + return ""; // YYYY-MM-DDThh:mm:ss - return StreamableToString(time_struct->tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct->tm_mday) + "T" + - String::FormatIntWidth2(time_struct->tm_hour) + ":" + - String::FormatIntWidth2(time_struct->tm_min) + ":" + - String::FormatIntWidth2(time_struct->tm_sec); + return StreamableToString(time_struct.tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct.tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct.tm_mday) + "T" + + String::FormatIntWidth2(time_struct.tm_hour) + ":" + + String::FormatIntWidth2(time_struct.tm_min) + ":" + + String::FormatIntWidth2(time_struct.tm_sec); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. @@ -3502,26 +3840,15 @@ ScopedTrace::~ScopedTrace() // class OsStackTraceGetter -// Returns the current OS stack trace as an std::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. -// -string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, - int /* skip_count */) - GTEST_LOCK_EXCLUDED_(mutex_) { +const char* const OsStackTraceGetterInterface::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; + +string OsStackTraceGetter::CurrentStackTrace(int /*max_depth*/, + int /*skip_count*/) { return ""; } -void OsStackTraceGetter::UponLeavingGTest() - GTEST_LOCK_EXCLUDED_(mutex_) { -} - -const char* const -OsStackTraceGetter::kElidedFramesMarker = - "... " GTEST_NAME_ " internal frames ..."; +void OsStackTraceGetter::UponLeavingGTest() {} // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. @@ -3812,7 +4139,7 @@ void UnitTest::AddTestPartResult( // with another testing framework) and specify the former on the // command line for debugging. if (GTEST_FLAG(break_on_failure)) { -#if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // 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. @@ -3890,7 +4217,7 @@ int UnitTest::Run() { // 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 +# if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && !GTEST_OS_WINDOWS_RT // SetErrorMode doesn't exist on CE. SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); @@ -3993,17 +4320,10 @@ 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). + GTEST_DISABLE_MSC_WARNINGS_PUSH_(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 + GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_( &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( @@ -4583,7 +4903,11 @@ void UnitTestImpl::set_os_stack_trace_getter( // getter, and returns it. OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { if (os_stack_trace_getter_ == NULL) { +#ifdef GTEST_OS_STACK_TRACE_GETTER_ + os_stack_trace_getter_ = new GTEST_OS_STACK_TRACE_GETTER_; +#else os_stack_trace_getter_ = new OsStackTraceGetter; +#endif // GTEST_OS_STACK_TRACE_GETTER_ } return os_stack_trace_getter_; @@ -4882,6 +5206,58 @@ static const char kColorEncodedHelpMessage[] = "(not one in your own code or tests), please report it to\n" "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; +bool ParseGoogleTestFlag(const char* const arg) { + return 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)); +} + +#if GTEST_USE_OWN_FLAGFILE_FLAG_ +void LoadFlagsFromFile(const std::string& path) { + FILE* flagfile = posix::FOpen(path.c_str(), "r"); + if (!flagfile) { + fprintf(stderr, + "Unable to open file \"%s\"\n", + GTEST_FLAG(flagfile).c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::string contents(ReadEntireFile(flagfile)); + posix::FClose(flagfile); + std::vector lines; + SplitString(contents, '\n', &lines); + for (size_t i = 0; i < lines.size(); ++i) { + if (lines[i].empty()) + continue; + if (!ParseGoogleTestFlag(lines[i].c_str())) + g_help_flag = true; + } +} +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + // 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. @@ -4895,35 +5271,24 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { 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 + bool remove_flag = false; + if (ParseGoogleTestFlag(arg)) { + remove_flag = true; +#if GTEST_USE_OWN_FLAGFILE_FLAG_ + } else if (ParseStringFlag(arg, kFlagfileFlag, >EST_FLAG(flagfile))) { + LoadFlagsFromFile(GTEST_FLAG(flagfile)); + remove_flag = true; +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ + } 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 (remove_flag) { + // 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. @@ -4937,12 +5302,6 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { // 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; } } diff --git a/Externals/libpng/png/png.vcxproj b/Externals/libpng/png/png.vcxproj index e629708347..2d5eb90cd1 100644 --- a/Externals/libpng/png/png.vcxproj +++ b/Externals/libpng/png/png.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/libusb/libusb/os/threads_windows.h b/Externals/libusb/libusb/os/threads_windows.h index 2b829253b4..b28da25555 100644 --- a/Externals/libusb/libusb/os/threads_windows.h +++ b/Externals/libusb/libusb/os/threads_windows.h @@ -43,11 +43,16 @@ typedef struct usbi_cond_t_ usbi_cond_t; // We *were* getting timespec from pthread.h: #if (!defined(HAVE_STRUCT_TIMESPEC) && !defined(_TIMESPEC_DEFINED)) #define HAVE_STRUCT_TIMESPEC 1 +// (shuffle2) see https://github.com/libusb/libusb/pull/60 +#if defined(_MSC_VER) && (_MSC_VER >= 1900) +#include +#else #define _TIMESPEC_DEFINED 1 struct timespec { long tv_sec; long tv_nsec; }; +#endif #endif /* HAVE_STRUCT_TIMESPEC | _TIMESPEC_DEFINED */ // We *were* getting ETIMEDOUT from pthread.h: diff --git a/Externals/libusb/libusb_static_2013.vcxproj b/Externals/libusb/libusb_static_2013.vcxproj index 9e0711de55..f389ea7eed 100644 --- a/Externals/libusb/libusb_static_2013.vcxproj +++ b/Externals/libusb/libusb_static_2013.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -17,7 +17,7 @@ StaticLibrary - v120 + v140 Unicode @@ -67,4 +67,4 @@ - + \ No newline at end of file diff --git a/Externals/miniupnpc/miniupnpc.vcxproj b/Externals/miniupnpc/miniupnpc.vcxproj index 7f832784a9..a9f1a55b27 100644 --- a/Externals/miniupnpc/miniupnpc.vcxproj +++ b/Externals/miniupnpc/miniupnpc.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/msvcrt/x64/msvcp120.dll b/Externals/msvcrt/x64/msvcp120.dll deleted file mode 100644 index 4ea1efa734..0000000000 Binary files a/Externals/msvcrt/x64/msvcp120.dll and /dev/null differ diff --git a/Externals/msvcrt/x64/msvcr120.dll b/Externals/msvcrt/x64/msvcr120.dll deleted file mode 100644 index d711c92232..0000000000 Binary files a/Externals/msvcrt/x64/msvcr120.dll and /dev/null differ diff --git a/Externals/polarssl/visualc/PolarSSL.vcxproj b/Externals/polarssl/visualc/PolarSSL.vcxproj index 843b4c8c5f..7b7ff30808 100644 --- a/Externals/polarssl/visualc/PolarSSL.vcxproj +++ b/Externals/polarssl/visualc/PolarSSL.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode @@ -110,4 +110,4 @@ - + \ No newline at end of file diff --git a/Externals/portaudio/build/portaudio.vcxproj b/Externals/portaudio/build/portaudio.vcxproj index 38c6a907ec..d8d435c991 100644 --- a/Externals/portaudio/build/portaudio.vcxproj +++ b/Externals/portaudio/build/portaudio.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/soundtouch/SoundTouch.vcxproj b/Externals/soundtouch/SoundTouch.vcxproj index ebcaba69f1..17590bd2e6 100644 --- a/Externals/soundtouch/SoundTouch.vcxproj +++ b/Externals/soundtouch/SoundTouch.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/wxWidgets3/build/msw/wx_base.vcxproj b/Externals/wxWidgets3/build/msw/wx_base.vcxproj index a8e473b01a..9550852f37 100644 --- a/Externals/wxWidgets3/build/msw/wx_base.vcxproj +++ b/Externals/wxWidgets3/build/msw/wx_base.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -698,7 +698,9 @@ - + + true + @@ -726,7 +728,9 @@ - + + true + @@ -778,7 +782,9 @@ true - + + true + true @@ -807,7 +813,9 @@ - + + true + true @@ -892,7 +900,9 @@ - + + true + @@ -917,7 +927,9 @@ - + + true + @@ -951,14 +963,20 @@ true - - + + true + + + true + - + + true + @@ -975,23 +993,31 @@ - + + true + - + + true + - + + true + true - + + true + @@ -1035,7 +1061,9 @@ true - + + true + @@ -1057,7 +1085,9 @@ - + + true + @@ -1090,9 +1120,13 @@ - + + true + - + + true + @@ -1104,14 +1138,18 @@ - + + true + - + + true + @@ -1126,18 +1164,24 @@ - + + true + - + + true + - + + true + true @@ -1156,7 +1200,9 @@ - + + true + true @@ -1169,7 +1215,9 @@ - + + true + @@ -1224,7 +1272,9 @@ - + + true + @@ -1255,7 +1305,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Externals/wxWidgets3/include/wx/compiler.h b/Externals/wxWidgets3/include/wx/compiler.h index 5ad4df8561..0be92d7da7 100644 --- a/Externals/wxWidgets3/include/wx/compiler.h +++ b/Externals/wxWidgets3/include/wx/compiler.h @@ -53,6 +53,9 @@ # define __VISUALC11__ #elif __VISUALC__ < 1900 # define __VISUALC12__ +#elif __VISUALC__ < 2000 + /* There is no __VISUALC13__! */ +# define __VISUALC14__ #else # pragma message("Please update wx/compiler.h to recognize this VC++ version") #endif @@ -102,7 +105,13 @@ # define wxVISUALC_VERSION(major) 0 # define wxCHECK_VISUALC_VERSION(major) 0 #else -# define wxVISUALC_VERSION(major) ( (6 + major) * 100 ) + /* + Things used to be simple with the _MSC_VER value and the version number + increasing in lock step, but _MSC_VER value of 1900 is VC14 and not the + non existing (presumably for the superstitious reasons) VC13, so we now + need to account for this with an extra offset. + */ +# define wxVISUALC_VERSION(major) ( (6 + (major >= 14 ? 1 : 0) + major) * 100 ) # define wxCHECK_VISUALC_VERSION(major) ( __VISUALC__ >= wxVISUALC_VERSION(major) ) #endif diff --git a/Externals/wxWidgets3/wx/wxmsw.h b/Externals/wxWidgets3/wx/wxmsw.h index 93950bf567..40ad33a41b 100644 --- a/Externals/wxWidgets3/wx/wxmsw.h +++ b/Externals/wxWidgets3/wx/wxmsw.h @@ -1247,8 +1247,8 @@ // Default is 1 for wxUSE_ENH_METAFILE and 0 for wxUSE_WIN_METAFILES_ALWAYS. // // Recommended setting: default or 0 for everything for portable programs. -#define wxUSE_METAFILE 1 -#define wxUSE_ENH_METAFILE 1 +#define wxUSE_METAFILE 0 +#define wxUSE_ENH_METAFILE 0 #define wxUSE_WIN_METAFILES_ALWAYS 0 // ---------------------------------------------------------------------------- diff --git a/Externals/xxhash/xxhash.vcxproj b/Externals/xxhash/xxhash.vcxproj index f3325aec38..4e43687eb7 100644 --- a/Externals/xxhash/xxhash.vcxproj +++ b/Externals/xxhash/xxhash.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode @@ -50,4 +50,4 @@ - + \ No newline at end of file diff --git a/Externals/zlib/zlib.vcxproj b/Externals/zlib/zlib.vcxproj index 748df1963d..eb8d2846f4 100644 --- a/Externals/zlib/zlib.vcxproj +++ b/Externals/zlib/zlib.vcxproj @@ -1,5 +1,5 @@ - - + + Debug @@ -16,7 +16,7 @@ StaticLibrary - v120 + v140 Unicode diff --git a/Languages/Languages.vcxproj b/Languages/Languages.vcxproj index 49b39701f7..2577ffe76e 100644 --- a/Languages/Languages.vcxproj +++ b/Languages/Languages.vcxproj @@ -1,5 +1,5 @@  - + Debug @@ -44,12 +44,12 @@ Utility true - v120 + v140 Utility false - v120 + v140 diff --git a/Readme.md b/Readme.md index 81fe9a38c4..7cae32fa63 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,6 @@ # Dolphin - A GameCube / Wii / Triforce Emulator -[Homepage](https://dolphin-emu.org/) | [Project Site](https://github.com/dolphin-emu/dolphin) | [Forums](https://forums.dolphin-emu.org/) | [Wiki](https://wiki.dolphin-emu.org/) | [Issue Tracker](https://code.google.com/p/dolphin-emu/issues/list) | [Coding Style](https://github.com/dolphin-emu/dolphin/blob/master/Contributing.md) | [Transifex Page](https://www.transifex.com/projects/p/dolphin-emu/) +[Homepage](https://dolphin-emu.org/) | [Project Site](https://github.com/dolphin-emu/dolphin) | [Forums](https://forums.dolphin-emu.org/) | [Wiki](https://wiki.dolphin-emu.org/) | [Issue Tracker](https://bugs.dolphin-emu.org/projects/emulator/issues) | [Coding Style](https://github.com/dolphin-emu/dolphin/blob/master/Contributing.md) | [Transifex Page](https://www.transifex.com/projects/p/dolphin-emu/) Dolphin is an emulator for running GameCube, Wii, and Triforce games on Windows, Linux, OS X, and recent Android devices. It's licensed under @@ -9,6 +9,7 @@ the terms of the GNU General Public License, version 2 or later (GPLv2+). Please read the [FAQ](https://dolphin-emu.org/docs/faq/) before using Dolphin. ## System Requirements +### Desktop * OS * Microsoft Windows (Vista or higher). * Linux. @@ -21,11 +22,22 @@ Please read the [FAQ](https://dolphin-emu.org/docs/faq/) before using Dolphin. * A reasonably modern graphics card (Direct3D 10.0 / OpenGL 3.0). * A graphics card that supports Direct3D 11 / OpenGL 4.4 is recommended. -## Installation on Windows +### Android +* OS + * Android 5.0 (Lollipop) or higher. +* Processor + * An ARM processor with support for 64-bit applications. (An Intel x86 processor could also work in theory, but no known x86 devices support 64-bit applications.) +* Graphics + * A graphics processor that supports OpenGL ES 3.0 or higher. Performance varies heavily with [driver quality](https://dolphin-emu.org/blog/2013/09/26/dolphin-emulator-and-opengl-drivers-hall-fameshame/). + * A graphics processor that supports standard desktop OpenGL features is recommended for best performance. + +Dolphin can only be installed on devices that satisfy the above requirements. Attempting to install on an unsupported device will fail and display an error message. + +## Building for Windows Use the solution file `Source/dolphin-emu.sln` to build Dolphin on Windows. -Visual Studio 2013 is a hard requirement since previous versions don't support -many C++ features that we use. Other compilers might be able to build Dolphin -on Windows but have not been tested and are not recommended to be used. +Visual Studio 2015 is a hard requirement. Other compilers might be able to +build Dolphin on Windows but have not been tested and are not recommended to +be used. An installer can be created by using the `Installer_win32.nsi` and `Installer_x64.nsi` scripts in the Installer directory. This will require the @@ -33,7 +45,7 @@ Nullsoft Scriptable Install System (NSIS) to be installed. Creating an installer is not necessary to run Dolphin since the Build directory contains a working Dolphin distribution. -## Installation on Linux and OS X +## Building for Linux and OS X Dolphin requires [CMake](http://www.cmake.org/) for systems other than Windows. Many libraries are bundled with Dolphin and used if they're not installed on your system. CMake will inform you if a bundled library is used or if you need to install any @@ -49,30 +61,38 @@ On OS X, an application bundle will be created in `./Binaries`. On Linux, it's strongly recommended to perform a global installation via `sudo make install`. -## Installation on Android -Dolphin requires [Android Studio](http://developer.android.com/tools/studio/index.html) to build -the Android UI. Import the Gradle project located in `./Source/Android`, and then execute the -Gradle task `assembleDebug` to build, or `installDebug` to install the UI onto a connected device. +## Building for Android -In order to launch the app, you must build and include the native Dolphin libraries into the UI project. -(Building native code requires the [Android NDK](https://developer.android.com/tools/sdk/ndk/index.html).) -Android Studio will do this for you if you create `Source/Android/build.properties`, and place the -following inside: +These instructions assume familiarity with Android development. If you do not have an +Android dev environment set up, see [AndroidSetup.md](AndroidSetup.md). + +If using Android Studio, import the Gradle project located in `./Source/Android`. + +Android apps are compiled using a build system called Gradle. Dolphin's native component, +however, is compiled using CMake. The Gradle script will attempt to run a CMake build +automatically while building the Java code, if you create the file `Source/Android/build.properties`, +and place the following inside: ``` -makeArgs= +# Specifies arguments for the 'make' command. Can be blank. +makeArgs= + +# The path to your machine's Git executable. Will autodetect if blank (on Linux only). +gitPath= + +# The path to the CMake executable. Will autodetect if blank (on Linux only). +cmakePath= + +# The path to the extracted NDK package. Will autodetect if blank (on Linux only). +ndkPath= ``` -Replace `` with any arguments you want to pass to `make`. If you need to use a specific -version of git, cmake, or the NDK, you can also add `gitPath=`, `cmakePath=` or -`ndkPath=`, replacing `` with the actual paths. Otherwise, these will be found -automatically. Then execute the `assembleDebug` or `installDebug` task corresponding to the -hardware platform you are targeting. For example, to deploy to a Nexus 9, which runs the AArch64 -architecture, execute `installArm_64Debug`. A list of available tasks can be found in Android -Studio in the Gradle tray, located at the top-right corner of the IDE by default. +If you prefer, you can run the CMake step manually, and it will copy the resulting +binary into the correct location for inclusion in the Android APK. -The native libraries will be compiled, and copied into `./Source/Android/app/libs`. Android Studio -and Gradle will include any libraries in that folder into the APK at build time. +Execute the Gradle task `assembleArm_64Debug` to build, or `installArm_64Debug` to +install the application onto a connected device. If other ABIs are eventually supported, +execute the tasks corresponding to the desired ABI. ## Uninstalling When Dolphin has been installed with the NSIS installer, you can uninstall diff --git a/Source/Android/.gitignore b/Source/Android/.gitignore index a053548512..3fbf1ea2ff 100644 --- a/Source/Android/.gitignore +++ b/Source/Android/.gitignore @@ -36,7 +36,6 @@ workspace.xml tasks.xml .gradle/* .idea -gradle/ build/ *.so *.iml diff --git a/Source/Android/app/build.gradle b/Source/Android/app/build.gradle index b936e0604d..62588307e0 100644 --- a/Source/Android/app/build.gradle +++ b/Source/Android/app/build.gradle @@ -1,7 +1,8 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 21 + // Leanback support requires >22 + compileSdkVersion 22 buildToolsVersion "22.0.1" lintOptions { @@ -75,10 +76,13 @@ android { } dependencies { - compile 'com.android.support:support-v13:22.2.0' - compile 'com.android.support:cardview-v7:22.2.0' - compile 'com.android.support:recyclerview-v7:22.2.0' - compile 'com.android.support:design:22.2.0' + compile 'com.android.support:support-v13:22.2.1' + compile 'com.android.support:cardview-v7:22.2.1' + compile 'com.android.support:recyclerview-v7:22.2.1' + compile 'com.android.support:design:22.2.1' + + // Android TV UI libraries. + compile 'com.android.support:leanback-v17:22.2.1' // For showing the banner as a circle a-la Material Design Guidelines compile 'de.hdodenhof:circleimageview:1.2.2' @@ -134,7 +138,11 @@ task compileNative(type: Exec, dependsOn: 'setupCMake') { executable 'make' - args buildProperties.makeArgs + if (buildProperties.makeArgs == null || buildProperties.makeArgs.isEmpty()) { + // TODO + } else { + args buildProperties.makeArgs + } } else { executable 'echo' args 'No build.properties found; skipping native build.' @@ -144,13 +152,15 @@ task compileNative(type: Exec, dependsOn: 'setupCMake') { String getExecutablePath(String command) { def propsFile = rootProject.file("build.properties") def path = null + if (propsFile.canRead()) { def buildProperties = new Properties() buildProperties.load(new FileInputStream(propsFile)) println buildProperties path = buildProperties[command + "Path"] } - if (path == null) { + + if (path == null || path.isEmpty()) { try { def stdout = new ByteArrayOutputStream() @@ -164,21 +174,25 @@ String getExecutablePath(String command) { project.logger.error("Gradle error: Couldn't find " + command + " executable.") } } + if (path != null) { project.logger.quiet("Gradle: Found " + command + " executuable:" + path) } + return path } String getNdkPath() { def propsFile = rootProject.file("build.properties") def ndkPath = null + if (propsFile.canRead()) { def buildProperties = new Properties() buildProperties.load(new FileInputStream(propsFile)) ndkPath = buildProperties.ndkPath } - if (ndkPath == null) { + + if (ndkPath == null || ndkPath.isEmpty()) { try { def stdout = new ByteArrayOutputStream() @@ -194,6 +208,7 @@ String getNdkPath() { project.logger.error("Gradle error: Couldn't find NDK.") } } + if (ndkPath != null) { project.logger.quiet("Gradle: Found Android NDK: " + ndkPath) } diff --git a/Source/Android/app/src/arm_64/res/values/arrays.xml b/Source/Android/app/src/arm_64/res/values/arrays.xml index 12ed1695da..8f2ed0edff 100644 --- a/Source/Android/app/src/arm_64/res/values/arrays.xml +++ b/Source/Android/app/src/arm_64/res/values/arrays.xml @@ -6,10 +6,12 @@ @string/interpreter + @string/cached_interpreter @string/jit_arm64_recompiler 0 + 5 4 diff --git a/Source/Android/app/src/main/AndroidManifest.xml b/Source/Android/app/src/main/AndroidManifest.xml index 30fffd11e9..e08b2dd0a8 100644 --- a/Source/Android/app/src/main/AndroidManifest.xml +++ b/Source/Android/app/src/main/AndroidManifest.xml @@ -33,11 +33,22 @@ - + + + + + + + + + + { - private static final int REQUEST_ADD_DIRECTORY = 1; + public static final int REQUEST_ADD_DIRECTORY = 1; + public static final int REQUEST_EMULATE_GAME = 2; /** * It is important to keep track of loader ID separately from platform ID (see Game.java) @@ -115,15 +116,30 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag @Override protected void onActivityResult(int requestCode, int resultCode, Intent result) { - // If the user picked a file, as opposed to just backing out. - if (resultCode == RESULT_OK) + switch (requestCode) { - // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity; - // other activities might use this callback in the future (don't forget to change Javadoc!) - if (requestCode == REQUEST_ADD_DIRECTORY) - { - refreshFragment(); - } + case REQUEST_ADD_DIRECTORY: + // If the user picked a file, as opposed to just backing out. + if (resultCode == RESULT_OK) + { + // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity; + // other activities might use this callback in the future (don't forget to change Javadoc!) + if (requestCode == REQUEST_ADD_DIRECTORY) + { + refreshFragment(); + } + } + break; + + case REQUEST_EMULATE_GAME: + // Invalidate Picasso image so that the new screenshot is animated in. + PlatformGamesFragment fragment = getPlatformFragment(mViewPager.getCurrentItem()); + + if (fragment != null) + { + fragment.refreshScreenshotAtPosition(resultCode); + } + break; } } @@ -211,7 +227,7 @@ public final class MainActivity extends AppCompatActivity implements LoaderManag GameProvider.URI_GAME, // URI of table to query null, // Return all columns GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform - new String[]{Integer.toString(id)}, // Platform id is Loader id minus 1 + new String[]{Integer.toString(id)}, // Platform id is Loader id GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order ); diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java new file mode 100644 index 0000000000..3f3b8c168d --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/activities/TvMainActivity.java @@ -0,0 +1,290 @@ +package org.dolphinemu.dolphinemu.activities; + +import android.app.Activity; +import android.app.ActivityOptions; +import android.app.FragmentManager; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.os.Bundle; +import android.preference.PreferenceManager; +import android.support.v17.leanback.app.BrowseFragment; +import android.support.v17.leanback.database.CursorMapper; +import android.support.v17.leanback.widget.ArrayObjectAdapter; +import android.support.v17.leanback.widget.CursorObjectAdapter; +import android.support.v17.leanback.widget.HeaderItem; +import android.support.v17.leanback.widget.ListRow; +import android.support.v17.leanback.widget.ListRowPresenter; +import android.support.v17.leanback.widget.OnItemViewClickedListener; +import android.support.v17.leanback.widget.Presenter; +import android.support.v17.leanback.widget.Row; +import android.support.v17.leanback.widget.RowPresenter; +import android.widget.Toast; + +import org.dolphinemu.dolphinemu.NativeLibrary; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.adapters.GameRowPresenter; +import org.dolphinemu.dolphinemu.adapters.SettingsRowPresenter; +import org.dolphinemu.dolphinemu.model.Game; +import org.dolphinemu.dolphinemu.model.GameDatabase; +import org.dolphinemu.dolphinemu.model.GameProvider; +import org.dolphinemu.dolphinemu.model.TvSettingsItem; +import org.dolphinemu.dolphinemu.services.AssetCopyService; +import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder; + +public final class TvMainActivity extends Activity +{ + protected BrowseFragment mBrowseFragment; + + private ArrayObjectAdapter mRowsAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_tv_main); + + final FragmentManager fragmentManager = getFragmentManager(); + mBrowseFragment = (BrowseFragment) fragmentManager.findFragmentById( + R.id.fragment_game_list); + + // Set display parameters for the BrowseFragment + mBrowseFragment.setHeadersState(BrowseFragment.HEADERS_ENABLED); + mBrowseFragment.setTitle(getString(R.string.app_name)); + mBrowseFragment.setBadgeDrawable(getResources().getDrawable( + R.drawable.ic_launcher, null)); + mBrowseFragment.setBrandColor(getResources().getColor(R.color.dolphin_blue_dark)); + + buildRowsAdapter(); + + mBrowseFragment.setOnItemViewClickedListener( + new OnItemViewClickedListener() + { + @Override + public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) + { + // Special case: user clicked on a settings row item. + if (item instanceof TvSettingsItem) + { + TvSettingsItem settingsItem = (TvSettingsItem) item; + + switch (settingsItem.getItemId()) + { + case R.id.menu_refresh: + getContentResolver().insert(GameProvider.URI_REFRESH, null); + + // TODO Let the Activity know the data is refreshed in some other, better way. + recreate(); + break; + + case R.id.menu_settings: + // Launch the Settings Actvity. + Intent settings = new Intent(TvMainActivity.this, SettingsActivity.class); + startActivity(settings); + break; + + case R.id.button_add_directory: + Intent fileChooser = new Intent(TvMainActivity.this, AddDirectoryActivity.class); + + // The second argument to this method is read below in onActivityResult(). + startActivityForResult(fileChooser, MainActivity.REQUEST_ADD_DIRECTORY); + + break; + + default: + Toast.makeText(TvMainActivity.this, "Unimplemented menu option.", Toast.LENGTH_SHORT).show(); + break; + } + } + else + { + TvGameViewHolder holder = (TvGameViewHolder) itemViewHolder; + // Start the emulation activity and send the path of the clicked ISO to it. + Intent intent = new Intent(TvMainActivity.this, EmulationActivity.class); + + intent.putExtra("SelectedGame", holder.path); + intent.putExtra("SelectedTitle", holder.title); + intent.putExtra("ScreenPath", holder.screenshotPath); + + ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation( + TvMainActivity.this, + holder.imageScreenshot, + "image_game_screenshot"); + + startActivity(intent, options.toBundle()); + } + } + }); + + // Stuff in this block only happens when this activity is newly created (i.e. not a rotation) + if (savedInstanceState == null) + { + NativeLibrary.SetUserDirectory(""); // Auto-Detect + + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + boolean assetsCopied = preferences.getBoolean("assetsCopied", false); + + // Only perform these extensive copy operations once. + if (!assetsCopied) + { + // Copy assets into appropriate locations. + Intent copyAssets = new Intent(this, AssetCopyService.class); + startService(copyAssets); + } + } + } + + /** + * Callback from AddDirectoryActivity. Applies any changes necessary to the GameGridActivity. + * + * @param requestCode An int describing whether the Activity that is returning did so successfully. + * @param resultCode An int describing what Activity is giving us this callback. + * @param result The information the returning Activity is providing us. + */ + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent result) + { + switch (requestCode) + { + case MainActivity.REQUEST_ADD_DIRECTORY: + // If the user picked a file, as opposed to just backing out. + if (resultCode == RESULT_OK) + { + // Sanity check to make sure the Activity that just returned was the AddDirectoryActivity; + // other activities might use this callback in the future (don't forget to change Javadoc!) + if (requestCode == MainActivity.REQUEST_ADD_DIRECTORY) + { + // TODO Let the Activity know the data is refreshed in some other, better way. + recreate(); + } + } + break; + } + } + + private void buildRowsAdapter() + { + mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter()); + + // For each platform + for (int platformIndex = 0; platformIndex <= Game.PLATFORM_ALL; ++platformIndex) + { + ListRow row = buildGamesRow(platformIndex); + + // Add row to the adapter only if it is not empty. + if (row != null) + { + mRowsAdapter.add(row); + } + } + + ListRow settingsRow = buildSettingsRow(); + mRowsAdapter.add(settingsRow); + + mBrowseFragment.setAdapter(mRowsAdapter); + } + + private ListRow buildGamesRow(int platform) + { + // Create an adapter for this row. + CursorObjectAdapter row = new CursorObjectAdapter(new GameRowPresenter()); + + Cursor games; + if (platform == Game.PLATFORM_ALL) + { + // Get all games. + games = getContentResolver().query( + GameProvider.URI_GAME, // URI of table to query + null, // Return all columns + null, // Return all games + null, // Return all games + GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order + ); + } + else + { + // Get games for this particular platform. + games = getContentResolver().query( + GameProvider.URI_GAME, // URI of table to query + null, // Return all columns + GameDatabase.KEY_GAME_PLATFORM + " = ?", // Select by platform + new String[]{Integer.toString(platform)}, // Platform id + GameDatabase.KEY_GAME_TITLE + " asc" // Sort by game name, ascending order + ); + } + + // If cursor is empty, don't return a Row. + if (!games.moveToFirst()) + { + return null; + } + + row.changeCursor(games); + row.setMapper(new CursorMapper() + { + @Override + protected void bindColumns(Cursor cursor) + { + // No-op? Not sure what this does. + } + + @Override + protected Object bind(Cursor cursor) + { + return Game.fromCursor(cursor); + } + }); + + String headerName; + switch (platform) + { + case Game.PLATFORM_GC: + headerName = "GameCube Games"; + break; + + case Game.PLATFORM_WII: + headerName = "Wii Games"; + break; + + case Game.PLATFORM_WII_WARE: + headerName = "WiiWare"; + break; + + case Game.PLATFORM_ALL: + headerName = "All Games"; + break; + + default: + headerName = "Error"; + break; + } + + // Create a header for this row. + HeaderItem header = new HeaderItem(platform, headerName); + + // Create the row, passing it the filled adapter and the header, and give it to the master adapter. + return new ListRow(header, row); + } + + private ListRow buildSettingsRow() + { + ArrayObjectAdapter rowItems = new ArrayObjectAdapter(new SettingsRowPresenter()); + + rowItems.add(new TvSettingsItem(R.id.menu_refresh, + R.drawable.ic_refresh_tv, + R.string.grid_menu_refresh)); + + rowItems.add(new TvSettingsItem(R.id.menu_settings, + R.drawable.ic_settings_tv, + R.string.grid_menu_settings)); + + rowItems.add(new TvSettingsItem(R.id.button_add_directory, + R.drawable.ic_add_tv, + R.string.add_directory_title)); + + // Create a header for this row. + HeaderItem header = new HeaderItem(R.string.settings, getString(R.string.settings)); + + return new ListRow(header, rowItems); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java index a9a7be930e..e74bd6f96d 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameAdapter.java @@ -1,9 +1,11 @@ package org.dolphinemu.dolphinemu.adapters; import android.app.Activity; +import android.app.ActivityOptions; import android.content.Intent; import android.database.Cursor; import android.database.DataSetObserver; +import android.graphics.Bitmap; import android.graphics.Rect; import android.support.v7.widget.RecyclerView; import android.util.Log; @@ -15,6 +17,7 @@ import com.squareup.picasso.Picasso; import org.dolphinemu.dolphinemu.R; import org.dolphinemu.dolphinemu.activities.EmulationActivity; +import org.dolphinemu.dolphinemu.activities.MainActivity; import org.dolphinemu.dolphinemu.dialogs.GameDetailsDialog; import org.dolphinemu.dolphinemu.model.GameDatabase; import org.dolphinemu.dolphinemu.viewholders.GameViewHolder; @@ -80,14 +83,15 @@ public final class GameAdapter extends RecyclerView.Adapter impl if (mCursor.moveToPosition(position)) { String screenPath = mCursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH); - Picasso.with(holder.imageScreenshot.getContext()) - .invalidate(screenPath); // Fill in the view contents. Picasso.with(holder.imageScreenshot.getContext()) .load(screenPath) .fit() .centerCrop() + .noFade() + .noPlaceholder() + .config(Bitmap.Config.RGB_565) .error(R.drawable.no_banner) .into(holder.imageScreenshot); @@ -112,8 +116,6 @@ public final class GameAdapter extends RecyclerView.Adapter impl { Log.e("DolphinEmu", "Can't bind view; dataset is not valid."); } - - } /** @@ -220,8 +222,17 @@ public final class GameAdapter extends RecyclerView.Adapter impl intent.putExtra("SelectedGame", holder.path); intent.putExtra("SelectedTitle", holder.title); + intent.putExtra("ScreenPath", holder.screenshotPath); + intent.putExtra("GridPosition", holder.getAdapterPosition()); - view.getContext().startActivity(intent); + ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation( + (Activity) view.getContext(), + holder.imageScreenshot, + "image_game_screenshot"); + + ((Activity) view.getContext()).startActivityForResult(intent, + MainActivity.REQUEST_EMULATE_GAME, + options.toBundle()); } /** diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java new file mode 100644 index 0000000000..3b0b8095ce --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/GameRowPresenter.java @@ -0,0 +1,118 @@ +package org.dolphinemu.dolphinemu.adapters; + +import android.graphics.Bitmap; +import android.support.v17.leanback.widget.ImageCardView; +import android.support.v17.leanback.widget.Presenter; +import android.view.ViewGroup; +import android.widget.ImageView; + +import com.squareup.picasso.Picasso; + +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.model.Game; +import org.dolphinemu.dolphinemu.viewholders.TvGameViewHolder; + +/** + * The Leanback library / docs call this a Presenter, but it works very + * similarly to a RecyclerView.ViewHolder. + */ +public final class GameRowPresenter extends Presenter +{ + public ViewHolder onCreateViewHolder(ViewGroup parent) + { + // Create a new view. + ImageCardView gameCard = new ImageCardView(parent.getContext()) + { + @Override + public void setSelected(boolean selected) + { + setCardBackground(this, selected); + super.setSelected(selected); + } + }; + + gameCard.setMainImageAdjustViewBounds(true); + gameCard.setMainImageDimensions(480, 320); + gameCard.setMainImageScaleType(ImageView.ScaleType.CENTER_CROP); + + gameCard.setFocusable(true); + gameCard.setFocusableInTouchMode(true); + + setCardBackground(gameCard, false); + + // Use that view to create a ViewHolder. + return new TvGameViewHolder(gameCard); + } + + public void onBindViewHolder(ViewHolder viewHolder, Object item) + { + TvGameViewHolder holder = (TvGameViewHolder) viewHolder; + Game game = (Game) item; + + String screenPath = game.getScreenshotPath(); + + // Fill in the view contents. + Picasso.with(holder.imageScreenshot.getContext()) + .load(screenPath) + .fit() + .centerCrop() + .noFade() + .noPlaceholder() + .config(Bitmap.Config.RGB_565) + .error(R.drawable.no_banner) + .into(holder.imageScreenshot); + + holder.cardParent.setTitleText(game.getTitle()); + holder.cardParent.setContentText(game.getCompany()); + + // TODO These shouldn't be necessary once the move to a DB-based model is complete. + holder.gameId = game.getGameId(); + holder.path = game.getPath(); + holder.title = game.getTitle(); + holder.description = game.getDescription(); + holder.country = game.getCountry(); + holder.company = game.getCompany(); + holder.screenshotPath = game.getScreenshotPath(); + + switch (game.getPlatform()) + { + case Game.PLATFORM_GC: + holder.cardParent.setTag(R.color.dolphin_accent_gamecube); + break; + + case Game.PLATFORM_WII: + holder.cardParent.setTag(R.color.dolphin_accent_wii); + break; + + case Game.PLATFORM_WII_WARE: + holder.cardParent.setTag(R.color.dolphin_accent_wiiware); + break; + + default: + holder.cardParent.setTag(android.R.color.holo_red_dark); + break; + } + } + + public void onUnbindViewHolder(ViewHolder viewHolder) + { + // no op + } + + public void setCardBackground(ImageCardView view, boolean selected) + { + int backgroundColor; + + if (selected) + { + // TODO: 7/20/15 Try using view tag to set color + backgroundColor = (int) view.getTag(); + } + else + { + backgroundColor = R.color.tv_card_unselected; + } + + view.setInfoAreaBackgroundColor(view.getResources().getColor(backgroundColor)); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java new file mode 100644 index 0000000000..beef06a218 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/adapters/SettingsRowPresenter.java @@ -0,0 +1,47 @@ +package org.dolphinemu.dolphinemu.adapters; + + +import android.content.res.Resources; +import android.support.v17.leanback.widget.ImageCardView; +import android.support.v17.leanback.widget.Presenter; +import android.view.ViewGroup; + +import org.dolphinemu.dolphinemu.model.TvSettingsItem; +import org.dolphinemu.dolphinemu.viewholders.TvSettingsViewHolder; + +public final class SettingsRowPresenter extends Presenter +{ + public Presenter.ViewHolder onCreateViewHolder(ViewGroup parent) + { + // Create a new view. + ImageCardView settingsCard = new ImageCardView(parent.getContext()); + + settingsCard.setMainImageAdjustViewBounds(true); + settingsCard.setMainImageDimensions(192, 160); + + + settingsCard.setFocusable(true); + settingsCard.setFocusableInTouchMode(true); + + // Use that view to create a ViewHolder. + return new TvSettingsViewHolder(settingsCard); + } + + public void onBindViewHolder(Presenter.ViewHolder viewHolder, Object item) + { + TvSettingsViewHolder holder = (TvSettingsViewHolder) viewHolder; + TvSettingsItem settingsItem = (TvSettingsItem) item; + + Resources resources = holder.cardParent.getResources(); + + holder.itemId = settingsItem.getItemId(); + + holder.cardParent.setTitleText(resources.getString(settingsItem.getLabelId())); + holder.cardParent.setMainImage(resources.getDrawable(settingsItem.getIconId(), null)); + } + + public void onUnbindViewHolder(Presenter.ViewHolder viewHolder) + { + // no op + } +} \ No newline at end of file diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java index 9d23736cb6..1eb1684531 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/EmulationFragment.java @@ -81,9 +81,12 @@ public final class EmulationFragment extends Fragment implements SurfaceHolder.C mSurfaceView.getHolder().addCallback(this); // If the input overlay was previously disabled, then don't show it. - if (!mPreferences.getBoolean("showInputOverlay", true)) + if (mInputOverlay != null) { - mInputOverlay.setVisibility(View.GONE); + if (!mPreferences.getBoolean("showInputOverlay", true)) + { + mInputOverlay.setVisibility(View.GONE); + } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java new file mode 100644 index 0000000000..bbd9807b9b --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/LoadStateFragment.java @@ -0,0 +1,55 @@ +package org.dolphinemu.dolphinemu.fragments; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.GridLayout; + +import org.dolphinemu.dolphinemu.BuildConfig; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.activities.EmulationActivity; + +public final class LoadStateFragment extends Fragment implements View.OnClickListener +{ + public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".load_state"; + public static final int FRAGMENT_ID = R.layout.fragment_state_load; + + public static LoadStateFragment newInstance() + { + LoadStateFragment fragment = new LoadStateFragment(); + + // TODO Add any appropriate arguments to this fragment. + + return fragment; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + View rootView = inflater.inflate(FRAGMENT_ID, container, false); + + GridLayout grid = (GridLayout) rootView.findViewById(R.id.grid_state_slots); + for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++) + { + Button button = (Button) grid.getChildAt(childIndex); + + button.setOnClickListener(this); + } + + // So that item clicked to start this Fragment is no longer the focused item. + grid.requestFocus(); + + return rootView; + } + + @Override + public void onClick(View button) + { + ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId()); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java new file mode 100644 index 0000000000..d894f32373 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/MenuFragment.java @@ -0,0 +1,52 @@ +package org.dolphinemu.dolphinemu.fragments; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.dolphinemu.dolphinemu.BuildConfig; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.activities.EmulationActivity; + +public final class MenuFragment extends Fragment implements View.OnClickListener +{ + public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".ingame_menu"; + public static final int FRAGMENT_ID = R.layout.fragment_ingame_menu; + private TextView mTitleText; + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + View rootView = inflater.inflate(FRAGMENT_ID, container, false); + + LinearLayout options = (LinearLayout) rootView.findViewById(R.id.layout_options); + for (int childIndex = 0; childIndex < options.getChildCount(); childIndex++) + { + Button button = (Button) options.getChildAt(childIndex); + + button.setOnClickListener(this); + } + + mTitleText = (TextView) rootView.findViewById(R.id.text_game_title); + + return rootView; + } + + @Override + public void onClick(View button) + { + ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId()); + } + + public void setTitleText(String title) + { + mTitleText.setText(title); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java index 4957090ed3..c1d1b1c8e7 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/PlatformGamesFragment.java @@ -1,12 +1,12 @@ package org.dolphinemu.dolphinemu.fragments; -import android.app.Activity; import android.app.Fragment; import android.app.LoaderManager; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; import android.support.annotation.Nullable; +import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; @@ -57,6 +57,15 @@ public class PlatformGamesFragment extends Fragment RecyclerView.LayoutManager layoutManager = new GridLayoutManager(getActivity(), getResources().getInteger(R.integer.game_grid_columns)); recyclerView.setLayoutManager(layoutManager); + recyclerView.setItemAnimator(new DefaultItemAnimator() + { + @Override + public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder, int fromX, int fromY, int toX, int toY) + { + dispatchChangeFinished(newHolder, false); + return true; + } + }); recyclerView.addItemDecoration(new GameAdapter.SpacesItemDecoration(8)); @@ -70,10 +79,9 @@ public class PlatformGamesFragment extends Fragment return rootView; } - @Override - public void onAttach(Activity activity) + public void refreshScreenshotAtPosition(int position) { - super.onAttach(activity); + mAdapter.notifyItemChanged(position); } public void refresh() diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java new file mode 100644 index 0000000000..a5e9e6d441 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/fragments/SaveStateFragment.java @@ -0,0 +1,55 @@ +package org.dolphinemu.dolphinemu.fragments; + +import android.app.Fragment; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.GridLayout; + +import org.dolphinemu.dolphinemu.BuildConfig; +import org.dolphinemu.dolphinemu.R; +import org.dolphinemu.dolphinemu.activities.EmulationActivity; + +public final class SaveStateFragment extends Fragment implements View.OnClickListener +{ + public static final String FRAGMENT_TAG = BuildConfig.APPLICATION_ID + ".save_state"; + public static final int FRAGMENT_ID = R.layout.fragment_state_save; + + public static SaveStateFragment newInstance() + { + SaveStateFragment fragment = new SaveStateFragment(); + + // TODO Add any appropriate arguments to this fragment. + + return fragment; + } + + @Nullable + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) + { + View rootView = inflater.inflate(FRAGMENT_ID, container, false); + + GridLayout grid = (GridLayout) rootView.findViewById(R.id.grid_state_slots); + for (int childIndex = 0; childIndex < grid.getChildCount(); childIndex++) + { + Button button = (Button) grid.getChildAt(childIndex); + + button.setOnClickListener(this); + } + + // So that item clicked to start this Fragment is no longer the focused item. + grid.requestFocus(); + + return rootView; + } + + @Override + public void onClick(View button) + { + ((EmulationActivity) getActivity()).onMenuItemClicked(button.getId()); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java index f3ef6f7514..33a9f27c54 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/Game.java @@ -3,13 +3,12 @@ package org.dolphinemu.dolphinemu.model; import android.content.ContentValues; import android.database.Cursor; -import java.io.File; - public final class Game { public static final int PLATFORM_GC = 0; public static final int PLATFORM_WII = 1; public static final int PLATFORM_WII_WARE = 2; + public static final int PLATFORM_ALL = 3; // Copied from IVolume::ECountry. Update these if that is ever modified. public static final int COUNTRY_EUROPE = 0; @@ -33,13 +32,13 @@ public final class Game private String mDescription; private String mPath; private String mGameId; - private String mScreenshotFolderPath; + private String mScreenshotPath; private String mCompany; private int mPlatform; private int mCountry; - public Game(int platform, String title, String description, int country, String path, String gameId, String company) + public Game(int platform, String title, String description, int country, String path, String gameId, String company, String screenshotPath) { mPlatform = platform; mTitle = title; @@ -48,7 +47,7 @@ public final class Game mPath = path; mGameId = gameId; mCompany = company; - mScreenshotFolderPath = PATH_SCREENSHOT_FOLDER + getGameId() + "/"; + mScreenshotPath = screenshotPath; } public int getPlatform() @@ -86,27 +85,9 @@ public final class Game return mGameId; } - public String getScreenshotFolderPath() + public String getScreenshotPath() { - return mScreenshotFolderPath; - } - - public String getScreenPath() - { - // Count how many screenshots are available, so we can use the most recent one. - File screenshotFolder = new File(mScreenshotFolderPath.substring(mScreenshotFolderPath.indexOf('s') - 1)); - int screenCount = 0; - - if (screenshotFolder.isDirectory()) - { - screenCount = screenshotFolder.list().length; - } - - String screenPath = mScreenshotFolderPath - + getGameId() + "-" - + screenCount + ".png"; - - return screenPath; + return mScreenshotPath; } public static ContentValues asContentValues(int platform, String title, String description, int country, String path, String gameId, String company) @@ -135,6 +116,7 @@ public final class Game cursor.getInt(GameDatabase.GAME_COLUMN_COUNTRY), cursor.getString(GameDatabase.GAME_COLUMN_PATH), cursor.getString(GameDatabase.GAME_COLUMN_GAME_ID), - cursor.getString(GameDatabase.GAME_COLUMN_COMPANY)); + cursor.getString(GameDatabase.GAME_COLUMN_COMPANY), + cursor.getString(GameDatabase.GAME_COLUMN_SCREENSHOT_PATH)); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java new file mode 100644 index 0000000000..ccd87bfa4c --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/model/TvSettingsItem.java @@ -0,0 +1,31 @@ +package org.dolphinemu.dolphinemu.model; + + +public final class TvSettingsItem +{ + private final int mItemId; + private final int mIconId; + private final int mLabelId; + + public TvSettingsItem(int itemId, int iconId, int labelId) + { + mItemId = itemId; + mIconId = iconId; + mLabelId = labelId; + } + + public int getItemId() + { + return mItemId; + } + + public int getIconId() + { + return mIconId; + } + + public int getLabelId() + { + return mLabelId; + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java index 1f6f94bc8a..558a34be37 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/services/AssetCopyService.java @@ -61,6 +61,7 @@ public final class AssetCopyService extends IntentService // Always copy over the GCPad config in case of change or corruption. // Not a user configurable file. copyAsset("GCPadNew.ini", ConfigDir + File.separator + "GCPadNew.ini"); + copyAsset("WiimoteNew.ini", ConfigDir + File.separator + "WiimoteNew.ini"); // Load the configuration keys set in the Dolphin ini and gfx ini files // into the application's shared preferences. diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java index 168bd2dd93..dd8959129b 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/utils/UserPreferences.java @@ -45,14 +45,13 @@ public final class UserPreferences else editor.putString("cpuCorePref", getConfig("Dolphin.ini", "Core", "CPUCore", "3")); - editor.putBoolean("dualCorePref", getConfig("Dolphin.ini", "Core", "CPUThread", "False").equals("True")); - editor.putBoolean("fastmemPref", getConfig("Dolphin.ini", "Core", "Fastmem", "False").equals("True")); + editor.putBoolean("dualCorePref", getConfig("Dolphin.ini", "Core", "CPUThread", "True").equals("True")); editor.putString("gpuPref", getConfig("Dolphin.ini", "Core", "GFXBackend", "OGL")); editor.putBoolean("showFPS", getConfig("gfx_opengl.ini", "Settings", "ShowFPS", "False").equals("True")); editor.putBoolean("drawOnscreenControls", getConfig("Dolphin.ini", "Android", "ScreenControls", "True").equals("True")); - editor.putString("internalResolution", getConfig("gfx_opengl.ini", "Settings", "EFBScale", "2") ); + editor.putString("internalResolution", getConfig("gfx_opengl.ini", "Settings", "EFBScale", "2")); editor.putString("FSAA", getConfig("gfx_opengl.ini", "Settings", "MSAA", "0")); editor.putString("anisotropicFiltering", getConfig("gfx_opengl.ini", "Enhancements", "MaxAnisotropy", "0")); editor.putString("postProcessingShader", getConfig("gfx_opengl.ini", "Enhancements", "PostProcessingShader", "")); @@ -62,10 +61,14 @@ public final class UserPreferences editor.putBoolean("disableFog", getConfig("gfx_opengl.ini", "Settings", "DisableFog", "False").equals("True")); editor.putBoolean("skipEFBAccess", getConfig("gfx_opengl.ini", "Hacks", "EFBAccessEnable", "False").equals("True")); editor.putBoolean("ignoreFormatChanges", getConfig("gfx_opengl.ini", "Hacks", "EFBEmulateFormatChanges", "False").equals("True")); - editor.putString("stereoscopyMode", getConfig("gfx_opengl.ini", "Enhancements", "StereoMode", "0")); + editor.putString("stereoscopyMode", getConfig("gfx_opengl.ini", "Enhancements", "StereoMode", "0")); editor.putBoolean("stereoSwapEyes", getConfig("gfx_opengl.ini", "Enhancements", "StereoSwapEyes", "False").equals("True")); editor.putString("stereoDepth", getConfig("gfx_opengl.ini", "Enhancements", "StereoDepth", "20")); editor.putString("stereoConvergence", getConfig("gfx_opengl.ini", "Enhancements", "StereoConvergence", "20")); + editor.putBoolean("enableController1", getConfig("Dolphin.ini", "Settings", "SIDevice0", "6") == "6"); + editor.putBoolean("enableController2", getConfig("Dolphin.ini", "Settings", "SIDevice1", "0") == "6"); + editor.putBoolean("enableController3", getConfig("Dolphin.ini", "Settings", "SIDevice2", "0") == "6"); + editor.putBoolean("enableController4", getConfig("Dolphin.ini", "Settings", "SIDevice3", "0") == "6"); String efbCopyOn = getConfig("gfx_opengl.ini", "Hacks", "EFBCopyEnable", "True"); String efbToTexture = getConfig("gfx_opengl.ini", "Hacks", "EFBToTextureEnable", "True"); @@ -106,7 +109,6 @@ public final class UserPreferences editor.putString("externalFrameBuffer", "Real"); } - editor.putBoolean("disableDestinationAlpha", getConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", "False").equals("True")); editor.putBoolean("fastDepthCalculation", getConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", "True").equals("True")); editor.putString("aspectRatio", getConfig("gfx_opengl.ini", "Settings", "AspectRatio", "0")); @@ -135,9 +137,6 @@ public final class UserPreferences // Current CPU core being used. Falls back to interpreter upon error. String currentEmuCore = prefs.getString("cpuCorePref", "0"); - // Fastmem JIT core usage - boolean isUsingFastmem = prefs.getBoolean("fastmemPref", false); - // Current video backend being used. Falls back to software rendering upon error. String currentVideoBackend = prefs.getString("gpuPref", "Software Rendering"); @@ -162,9 +161,6 @@ public final class UserPreferences // External frame buffer emulation. Falls back to disabled upon error. String externalFrameBuffer = prefs.getString("externalFrameBuffer", "Disabled"); - // Whether or not to disable destination alpha. - boolean disableDstAlphaPass = prefs.getBoolean("disableDestinationAlpha", false); - // Whether or not to use fast depth calculation. boolean useFastDepthCalc = prefs.getBoolean("fastDepthCalculation", true); @@ -207,10 +203,16 @@ public final class UserPreferences // Stereoscopy convergence String stereoscopyConvergence = prefs.getString("stereoConvergence", "20"); + // Controllers + // Controller 1 never gets disconnected due to touch screen + //boolean enableController1 = prefs.getBoolean("enableController1", true); + boolean enableController2 = prefs.getBoolean("enableController2", false); + boolean enableController3 = prefs.getBoolean("enableController3", false); + boolean enableController4 = prefs.getBoolean("enableController4", false); + // CPU related Settings NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUCore", currentEmuCore); NativeLibrary.SetConfig("Dolphin.ini", "Core", "CPUThread", isUsingDualCore ? "True" : "False"); - NativeLibrary.SetConfig("Dolphin.ini", "Core", "Fastmem", isUsingFastmem ? "True" : "False"); // General Video Settings NativeLibrary.SetConfig("Dolphin.ini", "Core", "GFXBackend", currentVideoBackend); @@ -264,7 +266,6 @@ public final class UserPreferences NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "UseRealXFB", "True"); } - NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "DstAlphaPass", disableDstAlphaPass ? "True" : "False"); NativeLibrary.SetConfig("gfx_opengl.ini", "Settings", "FastDepthCalc", useFastDepthCalc ? "True" : "False"); //-- Enhancement Settings --// @@ -280,5 +281,9 @@ public final class UserPreferences NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoSwapEyes", stereoscopyEyeSwap ? "True" : "False"); NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoDepth", stereoscopySeparation); NativeLibrary.SetConfig("gfx_opengl.ini", "Enhancements", "StereoConvergence", stereoscopyConvergence); + NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice0", "6"); + NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice1", enableController2 ? "6" : "0"); + NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice2", enableController3 ? "6" : "0"); + NativeLibrary.SetConfig("Dolphin.ini", "Settings", "SIDevice3", enableController4 ? "6" : "0"); } } diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java new file mode 100644 index 0000000000..d27a671c2f --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvGameViewHolder.java @@ -0,0 +1,39 @@ +package org.dolphinemu.dolphinemu.viewholders; + +import android.support.v17.leanback.widget.ImageCardView; +import android.support.v17.leanback.widget.Presenter; +import android.view.View; +import android.widget.ImageView; + +/** + * A simple class that stores references to views so that the GameAdapter doesn't need to + * keep calling findViewById(), which is expensive. + */ +public final class TvGameViewHolder extends Presenter.ViewHolder +{ + public ImageCardView cardParent; + + public ImageView imageScreenshot; + + public String gameId; + + // TODO Not need any of this stuff. Currently only the properties dialog needs it. + public String path; + public String title; + public String description; + public int country; + public String company; + public String screenshotPath; + + public int backgroundColor; + + public TvGameViewHolder(View itemView) + { + super(itemView); + + itemView.setTag(this); + + cardParent = (ImageCardView) itemView; + imageScreenshot = cardParent.getMainImageView(); + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java new file mode 100644 index 0000000000..3264e93f5b --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/viewholders/TvSettingsViewHolder.java @@ -0,0 +1,23 @@ +package org.dolphinemu.dolphinemu.viewholders; + + +import android.support.v17.leanback.widget.ImageCardView; +import android.support.v17.leanback.widget.Presenter; +import android.view.View; + +public final class TvSettingsViewHolder extends Presenter.ViewHolder +{ + public ImageCardView cardParent; + + // Determines what action to take when this item is clicked. + public int itemId; + + public TvSettingsViewHolder(View itemView) + { + super(itemView); + + itemView.setTag(this); + + cardParent = (ImageCardView) itemView; + } +} diff --git a/Source/Android/app/src/main/res/animator/menu_slide_in.xml b/Source/Android/app/src/main/res/animator/menu_slide_in.xml new file mode 100644 index 0000000000..e6f9ae6d8e --- /dev/null +++ b/Source/Android/app/src/main/res/animator/menu_slide_in.xml @@ -0,0 +1,17 @@ + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/animator/menu_slide_out.xml b/Source/Android/app/src/main/res/animator/menu_slide_out.xml new file mode 100644 index 0000000000..85c2556e48 --- /dev/null +++ b/Source/Android/app/src/main/res/animator/menu_slide_out.xml @@ -0,0 +1,18 @@ + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/drawable/ic_add_tv.png b/Source/Android/app/src/main/res/drawable/ic_add_tv.png new file mode 100644 index 0000000000..7332c75727 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable/ic_add_tv.png differ diff --git a/Source/Android/app/src/main/res/drawable/ic_refresh_tv.png b/Source/Android/app/src/main/res/drawable/ic_refresh_tv.png new file mode 100644 index 0000000000..8bae5d34ab Binary files /dev/null and b/Source/Android/app/src/main/res/drawable/ic_refresh_tv.png differ diff --git a/Source/Android/app/src/main/res/drawable/ic_settings_tv.png b/Source/Android/app/src/main/res/drawable/ic_settings_tv.png new file mode 100644 index 0000000000..9e242e7748 Binary files /dev/null and b/Source/Android/app/src/main/res/drawable/ic_settings_tv.png differ diff --git a/Source/Android/app/src/main/res/layout-television/activity_emulation.xml b/Source/Android/app/src/main/res/layout-television/activity_emulation.xml new file mode 100644 index 0000000000..06fe747c39 --- /dev/null +++ b/Source/Android/app/src/main/res/layout-television/activity_emulation.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml b/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml new file mode 100644 index 0000000000..787de65186 --- /dev/null +++ b/Source/Android/app/src/main/res/layout-television/fragment_emulation.xml @@ -0,0 +1,14 @@ + + + + + diff --git a/Source/Android/app/src/main/res/layout/activity_emulation.xml b/Source/Android/app/src/main/res/layout/activity_emulation.xml index 63ea99ba83..9e4e84e151 100644 --- a/Source/Android/app/src/main/res/layout/activity_emulation.xml +++ b/Source/Android/app/src/main/res/layout/activity_emulation.xml @@ -1,5 +1,19 @@ + android:id="@+id/frame_content" + > + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout/activity_main.xml b/Source/Android/app/src/main/res/layout/activity_main.xml index 53d4de6e72..845ff24b45 100644 --- a/Source/Android/app/src/main/res/layout/activity_main.xml +++ b/Source/Android/app/src/main/res/layout/activity_main.xml @@ -3,8 +3,7 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/coordinator_main" android:layout_width="match_parent" - android:layout_height="match_parent" - android:fitsSystemWindows="true"> + android:layout_height="match_parent"> + + + + + \ No newline at end of file diff --git a/Source/Android/app/src/main/res/layout/card_game.xml b/Source/Android/app/src/main/res/layout/card_game.xml index b18bc9e7ee..542969ebd6 100644 --- a/Source/Android/app/src/main/res/layout/card_game.xml +++ b/Source/Android/app/src/main/res/layout/card_game.xml @@ -20,7 +20,7 @@ android:id="@+id/image_game_screen" android:layout_width="match_parent" android:layout_height="0dp" - android:transitionName="image_game_screen" + android:transitionName="image_game_screenshot" android:layout_weight="1" tools:src="@drawable/placeholder_screenshot" tools:scaleType="centerCrop"/> @@ -33,7 +33,6 @@ android:layout_marginLeft="16dp" android:layout_marginRight="16dp" android:layout_marginTop="16dp" - android:layout_toStartOf="@+id/button_details" android:ellipsize="end" android:lines="1" android:maxLines="1" diff --git a/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml new file mode 100644 index 0000000000..44093dc324 --- /dev/null +++ b/Source/Android/app/src/main/res/layout/fragment_ingame_menu.xml @@ -0,0 +1,69 @@ + + + + + + + + + +